text:
---
title: Happy Camper quote
taxonomy:
    category: docs
---

## What is this?
The quote that sits below the recent work module on the front page below the main content.

![Camper](/images/camper/camper.png)

## Steps to recreate this layout

This item is a custom html module published to the grid17 module.

The background colour used for this row is one of the row styles that can be assigned by row via the template settings. See below for more details.

** Module Manager **
1. Navigate to the module manager in your Joomla administrator via extensions > Module Manager
2. Click new
3. Select the custom html type module
4. Copy the markup displayed below into the text area of the custom module.
5. Assign the module to a module position (sidebar2).
6. Ensure the module is published
7. Give the module a title
8. Set the module title to be hidden
9. Save your new module.

## Markup used in the module

Cras nec lorem eget ligula varius aliquet at et mi.

A Happy Camper

## Row Styles set in the template
The background colour used for this row is determined by the template and can be found in the theme panel in the template administrator.

The row style is applied to a row of modules grouped by their respective rows.

- Top row - top1,top2,top3,top4
- Banner row - banner
- Grid1 row - grid1,grid2,grid3,grid4
- Grid2 row - grid5,grid6,grid7,grid8
- Grid3 row - grid9,grid10,grid11,grid12
- Grid4 row - grid13,grid14,grid15,grid16
- Grid5 row - grid17,grid18,grid19,grid20
- Grid6 row - grid21,grid22,grid23,grid24
- Bottom row - bottom1,bottom2,bottom3,bottom4,bottom5,bottom6
- Top row - top1,top2,top3,top4

** Row Styles in the template settings **
![Row styles](/images/row-styles/row-style.png)

** Example Options **
![Row Style Options](/images/row-styles/row-style-options.png)


text:
---
title: "\n\t\t\t\tMacBook Air vs MacBook Pro for 2012.\t\t"
date: 2012-05-14 00:00:00 Z
categories:
- jim
author<EMAIL_ADDRESS>comments: true
excerpt: "\n\t\t\t\t\t\t"
layout: post
link: https://jim.am/macbook-air-vs-macbook-pro-for-2012/
wordpress_id: 5297
---

