text:
# HTTP Protocol Binding for CloudEvents - Version 1.0.3-wip

## Abstract

The HTTP Protocol Binding for CloudEvents defines how events are mapped to HTTP
1.1 request and response messages.

## Table of Contents

1. [Introduction](#1-introduction)

- 1.1. [Conformance](#11-conformance)
- 1.2. [Relation to HTTP](#12-relation-to-http)
- 1.3. [Content Modes](#13-content-modes)
- 1.4. [Event Formats](#14-event-formats)
- 1.5. [Security](#15-security)

2. [Use of CloudEvents Attributes](#2-use-of-cloudevents-attributes)

- 2.1. [datacontenttype Attribute](#21-datacontenttype-attribute)
- 2.2. [data](#22-data)

3. [HTTP Message Mapping](#3-http-message-mapping)

- 3.1. [Binary Content Mode](#31-binary-content-mode)
- 3.2. [Structured Content Mode](#32-structured-content-mode)
- 3.3. [Batched Content Mode](#33-batched-content-mode)

4. [References](#4-references)

## 1. Introduction

[CloudEvents][ce] is a standardized and protocol-agnostic definition of the
structure and metadata description of events. This specification defines how the
elements defined in the CloudEvents specification are to be used in [HTTP
1.1][rfc7230] requests and response messages.

### 1.1. Conformance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in [RFC2119][rfc2119].

### 1.2. Relation to HTTP

This specification does not prescribe rules constraining the use or handling of
specific [HTTP methods][rfc7231-section-4], and it also does not constrain the
[HTTP target resource][rfc7230-section-5-1] that is used for transferring or
soliciting events.

Events can be transferred with all standard or application-defined HTTP request
methods that support payload body transfers. Events can be also be transferred
in HTTP responses and with all HTTP status codes that permit payload body
transfers.

All examples herein that show HTTP methods, HTTP target URIs, and HTTP status
codes are non-normative illustrations.

This specification also applies equivalently to HTTP/2 ([RFC7540][rfc7540]),
which is compatible with HTTP 1.1 semantics.

### 1.3. Content Modes

The CloudEvents specification defines three content modes for transferring
events: _structured_, _binary_ and _batch_. The HTTP protocol binding supports
all three content modes. Every compliant implementation SHOULD
support both structured and binary modes.

In the _binary_ content mode, the value of the event `data` is placed into the
HTTP request, or response, body as-is, with the `datacontenttype` attribute
value declaring its media type in the HTTP `Content-Type` header; all other
event attributes are mapped to HTTP headers.

In the _structured_ content mode, event metadata attributes and event data are
placed into the HTTP request or response body using an
[event format](#14-event-formats) that supports
[structured-mode messages][ce-message].

In the _batched_ content mode, event metadata attributes and event data of
multiple events are batched into a single HTTP request or response body using
an [event format](#14-event-formats) that supports batching
[structured-mode messages][ce-message].

### 1.4. Event Formats

Event formats, used with the _structured_ content mode, define how an event is
expressed in a particular data format. All implementations of this specification
that support the _structured_ content mode MUST support the non-batching [JSON
event format][json-format], but MAY support any additional, including
proprietary, formats.

Event formats MAY additionally define how a batch of events is expressed. Those
can be used with the _batched_ content mode.

### 1.5. Security

This specification does not introduce any new security features for HTTP, or
mandate specific existing features to be used. This specification applies
identically to [HTTP over TLS][rfc2818].

## 2. Use of CloudEvents Attributes

This specification does not further define any of the core [CloudEvents][ce]
event attributes.

This mapping is intentionally robust against changes, including the addition and
removal of event attributes, and also accommodates vendor extensions to the
event metadata.

### 2.1. datacontenttype Attribute

The `datacontenttype` attribute is assumed to contain a [RFC2046][rfc2046]
compliant media-type expression.

### 2.2. data

`data` is assumed to contain opaque application data that is encoded as declared
by the `datacontenttype` attribute.

An application is free to hold the information in any in-memory representation
of its choosing, but as the value is transposed into HTTP as defined in this
specification, the assumption is that the `data` value is made available as a
sequence of bytes.

For instance, if the declared `datacontenttype` is
`application/json;charset=utf-8`, the expectation is that the `data` value is
made available as [UTF-8][rfc3629] encoded JSON text to HTTP.

## 3. HTTP Message Mapping

The event binding is identical for both HTTP request and response messages.

The content mode is chosen by the sender of the event, which is either the
requesting or the responding party. Gestures that might allow solicitation of
events using a particular mode might be defined by an application, but are not
defined here. The _batched_ mode MUST NOT be used unless solicited, and the
gesture SHOULD allow the receiver to choose the maximum size of a batch.

The receiver of the event can distinguish between the three modes by inspecting
the `Content-Type` header value. If the value is prefixed with the CloudEvents
media type `application/cloudevents`, indicating the use of a known
[event format](#14-event-formats), the receiver uses _structured_ mode. If the
value is prefixed with `application/cloudevents-batch`, the receiver uses the
_batched_ mode. Otherwise it defaults to _binary_ mode.

If a receiver detects the CloudEvents media type, but with an event format that
it cannot handle, for instance `application/cloudevents+avro`, it MAY still
treat the event as binary and forward it to another party as-is.

When the `Content-Type` header value is not prefixed with the CloudEvents media
type, knowing when the message ought to be parsed as a CloudEvent can be a
challenge. While this specification can not mandate that senders do not include
any of the CloudEvents HTTP headers when the message is not a CloudEvent, it
would be reasonable for a receiver to assume that if the message has all of the
mandatory CloudEvents attributes as HTTP headers then it's probably a
CloudEvent. However, as with all CloudEvent messages, if it does not adhere to
all of the normative language of this specification then it is not a valid
CloudEvent.

### 3.1. Binary Content Mode

The _binary_ content mode accommodates any shape of event data, and allows for
efficient transfer and without transcoding effort.

#### 3.1.1. HTTP Content-Type

For the _binary_ mode, the HTTP `Content-Type` header value corresponds to
(MUST be populated from or written to) the CloudEvents `datacontenttype`
attribute. Note that a `ce-datacontenttype` HTTP header MUST NOT also be
present in the message.

#### 3.1.2. Event Data Encoding

The [`data`](#22-data) byte-sequence is used as the HTTP message body.

#### 3.1.3. Metadata Headers

All other [CloudEvents][ce] attributes, including extensions, MUST be
individually mapped to and from distinct HTTP message header.

CloudEvents extensions that define their own attributes MAY define a secondary
mapping to HTTP headers for those attributes, especially if specific attributes
need to align with HTTP features or with other specifications that have explicit
HTTP header bindings. Note that these attributes MUST also still appear in the
HTTP message as HTTP headers with the `ce-` prefix as noted in
[HTTP Header Names](#3131-http-header-names).

##### <IP_ADDRESS>. HTTP Header Names

Except where noted, all CloudEvents context attributes, including extensions,
MUST be mapped to HTTP headers with the same name as the attribute name but
prefixed with `ce-`.

Examples:

    * `time` maps to `ce-time`
    * `id` maps to `ce-id`
    * `specversion` maps to `ce-specversion`

Note: per the [HTTP](https://tools.ietf.org/html/rfc7230#section-3.2)
specification, header names are case-insensitive.

##### <IP_ADDRESS>. HTTP Header Values

The value for each HTTP header is constructed from the respective attribute
type's [canonical string representation][ce-types].

Some CloudEvents metadata attributes can contain arbitrary UTF-8 string content,
and per [RFC7230, section 3][rfc7230-section-3], HTTP headers MUST only use
printable characters from the US-ASCII character set, and are terminated by a
CRLF sequence with OPTIONAL whitespace around the header value.

When encoding a CloudEvent as an HTTP message, string values
represented as HTTP header values MUST be percent-encoded as
described below. This is compatible with [RFC3986, section
2.1][rfc3986-section-2-1] but is more specific about what needs
encoding. The resulting string SHOULD NOT be further encoded.
(Rationale: quoted string escaping is unnecessary when every space
and double-quote character is already percent-encoded.)

When decoding an HTTP message into a CloudEvent, any HTTP header
value MUST first be unescaped with respect to double-quoted strings,
as described in [RFC7230, section 3.2.6][rfc7230-section-3-2-6]. A single
round of percent-decoding MUST then be performed as described
below. HTTP headers for CloudEvent attribute values do not support
parenthetical comments, so the initial unescaping only needs to handle
double-quoted values, including processing backslash escapes within
double-quoted values. Header values produced via the
percent-encoding described here will never include double-quoted
values, but they MUST be supported when receiving events, for
compatibility with older versions of this specification which did
not require double-quote and space characters to be percent-encoded.

Percent encoding is performed by considering each Unicode character
within the attribute's canonical string representation. Any
character represented in memory as a [Unicode surrogate
pair][surrogate-pair] MUST be treated as a single Unicode character.
The following characters MUST be percent-encoded:

- Space (U+0020)
- Double-quote (U+0022)
- Percent (U+0025)
- Any characters outside the printable ASCII range of U+0021-U+007E
  inclusive

Attribute values are already constrained to prohibit characters in
the range U+0000-U+001F inclusive and U+007F-U+009F inclusive;
however for simplicity and to account for potential future changes,
it is RECOMMENDED that any HTTP header encoding implementation treats
such characters as requiring percent-encoding.

Space and double-quote are encoded to avoid requiring any further
quoting. Percent is encoded to avoid ambiguity with percent-encoding
itself.

Steps to encode a Unicode character:

- Encode the character using UTF-8, to obtain a byte sequence.
- Encode each byte within the sequence as `%xy` where `x` is a
  hexadecimal representation of the most significant 4 bits of the byte,
  and `y` is a hexadecimal representation of the least significant 4
  bits of the byte.

Percent-encoding SHOULD be performed using upper-case for values A-F,
but decoding MUST accept lower-case values.

When performing percent-decoding (when decoding an HTTP message to a
CloudEvent), values that have been unncessarily percent-encoded MUST be
accepted, but encoded byte sequences which are invalid in UTF-8 MUST be
rejected. (For example, "%C0%A0" is an overlong encoding of U+0020, and
MUST be rejected.)

Example: a header value of "Euro € 😀" SHOULD be encoded as follows:

- The characters, 'E', 'u', 'r', 'o' do not require encoding
- Space, the Euro symbol, and the grinning face emoji require encoding.
  They are characters U+0020, U+20AC and U+1F600 respectively.
- The encoded HTTP header value is therefore "Euro%20%E2%82%AC%20%F0%9F%98%80"
  where "%20" is the encoded form of space, "%E2%82%AC" is the encoded form
  of the Euro symbol, and "%F0%9F%98%80" is the encoded form of the
  grinning face emoji.

#### 3.1.4. Examples

This example shows the _binary_ mode mapping of an event with an HTTP POST
request:

```text
POST /someresource HTTP/1.1
Host: webhook.example.com
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}
```

This example shows a response containing an event:

```text
HTTP/1.1 200 OK
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}
```

### 3.2. Structured Content Mode

The _structured_ content mode keeps event metadata and data together in the
payload, allowing simple forwarding of the same event across multiple routing
hops, and across multiple protocols.

#### 3.2.1. HTTP Content-Type

The [HTTP `Content-Type`][content-type] header MUST be set to the media type of
an [event format](#14-event-formats).

Example for the [JSON format][json-format]:

```text
Content-Type: application/cloudevents+json; charset=UTF-8
```

#### 3.2.2. Event Data Encoding

The chosen [event format](#14-event-formats) defines how all attributes, and
`data`, are represented.

The event metadata and data is then rendered in accordance with the event format
specification and the resulting data becomes the HTTP message body.

#### 3.2.3. Metadata Headers

Implementations MAY include the same HTTP headers as defined for the
[binary mode](#313-metadata-headers).

All CloudEvents metadata attributes MUST be mapped into the payload, even if
they are also mapped into HTTP headers.

#### 3.2.4. Examples

This example shows a JSON event format encoded event, sent with a PUT request:

```text

PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

```

This example shows a JSON encoded event returned in a response:

```text

HTTP/1.1 200 OK
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

```

### 3.3. Batched Content Mode

In the _batched_ content mode several events are batched into a single HTTP
request or response body. The chosen [event format](#14-event-formats) MUST
define how a batch is represented, including a suitable media type.

#### 3.3.1. HTTP Content-Type

The [HTTP `Content-Type`][content-type] header MUST be set to the media type of
the batch mode for the [event format](#14-event-formats).

Example for the [JSON Batch format][json-batch-format]:

```text
Content-Type: application/cloudevents-batch+json; charset=UTF-8
```

#### 3.3.2. Event Data Encoding

The chosen [event format](#14-event-formats) defines how a batch of events and
all event attributes, and `data`, are represented.

The batch of events is then rendered in accordance with the event format
specification and the resulting data becomes the HTTP message body.

#### 3.3.3. Examples

This example shows two batched CloudEvents, sent with a PUT request:

```text

PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]

```

This example shows two batched CloudEvents returned in a response:

```text

HTTP/1.1 200 OK
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]

```

## 4. References

- [RFC2046][rfc2046] Multipurpose Internet Mail Extensions (MIME) Part Two:
  Media Types
- [RFC2119][rfc2119] Key words for use in RFCs to Indicate Requirement Levels
- [RFC2818][rfc2818] HTTP over TLS
- [RFC3629][rfc3629] UTF-8, a transformation format of ISO 10646
- [RFC3986][rfc3986] Uniform Resource Identifier (URI): Generic Syntax
- [RFC4627][rfc4627] The application/json Media Type for JavaScript Object
  Notation (JSON)
- [RFC4648][rfc4648] The Base16, Base32, and Base64 Data Encodings
- [RFC6839][rfc6839] Additional Media Type Structured Syntax Suffixes
- [RFC7159][rfc7159] The JavaScript Object Notation (JSON) Data Interchange
  Format
- [RFC7230][rfc7230] Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and
  Routing
- [RFC7231][rfc7231] Hypertext Transfer Protocol (HTTP/1.1): Semantics and
  Content
- [RFC7540][rfc7540] Hypertext Transfer Protocol Version 2 (HTTP/2)

[ce]: ../spec.md
[ce-message]: ../spec.md#message
[ce-types]: ../spec.md#type-system
[json-format]: ../formats/json-format.md
[json-batch-format]: ../formats/json-format.md#4-json-batch-format
[content-type]: https://tools.ietf.org/html/rfc7231#section-<IP_ADDRESS>
[json-value]: https://tools.ietf.org/html/rfc7159#section-3
[json-array]: https://tools.ietf.org/html/rfc7159#section-5
[rfc2046]: https://tools.ietf.org/html/rfc2046
[rfc2119]: https://tools.ietf.org/html/rfc2119
[rfc2818]: https://tools.ietf.org/html/rfc2818
[rfc3629]: https://tools.ietf.org/html/rfc3629
[rfc3986]: https://tools.ietf.org/html/rfc3986
[rfc3986-section-2-1]: https://tools.ietf.org/html/rfc3986#section-2.1
[rfc4627]: https://tools.ietf.org/html/rfc4627
[rfc4648]: https://tools.ietf.org/html/rfc4648
[rfc6839]: https://tools.ietf.org/html/rfc6839#section-3.1
[rfc7159]: https://tools.ietf.org/html/rfc7159
[rfc7230]: https://tools.ietf.org/html/rfc7230
[rfc7230-section-3]: https://tools.ietf.org/html/rfc7230#section-3
[rfc7230-section-3-2-6]: https://tools.ietf.org/html/rfc7230#section-3.2.6
[rfc7230-section-5-1]: https://tools.ietf.org/html/rfc7230#section-5.1
[rfc7231]: https://tools.ietf.org/html/rfc7231
[rfc7231-section-4]: https://tools.ietf.org/html/rfc7231#section-4
[rfc7540]: https://tools.ietf.org/html/rfc7540
[surrogate-pair]: http://unicode.org/glossary/#surrogate_pair

repository: cloudevents/spec

repo_name: cloudevents/spec


text:
---
layout: post
title: Reducer
feature-img: "assets/img/portfolio/cabin.png"
img: "assets/img/portfolio/cabin.png"
tags: [project 1, technical proficiency]
date: 2019-08-07
color: brown
---

Reducers is a functionality to manage the state changes. It is high level than original state of React. The Reducer function will accepts two parameter. One for state data and other for user action which is what sort of operations user do. I just try this for a sample, but it was kind of useful. Just list code below:

#### Description:
* state is state I define inside of main component, in here just to store a number to count.
* action is a user operation which are click button either increment or decrement in this case.
* action has second parameter which called payload just to pass a value that what I want to change.

```javascript
// import useReducer
import React, { useReducer } from 'react';

// define reducer function outside the component
const reducer = (state, action) => {
    // state === { count: number }
    // action === { type: 'increment' || 'decrement, payload: 1 }
    switch (action.type) {
        case 'increment':
            return { ...state, count: state.count + action.payload };
            break;
        case 'decrement':
            return { ...state, count: state.count - action.payload };
            break;
        default:
            return state;
            break;
    }
}

// component
const CounterScreen = () => {
    // define useReducer state, default value by 0, and ref reducer function we have define above
    const [state, dispatch] = useReducer(reducer, { count: 0 });
    return (
        <View>
            <Button
                title="Increease"
                // use dispatch methode to call reducer, pass the type of action and the value of action with two parameter
                onPress={() => {
                    dispatch({ type: 'increment', payload: 1 });
                }}>
            </Button>
            <Button
                title="Decreease"
                onPress={() => {
                    dispatch({ type: 'decrement', payload: 1 });
                }}
            ></Button>
            // output the state.count value just like use normal state
            <Text>Current Count: {state.count}</Text>
        </View>
    )
};
```

license: MIT

repository: aemooooon/Project-Portfolio

branch_name: refs/heads/master

extension: md

gha_language: HTML

gha_license_id: MIT

license_type: permissive

repo_name: aemooooon/Project-Portfolio


text:
# HBP Collaboratory demo app
The following example is a very simple web application that iteracts with some of the Collaboratory APIs. The goal is to show how to integrate it into the Collaboratory as an app.
Consider it as the Hello World of a Collaboratory app.

## Requirements
* python (to run a HTTPS server locally)

## Project Structure
| File | Description |
| ---- | ----------- |
| index.html | The main HTML page |
| app.js | The application code |
| lib/hello.js | JavaScript SDK for authenticating with OAuth2 |
| lib/hbp.hello.js | hello.js module to authenticate with your HBP account [Read more](https://github.com/HumanBrainProject/hbp.hello.js)|
| lib/jquery.js | The popular javascript framework |
| lib/hbp-collaboratory-theme.css | The Collaboratory CSS theme. This theme is based on Twitter Bootstrap. Using it ensures a consistent look and feel with the Collaboratory. [Read more](https://github.com/HumanBrainProject/hbp-collaboratory-theme) |
| fonts/ | Contains fonts required by the theme stylesheet |
| runserver | A Python script to run a local https server |

## Description
This app doesn't do much: it authenticates the user and uses the HBP REST apis to fetch the user profile info and info about the collab where it is running.

## How to run it
To make this example work as a Collaboratory application, you need to:

### Create an Oauth2 client
Go to the [OpenID Connect Client Manager](
https://collab.humanbrainproject.eu/#/collab/54/nav/1051) and register a new client as follows:
* Application type: `Implicit flow`
* Redirect URL: `https://localhost:4443`
* Scopes: check `hbp.collab`

### modify the code to use your client ID
in app.js, look for the string YOUR_CLIENT_ID and replace it by the the one generated in the previous step.

### make the application accessible through HTTPS
For testing purpose ONLY, you can run a local https server as follows:

`$ . ./runserver`

During the first launch, it will generate a local https certificate. Before going to the next step, ensure your computer trust your self-signed certificate; otherwise the webpage will not be display.

Your page will be available at the URL: [https://localhost:4443/](https://localhost:4443/)

### Register the application in the Collaboratory
To make your application accessible in the Collaboratory, you need to be able to add it to a Collab navigation. To do so, it is necessary to register your application using the Apps Manager page in the How to develop apps Collab.

* Click the _Register App_ button
* Enter your application _title_ and _description_
* Enter the _main URL_ for your application, which is the URL obtained in the previous step
* Use `Prototype` as _category_
* Ensure the _visibility_ of the app is private because you don’t want everybody to use your example application.
* Hit the _save_ button.

### Create a new Navigation Item using this application¶
You can now navigate to one of your collab and create a new instance of your application. When you access your application instance for the first time, you should see the authorization page. Once approved, a page with a single button will be displayed. Once the user hits the button, the collab title, description and the raw result of the query should be displayed as well.

## What’s Next
You did the quick tour, now is the time to start developing your own application using your preferred web stack.
Here you can find more documentation here:
https://collab.humanbrainproject.eu/#/collab/54


text:
For Ubuntu users, see this link first:

   https://github.com/edincoin/EDINARCOIN/wiki/build-ubuntu

Windows:

   https://github.com/edincoin/EDINARCOIN/wiki/BUILD_WIN32

OS X:

   https://github.com/edincoin/EDINARCOIN/wiki/Building-on-OS-X

and then proceed with:

    git clone https://github.com/edincoin/EDINARCOIN.git
    cd EDINARCOIN
    git submodule update --init --recursive
    cmake .
    make
    programs/witness_node/witness_node --data-dir=data/witness --seed-node=<IP_ADDRESS>:5908 --rpc-endpoint=<IP_ADDRESS>:8899 --genesis-json=genesis.json

Then, in a separate terminal window, start the command-line wallet `cli_wallet`:

    programs/cli_wallet/cli_wallet --server-rpc-endpoint=ws://<IP_ADDRESS>:8899

To set password:

    >>> set_password password
    >>> unlock password

To import your key:

    >>> import_key your_account_name your_private_key true
To import your initial balance:

    >>> import_balance your_account_name [your_private_key] true

If you send private keys over this connection, `rpc-endpoint` should be bound to localhost for security.

A list of CLI wallet commands is available here:

   https://github.com/edincoin/EDINARCOIN/blob/master/libraries/wallet/include/graphene/wallet/wallet.hpp

Information about delayed_node is availiable here:

   https://github.com/edincoin/EDINARCOIN/wiki/Delayed%20node

repository: reactivespace/Dex

repo_name: reactivespace/Dex


text:
WordACross
==========

Whats this?

I had an idea for an Android word game called Word A Cross.  When you release, the word is automatically detected from
a dictionary and converted into points and more word blocks fall from above.

Will it work anymore? I don't know because I gave my last Android phone to our corporate tester and the Android
emulator is too painful to load.

I built it off the old Android Cocoas2D Open GL gaming library and then wrapped that with my own custom
model view controller framework. I used a modified MVC framework concept I had seen used in a large Flex 4
app I was working on to wire the views (activities), controllers and models in an eventful manner.

SQLite was way too slow and heavy for the dictionary, had to serialize it into a flat file.

repository: rexstjohn/WordACross

repo_name: rexstjohn/WordACross


text:
# PayID

## Specs

You can find the specs here: https://github.com/payid-org/rfcs/tree/master/dist/spec

- [PayID Whitepaper](https://payid.org/whitepaper.pdf)
- [The 'payid' URI Scheme](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-uri.txt)
- [PayID Discovery](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-discovery.txt)
- [PayID Protocol](https://github.com/payid-org/rfcs/blob/master/dist/spec/payid-protocol.txt)
- [Verifiable PayID Protocol](https://github.com/payid-org/rfcs/blob/master/dist/spec/verifiable-payid-protocol.txt)

The source code for each spec is in [src/spec](https://github.com/payid-org/rfcs/tree/master/src/spec).

## Implementations

Known implementations of PayID and PayID Discovery:

- JavaScript: TBD.
- Java: TBD.
- Swift: TBD.

If you would like to update this list, please feel free to open a pull request against this repository.

## Generating the Spec

Uses [kramdown-rfc2629](https://github.com/cabo/kramdown-rfc2629/), [xml2rfc](http://xml2rfc.ietf.org/) and [Grunt](http://gruntjs.com/) with [Grunt kramdown_rfc2629 task](https://github.com/hildjj/grunt-kramdown-rfc2629/)

From root directory of the repo run:

```sh
    # IETF RFC tools
    gem install kramdown-rfc2629
    pip3 install xml2rfc

    # PayID RFC dependencies
    npm install
    grunt kramdown_rfc2629
```

To watch edits to `payid-uri.md` or `payid-discovery.md` and auto-generate output when changes are saved run:

    grunt watch

repository: jscottbranson/rfcs

repo_name: jscottbranson/rfcs


text:
# Challenge Summary
<!-- Description of the challenge -->
Write a breadth first traversal method which takes a Binary Tree as its unique input.
## Whiteboard Process
<!-- Embedded whiteboard image -->
![](../../img/breadth_first.jpg)
## Approach & Efficiency
<!-- What approach did you take? Why?  Show how to run your code, and examples of it in action -->
  node1.left = TNode(7)
  node1.left.right = TNode(6)
  node1.left.right.left = TNode(5)
  node1.left.right.right = TNode(11)
  node1.left.left = TNode(2)
  node1.right = TNode(5)
  node1.right.right = TNode(9)
  node1.right.right.left = TNode(4)
  binary_tree = Binary_tree(node1)

  result = [2, 7, 5, 2, 6, 9, 5, 11, 4]

branch_name: refs/heads/main

gha_language: JavaScript


text:
# Vide

[![Docker Build](https://img.shields.io/docker/cloud/build/mastertinner/vide.svg?style=flat-square)](https://hub.docker.com/r/mastertinner/vide)
![Docker Pulls](https://img.shields.io/docker/pulls/mastertinner/vide.svg?style=flat-square)

A containerized IDE powered by [NeoVim](https://neovim.io/).

This container is filled with all the good stuff from [my Vim config](https://github.com/mastertinner/dotfiles/). It contains a full "IDE" and is optimized for editing [Go](https://golang.org), [Rust](https://www.rust-lang.org), [JavaScript](https://en.wikipedia.org/wiki/JavaScript), [TypeScript](https://www.typescriptlang.org), [Markdown](https://en.wikipedia.org/wiki/Markdown) and [shell scripts](https://en.wikipedia.org/wiki/Shell_script).

## Usage

By default, the container-internal `/src` directory will be opened. You'll therefore have to mount your project into there:

```shell
$ docker run --rm -it -v "${PWD}:/src" mastertinner/vide
```

The container comes with most supported programming languages and tools preinstalled so you can run `:terminal` to run commands.

## Caveats

### Docker Detach keys

`ctrl + p` triggers a fuzzy search for files. Since this key binding is already used in Docker for detaching from containers, you'll have to press it twice to trigger the fuzzy search. To mitigate this, simply add the following line to your `~/.docker.config.json` to change the default keys:

```json
  "detachKeys": "ctrl-e,e"
```

### Resources

Some async jobs like linting JavaScript can be rather resource intensive. If the containers feels slow, consider giving Docker more memory ;-)

repository: AlexRogalskiy/vide

repo_name: AlexRogalskiy/vide


text:
---
title: Internals
subtitle:
tags: []
author: greenknot
layout: doc_sp
---

#### Sections in this article
{:.no_toc}
* TOC
{:toc}

## Introduction

The emulator is actually a userland application cross-compiled for the ARM
architecture. It opens the target app (`app.elf`) from the filesystem and maps
it as is in memory. The emulator is launched with `qemu-arm-static` and
eventually jumps to the app entrypoint.

Apps can be debugged with `gdb-multiarch` thanks to `qemu-arm-static`.

## Syscall hooks

The `svc` instruction is replaced with `udf` (undefined) to generate a `SIGILL`
signal upon execution. It allows to catch syscalls and emulate them. It can
unfortunately lead to unexpected bytes being patched if `\x01\xdf` is found in
the binary (and isn't the `svc` instruction).

A disassembler could give better results, but it doesn't look worth it. As a
side note, the `SVC_Call()` function can't be hooked because some syscalls are
inlined.

Other alternatives were considered (for instance `seccomp` or `ptrace`) but they
seem not practicable because QEMU don't support the
[associated syscalls](https://github.com/qemu/qemu/blob/1c4c6fcd1a2ae56e98be3a441e19a0933c508a51/linux-user/syscall.c#L7402).


text:
# Targeted Attacks and Defenses in Federated Learning

Note: This directory is a work-in-progress.

## Overview

This directory contains source code for
[TFF](https://www.tensorflow.org/federated) implementation of targeted attacks
and defenses considered in
[Can You Really Back door Federated Learning?](https://arxiv.org/abs/1911.07963)
The TFF implementation of basic federated learning is based on
[Simple_Fedavg](https://github.com/tensorflow/federated/blob/main/tensorflow_federated/examples/simple_fedavg).
The attack model we are considering is primarily based on the model replacement
attacks proposed in the following two papers:

*   [Analyzing Federated Learning Through an Adversarial Lens](https://arxiv.org/abs/1811.12470).
*   [How To Back door Federated Learning?](https://arxiv.org/abs/1807.00459)

## Implementation and Sample Script

For implementation of unconstrainted and norm bounded attack, please see
`ClientExplicitBoost` and `ClientProjectBoost` in `attacked_fedavg.py`. For the
implementation of various defenses, please see `aggregate_fn.py`. For a sample
script of how to use the package, please see `emnist_with_targeted_attack.py`.

## Dependencies

*   [tensorboard](https://pypi.org/project/tensorboard/)
*   [SciPY](https://www.scipy.org/)

repository: google-research/federated

gha_language: Python

repo_name: google-research/federated


text:
# scanner for Raspberry Pi

Use [Picamera](https://picamera.readthedocs.io/en/release-1.13/index.html) to capture an image and scan it for any legible barcodes or QR codes using [zbar](https://pypi.python.org/pypi/zbar-py/1.0.4).

Successfully scanning a barcode publishes the encoded information to AWS SNS. It will also illuminate the activity LED (gpio16) on the board.

repository: wbornor/scanner

repo_name: wbornor/scanner


text:
# cfiles

`cfiles` is a terminal file manager with vim like keybindings, written in C using the ncurses
library. It aims to provide an interface like [ranger](https://github.com/ranger/ranger) while being lightweight, fast and
minimal.

![screenshot](cf.png)

## Dependencies
- `ncursesw`
- `cp`and `mv` for copying and moving
- `fzf` for searching
- `w3mimgdisplay` or `Überzug` for image previews
- `mediainfo` for viewing media info and file sizes
- `atool` for archive previews
- `poppler`(specifically `pdftoppm`) for pdf previews

## Compiling and Installation
#### Arch Linux
Arch Linux users can use the [AUR](https://aur.archlinux.org/packages/cfiles) package.

#### macOS
macOS users can use [brew](https://github.com/mananapr/homebrew-cfiles)

#### Others
To compile, run

    make

and then run,

    sudo make install

to install.

## Keybindings
| Key | Function |
|:---:| --- |
| h j k l | Navigation keys |
| G | Go to end |
| g | Go to top |
| H | Go to top of current view |
| M | Go to middle of current view |
| L | Go to bottom of current view |
| f | Search using fzf |
| F | Search using fzf in the present directory |
| S | Open Shell in present directory |
| space | Add/Remove to/from selection list |
| tab | View selection list |
| e | Edit selection list |
| u | Empty selection list |
| y | Copy files from selection list |
| v | Move files from selection list |
| a | Rename Files in selection list |
| dd | Move files from selection list to trash |
| dD | Remove selected files |
| i | View mediainfo and general info |
| I | View preview |
| . | Toggle hidden files |
| b | Toggle borders |
| ' | View/Goto bookmarks |
| m | Add bookmark |
| p | Run external script |
| r | Reload |
| q | Quit |

## Directories Used
`cfiles` uses `$XDG_CACHE_HOME/cfiles` directory to store the clipboard file. This is used so that the clipboard
can be shared between multiple instances of `cfiles`. That's why I won't be adding tabs in `cfiles` because multiple
instances can be openend and managed by any terminal multiplexer or your window manager.
Note that this also means the selection list will persist even if all instances are closed.

`cfiles` also uses `$HOME/.local/share/Trash/files` as the Trash Directory, so make sure this directory exists before you try to delete a file.

For storing bookmarks, `cfiles` uses `$XDG_CACHE_HOME/cfiles/bookmarks` file. Bookmarks are stored in the form `<key>:<path>`. You can either edit this file directly
or press `m` in `cfiles` to add new bookmarks.

`cfiles` looks for external scripts in the `$XDG_CACHE_HOME/cfiles/scripts` directory. Make sure the scripts are executable before moving them to the scripts directory.

If `$XDG_CACHE_HOME` is not set, then `$HOME/.cache` is used.

## Opening Files
You can set `FILE_OPENER` in `config.h` to specify your file opening program. It is set to use `xdg-open` by default but you can change it to anything like `thunar`. macOS users need to set it to `open`.

## Image Previews
You can either go with `w3mimgdisplay` or `Überzug` ([link](https://github.com/seebye/ueberzug)) for image previews.
Each method has it's own pros and cons.

1. **Überzug**

To use `Überzug` for image previews, set `DISPLAYIMG` and `CLEARIMG` in `config.h` to the paths of `displayimg_uberzug` and `clearimg_uberzug` scripts respectively.
  * Pros
    1. Better previews when compared to `w3mimgdisplay`
  * Cons
    1. Can't generate previews for mp3 album arts
    2. Slower scrolling speed when compared to `w3mimgdisplay`
    3. Non functional scrolling with arrow keys

I personally use `Überzug` because I don't scroll too fast in my image directories. If I am looking for a specific file I just use `fzf` to directly go to it.

2. **w3mimgdisplay**

To use `w3mimgdisplay` for image previews, set `DISPLAYIMG` and `CLEARIMG` in `config.h` to the paths of `displayimg` and `clearimg` scripts respectively.
  * Pros
    1. Faster scrolling
    2. Can generate previews of album arts for mp3 files
  * Cons
    1. Previews are very inconsistent and may disappear on resizing the terminal or changing workspaces
    2. You may have to redraw the UI while scrolling by pressing `KEY_RELOAD` (defaults to R)

You may have to modify the scripts a little, about which you can read [here](https://wiki.vifm.info/index.php/How_to_preview_images).

## Why C?
I wanted to improve my C and learn ncurses so I decided this would be an ideal project.

Apart from this, I have always wanted an alternative to ranger that is faster while still having
a similar UI.

## Todo
- [x] Improve Upwards Scrolling
- [x] Show sorted directories before files
- [x] Fix the `G` keybinding
- [x] Add basic operations like deleting, copying etc.
- [x] Add rename functionality
- [x] Add option to show selection list
- [x] Show current progress or status of copying files
- [x] Add functionality to open files
- [x] Add image previews using w3mimgdisplay
- [x] Preserve aspect ratio in image previews
- [x] Add fuzzy file search using fzf
- [x] Find a way to redraw windows after displaying image previews or running fzf
- [x] Find a way to remove cursor after running fzf
- [x] Select the file directly from fzf
- [x] Supress output from xdg-open
- [x] Find a way to remember selection position of parent directory
- [x] Add open in terminal functionality
- [x] Add file previews
- [x] Improve file previews
- [x] Add config file for easy user customizability
- [x] Add more options in config file
- [x] Fix random segfaults
- [x] Show more info in the statusbar
- [x] Add color support
- [x] Add bookmarks
- [x] Add ability to run external scripts
- [x] Remove hardcoded paths
- [x] Use dynamic allocation wherever static arrays are used
- [x] Update README section about Image previews and add about `Uberzug`
- [x] Replace `system()` by safer functions
- [ ] Refactor Code

repository: jeunder/cfiles

repo_name: jeunder/cfiles


text:
# plzw
> Parallel LZW algorithms

## Overview
The Lempel–Ziv–Welch (LZW) is a lossless data compression algorithm capable of exploiting especially the presence of repetitive patterns, in the raw data, and acting a very effective compression.
This repository contains some parallel implementations of the algorithm in order to compare them, their performances and to quantify the requested computational resources to get the best outcome.

## Prerequisites

* [MPICH](https://www.mpich.org/)
* [OpenMP](https://www.openmp.org/)
* [Cuda toolkit](https://developer.nvidia.com/cuda-downloads)

## Get ready on Visual Studio
```sh
$ git clone https://github.com/FedericoBottoni/plzw
```
Open the solution and try to build the projects, if you can't, proceed to the installations and configuration of the dependencies:
* Install MS-MPI and set the environment configurations on the project's propriety [pages](https://docs.microsoft.com/en-us/archive/blogs/windowshpc/how-to-compile-and-run-a-simple-ms-mpi-program)
* Enable the OMP configuration option on the project's propriety [pages](https://docs.microsoft.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support)

## Running
You can run the different projects from the Release folder "plzw\x64\Release\" (or "plzw\Release\" if your system is Win32).
WARNING: This commands are defaults to run 4 processes in parallel implementations.

### Serial
```sh
$ PLZW_Serial.exe
```

### MPI
You can edit the number of processes from CLI, changing "-np 4" in "-np {number}"
```sh
$ mpiexec -np 4 PLZW_MPI.exe
```

### OpenMP
You can edit the number of processes defining DEFAULT_NPROCS
```sh
$ PLZW_OMP.exe
```

### CUDA
Available in CUDA branch, you can edit the grid and blocks sizes defining BLOCKS_GRID and THREADS_A_BLOCK
```sh
$ PLZW_CUDA.exe
```

## Author
**Federico Bottoni** - [github.com/FedericoBottoni](https://github.com/FedericoBottoni)

repository: FedericoBottoni/plzw

repo_name: FedericoBottoni/plzw


text:
# Moonbas3's New Fashioned #

![Moonbas3 New Fashioned](https://i.imgur.com/HqXth1P.jpg)

## Discussion

As a long time fan of the Old Fashioned, I was sitting in a bar in Birmingham one day and ordering them by the score while talking to some friends. One of the bartenders asked me if I had ever heard of a New Fashioned. To which I replied no, but please procure this wonderful new beverage for me. After tasting it, I realized I had found a great complementary drink for lighter non-red meat dishes. I have since made my own amaretto and use that in this recipe, but it is far from required..

Making Old and New Fashioned's is fun for an aspiring amateur bartender. You get to muddle and mix, slice and stir. Something about it incorporates everything that is good in being a mixologist while still preserving the basics.

The only difference between this and a traditional Old Fashioned is the addition of the amaretto. Some people also use 1 tsp of wild flower honey instead of the sugar cube, but I enjoy proper muddling.

## Required Equipment

* Muddler
* Whiskey Glass
* Big Ol' Ice Cubes (optional)

## Ingredients

* 3oz (1 shots) of Wild Roses Bourbon
* 1oz Amaretto
* 2 dashes of Angostura Bitters
* Big Ol' Ice Ball
* Orange Round
* Sugar Cube
* Seltzer Water

## Directions

1. Put sugar cube into whiskey glass, add a splash of seltzer water, and muddle until smooth.
2. Slice the orange round, put it and the big ol' ice ball into the whiskey glass.
3. Add Bourbon, Amaretto and Bitters to the glass.
4. Stir stir stir, and serve.
5. (Optional) Add maraschino cherry.


text:
# Add Multiple Projects To Solution

[![Build Status](https://dev.azure.com/guudan/GithubBuildAndRelease/_apis/build/status/Build%20Vs.AddMultipleProjectsToSolution?branchName=master)](https://dev.azure.com/guudan/GithubBuildAndRelease/_build/latest?definitionId=3&branchName=master)

<!-- Update the VS Gallery link after you upload the VSIX-->

Download this extension from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=MaciejGudanowicz.AddMultipleProjectsToSolution).
<!--
or get the [CI build](http://vsixgallery.com/extension/2ed01419-2b11-4128-a2ca-0adfa0fc7498/).
-->

---------------------------------------

Visual Studio extension that allows adding multiple existing projects into
the solution. Optionally creates the solution folder structure reflecting
to the physical hierarchy on disk.

See the [change log](CHANGELOG.md) for changes and road map.

## Features

- Add mutliple projects to solution.
	- Load projects from given directory (recursive search by file extension).
    - Select which projects to add to the solution.
    - Define if solution folders hierarchy should be also created.

### Add multiple projects to solution
To add existing projects to the solution:
1. Right click the Solution node in Solution Explorer select Add -> Multiple Projects

![Click Add Multiple Command](docs/img/ClickAddMultipleCommand.png)

2. Click Load Projects From Folder

![Click Load From Folder](docs/img/ClickLoadFromFolder.png)

3. Select directory and click Add

![Select Folder For Loading Projects](docs/img/SelectFolderForLoadingProjects.png)

4. Found project will be displayed in the folder hierarchy in which they are defined on disk.
	- Select projects that you want to add to the solution.
    - Define if solution folders should be created.
    - Click Add.

![Select Projects To Add](docs/img/SelectProjectsToAdd.png)

5. Review the structure of projects that will be created and press Start.

![Add Progress Review Configuration](docs/img/AddProgressReviewConfiguration.png)

6. Check results.

The state of the operation is indicated by the icon next to the project.
When you will hover with mause over the icon the details will be displayed.

On the bottom of the window total number of errors and processed projects is displayed.

![Add Progress Review Results](docs/img/AddProgressReviewResults.png)

7. The result of the operation.

If you want to add projects without solution folders check configuration in step 4.

![Add Result With Solution Folders](docs/img/AddResultWithSolutionFolders.png)

## Contribute
Check out the [contribution guidelines](CONTRIBUTING.md)
if you want to contribute to this project.

For cloning and building this project yourself, make sure
to install the
[Extensibility Tools 2015](https://visualstudiogallery.msdn.microsoft.com/ab39a092-1343-46e2-b0f1-6a3f91155aa6)
extension for Visual Studio which enables some features
used by this project.

## License
[MIT License](LICENSE)


text:
* Attending: Todd Parker, John Bender, Jasper de Groot, Anne-Gaelle Colom, Gabriel Schulhof, Alex Schmitz

## Todd
* No meeting last week
* Team is focused on 1.4 work
* New icon set is coming along nicely
* Spoke to Dragan who may be able to help us with docs and FAQs, he’s been doing great work on Stack Overflow support

## John Bender
* content widget
  - changePage is now an alias for element.content( “change” )
  - tests continue
  - further thinking here: https://github.com/jquery/jquery-mobile/issues/5427#issuecomment-18353408
* Talked with the intel folks

## Jasper de Groot
* Almost finished with “next”, just few more small things to look into examples of new markup: http://view.jquerymobile.com/next/demos/test/theming/
* One issue: inheritance of popup theme or collapsible content theme
* Going to update unit tests, demo center, API docs, 1.4 changelog wiki one widget at the time
* Also want to create test pages (kitchen sink)

## Anne-Gaelle Colom
* Api docs:
  - Icons page: http://api.jquerymobile.com/icons/
  - Minor fixes (typos/rearrangements/added links)
  - updated logo for Codiqa on resources page

## Gabriel Schulhof
* Starting work on widget cleanup with Alex

## Alexander Schmitz
* Fixed ability to view directories on jquerymobile.com
* gnarf added me to infrastructure so any needs we have there i can help with now
* merged toolbar widget into master
  - page.sections is gone
  - toolbars now work outside pages
  - true persistent toolbars
* listviews now work outside pages
* First pass at panels outside pages.
  - in branch ext-panels
  - so far everything seems to be working just need some css tweaks
* looked into pointer event polyfills
  - will replace vmouse events except for vclick
  - ui starting https://github.com/jquery/jquery-pointer-events
  - looked into other fast click solutions : ours seems to be the most robust currently but we need to make it work with pointer events
  - Going to look into making this update Kinblas agreed to help with anything i need regarding vClick and vMouse
* Triage & bug fixing

gha_license_id: NOASSERTION


text:
# WordPress Tools

A command line tool to help manage your WordPress sites.

[![Build Status](https://travis-ci.org/welaika/wordpress_tools.png?branch=master)](https://travis-ci.org/welaika/wordpress_tools)

## Installation

    gem install wordpress_tools

## Usage

Create a new WordPress site in directory `mysite`. This downloads the latest stable release of WordPress (you can also specify a locale):

    wordpress new mysite
    wordpress new mysite --locale=fr_FR

Get some help:

    wordpress help

## Caveats

- If you attempt to download a WordPress localization that's outdated, the latest English version will be downloaded instead.
- Not tested on Windows.

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Add some specs
4.  Push to the branch (`git push origin my-new-feature`)
6. Create new Pull Request

## License

(The MIT License)

Copyright © 2013 weLaika

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


text:
# yo

## Custom User Notifications with Swift

### Overview
`yo` is a simple app for sending custom, *persistent* notifications to the Notification Center in OS X Yosemite and Mavericks. It allows customizing the various text fields and button labels, as well as the application to open when the (optional) action button has been clicked. Further, it allows you to configure the application icon to be displayed with the notification, although there are some caveats to this as detailed below. Also, admins using the Casper Suite should make sure to read the Casper section below.

It differs from [terminal-notifier](https://github.com/alloy/terminal-notifier) in that it creates persistent notifications that remain in place until clicked. As such, it allows you to customize these buttons and their actions. Also, it allows you to customize the application icon displayed (kind of... again, see below).

If you just want a notification, download the current installer package from the [releases](https://github.com/sheagcraig/yo/releases) page. Please note, the installer package does not include the Casper scripts.

If you want to customize the icon/app name/etc, you will need to modify the XCode project and build it yourself. Instructions are provided below.

Finally, thanks to @jatoben for the gracious sharing of his Swift [CommandLine](https://github.com/jatoben/CommandLine) library/Framework on GitHub.

### Build & Installation
You only need to follow these instructions if you want to build the app yourself. Obviously, you'll need a recent XCode.

1. Clone the project.
2. Open the project in XCode and set the App Icon to your desired icon. Please read the Icon section below for more info on what is going on here. To change the icon provided with yo, open the project in XCode and navigate to the Images.xcassets file in the file browser. Simply drag a 128x128px replacement png over the one already in place. Optionally, if you want *more* icon sizes, feel free to go nuts and fill them all in.
3. Build. (CMD-B)
4. Copy the built app (Contextual-click on the Products->yo.app->Show in Finder) wherever you see fit, although `/Applications/Utilities` seems like a suitable place. Alternately, you can use the Product->Archive menu option to export a copy of the app or build an installer package (if you have a developer ID).

Note: If you Run/(CMD-R) from XCode, it will just report back usage with a command line parsing error. Just ignore that and run from the command line.

### Usage
The yo installer package adds a command line script to `/usr/local/bin/yo` which is the preferred method for calling yo. If you are building the app with custom icons, feel free to copy this script wherever is convenient, although `/usr/local/bin/` is in the default `PATH`.

Due to its install location being in the default PATH, you can then call yo by simply typing `yo -t "This is amazing"`, for example. (`yo -h` will give you full usage information).

The yo script will test for a console user prior to execution and bail if nobody is logged in. If there is no console user, there is no notification center, and yo can't do anything. Therefore, this script ensures it only runs when possible to succeed.

#### Note:
The yo app by itself, if opened via double-clicking the app, running from Spotlight/Launchpad, etc, does nothing. It must be called with arguments, and the actual binary `yo.app/Contents/MacOS/yo` is what is executable. However, this only works if a user is currently logged in.

If you are experiencing weird hanging or no notifications being sent, check to make sure yo isn't already running. For automated messaging via a management system's triggers, it is recommended that you stick to using the script as per above. If you really want to run it "raw": from the actual binary inside (not from running or calling the "yo.app") the full path to call yo is `/Applications/Utilities/yo.app/Contents/MacOS/yo`.

#### Arguments:
```
Usage: /Applications/Utilities/yo.app/Contents/MacOS/yo [options]
-t, --title:
Title for notification. REQUIRED.
-s, --subtitle:
Subtitle for notification.
-n, --info:
Informative text.
-b, --action-btn:
Include an action button, with the button label text supplied to this argument.
-a, --action-path:
Application to open if user selects the action button. Provide the full path as the argument. This option only does something if -b/--action-btn is also specified.
-B, --bash-action:
Bash script to run. Be sure to properly escape all reserved characters. This option only does something if -b/--action-btn is also specified. Defaults to opening nothing.
-o, --other-btn:
Alternate label for cancel button text.
-i, --icon:
Complete path to an alternate icon to use for the notification.
-c, --content-image:
Path to an image to use for the notification's 'contentImage' property.
-z, --delivery-sound:
Optional (Defaults to the system's default notification sound). The name of the sound to play when delivering or 'None'. The name must not include the extension, nor any path components, and should be located in '/Library/Sounds' or '~/Library/Sounds'. See the README for more info.
-d, --ignores-do-not-disturb:
Set to make your notification appear even if computer is in do-not-disturb mode.
-l, --lockscreen-only:
Set to make your notification appear only if computer is locked. If set, no buttons will be available.
-p, --poofs-on-cancel:
Set to make your notification 'poof' when the cancel button is hit.
-m, --banner-mode:
Does not work! Set if you would like to send a non-persistent notification. No buttons will be available if set.
-h, --help:
Show help.
```

Notes:
- Title is mandatory. All other arguments are optional.
- `-m/--banner-mode` does not seem to work at this time.
- The `-a/--action` argument needs a path or URL. yo just calls `open`, so anything that would work there, should work here.
- If a "cancel" button doesn't make sense for your needs, but you don't want two buttons on your notification, just use `-o/--other-btn` with a label that seems appropriate, like "Accept", or perhaps "Confirm", but no `-b/--btext`.
- Remember, this is (probably) a Bash shell. If you don't escape reserved characters like `!` you may get unexpected results. (`!` is the Bash history expansion operator!)

### Sound
If you want to use a different sound, you must provide the *name* of the sound to the -z argument, not the filename, and not the path. I.e "Sosumi", not "Sosumi.aiff" or "/System/Library/Sosumi.aiff".

The search path is:
- ~/Library/Sounds
- /Library/Sounds
- /Network/Library/Sounds
- /System/Library/Sounds (This is where all of the builtin sounds live)

If you want to include a custom sound, it needs to be available in one of those paths. So for example, if you wanted to use the sound file "TotalEclipseOfTheHeart.aiff", copy it to `/Library/Sounds` (which may not exist by default), and use the delivery sound option like this:
`yo.ap -t "Some title" -z "TotalEclipseOfTheHeart"`

Sounds must be a aiff; extension .aif is not valid.

### Emoji
Emoji characters are allowed, although getting them into a bash command line context is tricky.

You can drag an emoji from the Special Characters palette. That's the easiest way.

Otherwise, if you need the hex code, find it in the Special Characters and go to bash:
```
echo -ne '<drag the emoji here>' | hexdump
```
This will print out the hex code for the emoji. It's the rightmost column of values that are in hex. You have to slap a \x before each two-characters, and then you can echo it back up as a command substitution...

Complete process:
```
$ echo -ne '💩' | hexdump
0000000 f0 9f 92 a9
0000004

# So 'f09f92a9' is the hex value...
$ /Applications/Utilities/yo.app/Contents/MacOS/yo -t $(echo -ne '\xf0\x9f\x92\xa9')
```
= Smiling poo emoji notification.

You can also do `printf '\xf0\x9f\x92\xa9'`.

### Examples
```
# Example of basic notification:
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time"

# Example with lots of text:
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time" -s "Chorizo is best." -n "Although I also enjoy al pastor of course."

# Example with emoji and tons of escaped characters:
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "$(printf "\xf0\x9f\x92\xa9\n") says, \"Let's dance$(printf \!)\""

# Example with action button, opening a webpage in your default browser:
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time" -b "Yum" -a "http://en.wikipedia.org/wiki/Taco"

# Example opening an app:
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time" -b "Yum" -a "/Applications/TacoParty.app"

# Example-What if you want a one-button persistent notification that doesn't *do* anything?
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time" -o "Accept"

# Example-alternate icon using the -i argument
/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Taco Time" -i "/Users/blanconino/Pictures/taco.png"

# Example-custom sound and bash script with escaped characters.
 This script is the safest way to ensure your notifications post,
and do so without jacking up the computer. Like the yo script installed in
/usr/local/bin, yo-casper only runs if a GUI user is logged in.

#### Why Bother?
Running yo with the Policy/Files & Processes/Execute Command function
of Casper results in scoped client machines becoming unable to
check-in or run further policies. This is due to something broken in
Casper's Execute Command function that prevents yo from ever
completing. Furthermore, using `"` instead of `'` for quoting causes strange
things to happen to the arguments. Therefore, do not use Execute Command.

#### Where are the Casper Scripts?
The folder containing yo-casper.py and the extension attribute to work with it are not included in the installer package, since managed client machines will not need these components. You can get them from the GitHub page by cloning the project or downloading as a zip, expanding, and then looking in the `casper` folder. Or you can just cut and paste from GitHub directly into the Scripts and Extension Attributes sections of your JSS.

#### Using yo-casper
yo-casper.py hardcodes the following arguments to yo in the 4th-11th
parameter fields for Casper scripts. As such, you should rename them
in Casper Admin to match:

4. Title
5. Subtitle
6. Info
7. Action Button
8. Action Path
9. Bash Action
10. Other Button
11. Icon

![Casper Admin Settings for yo-casper.py](https://raw.githubusercontent.com/sheagcraig/yo/master/casper/casper-script-setup.png)

Any policy posting a notification with yo should probably have the
frequency of "Ongoing" coupled with being scoped to a smart group if you want
to ensure that the notification is posted.

If a computer checks in and no console user is available, yo will not post a
notification (because it can't!). You probably are posting a notification
because you want the user to see it, thus, a frequency of ongoing keeps trying.

However, now your users are getting a notification every check-in-period, which
quickly deadens their soul and leads to ignoring your messages. To avoid this,
there are a couple of options:
1. Scope to a smart group that needs the notification, and add in some method
   for the computer to drop out of the group after it has received the
   notification, or performed the action you notified them about in the first
   place. For example, a notification to remove adware should no longer be
   offered once the computer has the adware removed (via a removal policy, with
   a followup-recon.

   Second example: You notify users about an impending OS update. Once
   they have received the update, they fall out of the group the notification
   is scoped to.
2. Use an extension attribute to determine whether a notification has been
   delivered. The yo-casper.py script logs to a file at /var/log/yo-casper.log.
   This log file includes the date stamp, arguments, and an md5 hash generated
   from the supplied arguments that will be consistent across all executions of
   that notification. Included in the `casper` folder is an extension attribute
   that can be used to determine whether a particular notification has been
   received.

   Add this EA to your JSS, and edit the `SEARCH_HASH` variable to use the hash
   for the notification you wish to send. You can run yo-casper.py on your own
   computer to quickly generate the hash exactly as the Policy/Scripts
   execution will.

   Then, create a smart group with criteria of that EA's value returning
   "False" and Computer Group is whatever group(s) you're interested in scoping
   the notification to.

   Finally, create your Policy with Scripts action, enter the arguments, and
   scope to the smart group created above.

   This is a lot of moving pieces. Sorry. Being awesome isn't easy.

![Extension Attribute](https://raw.githubusercontent.com/sheagcraig/yo/master/casper/OSUpdateNotificationSent.png)
![Extension Attribute](https://raw.githubusercontent.com/sheagcraig/yo/master/casper/OSUpdateNotificationSent2.png)
![Smart Group Criteria](https://raw.githubusercontent.com/sheagcraig/yo/master/casper/Edit_Smart_Computer_Group.png)

#### Recovering from Execute Command
Affected computers can be fixed by removing the broken Execute Command
policy from scope and running `killall jamf`.

#### But Some of the Args Are Missing?
Casper only allows 8 custom arguments, so if you would prefer other arguments
as options, feel free to edit the script to use the correct argument flags.

### Application Icon, Caveats, and Nerdery
#### Icons
Most organizations will probably want yo to display a custom icon in the notification. There are a couple of different ways notifications determine what to use for the icon:
1. By default, a notification uses the icon for the application sending the notification.
2. Using a private API, an application can specify an image file to use for the icon.

yo uses option 2 if you use the `--icon` option. However, since this is a private mechanism used by Apple to show album art in iTunes notifications, the application icon will *still* show up, just smaller, and to the side of the primary icon.

So if you really just want to use *your* icon, you need to build the project in XCode yourself. And even so, there are some issues about getting it to "know" that you've changed the icon.

Notification Center is picky about the icon it displays for your notification. If a notification has been sent previously, a subsequent icon change will not be detected or updated by Notification Center, as the original one has been cached.

Therefore, it is easiest to apply the icon you want before sending any notifications for the first time to avoid any hassles. If you get stuck with the wrong icon, you should be able to change the project Bundle Identifier in the project->General pane; or you can increment the build number in the same place. Arguably, you would want to change the Bundle Identifier to match your organization anyway.

See [here](http://stackoverflow.com/questions/11856766/osx-notification-center-icon) for more info.

#### The other nerdery
Normally, for a notification to be persistent (meaning, it stays onscreen until a button is clicked on the notification), the notification needs to be an "alert" style notification. To do this, yo sets the Info.plist key "NSUserNotificationAlertStyle" with value "alert". However, Apple does not allow just anyone to make "alerts". To use an alert in your app, the app has to be signed with a developer ID.

Or does it... There's another private API key that allows you to show buttons on a "banner", which is the default type, and available for unsigned apps. So that's what yo uses.

Of course, your results may vary. If you can't get the "alert" style notification to appear, try signing the project with your Developer ID and rebuilding.

repository: erikng/yo

repo_name: erikng/yo


text:
---
layout: post
title: OpenShift 4 UPI Installation on Libvirt/KVM
---

I am writing this blog post to document the procedure of installing OpenShift 4 UPI (User Provisioned Infrastructure) on KVM/Libvirt using the Baremetal procedure as reference. This can be a useful reference if you are looking to:

* Setup OpenShift 4 on your laptop, workstation or a server.
* Learn/Teach/Demo the OpenShift 4 UPI Installation procedure.

All you need is an internet connected host that has enough CPU/Memory and virtualization support for KVM.

If you follow along, by the end of this post, you should have a working OpenShift 4 cluster with 3 master nodes, 2 worker nodes and a VM acting as the external load balancer.

### Update 19Apr2020:

* Created a script to automate this procedure. See: https://github.com/kxr/ocp4_setup_upi_kvm
* Demo:
[![asciicast](https://asciinema.org/a/bw6Wja2vBLrAkpKHTV0yGeuzo.svg)](https://asciinema.org/a/bw6Wja2vBLrAkpKHTV0yGeuzo)

## Prerequisites and Assumptions

* Make sure that the host has a stable and fast connection to the internet. This is important as during the boostrap process, all the control plane nodes download roughly 4-5 GB of images from the container registry (quay.io).

* It is assumed that Virtualization support enabled in BIOS of the Host/Hypervisor and libvirt/KVM is already setup with the standard configuration. You are free however, to pick any one of libvirt's network for the VMs of this OpenShift cluster. Make sure that `libvirt-daemon-driver-network` is installed)

* It is also assumed that which ever libvirt's network you pick, has dhcp enabled on it. By default the "default" network has dhcp enabled. If for some reason, you want to create a segregated network for this OpenShift install, you can easily do it by:

  ~~~ bash
  # Pick a random subnet octet (192.168.XXX.0) for this network
  NET_OCT="133"
  /usr/bin/cp /usr/share/libvirt/networks/default.xml /tmp/new-net.xml
  sed -i "s/default/ocp-${NET_OCT}/" /tmp/new-net.xml
  sed -i "s/virbr0/ocp-$NET_OCT/" /tmp/new-net.xml
  sed -i "s/122/${NET_OCT}/g" /tmp/new-net.xml
  virsh net-define /tmp/new-net.xml
  virsh net-autostart ocp-${NET_OCT}
  virsh net-start ocp-${NET_OCT}
  systemctl restart libvirtd
  ~~~

* We need a DNS server and we will be using dnsmasq. You have two options (pick either one):

  1. **Use NetworkManager's embedded dnsmasq**

      This is preferable if you are running this on your laptop with dynamic interfaces getting IP/DNS from DHCP. dnsmasq in NetworkManager is not enabled by defualt. If you don't have this enabled and want to use this mode, you can simply enable it by:

     ~~~ bash
     echo -e "[main]\ndns=dnsmasq" > /etc/NetworkManager/conf.d/nm-dns.conf
     systemctl restart NetworkManager
     ~~~
      To read more about this feature I recommend reading this [Fedora Magazine post by Clark](https://fedoramagazine.org/using-the-networkmanagers-dnsmasq-plugin/).

  2. **Setup a separate dnsmasq server on the host**

      This is preferable if the network on the host is not being managed by NetworkManager. To setup dnsmasq run the following commands (adjust according to your environment):

     ~~~ bash
     yum -y install dnsmasq
     for x in $(virsh net-list --name); do virsh net-info $x | awk '/Bridge:/{print "except-interface="$2}'; done > /etc/dnsmasq.d/except-interfaces.conf
     sed -i '/^nameserver/i nameserver <IP_ADDRESS>' /etc/resolv.conf
     systemctl restart dnsmasq
     systemctl enable dnsmasq
     ~~~

## Installation Procedure

I am following the [OpenShift 4 UPI Installation documentation for bare-metal](https://docs.openshift.com/container-platform/4.2/installing/installing_bare_metal/installing-bare-metal.html) with some minor tweaks to get it working on KVM, so I recommend going through it once, if you haven't already.

**Note:** *I have intentionally tried to make this copy-paste friendly, to make it easily reproducible. This is my usual style of documenting setup procedures. It is expected that you start in single bash session and run these stream of commands one by one. Each block section is copy-paste-able at a time. If you find any breaking points or have any suggestions, please drop me a line.*

### 1- Download Files and Setup Environment

  * Start by switching to the root user if you are not already root:

    ~~~ bash
    sudo -i
    ~~~

  * Make sure you have screen installed.

    ~~~ bash
    yum -y install screen
    ~~~

  * Create and switch to a new directory to keep things clean:

    ~~~ bash
    mkdir ocp4 && cd ocp4
    ~~~

  * All the VMs will be created on the libvirt's network that you pick. By default libvirt has only one "default" network. You can find out libvirt's networks by running `virsh net-list`

    ~~~ bash
    VIR_NET="default"
    ~~~

  * Based on the libvirt's network selected, we need to find out the Network and IP address of libvirt's bridge interface.

    ~~~ bash
    HOST_NET=$(ip -4 a s $(virsh net-info $VIR_NET | awk '/Bridge:/{print $2}') | awk '/inet /{print $2}')
    HOST_IP=$(echo $HOST_NET | cut -d '/' -f1)
    ~~~

  * Set the dnsmasq configuration directory.

    If you are using NetworkManager's embedded dnsmasq, set it to "/etc/NetworkManager/dnsmasq.d".
    If you are using a separate dnsmasq installed on the host set it to "/etc/dnsmasq.d".

    ~~~ bash
    DNS_DIR="/etc/NetworkManager/dnsmasq.d"
    ~~~

  * **[DNS CHECK POINT]**

    At this point its worth double checking that your DNS is working as expected or the installation will fail later. Most of the installation I have seen failing is because of the DNS.

      1. Make sure that the hosts/hypervisor's dns is pointing to the local dnsmasq. The first entry in /etc/resolv.conf should be "nameserver <IP_ADDRESS>".

      2. Make sure that any entry in /etc/hosts is forward and reverse resolvable by libvirt/kvm. You can test this by adding a test record in /etc/hosts:

         `echo "<IP_ADDRESS> test.local" >> /etc/hosts`

         and then restart libvirtd so it picks up the hosts file:

         `systemctl restart libvirtd`

         and finally check if the forward and reverse lookup works:

         `dig test.local @${HOST_IP}`

         `dig -x <IP_ADDRESS> @${HOST_IP}`

         verify that you get answers in both the above dig queries.

      3. Make sure that any entry in the dnsmasq.d is also picked up by libvirt/kvm. You can test this by adding a test srv record:

         `echo "srv-host=test.local,yayyy.local,2380,0,10" > ${DNS_DIR}/temp-test.conf`

         and then reload dnsmasq (if you are using separate dnsmasq service then restart dnsmasq, if its NetworkManager's dnsmasq then reload NetworkManager):

         `# If using separate dnsmasq service

         `systemctl restart dnsmasq

         `# If using NetworkManager's dnsmasq

         `systemctl reload NetworkManager`

         and finally test that both libvirt and your host can resolve the srv record:

         `dig srv test.local`

         `dig srv test.local @${HOST_IP}`

         verify that you get the srv answer (yayy.local) in both the above dig queries.

      4. Clean up: remove the test entry in /etc/hosts and delete the ${DNS_DIR}/temp-test.conf file.

  * Pick a base domain for your cluster:

    ~~~ bash
    BASE_DOM="local"
    ~~~

  * Pick a cluster name:

    ~~~ bash
    CLUSTER_NAME="ocp41"
    ~~~

  * Pick your SSH public key (file):

    ~~~ bash
    SSH_KEY="/root/.ssh/id_rsa.pub"
    ~~~

  * Download your pull secret from [Red Hat OpenShift Cluster Manager](https://cloud.redhat.com/openshift/install/metal/user-provisioned) and load into a variable. You can also copy paste the pull secret. The variable PULL_SEC should have your pull secret without any newlines.

    **NOTE:** If you are copy-pasting the value of pull secret, its crucial to use single quotes (not double quotes).

    ~~~ bash
    # If loading from downloaded file
    PULL_SEC=$(cat </download/path>/pull-secret)
    # If copy-pasting, use single quotes
    PULL_SEC='<paste-pull-secret>'
    ~~~

  * Download the RHCOS Install kernel and initramfs and generate the treeinfo. *(I am doing this instead of using the RHCOS install ISO because it allows us to pass kernel arguments easily via `virt-install --extra-args` instead of typing it manually in the VM's console)*

    ~~~ bash
    mkdir rhcos-install
    wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.2/4.2.0/rhcos-4.2.0-x86_64-installer-kernel -O rhcos-install/vmlinuz
    wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.2/4.2.0/rhcos-4.2.0-x86_64-installer-initramfs.img -O rhcos-install/initramfs.img

    cat <<EOF > rhcos-install/.treeinfo
    [general]
    arch = x86_64
    family = Red Hat CoreOS
    platforms = x86_64
    version = 4.2.0
    [images-x86_64]
    initrd = initramfs.img
    kernel = vmlinuz
    EOF
    ~~~

  * Download the RHCOS bios image:

    ~~~ bash
    wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.2/4.2.0/rhcos-4.2.0-x86_64-metal-bios.raw.gz
    ~~~

  * Download the RHEL guest image for KVM. We will use this to setup an external load balancer using haproxy. Visit [RHEL download page](https://access.redhat.com/downloads/content/69/ver=/rhel---7/7.7/x86_64/product-software) (login required) and copy the download link of Red Hat Enterprise Linux KVM Guest Image (right-click on "Download Now" and copy link location). Then use wget to download the qcow2 image (its important to put the link in quotes):

    ~~~ bash
    wget "<rhel_kvm_image_url>" -O /var/lib/libvirt/images/${CLUSTER_NAME}-lb.qcow2
    ~~~

  * Set the Red Hat Customer Portal credentials. We will need this when we register the RHEL guest to install haproxy.

    ~~~ bash
    RHNUSER='<your-rhn-user-name>'
    RHNPASS='<your-rhn-password>'
    ~~~

  * Download and extract the OpenShift client and install binaries:

    ~~~ bash
    wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.2.0/openshift-install-linux-4.2.0.tar.gz
    wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.2.0/openshift-client-linux-4.2.0.tar.gz

    tar xf openshift-client-linux-4.2.0.tar.gz
    tar xf openshift-install-linux-4.2.0.tar.gz
    rm -f README.md
    ~~~

  * Create the installation directory for the OpenShift installer:

    ~~~ bash
    mkdir install_dir
    ~~~

  * Generate the install-config.yaml:

    ~~~ bash
	cat <<EOF > install_dir/install-config.yaml
    apiVersion: v1
    baseDomain: ${BASE_DOM}
    compute:
    - hyperthreading: Disabled
      name: worker
      replicas: 0
    controlPlane:
      hyperthreading: Disabled
      name: master
      replicas: 3
    metadata:
      name: ${CLUSTER_NAME}
    networking:
      clusterNetworks:
      - cidr: <IP_ADDRESS>/14
        hostPrefix: 23
      networkType: OpenShiftSDN
      serviceNetwork:
      - <IP_ADDRESS>/16
    platform:
      none: {}
    pullSecret: '${PULL_SEC}'
    sshKey: '$(cat $SSH_KEY)'
    EOF
	~~~

  * Generate the ignition files:

    ~~~ bash
	./openshift-install create ignition-configs --dir=./install_dir
    ~~~

  * Start python's webserver, serving the current directory in screen:

    ~~~ bash
    # Pick a port that you want to listen on
    WEB_PORT="1234"
    screen -S ${CLUSTER_NAME} -dm bash -c "python3 -m http.server ${WEB_PORT}"
    ~~~

  * Make sure that the VMs can access the host on the web port. Ignore this if you don't have iptables/firewalld turned on.

    ~~~ bash
    # If using firewalld
    firewall-cmd --add-source=${HOST_NET}
    firewall-cmd --add-port=${WEB_PORT}/tcp

    # If using iptables
    iptables -I INPUT -p tcp -m tcp --dport ${WEB_PORT} -s ${HOST_NET} -j ACCEPT
    ~~~

    Note: We are intentionally not opening the port permanently. We only need it in the next section when we spawn up coreos vms.

  * **[CHECK POINT]**

    At this point, make sure that our current directory (ocp4) is being served by python. Also make sure that you can access the ignition (ing) and image (img) files. Simply visit http://localhost:1234 on the host using a browser or curl. Also double check the URLs we are going to pass to the RHCOS installer kernel in the next three commands.  Wait for VMs to be properly installed and powered off. You can use the following command to watch the status of the VMs:

    `watch "virsh list --all | grep '${CLUSTER_NAME}-'"`

    If the coreos VMs are note getting turned off, it most likely means that coreos was unable to fetch the image and ignition files. Open the VMs conosle to see what is going on.

### 3- Setup DNS and Load balancing

  * We will tell dnsmasq to treat our cluster domain <cluster-name>.<base-domain> as local.

    ~~~ bash
    echo "local=/${CLUSTER_NAME}.${BASE_DOM}/" > ${DNS_DIR}/${CLUSTER_NAME}.conf
    ~~~

  * Start up all the VMs.

    ~~~ bash
    for x in lb bootstrap master-1 master-2 master-3 worker-1 worker-2
    do
      virsh start ${CLUSTER_NAME}-$x
    done
    ~~~

  * Find the IP and MAC address of the bootstrap VM. Add DHCP reservation (so the VM always get the same IP) and an entry in /etc/hosts:

    ~~~ bash
    IP=$(virsh domifaddr "${CLUSTER_NAME}-bootstrap" | grep ipv4 | head -n1 | awk '{print $4}' | cut -d'/' -f1)
    MAC=$(virsh domifaddr "${CLUSTER_NAME}-bootstrap" | grep ipv4 | head -n1 | awk '{print $2}')
    virsh net-update ${VIR_NET} add-last ip-dhcp-host --xml "<host mac='$MAC' ip='$IP'/>" --live --config
    echo "$IP bootstrap.${CLUSTER_NAME}.${BASE_DOM}" >> /etc/hosts
    ~~~

  * Find the IP and MAC address of the master VMs. Add DHCP reservation (so the VMs always gets the same IP), and an entry in /etc/hosts. We will also add the corresponding etcd host and SRV record:

    ~~~ bash
    for i in {1..3}
    do
      IP=$(virsh domifaddr "${CLUSTER_NAME}-master-${i}" | grep ipv4 | head -n1 | awk '{print $4}' | cut -d'/' -f1)
      MAC=$(virsh domifaddr "${CLUSTER_NAME}-master-${i}" | grep ipv4 | head -n1 | awk '{print $2}')
      virsh net-update ${VIR_NET} add-last ip-dhcp-host --xml "<host mac='$MAC' ip='$IP'/>" --live --config
      echo "$IP master-${i}.${CLUSTER_NAME}.${BASE_DOM}" \
      "etcd-$((i-1)).${CLUSTER_NAME}.${BASE_DOM}" >> /etc/hosts
      echo "srv-host=_etcd-server-ssl._tcp.${CLUSTER_NAME}.${BASE_DOM},etcd-$((i-1)).${CLUSTER_NAME}.${BASE_DOM},2380,0,10" >> ${DNS_DIR}/${CLUSTER_NAME}.conf
    done
    ~~~

  * Find the IP and MAC address of the worker VMs. Add DHCP reservation (so the VM always get the same IP) and an entry in /etc/hosts.

    ~~~ bash
    for i in {1..2}
    do
       IP=$(virsh domifaddr "${CLUSTER_NAME}-worker-${i}" | grep ipv4 | head -n1 | awk '{print $4}' | cut -d'/' -f1)
       MAC=$(virsh domifaddr "${CLUSTER_NAME}-worker-${i}" | grep ipv4 | head -n1 | awk '{print $2}')
       virsh net-update ${VIR_NET} add-last ip-dhcp-host --xml "<host mac='$MAC' ip='$IP'/>" --live --config
       echo "$IP worker-${i}.${CLUSTER_NAME}.${BASE_DOM}" >> /etc/hosts
    done
    ~~~

  * Find the IP and MAC address of the load balancer VM. Add DHCP reservation (so the VM always get the same IP) and an entry in /etc/hosts. We will also add the api and api-int host records as they should point to this load balancer.

    ~~~ bash
    LBIP=$(virsh domifaddr "${CLUSTER_NAME}-lb" | grep ipv4 | head -n1 | awk '{print $4}' | cut -d'/' -f1)
    MAC=$(virsh domifaddr "${CLUSTER_NAME}-lb" | grep ipv4 | head -n1 | awk '{print $2}')
    virsh net-update ${VIR_NET} add-last ip-dhcp-host --xml "<host mac='$MAC' ip='$LBIP'/>" --live --config
    echo "$LBIP lb.${CLUSTER_NAME}.${BASE_DOM}" \
    "api.${CLUSTER_NAME}.${BASE_DOM}" \
    "api-int.${CLUSTER_NAME}.${BASE_DOM}" >> /etc/hosts
    ~~~

  * Create the wild-card DNS record and point it to the load balancer:

    ~~~ bash
    echo "address=/apps.${CLUSTER_NAME}.${BASE_DOM}/${LBIP}" >> ${DNS_DIR}/${CLUSTER_NAME}.conf
    ~~~

  * Configure load balancing (haproxy). We will add frontend/backend configuration in haproxy to point the required ports (6443, 22623, 80, 443) to their corresponding endpoints:

    ~~~ bash
    # Optional,
    # Just to make sure SSH access is clear

    ssh-keygen -R lb.${CLUSTER_NAME}.${BASE_DOM}
    ssh-keygen -R $LBIP
    ssh -o StrictHostKeyChecking=no lb.${CLUSTER_NAME}.${BASE_DOM} true
    ~~~

    ~~~ bash
    ssh lb.${CLUSTER_NAME}.${BASE_DOM} <<EOF

    # Allow haproxy to listen on custom ports
    semanage port -a -t http_port_t -p tcp 6443
    semanage port -a -t http_port_t -p tcp 22623

    echo '
    global
      log <IP_ADDRESS> local2
      chroot /var/lib/haproxy
      pidfile /var/run/haproxy.pid
      maxconn 4000
      user haproxy
      group haproxy
      daemon
      stats socket /var/lib/haproxy/stats

    defaults
      mode tcp
      log global
      option tcplog
      option dontlognull
      option redispatch
      retries 3
      timeout queue 1m
      timeout connect 10s
      timeout client 1m
      timeout server 1m
      timeout check 10s
      maxconn 3000
    # 6443 points to control plan
    frontend ${CLUSTER_NAME}-api *:6443
      default_backend master-api
    backend master-api
      balance source
      server bootstrap bootstrap.${CLUSTER_NAME}.${BASE_DOM}:6443 check
      server master-1 master-1.${CLUSTER_NAME}.${BASE_DOM}:6443 check
      server master-2 master-2.${CLUSTER_NAME}.${BASE_DOM}:6443 check
      server master-3 master-3.${CLUSTER_NAME}.${BASE_DOM}:6443 check

    # 22623 points to control plane
    frontend ${CLUSTER_NAME}-mapi *:22623
      default_backend master-mapi
    backend master-mapi
      balance source
      server bootstrap bootstrap.${CLUSTER_NAME}.${BASE_DOM}:22623 check
      server master-1 master-1.${CLUSTER_NAME}.${BASE_DOM}:22623 check
      server master-2 master-2.${CLUSTER_NAME}.${BASE_DOM}:22623 check
      server master-3 master-3.${CLUSTER_NAME}.${BASE_DOM}:22623 check

    # 80 points to worker nodes
    frontend ${CLUSTER_NAME}-http *:80
      default_backend ingress-http
    backend ingress-http
      balance source
      server worker-1 worker-1.${CLUSTER_NAME}.${BASE_DOM}:80 check
      server worker-2 worker-2.${CLUSTER_NAME}.${BASE_DOM}:80 check

    # 443 points to worker nodes
    frontend ${CLUSTER_NAME}-https *:443
      default_backend infra-https
    backend infra-https
      balance source
      server worker-1 worker-1.${CLUSTER_NAME}.${BASE_DOM}:443 check
      server worker-2 worker-2.${CLUSTER_NAME}.${BASE_DOM}:443 check
    ' > /etc/haproxy/haproxy.cfg

    systemctl start haproxy
    systemctl enable haproxy
    EOF
    ~~~

  * **[CHECK POINT]**

    Make sure haproxy in the load balancer VM is up and running and listening on the desired ports:

    `ssh lb.${CLUSTER_NAME}.${BASE_DOM} systemctl status haproxy`

    `ssh lb.${CLUSTER_NAME}.${BASE_DOM} netstat -nltupe | grep ':6443\|:22623\|:80\|:443'`

  * Reload NetworkManager and Libvirt for DNS entries to be loaded properly:

    ~~~ bash
    systemctl reload NetworkManager
    systemctl restart libvirtd
    ~~~

    If you are using separate dnsmasq, restart it:

    ~~~ bash
    systemctl restart dnsmasq
    ~~~

### 4- BootStrap OpenShift 4 Cluster

  * Start the OpenShift installation, stopping at bootrap completion:

    ~~~ bash
    ./openshift-install --dir=install_dir wait-for bootstrap-complete
    ~~~

  * **[CHECK POINT]**

    The OpenShift bootstrap process has started and the control plane will now download a bunch of container images from the registry (quay.io). If internet connection is slow, this will take a long time and might timeout.

    From a new terminal on the host, ssh into the bootstrap node and watch the bootkube.service service:

    `ssh core@<bootstrap-node> journalctl -b -f -u bootkube.service`

    Wait until the installer gives you the following message:

    ~~~ bash
    INFO API v1.13.4+8560dd6 up
    INFO Waiting up to 30m0s for bootstrapping to complete...
    DEBUG Bootstrap status: complete
    INFO It is now safe to remove the bootstrap resources
    ~~~

  * At this point the bootstrap should have successfully finished and the openshift-install should have told you to that its now safe to remove the bootstrap.

    You can login to your openshift cluster and make sure that all the nodes are in a ready state:

    ~~~ bash
    export KUBECONFIG=install_dir/auth/kubeconfig
    ./oc get nodes
    ~~~

  * Once you have verified that all cluster nodes (3 master and 2 worker) are in a ready state, lets remove the boostrap entries from our load balancer (haproxy).

    ~~~ bash
    ssh lb.${CLUSTER_NAME}.${BASE_DOM} <<EOF
    sed -i '/bootstrap\.${CLUSTER_NAME}\.${BASE_DOM}/d' /etc/haproxy/haproxy.cfg
    systemctl restart haproxy
    EOF
    ~~~

  * Delete the bootstrap VM

    ~~~ bash
    virsh destroy ${CLUSTER_NAME}-bootstrap
    virsh undefine ${CLUSTER_NAME}-bootstrap --remove-all-storage
    ~~~

  * We can close the screen session running the python web server.

    ~~~ bash
    screen -S ${CLUSTER_NAME} -X quit
    ~~~

  * Since we do not have a RWX storage type at the moment, we will patch image registry configuration to use "EmptyDir" for storage.

    **NOTE:** This command will fail early on, as the cluster operators are being rolled out. If it fails try after a minute or so.

    ~~~ bash
    ./oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"storage":{"emptyDir":{}}}}'`
    ~~~

  * At this point OpenShift's cluster operators are being rolled out. Wait for the cluster operators to be fully available.

    ~~~ bash
    watch "./oc get clusterversion; echo; ./oc get clusteroperators"
    ~~~

  * **[CHECK POINT]**

    When all the cluster operators are fully available, it should look some thing like this:

    ~~~ bash
    # ./oc get clusteroperators
    NAME                               VERSION AVAILABLE PROGRESSING DEGRADED SINCE
    authentication                     4.1.9 True False False 11m
    cloud-credential                   4.1.9 True False False 24m
    cluster-autoscaler                 4.1.9 True False False 24m
    console                            4.1.9 True False False 13m
    dns                                4.1.9 True False False 22m
    image-registry                     4.1.9 True False False 2m58s
    ingress                            4.1.9 True False False 16m
    kube-apiserver                     4.1.9 True False False 20m
    kube-controller-manager            4.1.9 True False False 20m
    kube-scheduler                     4.1.9 True False False 20m
    machine-api                        4.1.9 True False False 23m
    machine-config                     4.1.9 True False False 22m
    marketplace                        4.1.9 True False False 16m
    monitoring                         4.1.9 True False False 13m
    network                            4.1.9 True False False 22m
    node-tuning                        4.1.9 True False False 16m
    openshift-apiserver                4.1.9 True False False 18m
    openshift-controller-manager       4.1.9 True False False 20m
    openshift-samples                  4.1.9 True False False 6m13s
    operator-lifecycle-manager         4.1.9 True False False 20m
    operator-lifecycle-manager-catalog 4.1.9 True False False 20m
    service-ca                         4.1.9 True False False 23m
    service-catalog-apiserver          4.1.9 True False False 17m
    service-catalog-controller-manager 4.1.9 True False False 18m
    storage                            4.1.9 True False False 17m

    # ./oc get clusterversion
    NAME    VERSION AVAILABLE PROGRESSING SINCE STATUS
    version 4.1.9   True      False       3m46s Cluster version is 4.1.9
    ~~~

### 5- Finish Installation and Access the Cluster

  * At this point you are pretty much done. Finish the installation by running:

    ~~~ bash
    ./openshift-install --dir=install_dir wait-for install-complete
    ~~~

  * **[CHECK POINT]**

    The opshift-install should give you an output similar to:

    ~~~ bash
    INFO Waiting up to 30m0s for the cluster at https://api.ocp41.local:6443 to initialize...
    INFO Waiting up to 10m0s for the openshift-console route to be created...
    INFO Install complete!
    INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/knaeem/Desktop/ocp4/install_dir/auth/kubeconfig'
    INFO Access the OpenShift web-console here: https://console-openshift-console.apps.ocp41.local
    INFO Login to the console with user: kubeadmin, password: XXXX-XXXX-XXXX-XXXX
    ~~~

  * You can now login to the cluster using the kubeadmin user from the command-line:

    ~~~ bash
    KUBE_PASS=$(cat install_dir/auth/kubeadmin-password)
    ./oc login -u kubeadmin -p $KUBE_PASS
    ~~~

  * Access the cluster from the browser:

    ~~~ bash
    xdg-open https://console-openshift-console.apps.${CLUSTER_NAME}.${BASE_DOM}
    ~~~

    ![OpenShift 4 Screenshot]({{ "/" | relative_url }}public/media/openshift-4-upi-install-libvirt-kvm/Screenshot_2019-08-17_Login_Red_Hat_OpenShift_Container_Platform.png)

    ![OpenShift 4 Screenshot]({{ "/" | relative_url }}public/media/openshift-4-upi-install-libvirt-kvm/Screenshot_2019-08-17_Cluster_Status_Red_Hat_OpenShift_Container_Platform.png)

    ![OpenShift 4 Screenshot]({{ "/" | relative_url }}public/media/openshift-4-upi-install-libvirt-kvm/Screenshot_2019-08-17_Nodes_Red_Hat_OpenShift_Container_Platform.png)

    ![OpenShift 4 Screenshot]({{ "/" | relative_url }}public/media/openshift-4-upi-install-libvirt-kvm/Screenshot_2019-08-17_Projects_Red_Hat_OpenShift_Container_Platform.png)

## Known Issues

  * Make sure that virtualization support is enabled in BIOS. If its not enabled, libvirt will probably not complain but the CPU emulation will make the VMs super slow and the CoreOS VMs won't boot properly.

  * If you are getting timed out while waiting for Kubernetes API and the installer (`./openshift-install --dir=install_dir wait-for bootstrap-complete`) throws the following error:

    `FATAL waiting for Kubernetes API: context deadline exceeded`

    Check the following:

    * Make sure that you have good internet speed. If the internet is slow it might cause the installer to timeout before the images get downloaded.

    * Make sure the first nameserver on the host in /etc/resolv.conf is <IP_ADDRESS>, and that NetworkManager restart is not resetting it to something else.

    * Login into the one of the master node `ssh<EMAIL_ADDRESS>using the ssh key you selected during the setup. Then become root (sudo -i) and run (critctl ps). You should see a container named "discover". See the logs of this container (crictl logs <container-id>) to get a clue on why things are not starting up.

    * If have figured out and fixed the issue, its safe re run this command (./openshift-install --dir=install_dir wait-for bootstrap-complete). You don't have to scratch every thing and re-run.


text:
### [CVE-2017-5111](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5111)
![](https://img.shields.io/static/v1?label=Product&message=Google%20Chrome%20prior%20to%2061.0.3163.79%20for%20Linux%2C%20Windows%20and%20Mac&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Vulnerability&message=Use%20after%20free&color=brighgreen)

### Description

A use after free in PDFium in Google Chrome prior to 61.0.3163.79 for Linux, Windows, and Mac allowed a remote attacker to potentially exploit memory corruption via a crafted PDF file.

### POC

#### Reference
No PoCs from references.

#### Github
- https://github.com/0xCyberY/CVE-T4PDF
- https://github.com/ARPSyndicate/cvemon

repository: trickest/cve

repo_name: trickest/cve


text:
# Shorturl

Shorturl is a small web application built with Lumen and VueJS.

## Installation
Clone the repo and enter the directory:

```
git clone git@github.com:jeffbulotano/shorturl.git shorturl

cd shorturl
```

Install packages:

```
composer install
```
or if you don't need dev dependencies:
```
composer install --no-dev
```

Copy sample environment file:
```
cp .env.example .env
```

Modify .env file with your preferred text editor:
```
APP_NAME=Lumen # Modify this with what you want to name your app
APP_ENV=local # Change to production when your app is launched
APP_KEY= # 32 character random string
APP_DEBUG=true # false is recommended for production
APP_URL=http://localhost # Set to the URL that you will be running the app on
APP_TIMEZONE=UTC

LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=

DB_CONNECTION=mysql
DB_HOST=<IP_ADDRESS>
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
QUEUE_CONNECTION=sync

HASH_ID_SALT=testsalt # String that is used to create the hash for short links
HASH_ID_PADDING=5 # Minimum length of hash for short links
```

*NOTE It is important that you change APP_URL, DB_DATABASE, DB_USERNAME, DB_PASSWORD for the application to work.

Run migration:
```
php artisan migrate
```

Your app is now ready!

## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

## TODO
Improvements on URL validation.

repository: jeffbulotano/shorturl

gha_language: PHP

repo_name: jeffbulotano/shorturl


text:
Usage:
  cush <main> -o <dest> [-t <platform>] [-p]

The `main` path must have a file extension.

Options:
  -o  The bundle path (eg: "bundle.js" or "bundle.web.js")
  -t  The target platform
  -p  Enable production mode

repository: aleclarson/cush-cli

gha_language: CoffeeScript

repo_name: aleclarson/cush-cli


text:
# Shell engine usage document

This article mainly introduces the configuration, deployment and use of Shell engine in Linkis1.0
## 1. The environment configuration before using the Shell engine

If you want to use the shell engine on your server, you need to ensure that the user's PATH has the bash execution directory and execution permissions.

| Environment variable name | Environment variable content | Remarks             |
|---------------------------|------------------------------|---------------------|
| sh execution environment  | bash environment variables    | bash is recommended |

Table 1-1 Environmental configuration list

## 2. Shell engine configuration and deployment

### 2.1 Shell version selection and compilation

The shell engine does not need to be compiled by the user, and the compiled shell engine plug-in package can be used directly.
### 2.2 shell engineConn deployment and loading

Here you can use the default loading method to be used normally.

### 2.3 Labels of the shell engine

Here you can use the default dml.sql to insert it and it can be used normally.

## 3. Use of Shell Engine

### Ready to operate

Before submitting the shell on linkis, you only need to ensure that there is the path of the shell in your user's $PATH.

### 3.1 How to use Scriptis

The use of Scriptis is the simplest. You can directly enter Scriptis, right-click the directory and create a new shell script, write shell code and click Execute.

The execution principle of the shell is that the shell engine starts a system process to execute through the ProcessBuilder that comes with java, and redirects the output of the process to the engine and writes it to the log.

![](../Images/EngineUsage/shell-run.png)

Figure 3-1 Screenshot of shell execution effect

### 3.2 How to use workflow

The DSS workflow also has a shell node. You can drag in the workflow node, then double-click to enter and edit the code, and then execute it in the form of a workflow.

Shell execution needs to pay attention to one point. If the workflow is executed in multiple lines, the success of the workflow node is determined by the last command. For example, the first two lines are wrong, but the shell return value of the last line is 0, then this node Is successful.

### 3.3 How to use Linkis Client

Linkis also provides a client method to call the shell task, the calling method is through the SDK provided by LinkisClient. We provide java and scala two ways to call, the specific usage can refer to <https://github.com/WeBankFinTech/Linkis/wiki/Linkis1.0%E7%94%A8%E6%88%B7%E4 %BD%BF%E7%94%A8%E6%96%87%E6%A1%A3>.

## 4. Shell engine user settings

The shell engine can generally set the maximum memory of the engine JVM.

repository: yangzhiyue/Linkis-Doc

repo_name: yangzhiyue/Linkis-Doc