Way back in August of 2011 I wrote about whether [I should buy a new MacBook Pro today](http://www.jim.am/should-i-buy-a-MacBook Pro-now-in-august-or-should-i-wait-for-the-MacBook Pro-2012/) or whether I should wait for the 2012 MacBook Pros to arrive (I’ll wait – there has to be a new MacBook Pro released any day now)

But this got me thinking. What if you can’t wait to buy a MacBook Pro and you need one now? Do you go with the MacBook Air instead of MacBook Pro?

**2012 MacBook Air vs MacBook Pro **

To start, I’m comparing the 13 inch versions of these models as there isn’t a 15 inch MacBook Air and it wouldn’t surprise me if Apple discontinued the 17 inch MBP any day now. So this leaves us comparing the 2012 Apple MacBook Pro vs the 2012 MacBook Air – both with 13.3 inch displays.

**Advantages of MacBook Air

**

Weight. It weigh less and for a portable computer this may be your buying decision right there.

Hard Drive Speed. The SSD drive smokes the standard hard drive in the MacBook Pro

Newer Technology when it comes to Airport speed and bluetooth technologies.

**Advantages of MacBook Pro**

Weight. I don’t care what the marketers would like you to believe – that extra pound and a half is a lot when it’s digging into your shoulder

Price. The MacBook Pro is cheaper by $100.

Speed. The MadcBook Pro is faster with a 2.4GHz processor compared to the MacBook Air’s 1.7GHz

Memory.You can upgrade the MacBook Pro with more RAM. the MacBook Air you’re stuck with the default 4GB for the lifetime of the computer.

Optical Drive. The MacBook Pro has one.

Facetime HD video camera

Thunderbolt port

Backlit Keyboard

Way more connections on the MacBook Pro. The Air is limited to thunderbolt and USB 2.0 and headphone and microphone.

As you can see, the advantage of the Air over the Pro this year so far is far lighter and the zippy SSD drive.

If you can handle the extra weight of the MacBook Pro, **that’s the one I would buy**. It’s $100 cheaper and less if you **[buy the MacBook Pro at Amazon](http://www.amazon.com/gp/product/B005CWIVYI/ref=as_li_ss_tl?ie=UTF8&tag=ramseeker-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B005CWIVYI)**. It all depends on how you plan on using your notebook. For me, I plug the notebook into a LED display and external hard drive and only unplug it for couch surfing or the odd trip out for coffee for a change of scenery.

I vote for the MacBook Pro.

license: MIT

repository: ramseeker/sidey

branch_name: refs/heads/master

extension: markdown

license_type: permissive

repo_name: ramseeker/sidey


text:
---
title: Networked Trade Platform
permalink: /initiatives/business/networked-trade-platform
third_nav_title: Business
---
#  A Smarter Way to Trade

When COVID-19 hit in 2020, many businesses had to shift their operations online. This transformed the way we buy our goods and services. Our supply chains had to be quickly reconfigured to make sure our people had what they needed, and it shone a spotlight on how continued effort is needed to make sure our trade links remain resilient.

As part of this effort, we built the Networked Trade Platform (NTP) that allows for a seamless way to manage trade documents digitally.

## Streamlining the Trading Process

Businesses that trade here are required to submit multiple documents to their trade partners, logistics providers, banks and financial institutions and Government agencies. This is a time-consuming process.

The NTP is a one-stop information management platform that offers a convenient, secure and seamless way of managing trade documents. It also includes networking features for local businesses to link up with local and foreign partners as well as share data and come up with new insights and services together.

Specifically, the NTP helps businesses to:

* **Innovate new services and applications based on market needs.** Since the NTP is developed on an open architecture, third-party solution providers or IT developers can easily access toolkits and data to develop innovative solutions on top of this framework.
* **Share data across borders securely**, giving rise to potentially exciting new insights for the industry.
* **Digitisation of documents quickly and securely**, helping to cut costs and streamline processes.

Learn more about the Network Trade Platform here.

repository: anushagovtech/smartnationsg

extension: md

repo_name: anushagovtech/smartnationsg


text:
# Create React Dependency

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/andrelmlins/create-react-dependency/blob/master/LICENSE) • [![Build Status](https://travis-ci.com/andrelmlins/create-react-dependency.svg?branch=master)](https://travis-ci.com/andrelmlins/create-react-dependency) • [![Dependencies](https://david-dm.org/andrelmlins/create-react-dependency.svg)](https://david-dm.org/andrelmlins/create-react-dependency) • [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/andrelmlins/create-react-dependency.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/andrelmlins/create-react-dependency/context:javascript)

Project similar to the [Create React App](https://github.com/facebook/create-react-app) for libraries and dependencies.

It creates a ready to publish project which you can upload to npm, yarn and/or your favorite package manager.

## Basic Use

```
npx create-react-dependency new my-dependency
cd my-dependency
npm start
```

## How to create a dependency or library?

### Yarn

```
yarn create create-react-dependency my-dependency
```

### NPX

```
npx create-react-dependency my-dependency
```

### NPM

```
npm init create-react-dependency my-dependency
```

## Projects

- [Create React Dependency](https://github.com/andrelmlins/create-react-dependency/blob/master/packages/create-react-dependency/README.md)
- [React Library Scripts](https://github.com/andrelmlins/create-react-dependency/blob/master/packages/react-dependency-scripts/README.md)

## License

Create React Dependency is open source software [licensed as MIT](https://github.com/andrelmlins/create-react-dependency/blob/master/LICENSE).

repository: dayanlemos/create-react-dependency

gha_license_id: MIT

repo_name: dayanlemos/create-react-dependency


text:
gitlab-ci-stack
======================================================================================
[![Build Status](https://travis-ci.org/jonashackt/gitlab-ci-stack.svg?branch=master)](https://travis-ci.org/jonashackt/gitlab-ci-stack)

Full CI pipeline project based on Gitlab & Gitlab CI running Docker, completely automated setup by Vagrant & Ansible, providing Let´s Encrypt certificates for private Servers, multiple Gitlab-Runners and the Gitlab Container Registry

[![asciicast](https://asciinema.org/a/205171.svg)](https://asciinema.org/a/205171)

This project is somehow based on the thought of https://github.com/marcelbirkner/docker-ci-tool-stack. But since the good old days of Jenkins times changed "a bit". Maybe today Jenkins incl. 2.x/Pipeline-plugin isn´t the way to go - or it´s just the way, if you really want to have a hard time. Why? Here are some points:

"Jenkins servers become snowflakes"

"Jenkins 2.0 tries to address this by promoting a Pipeline plugin (plus another plugin to visualize it), but it kind of misses the point."

https://content.pivotal.io/blog/comparing-bosh-ansible-chef-part-1

I heard from so many colleagues:

> "Hey Jonas you Jenkins fanboy. Have a look on all those cool new CI servers like Concourse, Circle CI oder even Gitlab CI! We don´t know, why you´re messing around with Jenkins..." .

## Table of Contents
* [Which one to choose?](#which-one-to-choose)
* [Gitlab CI](#gitlab-ci)
* [Why not just use Docker Compose to fire everything up?](#why-not-just-use-docker-compose-to-fire-everything-up)
* [Prerequisites](#prerequisites)
* [Let´s install & run Gitlab inside our Server/VagrantBox with Ansible](#lets-install--run-gitlab-inside-our-servervagrantbox-with-ansible)
* [Install & Configure Docker](#install--configure-docker)
* [Nice Gitlab URL with DNS configuration](#nice-gitlab-url-with-dns-configuration)
* [Enable https for Gitlab on public accessable server](#enable-https-for-gitlab-on-public-accessable-server)
* [Let´s Encrypt for our Gitlab on VirtualBox/Vagrant](#lets-encrypt-for-our-gitlab-on-virtualboxvagrant)
* [Configure the "self-created" Let´s Encrypt certificates in Gitlab (it´s the same process for other certificates then Let´s Encrypt)](#configure-the-self-created-lets-encrypt-certificates-in-gitlab-its-the-same-process-for-other-certificates-then-lets-encrypt)
* [Install Gitlab itself](#install-gitlab-itself)
* [Gitlab Container Registry](#gitlab-container-registry)
* [Ubuntu & Docker don´t know Let´s Encrypt so we need to copy the fullchain.pem instead of just the cert.pem!](#ubuntu--docker-dont-know-lets-encrypt-so-we-need-to-copy-the-fullchainpem-instead-of-just-the-certpem)
* [Install Gitlab Runner](#install-gitlab-runner)
* [Configure Gitlab Runner with shell executor](#configure-gitlab-runner-with-shell-executor)
* [Configure a Docker-in-Docker enabled gitlab-runner with the docker executor](#configure-a-docker-in-docker-enabled-gitlab-runner-with-the-docker-executor)
* [Changes needed in .gitlab-ci.yml for Docker-in-Docker compared to using a shell runner](#changes-needed-in-gitlab-ciyml-for-docker-in-docker-compared-to-using-a-shell-runner)
* [Configure a Docker socket binding enabled gitlab-runner with the docker executor](#configure-a-docker-socket-binding-enabled-gitlab-runner-with-the-docker-executor)
* [Changes needed in .gitlab-ci.yml for Docker-in-Docker compared to using a shell runner](#changes-needed-in-gitlab-ciyml-for-docker-in-docker-compared-to-using-a-shell-runner-1)
* [Configure .gitlab-ci.yml Jobs to run only on specific gitlab-runners](#configure-gitlab-ciyml-jobs-to-run-only-on-specific-gitlab-runners)
* [Using the Gitlab Container Registry](#using-the-gitlab-container-registry)
* [Namespaces (username, group or subgroup)](#namespaces-username-group-or-subgroup)
* [Import example project with .gitlab-ci.yml and run Gitlab CI pipeline](#import-example-project-with-gitlab-ciyml-and-run-gitlab-ci-pipeline)
* [GitLab Pages on self-hosted GitLab-Instance](#gitlab-pages-on-self-hosted-gitlab-instance)
* [Define another domain name for Pages](#define-another-domain-name-for-pages)
* [Let´s Encrypt Wildcard certificates with dehydrated & lexicon](#lets-encrypt-wildcard-certificates-with-dehydrated--lexicon)
* [Configure Pages in GitLab with Ansible](#configure-pages-in-gitlab-with-ansible)
* [A new Jekyll site](#a-new-jekyll-site)
* [Deploy Jekyll as GitLab Pages with GitLab CI & Docker](#deploy-jekyll-as-gitlab-pages-with-gitlab-ci--docker)
* [Links](#links)

## Which one to choose?

Well, ok then. Let´s give it a try. And because of all this here:

https://www.digitalocean.com/community/tutorials/ci-cd-tools-comparison-jenkins-gitlab-ci-buildbot-drone-and-concourse

https://www.slant.co/versus/2482/10699/~gitlab-ci_vs_concourse-ci

https://www.reddit.com/r/devops/comments/6cuj0s/concourse_jenkins_ci/

https://concourse-ci.org/concourse-vs.html

Therefore I wanted to have a deeper look into Gitlab.

## Gitlab CI

Today Gitlab not only offers a alternative to Bitbucket Server or GitHub Enterprise, they also offer an [alternate CI-Implementation](https://docs.gitlab.com/ce/ci/README.html):

![cicd_pipeline_infograph](screenshots/cicd_pipeline_infograph.png)

Source: https://docs.gitlab.com/ce/ci/README.html

## Why not just use Docker Compose to fire everything up?

Back in 2015 Marcel already fired up everything with Docker Compose (as I mentioned https://github.com/marcelbirkner/docker-ci-tool-stack).

What I really love is to achieve comprehensible solutions that are usable as is in your project.  You will always try to get a server and install Gitlab there.

To achieve a fully comprehensible setup here, we some DevOps tools FTW:

* Ansible: This shiny pice will contain __ALL__ steps necessary to provision a Gitlab server with __everything__ needed. It´s also a great documentation what´s needed to setup a Gitlab server.
* Vagrant: To just fire up a server locally that is based on a certain OS - because that´s needed to craft a Ansible playbook. But this is just for demonstration purposes - you can switch over to your Gitlab server by just editing the [hosts](hosts) and adding `[yourcompanygitlab]` together with it´s IP.

## Prerequisites

Be sure to have the following tools installed: Ansible, VirtualBox & Vagrant. On a Mac this is simple:

```
brew install ansible
brew cask install virtualbox
brew cask install vagrant
```

Our setup uses the [vagrant-dns Plugin](https://github.com/BerlinVagrant/vagrant-dns). Just install it with:

```
vagrant plugin install vagrant-dns
```

Now be sure to add your domain name into the [Vagrantfile](Vagrantfile). As I own the domain [jonashackt.io](jonashackt.io), I added the following:

```
    config.vm.hostname = "jonashackt"
    config.dns.tld = "io"
```

Be sure to configure your local DNS with:

```
vagrant dns --install
```

That´s all, we´re ready to fire up our server with:

```
vagrant up
```

If the server is up and running (this may take a while when doing it for the first time), we can execute Ansible.

Let´s do a connection check first:

```
ansible gitlab-ci-stack -i hosts -m ping
```

If this gave a `SUCCESS`, we can move on to really execute our Ansible playbooks.

> All the Installation process is based upon the "Omnibus GitLab installation" (NOT the from source option)

## Let´s install & run Gitlab inside our Server/VagrantBox with Ansible

To just execute the playbook and install everything needed to have a fully functional Gitlab-Instance, you only need to run the following Ansible Playbook.

Just be sure to configure your Domain name inside [prepare-gitlab.yml](prepare-gitlab.yml):

```
  vars:
    gitlab_domain: "gitlab.jonashackt.io"
```

and provide `providername`, `providerusername` & `providertoken` for your DNS Providers´s API in `--extra-vars` (and maybe whitelist your current Internet IP):

```
ansible-playbook -i hosts prepare-gitlab.yml --extra-vars "providername=yourProviderNameHere providerusername=yourUserNameHere providertoken=yourProviderTokenHere"
```

Only, if you don´t use Vagrant or an only internally accessible Server, you can ignore the extra-vars - Gitlab will handle Let´s Encrypt for you then:

```
ansible-playbook -i hosts prepare-gitlab.yml
```

If you want to know more about the installation Process, just read on:

## Install & Configure Docker

The [prepare-docker-ubuntu.yml](prepare-docker-ubuntu.yml) just walks through the [standard Docker docs guide on how to install Docker on Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/). If you use another Distro, you can simply change modules etc. to match your Linux.

The only thing special here is how we install Docker Compose, which [is described in the Docs](https://docs.docker.com/compose/install/#install-compose) with that unappealing way of always using a hard-coded version in the curl. Therefore the hint:

> Use the latest Compose release number in the download command.

But there´s a much nicer way, because [Python PIP](https://pypi.org/project/pip/) has the current package ready for us:

```
  - name: Install pip
    apt:
      name: python3-pip
      state: latest

  - name: Install Docker Compose
    pip:
      name: docker-compose
```

Now we don´t need to mess with maintaining the Docker Compose version number & the upgrade process any more!

## Nice Gitlab URL with DNS configuration

We don´t want to access Gitlab via a http://locahost:30080 call - instead we want to have something like http://docker.gitlab.ci!

To enable that on the Host machine, we need the [vagrant-dns Plugin](https://github.com/BerlinVagrant/vagrant-dns). Just install it with:

```
vagrant plugin install vagrant-dns
```

Now we configure a domain name such as `jonashackt` and a TLD like `io` in our Vagrantfile:

```
config.vm.hostname = "jonashackt"

config.dns.tld = "io"
```

Now we need to register the vagrant-dns Server with the TLD `io` as a DNS resolver:

```
vagrant dns --install
```

Now check with `scutil --dns` (on a Mac), if the resolver is part of your DNS configuration:

```
...

resolver #10
  domain   : io
  nameserver[0] : <IP_ADDRESS>
  port     : 5300
  flags    : Request A records, Request AAAA records
  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)

...
```

This looks good! Now after the usual `vagrant up`, try if you´re able to reach our Vagrant Box using our defined domain by typing e.g. `dscacheutil -q host -a name gitlab.jonashackt.io`:

```
$:gitlab-ci-stack jonashecht$ dscacheutil -q host -a name gitlab.jonashackt.io
  name: gitlab.jonashackt.io
  ip_address: <IP_ADDRESS>
```

But as we want to have the nice `docker.gitlab.ci` also available inside our Vagrant Box and the [vagrant-dns Plugin](https://github.com/BerlinVagrant/vagrant-dns) doesn´t support propagating the host´s DNS resolver to the Vagrant Boxes, we have a problem.

But luckily we have [VirtualBox as a virtualization provider for Vagrant](https://www.vagrantup.com/docs/virtualbox/common-issues.html), which supports the propagation of the host´s DNS resolver to the guest machines. All we have to do, is to use [this suggestion on serverfault](https://serverfault.com/a/506206/326340):, which will 'Using the host's resolver as a DNS proxy in NAT mode':

```
# Forward DNS resolver from host (vagrant dns) to box
virtualbox.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
```

After we configured that, we can do our well-known `vagrant up`.

Now we should be able to ping `gitlab.jonashackt.io`.

## Enable https for Gitlab on public accessable server

https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https

> From 10.7 we will automatically use [Let's Encrypt certificates if the external_url specifies https](https://docs.gitlab.com/omnibus/settings/ssl.html#let-39-s-encrypt-integration)), the certificate files are absent, and the embedded nginx will be used to terminate ssl connections.

If you have an externally accessable server and provision it with these Ansible scripts, you don´t have to worry about the process of obtaining Let´s Encrypt certificates and configuring them for Gitlab. Everything is just done for you by the Gitlab Installation process.

## Let´s Encrypt for our Gitlab on VirtualBox/Vagrant

__BUT__: The problem is our local setup here: Let´s Encrypt wont be able to validate the certificate for our domain, since it´s just a local DNS installation.

That sounds like we´re in need of a different way. Because if we just use our domain with https like https://gitlab.jonashackt.io/, our Browser will complain:

![insecure-https](screenshots/insecure-https.png)

and a `git push` will result into the following problem:

```
$ git push
fatal: unable to access 'https://gitlab.jonashackt.io/root/yourRepoNameHere/': SSL certificate problem: self signed certificate
```

Although Let´s Encrypt was designed to be used with public accessable websites, there are ways to create these Certificates for non-public servers also. All you need to have is a __regularly registered domain__ - which maybe sounds like a big issue, but isn´t really a problem! (don´t try to use already registered ones, this won´t work!)

If you don´t mind about the tld, choose something like `yourDomainName.yxz` or `yourDomainName.online`, which are available from 1$/year. Just be sure to pick [one from this provider list](https://github.com/AnalogJ/lexicon#providers).

__YOU NEED API ACCESS TO PROCEED!__: What all the blog posts only tell you at the end: Besides your regularly registered/purchased domain you´ll need API-access to your provider, which often isn´t included in the standard price of your domain! I choose https://www.namecheap.com/ and to use the [namecheap api](https://www.namecheap.com/support/api), you´ll need to [upgrade your balance to 50$](https://www.namecheap.com/support/knowledgebase/article.aspx/9739/63/api--faq#c).
And you often also need to whitelist the IP your approaching the DNS provider API from - in our case, use a tool like http://www.whatsmyip.org/ to get the IP and add it to your DNS providers API access IP whitelist (just be sure to double check this IP before you call the playbook!)

> There has been done some great work in the field of generating Let´s Encrypt certificates for private servers (see https://blog.thesparktree.com/generating-intranet-and-private-network-ssl)

The playbook [obtain-letsencrypt-certs-dehydrated-lexicon.yml](obtain-letsencrypt-certs-dehydrated-lexicon.yml) just automates all the steps described in the mentioned post. It uses [dehydrated](https://github.com/lukas2511/dehydrated) as an alternative Let´s Encrypt client togehter with [lexicon](https://github.com/AnalogJ/lexicon), which is standardises the way how to manipulate DNS records via their API [on multiple DNS providers](https://github.com/AnalogJ/lexicon#providers). We install both tools with Ansible:

```
  # This playbook should work for servers, that aren´t accessable from the internet (like our local Vagrant setup here)
  # Be sure to use a real/purchased domain!

  # The playbook automates all the steps mentioned here https://blog.thesparktree.com/generating-intranet-and-private-network-ssl
  - name: Update apt
    apt:
      update_cache: yes

  - name: Install openssl, curl, sed, grep, mktemp, git
    apt:
      name:
        - openssl
        - curl
        - sed
        - grep
        - mktemp
        - git
      state: latest

  # install this neat tool https://github.com/lukas2511/dehydrated
  - name: Install dehydrated
    git:
      repo: 'https://github.com/lukas2511/dehydrated.git'
      dest: /srv/dehydrated

  - name: Make dehydrated executable
    file:
      path: /srv/dehydrated/dehydrated
      mode: "+x"

  - name: Specify our internal domain
    shell: "echo '{{ gitlab_domain }}' > /srv/dehydrated/domains.txt"

  - name: Install build-essential, python-dev, libffi-dev, python3-pip
    apt:
      name:
        - build-essential
        - python-dev
        - libffi-dev
        - libssl-dev
        - python3-pip
      state: latest

  - name: Install requests[security]
    pip:
      name: "requests[security]"

  # install this neat tool https://github.com/AnalogJ/lexicon
  - name: Install dns-lexicon with correct provider (dns-lexicon[providernamehere])
    pip:
      name: "dns-lexicon[{{providername|lower}}]"
```

As we don´t have a publicly accessable server, we need to use `dns-01` challenges instead of the Let´s Encrypt standard `http-01`. Therefor dehydrated needs a hook file to work with `dns-01`. [lexicon](https://github.com/AnalogJ/lexicon) has such a file for us [/examples/dehydrated.default.sh](https://github.com/AnalogJ/lexicon/blob/master/examples/dehydrated.default.sh) and we copy it simply inside our playbook:

```
  - name: Configure lexicon with Dehydrated hook for dns-01 challenge
    get_url:
      url: https://raw.githubusercontent.com/AnalogJ/lexicon/master/examples/dehydrated.default.sh
      dest: /srv/dehydrated/dehydrated.default.sh
      mode: "+x"
```

At that point we need to use some private information about your DNS provider - because remember, the whole process could __only be done, if you have access to a real domain__. In order to grant lexicon access to your DNS provider´s API, we set some environment variables and then execute dehydrated:

```
  # be sure to check https://github.com/AnalogJ/lexicon#providers
  # the env variables are constructed with LEXICON_{DNS Provider Name}_{Auth Type}
  # since, the dynamic key name like LEXICON_{DNS Provider Name}_{Auth Type}, we can´t use the standard approach (http://docs.ansible.com/ansible/latest/user_guide/playbooks_environment.html)
  # because our Environment variable key names are dynamic based on the Provider name. Therefor we use the hint in https://stackoverflow.com/a/44570290/4964553
  # and construct the variables with "{'dynamic environment variable key name inkl. {{ vars }}':'{{ dynamic environment variable value}}'}"
  # If everything went fine, this should place the new Let´s Encrypt Certificates into /srv/dehydrated/certs/{{ gitlab_domain }}
  - name: Generate Certificates
    shell: "/srv/dehydrated/dehydrated --cron --hook /srv/dehydrated/dehydrated.default.sh --challenge dns-01 --accept-terms"
    environment:
      - PROVIDER: "{{providername|lower}}"
      - "{'LEXICON_{{providername|upper}}_USERNAME':'{{providerusername}}'}"
      - "{'LEXICON_{{providername|upper}}_TOKEN':'{{providertoken}}'}"
    ignore_errors: true
```

As you can see, all environment variables are set with the help of Ansible´s `--extra-vars` CLI like this:

```
ansible-playbook -i hosts prepare-gitlab.yml --skip-tags "docker,install_gitlab,gitlab_runner" --extra-vars "providername=yourProviderNameHere providerusername=yourUserNameHere providertoken=yourProviderTokenHere"
```

Just change `yourProviderNameHere`, `yourUserNameHere` and `yourProviderTokenHere` accordingly!

### Configure the "self-created" Let´s Encrypt certificates in Gitlab (it´s the same process for other certificates then Let´s Encrypt)

> Please don´t get confused with this part of the docs: https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-certificate-authorities, since that´s only needed, if you want to install a custom certificate authority and not necessary for correctly created Let´s Encrypt certificates (since the Let´s Encrypt authority is already trusted!)

[According to the docs there are 2 ways to configure HTTPS in Gitlab](https://docs.gitlab.com/omnibus/settings/nginx.html): The [automatic Let´s Encrypt way](https://docs.gitlab.com/omnibus/settings/ssl.html#let-39-s-encrypt-integration), which we sadly can´t use in our scenario here, where our Vagrant Box isn´t publically accessible - and [the way to manually configure HTTPS](https://docs.gitlab.com/omnibus/settings/nginx.html#manually-configuring-https), the one we need to choose here.

Therefore we set the `external_url` via the Environment variable `EXTERNAL_URL: "{{gitlab_url}}"` at the Gitlab Omnibus installation process to contain an `https`, in our example here: `https://gitlab.jonashackt.io` (remember you need to own the domain or at least need access to the DNS provider for the [Let´s Encrypt process for internal servers](https://github.com/jonashackt/gitlab-ci-stack#lets-encrypt-for-our-gitlab-on-virtualboxvagrant)).

After that, Gitlab Omnibus installation will look for certificates named `/etc/gitlab/ssl/gitlab.jonashackt.io.key` & `/etc/gitlab/ssl/gitlab.jonashackt.io.crt` - note that both file names are derived from the domain name `gitlab.jonashackt.io`.

Everything needed is done by the [letsencrypt.yml](letsencrypt.yml), it will just copy the generated certificates with the correct name to the correct location:

```
  - name: Create Gitlab cert import folder /etc/gitlab/ssl for later Gitlab Installation usage
    file:
      path: /etc/gitlab/ssl
      state: directory
    when: success

  - name: Copy certificate files to Gitlab cert import folder /etc/gitlab/ssl (see https://docs.gitlab.com/omnibus/settings/ssl.html#details-on-how-gitlab-and-ssl-work)
    copy:
      src: "{{ item.src }}"
      dest: "{{ item.dest }}"
      remote_src: yes
    with_items:
      - src: "/srv/dehydrated/certs/{{ gitlab_domain }}/fullchain.pem"
        dest: "/etc/gitlab/ssl/{{ gitlab_domain }}.crt"

      - src: "/srv/dehydrated/certs/{{ gitlab_domain }}/privkey.pem"
        dest: "/etc/gitlab/ssl/{{ gitlab_domain }}.key"

    when: success
```

Now you can use your Gitlab without cryptic error messages because of self-signed certificates:

![complete_https_letsencrypt_gitlab](screenshots/complete_https_letsencrypt_gitlab.png)

## Install Gitlab itself

The playbook [install-gitlab.yml](install-gitlab.yml) will walk through the standard Gitlab installation guide for Ubuntu - just automatically: https://about.gitlab.com/installation/#ubuntu (others are available also [like CentOS](https://about.gitlab.com/installation/#centos-6):

```
  - name: Update apt and autoremove
    apt:
      update_cache: yes
      cache_valid_time: 3600
      autoremove: yes

  - name: Install curl, openssh-server, ca-certificates & postfix
    apt:
      name:
        - curl
        - openssh-server
        - ca-certificates
        - postfix
      state: latest

  - name: Add the GitLab package repository
    shell: "curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash"

  - name: Update apt and autoremove
    apt:
      update_cache: yes
      cache_valid_time: 3600
      autoremove: yes

  - name: Install Gitlab with Omnibus-Installer
    apt:
      name: gitlab-ce
      state: latest
    environment:
      EXTERNAL_URL: "{{gitlab_url}}"
    ignore_errors: true
    register: gitlab_install_result

  - name: Gitlab Omnibus is based on Chef and will give many insight, what it does in the background
    debug:
      msg:
       - "The installation process said the following: "
       - "{{gitlab_install_result.stdout_lines}}"

  - name: Wait for Gitlab to start up
    wait_for:
      port: 443
      delay: 10
      sleep: 5

  - name: Let´s check, if Gitlab is up and running
    uri:
      url: "{{gitlab_url}}"

```

## Gitlab Container Registry

https://docs.gitlab.com/ee/user/project/container_registry.html

[Gitlab Container Registry domain configuration](https://docs.gitlab.com/ee/administration/container_registry.html#container-registry-domain-configuration)

If we just use our configured domain, we can follow the docs here: https://docs.gitlab.com/ee/administration/container_registry.html#configure-container-registry-under-an-existing-gitlab-domain

```
  - name: Activate Container Registry in /etc/gitlab/gitlab.rb
    lineinfile:
      path: /etc/gitlab/gitlab.rb
      line: " registry_external_url '{{ gitlab_registry_url }}'"

  - name: Reconfigure Gitlab to activate Container Registry
    shell: "gitlab-ctl reconfigure"
    register: reconfigure_result

  - name: Let´s see what Omnibus/Chef does
    debug:
      msg:
       - "The reconfiguration process gave the following: "
       - "{{reconfigure_result.stdout_lines}}"
```

The playbook [configure-gitlab-registry.yml](configure-gitlab-registry.yml) inserts the following needed config into the gitlab.rb: `registry_external_url 'https://gitlab.jonashackt.io:4567'` and this follows after a `sudo gitlab-ctl reconfigure`:

![configuring-gitlab-docker-registry](screenshots/configuring-gitlab-docker-registry.png)

### Ubuntu & Docker don´t know Let´s Encrypt so we need to copy the fullchain.pem instead of just the cert.pem!

The next problem was the following error while registering the gitlab-runners in [letsencrypt.yml](letsencrypt.yml):

```
ERROR: Registering runner... failed
runner=gyy8axxP status=couldn't execute POST against https://gitlab.jonashackt.io/api/v4/runners: Post https://gitlab.jonashackt.io/api/v4/runners: x509: certificate signed by unknown authority
PANIC: Failed to register this runner. Perhaps you are having network problems
```

To avoid that for now, I added the `--tls-ca-file` option like so: `--tls-ca-file=/etc/gitlab/ssl/gitlab.jonashackt.io.crt` which is described here: https://gitlab.com/gitlab-org/gitlab-runner/issues/230

But, then the next problem occured inside the Pipeline at the first step, where we want to use the Gitlab Container Registry:

```
Error response from daemon: Get https://gitlab.jonashackt.io:5000/v2/: x509: certificate signed by unknown authority
ERROR: Job failed: exit status 1
```

Luckily this problem was already solved by https://github.com/bkcsfi in https://github.com/moby/moby/issues/31602#issuecomment-379955352, where he states that the

```
I think you probably want to use fullchain.pem instead of cert.pem because neither docker (go lib) nor (ubuntu in my case) have LE root cert built in at this time

I have gitlab setup with LE certificate. Browser works fine, but docker fails to push to registry.
```

So all we have to do to tell the Gitlab Container Registry about our Let´s Encrypt certificates is to copy `/srv/dehydrated/certs/{{ gitlab_domain }}/fullchain.pem` instead of `/srv/dehydrated/certs/{{ gitlab_domain }}/cert.pem` to Gitlab certificates.

This configures also the Gitlab Container Registry, although it seems to be an configuration option for Gitlab itself only - just have a [look into the docs](https://docs.gitlab.com/ee/administration/container_registry.html#configure-container-registry-under-an-existing-gitlab-domain):

> If your TLS certificate is not in /etc/gitlab/ssl/gitlab.example.com.crt and key not in /etc/gitlab/ssl/gitlab.example.com.key uncomment the lines below ...

--> As our certiticates are named accordingly with the correct domain name, the Gitlab Container Registry also uses these certificates (and now our fullchain.pem). You can observe that while running an `sudo gitlab-ctl reconfigure` after you manually activated the `registry_external_url 'https://gitlab.jonashackt.io:4567'` inside the `/etc/gitlab/gitlab.rb`:

```
    ...

    - create new file /var/opt/gitlab/nginx/conf/gitlab-registry.conf
    - update content in file /var/opt/gitlab/nginx/conf/gitlab-registry.conf from none to 38ba8d
    --- /var/opt/gitlab/nginx/conf/gitlab-registry.conf	2018-05-23 07:06:18.857687999 +0000
    +++ /var/opt/gitlab/nginx/conf/.chef-gitlab-registry20180523-13668-614sno.conf	2018-05-23 07:06:18.857687999 +0000
    @@ -1 +1,59 @@
    +# This file is managed by gitlab-ctl. Manual changes will be
    +# erased! To change the contents below, edit /etc/gitlab/gitlab.rb
    +# and run `sudo gitlab-ctl reconfigure`.
    +
    +## Lines starting with two hashes (##) are comments with information.
    +## Lines starting with one hash (#) are configuration parameters that can be uncommented.
    +##
    +###################################
    +##         configuration         ##
    +###################################
    +
    +
    +server {
    +  listen *:4567 ssl;
    +  server_name  gitlab.jonashackt.io;
    +  server_tokens off; ## Don't show the nginx version number, a security best practice
    +
    +  client_max_body_size 0;
    +  chunked_transfer_encoding on;
    +
    +  ## Strong SSL Security
    +  ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
    +  ssl on;
    +  ssl_certificate /etc/gitlab/ssl/gitlab.jonashackt.io.crt;
    +  ssl_certificate_key /etc/gitlab/ssl/gitlab.jonashackt.io.key;

    ...
```

With this, we also don´t need to use the `--tls-ca-file` option to configure our gitlab-runners in [letsencrypt.yml](letsencrypt.yml) - the corresponding error is also gone now!

## Install Gitlab Runner

The [gitlab-runner.yml](gitlab-runner.yml) shows how to install and register the Gitlab Docker Runner in non-interactive mode:

As https://docs.gitlab.com/runner/install/linux-repository.html#installing-the-runner states, we need to add the Gitlab Runner package repository and install the Runner via apt-get.

Before we´re able to register the Runner, we need to extract the Registration Token somehow automatically from our Gitlab instance. Since there´s no API at the moment (see https://gitlab.com/gitlab-org/gitlab-ce/issues/24030, https://gitlab.com/gitlab-org/gitlab-runner/issues/1727), we need to obtain it quite hacky through a database call.

```
  # To register the Gitlab Runner, we need to obtain the Registration Token from our Gitlab instance
  # Because this will change every time we start up Gitlab (and/or Vagrant Box/Ansible setup, see https://gitlab.com/gitlab-org/gitlab-ce/issues/3703)
  # we need to access it somehow. Sadly there´s no API atm (see https://gitlab.com/gitlab-org/gitlab-ce/issues/24030,
  # https://gitlab.com/gitlab-org/gitlab-runner/issues/1727), so we have to dive directly into the Gitlab database :(
  - name: Extract Runner Registration Token via SQL query
    become: true
    become_user: gitlab-psql
    vars:
        ansible_ssh_pipelining: true
        query: "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"
        psql_exec: "/opt/gitlab/embedded/bin/psql"
        gitlab_db_name: "gitlabhq_production"
    shell: '{{ psql_exec }} -h /var/opt/gitlab/postgresql/ -d {{ gitlab_db_name }} -t -A -c "{{ query }}"'
    register: gitlab_runner_registration_token_result
```

## Configure Gitlab Runner with shell executor

As [the docs state](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#runner-configuration):

> There are three methods to enable the use of docker build and docker run during jobs; each with their own tradeoffs.

__Don't get confused:__ those three methods could be either applied to a the GitLab runner package installed directly on the host OS - or as an alternative to a GitLab runner pre-installed inside [a GitLab-provided Docker image called gitlab/gitlab-runner](https://hub.docker.com/r/gitlab/gitlab-runner/) - [see the docs for details](https://docs.gitlab.com/runner/register/#one-line-registration-command)

As "The simplest approach is to install GitLab Runner in shell execution mode", we use the `shell` executor for our setup primarily. The following ASCII art shows the simplicity of this approach:

```
                                    +----------------------------------------+
                                    |               shell runner             |
                                    |                                        |
                                    |                   uses                 |
                                    |                                        |
                                    |            HOST Docker-engine          |
                                    |                                        |
                                    |       with local image repository      |
                                    +----------------------------------------+
```

To register the Gitlab Docker Runner in [non-interactive mode](https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/commands/README.md#non-interactive-registration), we do the following inside our playbook:

```
  # see https://docs.gitlab.com/ce/ci/docker/using_docker_images.html#register-docker-runner
  # and this for non-interactive mode:
  # https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/commands/README.md#non-interactive-registration
  - name: Register Gitlab-Runners using shell executor
    shell: "gitlab-runner register --non-interactive --url '{{gitlab_url}}' --registration-token '{{gitlab_runner_registration_token}}' --description 'shell-runner-{{ item }}' --executor shell --tag-list shell"
    loop: "{{ range(1,gitlab_runner_count + 1)|list }}"
```

__Attention!__ Do not confuse these runner configurations with the "Non-Docker-in-Docker" gitlab-runner also named "docker"!

If you don't want to go with the flexible and locally testable solution using a Dockerfile and docker commands directly inside your `.gitlab-ci.yml` (be aware of the fact, that you can't develop your pipeline locally right now because of the missing pieces in the `gitlab-runner exec` implementation! (see https://gist.github.com/jonashackt/2cfbf366a6a6b70a78068ab043edb8f7 for details)), then there's another - sadly widly used - way of how to register GitLab runners described here: https://docs.gitlab.com/ce/ci/docker/using_docker_images.html#register-docker-runner __But as with its predecessors like Jenkins, GitLab must not be the goto CI solution in the future - and if you want to be able to change your CI system fast, I would advice you to NOT USE this way of GitLab CI!__.

### Configure a Docker-in-Docker enabled gitlab-runner with the docker executor

The second option on how to use standard Docker commands inside your `.gitlab-ci.yml`, is to use Docker-in-Docker (Dind) gitlab-runners - see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-workflow-with-docker-executor

Using this option, __the setup get's much more complex!__ In [this issue Tomasz Maczukin explains the setup very well](https://gitlab.com/gitlab-org/gitlab-ce/issues/41227):

```
                                    +----------------------------------------+
                                    |     HOST (docker-engine 1st level)     |
                                    |                                        |
                                    | /volume/for/builds # this is mounted   |
                                    |                      to all containers |
                                    |                      related to a job  |
                                    +----------------------------------------+
                                         ^                             ^
                                         |                             |
+----------------------------------------------+                 +----------------------------------------------+
|             docker:dind container            |       link      |         job container (docker:latest)        |
|                                              |---------------->|                                              |
| /       #containers root directory           | srvs_cnt:docker | /       #containers root directory           |
| /builds # builds directory mounted from host |                 | /builds # builds directory mounted from host |
|                                              |                 +----------------------------------------------+
|    with container local image repository     |
+----------------------------------------------+

```

There is also [a good blog post on the fallacies of Docker-in-Docker](https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/). If you still want to go that way though, read on.

Therefore we register our Dind runner like this - [incl. TLS enablement](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled) mounting the host certs therefore with ` --docker-volumes '/certs/client'` and as stated in the docs we also pin to `--docker-image 'docker:19.03.1'` the Docker version to prevent "unpredictable behavior, especially when new versions are released".

A downside of the Docker-in-Docker approach is also the usage of `--docker-privileged`, which can lead to security implications because we disable the security mechanisms of containers:

```
  - name: Register Gitlab-Runners using docker executor too
    shell: "gitlab-runner register --non-interactive --url '{{gitlab_url}}' --registration-token '{{gitlab_runner_registration_token}}' --description 'docker-in-docker-runner-{{ item }}' --executor docker --docker-image 'docker:19.03.1' --docker-privileged --docker-volumes '/certs/client' --tag-list dind"
    loop: "{{ range(1,gitlab_runner_count + 1)|list }}"

```

### Changes needed in .gitlab-ci.yml for Docker-in-Docker compared to using a shell runner

The example project https://github.com/jonashackt/gitlab-ci-dind-example provides a fully comprehensible example on how to use the Docker-in-Docker GitLab runner inside a [.gitlab-ci.yml](https://github.com/jonashackt/gitlab-ci-dind-example/blob/master/.gitlab-ci.yml):

```
# This .gitlab-ci.yml is an extension of the example provided in:
# https://github.com/jonashackt/restexamples/blob/master/.gitlab-ci.yml
# We use Docker in Docker here with a docker executor instead of the shell one
# --> Pinning the right Docker version for the service
image: docker:19.03.1

# Pinning the right Docker version for the service also
services:
  - docker:19.03.1-dind

variables:
  # see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled for Dind configuration
  # DOCKER_HOST: tcp://docker:2375 --> this should only be configured when using Kubernetes runners
  # When using dind, it's wise to use the overlayfs driver for
  # improved performance.
  DOCKER_DRIVER: overlay2
  # Specify to Docker where to create the certificates, Docker will
  # create them automatically on boot, and will create
  # `/certs/client` that will be shared between the service and job
  # container, thanks to volume mount from config.toml
  DOCKER_TLS_CERTDIR: "/certs"
  # see usage of Namespaces at https://docs.gitlab.com/ee/user/group/#namespaces
  REGISTRY_GROUP_PROJECT: $CI_REGISTRY/root/gitlab-ci-dind-example

# One of the new trends in Continuous Integration/Deployment is to:
# (see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html)
#
# 1. Create an application image
# 2. Run tests against the created image
# 3. Push image to a remote registry
# 4. Deploy to a server from the pushed image

stages:
  - build
  - test
  - push
  - deploy

# see how to login at https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#using-the-gitlab-container-registry
before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY

build-image:
  stage: build
  # the tag 'dind' advices only GitLab runners using this tag to pick up that job
  tags:
    - dind
  script:
    - docker build . --tag $REGISTRY_GROUP_PROJECT/gitlab-ci-dind-example:latest

...
```

Be sure to use a version-pinned Docker image with `image: docker:19.03.1` - since the configuration of the `.gitlab-ci.yml` depends on which Docker version you use. This setup here uses Docker `19.03.1`, from which on TLS-secured communication with the Docker daemon is the default (see https://about.gitlab.com/2019/07/31/docker-in-docker-with-docker-19-dot-03/ for more details).

The corresponding `dind` GitLab CI service should also be defined:

```
services:
  - docker:19.03.1-dind
```

Now if you don't use Kubernetes, than __you don't__ need to define the `DOCKER_HOST` variable starting from Docker `19.03.` on!

To speed up building speed, it's a good advice to use the overlayfs driver with `DOCKER_DRIVER: overlay2`.

Using `DOCKER_TLS_CERTDIR: "/certs"` tells Docker-in-Docker where to find the Docker generated certificates and establish a secured TLS connection to the Daemon.

The last step is to use `tags` to define the correct Gitlab runner for the `dind` jobs (see `Configure .gitlab-ci.yml Jobs to run only on specific gitlab-runners` paragraph).

### Configure a Docker socket binding enabled gitlab-runner with the docker executor

The [third option to to enable the use of docker build and docker run during jobs is to a Docker socket binding](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-socket-binding). It's also [often referred to a the "better Docker-in-Docker" option](https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/).

So let's also configure 2 GitLab runners with Docker socket binding enabled. We don't need to use `--docker-privileged` here, we just need to bind-mount the Docker socket:

```
  - name: Register Gitlab-Runners using docker executor too
    shell: "gitlab-runner register --non-interactive --url '{{gitlab_url}}' --registration-token '{{gitlab_runner_registration_token}}' --description 'docker-socket-runner-{{ item }}' --executor docker --docker-image 'docker:stable' --docker-volumes /var/run/docker.sock:/var/run/docker.sock --tag-list socket"
    loop: "{{ range(1,gitlab_runner_count + 1)|list }}"

```

We also tag this runner as the `socket` one, so we can explicitly let our Jobs run on that one.

### Changes needed in .gitlab-ci.yml for Docker-in-Docker compared to using a shell runner

The example project https://github.com/jonashackt/gitlab-ci-docker-socket-binding-example provides a fully comprehensible example on how to use the a Docker socket bound GitLab runner inside a [.gitlab-ci.yml](https://github.com/jonashackt/gitlab-ci-dind-example/blob/master/.gitlab-ci.yml):

```
# see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-socket-binding
image: docker:stable

# One of the new trends in Continuous Integration/Deployment is to:
# (see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html)
#
# 1. Create an application image
# 2. Run tests against the created image
# 3. Push image to a remote registry
# 4. Deploy to a server from the pushed image

stages:
  - build
  - test
  - push
  - deploy

# see usage of Namespaces at https://docs.gitlab.com/ee/user/group/#namespaces
variables:
  REGISTRY_GROUP_PROJECT: $CI_REGISTRY/root/gitlab-ci-shell-example

# see how to login at https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#using-the-gitlab-container-registry
before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY

build-image:
  stage: build
  # the tag 'shell' advices only GitLab runners using this tag to pick up that job
  tags:
    - socket
  script:
    - docker build . --tag $REGISTRY_GROUP_PROJECT/gitlab-ci-shell-example:latest

...
```

Besides the project name, there are only 2 differences to the shell runner needed here: Using `image: docker:stable` as the image for this pipeline and defining `socket` tag so that GitLab will only pick the correct Docker socket binding enabled runners for these jobs.

### Configure .gitlab-ci.yml Jobs to run only on specific gitlab-runners

As we register our gitlab-runners with tags like `dind` and `shell` - as we can see inside the runners configuration in the GitLab GUI also:

![gitlab-runners-with-tags](screenshots/gitlab-runners-with-tags.png)

So we can now configure our GitLab CI jobs to only run on these specific gitlab-runners - see https://docs.gitlab.com/ee/ci/yaml/#tags:

Use gitlab-runner 'shell':

```
build-image:
  stage: build
  tags:
    - shell
  script:
    - mvn clean install
```

Or use gitlab-runner 'dind':

```
build-image:
  stage: build
  tags:
    - dind
  script:
    - mvn clean install
```

and the Jobs will only be picked by the specifically tagges runners.

### Using the Gitlab Container Registry

https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#using-the-gitlab-container-registry

https://docs.gitlab.com/ee/user/project/container_registry.html#build-and-push-images

> Caution: Mind the Namespaces when working with Gitlab Container Registry!!!

### Namespaces (username, group or subgroup)

https://docs.gitlab.com/ee/user/group/#namespaces

## Import example project with .gitlab-ci.yml and run Gitlab CI pipeline

Now we´re nearly there. Just add a new password for the root user and login with that credentials. Then head over to to `Create a project` and there click on `Import Project` / `Repo by URL`:

![import-project](screenshots/import-project.png)

Paste the example Projects git URL into __Git repository URL__ field: `https://github.com/jonashackt/gitlab-ci-shell-example.git`, change Visibility Level to __Internal__ and hit __Create Project__.

Now at __CI / CD__ / __Pipelines__ fire up the Pipeline once (only this time manually since we didn´t push something new) and it should build a simple Spring Boot example project and push the resulting Image into our branch new Gitlab Container Registry:

![successful-first-pipeline-run](screenshots/successful-first-pipeline-run.png)

The example project [gitlab-ci-shell-example](https://github.com/jonashackt/gitlab-ci-shell-example) has a [prepared .gitlab-ci.yml already](https://github.com/jonashackt/gitlab-ci-shell-example/blob/master/.gitlab-ci.yml), so it should do everything smoothly:

```
# One of the new trends in Continuous Integration/Deployment is to:
# (see https://docs.gitlab.com/ee/ci/docker/using_docker_build.html)
#
# 1. Create an application image
# 2. Run tests against the created image
# 3. Push image to a remote registry
# 4. Deploy to a server from the pushed image

stages:
  - build
  - test
  - push
  - deploy

# see usage of Namespaces at https://docs.gitlab.com/ee/user/group/#namespaces
variables:
  REGISTRY_GROUP_PROJECT: $CI_REGISTRY/root/restexamples

# see how to login at https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#using-the-gitlab-container-registry
before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY

build-image:
  stage: build
  script:
    - docker build . --tag $REGISTRY_GROUP_PROJECT/restexamples:latest

test-image:
  stage: test
  script:
    - echo Insert fancy API test here!

push-image:
  stage: push
  script:
    - docker push $REGISTRY_GROUP_PROJECT/restexamples:latest

deploy-2-dev:
  stage: deploy
  script:
    - echo You should use Ansible here!
  environment:
    name: dev
    url: https://dev.jonashackt.io
```

And you should be able to see your newly pushed Image in the Gitlab Registry overview:

![gitlab-registry-overview](screenshots/gitlab-registry-overview.png)

And there´s also the Environments tab, witch is a great view on your Pipeline. Here you can track which Deployment went to which infrastructural stage:

![gitlab-environments](screenshots/gitlab-environments.png)

## GitLab Pages on self-hosted GitLab-Instance

GitLab supports to publish (and host) websites that are generated with a static site generator like Jekyll (https://docs.gitlab.com/ee/user/project/pages/).

https://docs.gitlab.com/ee/administration/pages/index.html

### Define another domain name for Pages

[As the docs state](https://docs.gitlab.com/ee/administration/pages/index.html#prerequisites):

> Have an exclusive root domain for serving GitLab Pages. Note that you cannot use a subdomain of your GitLab’s instance domain.

Which is mainly because of security reasons: `You should strongly consider running GitLab pages under a different hostname than GitLab to prevent XSS attacks`. GitLab and GitLab Pages would also share the same cookies and so on...

But: You don´t need a "real" root domain (which I interpret as seperate [Top-level domain](https://en.wikipedia.org/wiki/Top-level_domain) (TLD) ). I really struggled in the first place trying to use another TLD here. But we can simple serve our GitLab Pages at `pages.jonashackt.io`, which is simply another subdomain of the same top-level domain!

The great Vagrant DNS is [able to use multiple TLDs](https://github.com/BerlinVagrant/vagrant-dns#vm-options) with the `vm.dns.tlds` configuration key. Our [Vagrantfile](Vagrantfile) would then look like this:

```
# instead of
config.dns.tld = "io"

# we now use
config.dns.tlds = ["io", "me"]
```

A `scutil --dns` would reveal a new resolver together with our `io` one:

```
resolver #11
  domain   : io
  nameserver[0] : <IP_ADDRESS>
  port     : 5300
  flags    : Request A records, Request AAAA records
  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)

resolver #12
  domain   : me
  nameserver[0] : <IP_ADDRESS>
  port     : 5300
  flags    : Request A records, Request AAAA records
  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)
```

But it's nice, we don't need that here!

### Let´s Encrypt Wildcard certificates with dehydrated & lexicon

Let´s Encrypt is able to issue wildcard certificates [since early 2018](https://www.heise.de/security/meldung/Let-s-Encrypt-stellt-ab-sofort-Wildcard-Zertifikate-aus-3994552.html).

And our Let´s Encrypt client dehydrated is on [the list of ACME v2 supporting clients](https://letsencrypt.org/docs/client-options/), so it should be possible to [get a Wildcard certificate using dehydraded](https://github.com/lukas2511/dehydrated/blob/master/docs/domains_txt.md#wildcards):

> Support for wildcards was added by the ACME v2 protocol.

With this we simply need to create an `domains.txt` file containing the following:

```
gitlab.jonashackt.io
pages.jonashackt.io *.pages.jonashackt.io
```

> Be sure to verify if your DNS provider supports multiple TXT records for one domain! (see https://github.com/lukas2511/dehydrated/blob/master/docs/troubleshooting.md#dns-invalid-challenge-since-dehydrated-060--why-are-dns-challenges-deployed-first-and-verified-later)

We´re doing that right inside our [obtain-letsencrypt-certs-dehydrated-lexicon.yml](obtain-letsencrypt-certs-dehydrated-lexicon.yml) playbook using the Ansible copy module together with the `content` configuration:

```yaml
 # In addition to the GitLab domain, we need to issue a wildcard certificate for GitLab Pages
  # see https://github.com/lukas2511/dehydrated/blob/master/docs/domains_txt.md#wildcards
  # in the format service.example.com *.service.example.com
  - name: Specify our domains
    copy:
      dest: "/srv/dehydrated/domains.txt"
      content: |
        {{ gitlab_domain }}
        {{ gitlab_pages_domain }} *.{{ gitlab_pages_domain }}
```

The later executed dehydrated command will pick up the `domains.txt` file and retrieve all certificates for the domains mentioned inside the file:

```bash
/srv/dehydrated/dehydrated --cron --hook /srv/dehydrated/dehydrated.default.sh --challenge dns-01 --accept-terms
```

### Configure Pages in GitLab with Ansible

Simply run all the playbooks again or

```
# freshly generate certificates for GitLab pages with
ansible-playbook -i hosts prepare-gitlab.yml --tags "letsencrypt" --extra-vars "providername=yourProviderNameHere providerusername=yourUserNameHere providertoken=yourProviderTokenHere"

# then configure GitLab pages with
ansible-playbook -i hosts prepare-gitlab.yml --tags "pages"
```

After the successful playbook run you should be able to spot the new __Pages__ menu:

![gitlab-pages](screenshots/gitlab-pages.png)

### A new Jekyll site

There is a huge list of possible static site generators for the use with GitLab Pages. Just have a look here: https://gitlab.com/pages

I took Jekyll just out because I already know it from my personal site leveraging GitHub Pages: https://github.com/jonashackt/jonashackt.github.io

Using an example project would be easy - just pick https://gitlab.com/pages/jekyll and import it into your GitLab instance (__New Project__ / __Import__ etc).

But for comprehensibility reasons, let´s create a new [Jeykll](https://jekyllrb.com/) project from scratch. You´ll need some steps to accomplish this, since there are prerequisites (I'am using a Mac here, see this page for other OSses: https://jekyllrb.com/docs/installation/#requirements)

> make sure your ruby installation works and doesn´t interfer with Apple's system-wide ruby installation (which will lead to bad errors!)

```
# you need to have a ruby installation in place:
brew install ruby

# be sure to use the correct (brew installed) ruby version on your Mac - and not the system wide Apple version!
# therefore upgrade your user/.bash_profile file with adding:
export PATH="/usr/local/opt/ruby/bin:$PATH"

# upgrade to latest RubyGems (don´t do this with sudo(!), which would again alter your system wide Apple ruby version)
gem update --system

# then we need to install the packages bundler and jekyll
gem install bundler jekyll
```

Let's create a new git repository inside GitLab:

![gitlab-pages-empty-repository](screenshots/gitlab-pages-empty-repository.png)

Then clone it locally and then you should be able to create a new Jekyll blog within it:

```
jekyll new blog
```

If your ruby installation didn´t work, is broken or you just don´t want to hassle with that, you could also use the Docker ruby image and do everything inside a container:
```
docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app ruby:2.5 bash -c "gem install bundler jekyll; jekyll new blog; ls -l"
```

This will bootstrap a new Jekyll skeleton which should be buildalbe and shippable right out-of-the-box. Simply `cd` into the `blog` directory and run

```
bundle exec jekyll serve
```

If that brings some error like `Could not find foobar-package-3.0.3 in any of the sources` you might need to install dependencies with `bundle install` or `bundle install --path vendor/bundle`.

Now open your Browser and head to http://<IP_ADDRESS>:4000/ - you should see our new Blog freshly backed by Jekyll:

![gitlab-pages-local-jekyll](screenshots/gitlab-pages-local-jekyll.png)

### Deploy Jekyll as GitLab Pages with GitLab CI & Docker

Every GitLab Pages repository needs a `.gitlab-ci.yml`, that will use GitLab CI to run the Ruby based build process of Jekyll and publish your Static site.

I have prepared a working `docker run command` based on the [official ruby Docker image](https://hub.docker.com/_/ruby/), which will output the resulting site into `public` directory inside your Jekyll site:

```
docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app ruby:2.5 bash -c "bundle install; bundle exec jekyll build -d public"
```

Now with this it is easy to craft our `.gitlab-ci.yml`:

```
pages:
  stage: deploy
  script:
  - docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app ruby:2.5 bash -c "bundle install; bundle exec jekyll build -d public; ls -l"
  artifacts:
    paths:
    - public
  only:
  - master
```

Add all the files incl. the `.gitlab-ci.yml` to your Git repository - just be sure to extend your `.gitignore` like this:

```
_site
.sass-cache
.jekyll-metadata
public
vendor
.bundle
```

Then commit and push into GitLab. Your CI/CD pipeline should run successfully:

![gitlab-pages-successful-first-jekyll-build](screenshots/gitlab-pages-successful-first-jekyll-build.png)

Now go to __Settings/Pages__ inside your repository to find the URL where you can access your GitLab Page for this repository.

# Links

* Gitlab CI REFERENCE docs: https://docs.gitlab.com/ce/ci/yaml/README.html

* Install Gitlab with Docker: https://docs.gitlab.com/omnibus/docker/

* How to build Docker containers with Gitlab: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html

* Why to bind mount docker.sock into your Gitlab Docker Container (instead of using Docker-in-Docker): https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/

* Good, but little old post abt installing Gitlab https://gitlabfan.com/setting-up-your-own-fully-functional-gitlab-https-registry-ci-runners-79901ac617c0


text:
# Avalonia

| Gitter Chat | Windows Build Status | Linux/Mac Build Status |
|---|---|---|
| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Build Status](https://travis-ci.org/AvaloniaUI/Avalonia.svg?branch=master)](https://travis-ci.org/AvaloniaUI/Avalonia) |

## About

Avalonia is a WPF-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of OSs: Windows (.NET Framework, .NET Core), Linux (GTK), MacOS, Android and iOS.

Avalonia is now in alpha. This means that framework is now at a stage where you can have a play and hopefully create simple applications. There's still a lot missing, and you *will* find bugs, and the API *will* change, but this represents the first time where we've made it somewhat easy to have a play and experiment with the framework.

| Control catalog | Desktop platforms | Mobile platforms |
|---|---|---|
|  |  |  |

## Getting Started

Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started. After installing it, open "New Project" dialog in Visual Studio, choose "Avalonia" in "Visual C#" section, select "Avalonia .NET Core Application" and press OK (screenshot). Now you can write code and markup that will work on multiple platforms!

Avalonia is delivered via NuGet package manager. You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed))

Use these commands in Package Manager console to install Avalonia manually:
```
Install-Package Avalonia
Install-Package Avalonia.Desktop
```

## Bleeding Edge Builds

Try out the latest build of Avalonia available for download here:
https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master/artifacts

## Documentation

As mentioned above, Avalonia is still in alpha and as such there's not much documentation yet. You can take a look at the [getting started page](http://avaloniaui.net/tutorial/gettingstarted) for an overview of how to get started but probably the best thing to do for now is to already know a little bit about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/AvaloniaUI/Avalonia).

There's also a high-level [architecture document](http://avaloniaui.net/spec/architecture) that is currently a little bit out of date, and I've also started writing blog posts on Avalonia at http://grokys.github.io/.

Contributions are always welcome!

## Building and Using

See the [build instructions here](http://avaloniaui.net/guidelines/build).

## Contributing

Please read the [contribution guidelines](http://avaloniaui.net/guidelines/contributing) before submitting a pull request.

repository: StarkTiger/Avalonia

repo_name: StarkTiger/Avalonia


text:
# envconfig

[![Build Status](https://travis-ci.org/kelseyhightower/envconfig.svg)](https://travis-ci.org/kelseyhightower/envconfig)

```Go
import "github.com/kelseyhightower/envconfig"
```

## Documentation

See [godoc](http://godoc.org/github.com/kelseyhightower/envconfig)

## Usage

Set some environment variables:

```Bash
export MYAPP_DEBUG=false
export MYAPP_PORT=8080
export MYAPP_USER=Kelsey
export MYAPP_RATE="0.5"
export MYAPP_TIMEOUT="3m"
export MYAPP_USERS="rob,ken,robert"
export MYAPP_COLORCODES="red:1,green:2,blue:3"
```

Write some code:

```Go
package main

import (
    "fmt"
    "log"
    "time"

    "github.com/kelseyhightower/envconfig"
)

type Specification struct {
    Debug       bool
    Port        int
    User        string
    Users       []string
    Rate        float32
    Timeout     time.Duration
    ColorCodes  map[string]int
}

func main() {
    var s Specification
    err := envconfig.Process("myapp", &s)
    if err != nil {
        log.Fatal(err.Error())
    }
    format := "Debug: %v\nPort: %d\nUser: %s\nRate: %f\nTimeout: %s\n"
    _, err = fmt.Printf(format, s.Debug, s.Port, s.User, s.Rate, s.Timeout)
    if err != nil {
        log.Fatal(err.Error())
    }

    fmt.Println("Users:")
    for _, u := range s.Users {
        fmt.Printf("  %s\n", u)
    }

    fmt.Println("Color codes:")
    for k, v := range s.ColorCodes {
        fmt.Printf("  %s: %d\n", k, v)
    }
}
```

Results:

```Bash
Debug: false
Port: 8080
User: Kelsey
Rate: 0.500000
Timeout: 3m0s
Users:
  rob
  ken
  robert
Color codes:
  red: 1
  green: 2
  blue: 3
```

## Struct Tag Support

Envconfig supports the use of struct tags to specify alternate, default, and required
environment variables.

For example, consider the following struct:

```Go
type Specification struct {
    ManualOverride1 string `envconfig:"manual_override_1"`
    DefaultVar      string `default:"foobar"`
    RequiredVar     string `required:"true"`
    IgnoredVar      string `ignored:"true"`
    AutoSplitVar    string `split_words:"true"`
    RequiredAndAutoSplitVar    string `required:"true" split_words:"true"`
}
```

Envconfig has automatic support for CamelCased struct elements when the
`split_words:"true"` tag is supplied. Without this tag, `AutoSplitVar` above
would look for an environment variable called `MYAPP_AUTOSPLITVAR`. With the
setting applied it will look for `MYAPP_AUTO_SPLIT_VAR`. Note that numbers
will get globbed into the previous word. If the setting does not do the
right thing, you may use a manual override.

Envconfig will process value for `ManualOverride1` by populating it with the
value for `MYAPP_MANUAL_OVERRIDE_1`. Without this struct tag, it would have
instead looked up `MYAPP_MANUALOVERRIDE1`. With the `split_words:"true"` tag
it would have looked up `MYAPP_MANUAL_OVERRIDE1`.

```Bash
export MYAPP_MANUAL_OVERRIDE_1="this will be the value"

# export MYAPP_MANUALOVERRIDE1="and this will not"
```

If envconfig can't find an environment variable value for `MYAPP_DEFAULTVAR`,
it will populate it with "foobar" as a default value.

If envconfig can't find an environment variable value for `MYAPP_REQUIREDVAR`,
it will return an error when asked to process the struct.  If
`MYAPP_REQUIREDVAR` is present but empty, envconfig will not return an error.

If envconfig can't find an environment variable in the form `PREFIX_MYVAR`, and there
is a struct tag defined, it will try to populate your variable with an environment
variable that directly matches the envconfig tag in your struct definition:

```shell
export SERVICE_HOST=<IP_ADDRESS>
export MYAPP_DEBUG=true
```
```Go
type Specification struct {
    ServiceHost string `envconfig:"SERVICE_HOST"`
    Debug       bool
}
```

Envconfig won't process a field with the "ignored" tag set to "true", even if a corresponding
environment variable is set.

## Supported Struct Field Types

envconfig supports these struct field types:

  * string
  * int8, int16, int32, int64
  * bool
  * float32, float64
  * slices of any supported type
  * maps (keys and values of any supported type)
  * [encoding.TextUnmarshaler](https://golang.org/pkg/encoding/#TextUnmarshaler)
  * [encoding.BinaryUnmarshaler](https://golang.org/pkg/encoding/#BinaryUnmarshaler)
  * [time.Duration](https://golang.org/pkg/time/#Duration)

Embedded structs using these fields are also supported.

## Custom Decoders

Any field whose type (or pointer-to-type) implements `envconfig.Decoder` can
control its own deserialization:

```Bash
export DNS_SERVER=<IP_ADDRESS>
```

```Go
type IPDecoder net.IP

func (ipd *IPDecoder) Decode(value string) error {
    *ipd = IPDecoder(net.ParseIP(value))
    return nil
}

type DNSConfig struct {
    Address IPDecoder `envconfig:"DNS_SERVER"`
}
```

Also, envconfig will use a `Set(string) error` method like from the
[flag.Value](https://godoc.org/flag#Value) interface if implemented.

repository: knative/serving

branch_name: refs/heads/main

gha_language: Go

repo_name: knative/serving


text:
---
templateKey: blog-post
title: 'Girl Scout Bully Prevention Class - Jan. 13, 19'
order: 30
date: 2019-01-04T00:00:00.000Z
description: >-
  ATJIUJITSUNYC helps the Girl Scouts learn some BJJ to learn how to defend
  themselves and prevent bullying.
thumbnail: /img/girl-scouts-02.png
home: false
tags:
  - Blog
---
## We help the Girl Scouts prevent bullying

Bullying is a big problem that can be resolved with confidence and skill. We teach the girl scouts self defense in Brazilian Jiu-Jitsu. We never start fights, but we always defend ourselves and each other!

- - -

![

gha_language: CSS


text:
### npm-base-package
***

A basic npm package setup with grunt, jshint and blanket coverage reports for unit tests.

I wanted something basic that I could copy/paste and rename a few items in order to have jshint, coverage reports and grunt already setup with watchers.

Using this is quite simple. Just clone down the repo and it's a basic copy paste to your own folder.  Once you've copied it make the following changes:

***lib/module.js***
  ~ Rename file to the name of your package.

***test/module-tests.js***
  ~ Rename file to match module.name-tests.js and inside ensure you are requiring the correct module name.

***package.json***
  ~ Replace all instances of npm-base-package with your own, update git urls and update the entry point file reference.

### Private Use

There are times when you want to make a package that when used always creates a new instance of itself. Such as your typical "car" model.

Example usage of the private module would be:

```javascript
// it can be instantiated multiple ways
// declaring the class as a variable
var carClass = require('module-private');
// then using it
var car = carClass(options, eventHandlers);
var car = new carClass(options, eventHandlers);

// just using the class by itself
var car = require('module-private')(options, eventHandlers);
var car = new require('module-private')(options, eventHandlers);

// options and eventHandlers are objects
// e.g.
var car = require('module-private')({
    logger: console
}, {
    initialized: function () {
        console.log('ready to use');
    }
});
var car = new require('module-private')({
    logger: console
}, {
    initialized: function () {
        console.log('ready to use');
    }
});

// currently any event being subscribed to that is called immediately on setup must be subscribed to in the passed arguments
// any other event you create after that is fine to call with car.on('someevent', fn);
```

Each instance will be it's own.

### Shared Use

Note: If anyone knows how or why I can't setup event emitter to work like the private example let me know!

If you were to make helper module that once instantiated needed to be shared among many. Any changes by one caller affects all others.

Example usage of the shared module would be:

```javascript
var sharedModule = require('module-shared');
var instance1 = sharedModule(options);
var instance2 = sharedModule(options);
// because instance1 already "initialized" the module, the second call would just return the first one.

// setting a name means all instances will share the same variable
instance1.name = "name1";
console.log(instance2.name); // results in "name1"
```

repository: Icehunter/npm-base-package

repo_name: Icehunter/npm-base-package


text:
fabric8-persistence-demo
======================

Fabric8 + E-OSGi JPA 2.1 managed persistence (Aries + Hibernate 4.3.x) + REST service demonstration code.

# Pre-requisites

* JDK 7
* Maven 3.1.0 or newer

# Build and install

```
mvn clean install
```

# Provisioning

## Installation and initial configuration

* Download [latest build](https://repository.jboss.org/nexus/content/repositories/ea/io/fabric8/fabric8-karaf/) for ```fabric-karaf``` and extract it.
*(tested on fabric8-karaf-1.2.0.Beta3)*
* Extract it
* Start Fabric
```no-highlight
bin/fabric8
```

If everything goes well, you should get a Fabric shell that looks like this:

```
Please wait while Fabric8 is loading...
100% [========================================================================]

______    _          _      _____
|  ___|  | |        (_)    |  _  |
| |_ __ _| |__  _ __ _  ___ \ V /
|  _/ _` | '_ \| '__| |/ __|/ _ \
| || (_| | |_) | |  | | (__| |_| |
\_| \__,_|_.__/|_|  |_|\___\_____/
  Fabric8 Container (1.2.0.Beta3)
  http://fabric8.io/

Type 'help' to get started
and 'help [cmd]' for help on a specific command.
Hit '<ctrl-d>' or 'osgi:shutdown' to shutdown this container.

Open a browser to http://localhost:8181 to access the management console
```

## Define our own profile
```
profile-create --parents quickstarts-karaf-cxf-rest persistence-example
profile-edit --repositories mvn:com.github.pires.example/feature-persistence/0.1-SNAPSHOT/xml/features persistence-example
profile-edit --features persistence-aries-hibernate persistence-example
```

## Create and run new container with newly created profile

```
container-create-child --profile persistence-example root test
```

# Testing

In Hawt.io UI, go to ```API``` tab (in the parent container), check the host and port where ```UserService``` is available and point it down. Test the REST endpoint as you wish!

## REST API (JSON)

Create new user
```
PUT /user

Example JSON:
{
  "name":"Pires"
}
```

Count users
```
GET /user/count
```

List users
```
GET /user
```

### curl commands
```
curl -H "Accept: application/json" -H "Content-type: application/json" -X PUT -d '{"name":"Pires"}' http://localhost:8182/cxf/demo/user ; echo

curl -H "Accept: application/json" -H "Content-type: application/json" -X GET  http://localhost:8182/cxf/demo/user/count ; echo
```

# Developing

If you are changing these bundles remember you can use the ``fabric:watch *`` command.  Fabric will automatically update bundles that change after a ``mvn install``


text:
---
layout: postag
title: 'SYM'
shortdef: 'symbol'
---

Same as the English [Universal Dependencies:](http://universaldependencies.org/u/pos/SYM.html) documentation. We did not come across SYM tags in UD-Telugu-V1.

repository: PhyloStar/UDTelugu

repo_name: PhyloStar/UDTelugu


text:
### [Normal Horn Assembly](#normal-horn-assembly)

A normal horn is the standard horn for the DYNAMIXEL X540 series. The normal horn can be assembled to the output shaft wheel gear of a front case of DYNAMIXEL, and it can be used to connect DYNAMIXEL with frames.

![Horn_Assembly](/assets/images/dxl/x/assembly/x430/hn12-n101_assembly.png)

**WARNNING**: Be sure to align the thrust washer properly with the output shaft. Otherwise, the thrust washer can be damaged by the assembled horn.
  ![HowTo_Thrust_Washer](/assets/images/dxl/x/assembly/common/thrust_washer_02.png)
{: .notice--warning}

**NOTE**: Note that the position of align mark of the horn should be lined to the position of the align mark of the output shaft in assembly.
  ![Horn_Marking](/assets/images/dxl/x/assembly/common/horn_assembly_marking.png)
{: .notice}

### [Idler Horn Assembly](#idler-horn-assembly)

The idler horn can be used for an hinge frame assembly with the DYNAMIXEL normal horn.

Additionally, utilizing the hole of the idler horn provides a neat cable wiring solution. Click the ![](/assets/images/icon_unfold.png) note below for how-to.

![HowTo_Idler_Assembly](/assets/images/dxl/x/assembly/common/idler_assembly.png)

<details>
<summary>
![](/assets/images/icon_unfold.png) **Find Cable Wiring Throuh a Back Case Here**
</summary>

![](/assets/images/dxl/x/wiring_through_back_case.jpg)

{% include en/dxl/hollow_cabling.md %}
</details>

#### [Idler Horn Disassembly](#idler-horn-disassembly)

To disassemble the attached idler horn, push the button located on the reverse side of a back case and pull a hook to disconnect.

![HowTo_Idler_Disassembly](/assets/images/dxl/x/assembly/common/idler_disassably.png)

repository: ROBOTIS-GIT/emanual

gha_language: JavaScript

repo_name: ROBOTIS-GIT/emanual


text:
# SeReMAS
This repository complements the paper **SeReMAS: Self-Resilient Mobile Autonomous Systems Through Predictive Edge Computing** accepted for publication at IEEE International Conference on Sensing, Communication and Networking 2021.
[preprint](https://arxiv.org/abs/2105.15105)
conference - to come when published on IEEE
```bibtex
@article{callegaro2021seremas,
  title={SeReMAS: Self-Resilient Mobile AutonomousSystems Through Predictive Edge Computing},
  author={Callegaro, Davide and Levorato, Marco and Restuccia, Francesco},
  journal={arXiv preprint arXiv:2105.15105},
  year={2021}
}
```

[![Conference video teaser](https://i.ytimg.com/vi/Tv1cW5uag-8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDTbZjePPSVWaSjJ_w2jwzdpDvGAA)](https://www.youtube.com/watch?v=Tv1cW5uag-8&ab_channel=IEEESECONConference)

### Installation instructions:
- clone repository
```bash
git clone https://github.com/uci-iasl/SeReMAS.git
```
- enter the directory and create a Python3 virtual environment and install the requirements into the newly created virtual environment
```bash
cd SeReMAS
python3 -m venv venv
source venv/bin/activate
pip install -r requirements
```
- (install and) run a [SITL](https://ardupilot.org/dev/docs/setting-up-sitl-on-linux.html)
```bash
cd ardupilot/ArduCopter
sim_vehicle.py
```

### Fast run
Now we want to run 2 scripts: on is an edge server, which supports the computation of the drone.
You can run the edge server:
```bash
python edge.py localhost
```
Then run the drone script:
```bash
python drone_demo.py --fly --move --c <IP_ADDRESS>:14550 --model 2
```

### Add some visual
Note: if you want to see the drone moving in some sort of visual manner, I recommend the following setup.
- Download [SITL](https://ardupilot.org/dev/docs/setting-up-sitl-on-linux.html)
- When running the SITL simulator
```bash
cd ardupilot/ArduCopter
sim_vehicle.py
```
in the pop up terminal use
```bash
output add <IP_ADDRESS>:14553
```
This allows us to connect two instances to the simulated copter. One is the visualization, the other the SeReMAS framework.
- Connect QGroundControl - this will connect automatically to <IP_ADDRESS>:14550. If it does not happen, the GUI is easy to use. Send me an email if it takes more than 15mins!

Now run SeReMAS:
```bash
python drone_demo.py --fly --move --c <IP_ADDRESS>:14553 --model 2
```
You notice we changed the port we connect to. That's it, that's the magic.

### Suggestions
Use this software mainly for flying simualted MAVLink enabled environment.
Note that when using it on a real Unmanned Aerial Vehicle we always respect all local, regional and national regulations. We always have a strong reliable Radio Controlled connection to Return To Launch or Land or turn off if necessary. Multi-copters are inherently dangerous and their operation should be done with plenty of caution.

### Disclaimer
All the code provided is given as-is. This is prototype-grade code, not extensively tested. Run at your own risk.
We are not responsible for any improper use. Strongly suggest to use it only in simulated enviroment.

Let me know if I can help with an email to [dcallega@uci.edu](mailto:dcallega@uci.edu).

repository: uci-iasl/SeReMAS

repo_name: uci-iasl/SeReMAS


text:
# Connect-4-Minimax-AI

Overview

An artificial intelligence to play the board game connect four.
Developed in Java, the program works by looking ahead at all
possible future moves and evaluating the game's state.
From here, the best possible move is chosen. It features a pre-computed
look-up table for fast board evaluations and different player variations including;
a random insertion AI, a minimax AI, an alpha beta pruning minimax AI and human input.
A demonstration of a minimax tree is shown below.

Board Evaluation

The evaluation function simply looks all possible ways to make a four in a row and scores the board accordingly.
Additional points are also awarded for placement in the center column and on specific rows. The specific implementation
of the evaluation function can be seen in TableBuilder.java and can be seen in use in Game.java.

Running time for the algorithm grows exponentially as the depth of the minimax tree is increased. This makes searching 42 moves ahead computationally infeasible. My results when developing the program are shown in the graph below with the implementation of
basic logic (if statements) for the evaluation function, converting basic logic to a look-up table, and alpha beta pruning.

X = Tree Depth, Y = Milliseconds


text:
# news site

## team members

* Jason Zhu, 467138
* Zexi Liu, 467319

## docker compose

There are two container for this project, the php-apache web server and the mysql database.

An instance is running in <http://ec2-52-14-93-16.us-east-2.compute.amazonaws.com:9000/>. That is, the 80 port of web container is mapped to 9000 port of the host machine, the EC2 instance.

* the web server container is built via a Dockerfile under the root dir
    1. builds from FROM php:5.6-apache
    2. install mysql connection tools
    3. copy public_html/ into /var/www/html of the container

* the mysql container is built via a Dockerfile under the db/ dir
    1. it built from mysql:5.7.22
    2. initialize the database using db/init.sql, which defines the database schema

run following command if you edit some code and want to test:
```bash
docker-compose down
docker-compose build
docker-compose up
```

## Additiona Details

1. Users can delete and edit their story and articles in their own main page
2. the search bar is on the right top of the main page
3. test codes under /private/tests are now forbidden

## Creative Portion

1. create a user main page where users can find all news they post
2. create a user main page where users can find all comments they post
3. if you login, you can search all stories written by a user by his email

## structure of the dir

Php files for back-end logic and database are under /private dir and it's Forbidden.

```
.
├── README>MD
└── public_html
    ├── img
    └── private
        ├── User.php
        └── ...

```

## todo-list
the todo list is powered by a extension of vscode called Todo+
<https://marketplace.visualstudio.com/items?itemName=fabiospampinato.vscode-todo-plus>

repository: hellozexi/NewsShare

repo_name: hellozexi/NewsShare


text:
# Snapshot report for `test\generated\commands\zrange.test.js`

The actual snapshot is saved in `zrange.test.js.snap`.

Generated by [AVA](https://ava.li).

## scripts/redis-doc/commands/zrange.md example 1

> Snapshot 1

    [
      'await handy.zadd("myzset", [1, "one"])    => 1',
      'await handy.zadd("myzset", [2, "two"])    => 1',
      'await handy.zadd("myzset", [3, "three"])  => 1',
      'await handy.zrange("myzset", 0, -1)       => ["one","two","three"]',
      'await handy.zrange("myzset", 2, 3)        => ["three"]',
      'await handy.zrange("myzset", -2, -1)      => ["two","three"]',
    ]

## scripts/redis-doc/commands/zrange.md example 2

> Snapshot 1

    [
      'await handy.zrange("myzset", 0, 1, "WITHSCORES")  => []',
    ]

repository: liam-betsworth/handy-redis

repo_name: liam-betsworth/handy-redis


text:
# Transparent Blue
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/custom-components/hacs)
 ![GitHub release (latest by date)](https://img.shields.io/github/v/release/johlc/transparentblue?label=Version&style=flat-square&labelColor=2ea9f4&color=1473ae)
![GitHub All Releases](https://img.shields.io/github/downloads/johlc/transparentblue/total?&label=Total%20Downloads&style=flat-square&labelColor=2ea9f4&color=1473ae) ![.github/workflows/validate.yaml](https://github.com/JOHLC/transparentblue/workflows/.github/workflows/validate.yaml/badge.svg)

## A transparent blue theme for Home Assistant
This is a theme I created for Home Assistant called Transparent Blue. This is/was my first ever custom theme for Home Assistant and my first ever GitHub/HACS repository.

It can be installed via HACS or manually with help from the instructions below.

### Screenshots
**Main**

**Sidebar**

**Misc.**

[Included background image](https://github.com/JOHLC/transparentblue/blob/main/images/background.jpg)

## HACS installation - recommended

Transparent Blue is now a default repo in HACS!
1. Open HACS
2. Select "Frontend"
3. Click add (+)
4. Search for Transparent Blue and click it
5. Click Install
You should now be able to select this theme in Home Assistant

### Manual Installation - not recommended

1. Download the transparentblue.yaml file from the latest release
2. Upload the downloaded file to your "themes" directory
3. Add the resource reference to your lovelace config

You should now be able to select this theme in Home Assistant

#### Changing the background image

This theme uses a base64 encoded image. I use [this](https://www.base64-image.de/) website to encode my images.

To change the background of this theme, change the following in the .yaml file:

````
lovelace-background: 'center / cover no-repeat fixed url()'
````

In between the brackets in the url() section, add your own base64 string. Example: url('data:image/png;base64,YOURLONGSTRING)

You can also add a local image stored in your config/www directory or a publicly accessible image url like so

````
lovelace-background: 'center / cover no-repeat fixed url("/local/background.png")'
# OR
# lovelace-background: 'center / cover no-repeat fixed url("http://www.reportingday.com/wp-content/uploads/2018/06/Cat-Sleeping-Pics.jpg")'
````

#### Beta versions
From time to time I will be releasing beta versions. This is mainly for personal testing before merging dev branch changes. If you are using HACS you can enable / disable these beta versions by changing the setting "Show beta versions"

repository: avrghz/transparentblue

repo_name: avrghz/transparentblue


text:
# polygon.js

## Install

__nodejs__

`npm install polygon`

## Usage

Create a new polygon:

```javascript
var p = new Polygon([
  Vec2(0, 0),
  Vec2(10, 0),
  Vec2(0, 10)
]);

```

You can pass an array of `Vec2`s, arrays `[x, y]`, or objects `{ x: 10, y: 20 }`

## Supported Methods

* `each(function(prev, current, next, idx) {})`
* `point(idx)` - returns the point at index `idx`. note: this will wrap in both directions
* `dedupe(returnNew)` - ensure all of the points are unique
* `insert(vec2, index)` - insert `vec2` at the specified index
* `remove(vecOrIndex)` - remove the specified `vec2` or numeric index from this polygon
* `clean(returnNew)` - removes contiguous points that are the same
* `winding()` - returns the direction in which a polygon is wound (true === clockwise)
* `rewind(bool)` - rewinds the polygon in the specified direction (true === clockwise)
* `area()` - computes the area of the polygon
* `closestPointTo(vec2)` - finds the closest point in this polygon to `vec2`
* `center()` - returns a `Vec2` at the center of the AABB
* `scale(amount, origin, returnNew)` - scales this polygon around `origin` (default is `this.center()`) and will return a new polygon if requested with `returnNew`
* `containsPoint(vec2)` - returns true if `vec2` is inside the polygon
* `containsPolygon(poly)` - returns true if `poly` is completely contained in this polygon
* `aabb()` - returns an object `{x:_, y:_, w:_, h:_}` representing the axis-aligned bounding box of this polygyon
* `offset(amount)` - performs an offset/buffering operation on this polygon and returns a new one
* `line(index)` - return an array `[startpoint, endpoint]` representing the line at the specified `index`
* `lines(function(start, end, index) {})` - iterate over the lines in this polygon
* `selfIntersections` - find self-intersections and return them as a new polygon
* `pruneSelfIntersections` - remove self intersections from this polygon.  returns an array of polygons
* `length` - returns the number of points in this polygon
* `clone` - return a new instance of this polygon
* `rotate(rads, vec2, returnNew)` - rotate by origin `vec2` (default `this.center()`) by radians `rads` and return a clone if `returnNew` is specified
* `translate(vec2, returnNew)` - translate by `vec2` and return a clone if `returnNew` is specified
* `equal(poly)` - return true if this polygon has the same components and the incoming `poly`
* `contains(thing)` - works with an array of vec2's, an object containing a `.position` and `.radius`, an object populated with x1,y1,x2,y2, an object populated with x,y,w,h, and an object populated with x,y,width,height.  See the tests for more info
* `union(polygon)` returns a new polygon representing the boolean union of `this` and the incoming `polygon`
* `cut(polygon)` returns a new polygon representing the boolean cut of `polygon` from `this`
* `toArray()` convert this polygon into an array of arrays (`[[x, y]]`)

## license

MIT

repository: proglang/dts-generate-results

repo_name: proglang/dts-generate-results


text:
[![Build Status](https://travis-ci.org/wangliyao518/FilesOperationLibrary.svg?branch=master)](https://travis-ci.org/wangliyao518/FilesOperationLibrary)
[![Coverage Status](https://coveralls.io/repos/github/wangliyao518/FilesOperationLibrary/badge.svg?branch=master)](https://coveralls.io/github/wangliyao518/FilesOperationLibrary?branch=master)
[![BCH compliance](https://bettercodehub.com/edge/badge/wangliyao518/FilesOperationLibrary?branch=master)](https://bettercodehub.com/)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/d783e8848dfa4963b54ff69091bf4ff9)](https://www.codacy.com/app/wangliyao518/FilesOperationLibrary?utm_source=github.com&utm_medium=referral&utm_content=wangliyao518/FilesOperationLibrary&utm_campaign=Badge_Grade)
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](./LICENSE)

files operation library
==================

Basic files operation package with Robot Framework interface.

Requirements
============

* Python 2.7.x
* setuptools >= 2.1
* pip >= 1.5

installation
=============================

| pip install -U FilesOperationLibrary -i https://pypi.python.org/simple/