Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Yann Autissier | 52740d1c56 |
|
@ -1 +1,3 @@
|
||||||
.git*
|
.git*
|
||||||
|
build/cache/*
|
||||||
|
build/iso/*
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
/.env
|
/.env
|
||||||
|
/build
|
||||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,13 +1,5 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
## v1.0-alpha - 2022-11-29
|
|
||||||
|
|
||||||
* node is host
|
|
||||||
|
|
||||||
## v0.9.9 - 2022-11-22
|
|
||||||
|
|
||||||
* node name is `hostname`
|
|
||||||
|
|
||||||
## v0.9 - 2022-11-11
|
## v0.9 - 2022-11-11
|
||||||
|
|
||||||
* split make files in `myos` project and install files in `yaip` project
|
* split make files in `myos` project and install files in `yaip` project
|
||||||
|
@ -19,6 +11,7 @@ Beta release, welcome ipfs
|
||||||
* add arm64 support
|
* add arm64 support
|
||||||
* add ipfs stack
|
* add ipfs stack
|
||||||
* add x2go with ssh ecryptfs homedir
|
* add x2go with ssh ecryptfs homedir
|
||||||
|
* add zen stack
|
||||||
* update docker-compose to v2.5.0
|
* update docker-compose to v2.5.0
|
||||||
|
|
||||||
## v0.1-alpha - 2021-07-14
|
## v0.1-alpha - 2021-07-14
|
||||||
|
@ -32,10 +25,12 @@ Public release, code is doc
|
||||||
Initial import
|
Initial import
|
||||||
|
|
||||||
* import previous `infra` project
|
* import previous `infra` project
|
||||||
|
* remove any reference to previous project
|
||||||
* rename project to myos - make your own stack
|
* rename project to myos - make your own stack
|
||||||
|
|
||||||
## 2020
|
## 2020
|
||||||
|
|
||||||
|
* integration with drone.io
|
||||||
* makefile can be included in any project
|
* makefile can be included in any project
|
||||||
* multi user/environment
|
* multi user/environment
|
||||||
|
|
||||||
|
|
28
Makefile
28
Makefile
|
@ -1 +1,27 @@
|
||||||
include make/include.mk
|
MYOS ?= ../myos
|
||||||
|
MYOS_REPOSITORY ?= $(patsubst %/$(APP),%/myos,$(APP_REPOSITORY))
|
||||||
|
APP ?= $(lastword $(subst /, ,$(APP_REPOSITORY)))
|
||||||
|
APP_REPOSITORY ?= $(shell git config --get remote.origin.url 2>/dev/null)
|
||||||
|
$(MYOS):
|
||||||
|
-@git clone $(MYOS_REPOSITORY) $(MYOS)
|
||||||
|
-include $(MYOS)/make/include.mk
|
||||||
|
|
||||||
|
##
|
||||||
|
# APP
|
||||||
|
|
||||||
|
app-build: user install-build-config
|
||||||
|
$(call make,docker-compose-build docker-compose-up)
|
||||||
|
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call make,app-build-$(service)))
|
||||||
|
$(call make,docker-commit)
|
||||||
|
|
||||||
|
app-install: ansible-run app-update-default
|
||||||
|
|
||||||
|
app-start: $(foreach stack,$(STACK),start-stack-$(stack))
|
||||||
|
|
||||||
|
app-update: ansible-pull app-update-default
|
||||||
|
|
||||||
|
app-update-default: ENV_DIST := .env
|
||||||
|
app-update-default: ENV_FILE := /etc/default/myos
|
||||||
|
app-update-default: .env-update;
|
||||||
|
|
||||||
|
app-tests: ansible-tests
|
||||||
|
|
159
README.md
159
README.md
|
@ -1,86 +1,39 @@
|
||||||
# myos - Make Your Own Stack
|
# yaip - Yet Another Internet Project
|
||||||
|
|
||||||
Docker paas based on docker compose and make files.
|
Terraform a bunch of ressources to host your projects on Internet.
|
||||||
|
|
||||||
Make Your Own Stack provides common make targets to build and run docker projects.
|
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
This is beta software, use it at your own risks.
|
This is work in progress ;)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
You need `docker`, `git` and `make`.
|
You need `docker`, `git` and `make`.
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
* Include MYOS file `make/include.mk` adding the following lines to your project file `Makefile`.
|
|
||||||
|
|
||||||
```
|
|
||||||
MYOS ?= ../myos
|
|
||||||
MYOS_REPOSITORY ?= $(patsubst %/$(APP),%/myos,$(APP_REPOSITORY))
|
|
||||||
APP ?= $(lastword $(subst /, ,$(APP_REPOSITORY)))
|
|
||||||
APP_REPOSITORY ?= $(shell git config --get remote.origin.url 2>/dev/null)
|
|
||||||
$(MYOS):
|
|
||||||
-@git clone $(MYOS_REPOSITORY) $(MYOS)
|
|
||||||
-include $(MYOS)/make/include.mk
|
|
||||||
```
|
|
||||||
|
|
||||||
* Call the `make help` command to show available targets.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make help
|
|
||||||
Usage:
|
|
||||||
make [target]
|
|
||||||
|
|
||||||
Targets:
|
|
||||||
help This help
|
|
||||||
[...]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
* Configure myos for domain `domain.tld` and stack `default`
|
* Install yaip for domain localhost
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make bootstrap DOMAIN=domain.tld STACK=default
|
$ make install DOMAIN=localhost
|
||||||
```
|
```
|
||||||
|
|
||||||
* Start myos stack `host`
|
* Build an iso
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make host
|
$ make packer-build
|
||||||
```
|
|
||||||
|
|
||||||
`make host` starts the stack `host` with docker host services :
|
|
||||||
- consul (service discovery) on host port 8500
|
|
||||||
- fabio (load balancer) on host ports 80 and 443
|
|
||||||
- registrator (docker/consul bridge)
|
|
||||||
|
|
||||||
* Stop myos
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make shutdown
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Variables
|
### Variables
|
||||||
|
|
||||||
* DEBUG
|
|
||||||
|
|
||||||
Show executed commands.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make up DEBUG=true
|
|
||||||
```
|
|
||||||
|
|
||||||
* DRYRUN
|
* DRYRUN
|
||||||
|
|
||||||
Do nothing, show commands instead of executing it.
|
Do nothing, show commands instead of executing it.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make up DRYRUN=true
|
$ make install DRYRUN=true
|
||||||
```
|
```
|
||||||
|
|
||||||
* VERBOSE
|
* VERBOSE
|
||||||
|
@ -88,98 +41,11 @@ $ make up DRYRUN=true
|
||||||
Show called functions.
|
Show called functions.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make up VERBOSE=true
|
$ make install VERBOSE=true
|
||||||
```
|
|
||||||
|
|
||||||
* Show variable USER
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make print-USER
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Setup
|
|
||||||
|
|
||||||
* SETUP_LETSENCRYPT
|
|
||||||
|
|
||||||
Generate ${DOMAIN} certificate files with letsencrypt.
|
|
||||||
|
|
||||||
By default, myos generates invalid ${DOMAIN} certificate files with openssl.
|
|
||||||
You can use letsencrypt instead, to generate valid wildcard certificate files.
|
|
||||||
|
|
||||||
To achieve this, you must add following DNS entries to domain ${DOMAIN} to prove you own it:
|
|
||||||
|
|
||||||
```
|
|
||||||
_acme-challenge.${DOMAIN} IN CNAME ${DOMAIN}.acme.${DOMAIN}.
|
|
||||||
acme.${DOMAIN}. IN NS certbot.${DOMAIN}.
|
|
||||||
certbot.${DOMAIN}. IN A ${DOCKER_HOST_INET4}
|
|
||||||
```
|
|
||||||
|
|
||||||
In this config, DOCKER_HOST_INET4 should be the external IP address of the server running certbot.
|
|
||||||
Port 53 of this IP address must be reachable from internet and point to this server.
|
|
||||||
|
|
||||||
If you want a simple DNS configuration to host all your services on the same server, you can setup following DNS config:
|
|
||||||
|
|
||||||
```
|
|
||||||
@ IN A ${DOCKER_HOST_INET4}
|
|
||||||
*.${DOMAIN}. IN CNAME ${DOMAIN}.
|
|
||||||
_acme-challenge.${DOMAIN} IN CNAME ${DOMAIN}.acme.${DOMAIN}.
|
|
||||||
acme.${DOMAIN}. IN NS ${DOMAIN}.
|
|
||||||
```
|
|
||||||
|
|
||||||
This will point domain ${DOMAIN} to the IP address ${DOCKER_HOST_INET4} of this server, and point all subdomains *.{DOMAIN} to the ip address pointed by ${DOMAIN}.
|
|
||||||
|
|
||||||
At this point, you should be able to generate a valid certificate for *.${DOMAIN} using certbot [dns standalone](https://github.com/siilike/certbot-dns-standalone) plugin.
|
|
||||||
This task is done automatically when creating the host stack if SETUP_LETSENCRYPT variable is not empty.
|
|
||||||
|
|
||||||
If you already launched myos host stack before, the ${DOMAIN} certificates has been automatically generated by openssl and you should remove them before trying to generate them with letsencrypt.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make host-down
|
|
||||||
$ docker volume rm $(hostname)
|
|
||||||
```
|
|
||||||
|
|
||||||
You can then test the letsencrypt certificate generation using DEBUG mode that force to use the letsencrypt staging server.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make host SETUP_LETSENCRYPT=true DEBUG=true
|
|
||||||
```
|
|
||||||
|
|
||||||
If letsencrypt certificate generation fails, you can retry the generation of a staging certificate.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make host-certbot-staging
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the certificate generation is working, you can ask for a valid certificate.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make host-down
|
|
||||||
$ docker volume rm $(hostname)
|
|
||||||
$ make host SETUP_LETSENCRYPT=true
|
|
||||||
```
|
|
||||||
|
|
||||||
* SETUP_UFW
|
|
||||||
|
|
||||||
Control linux firewall rules with ufw.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ echo SETUP_UFW=true >> .env
|
|
||||||
$ make setup-ufw
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debug
|
### Debug
|
||||||
|
|
||||||
* Show docker compose yaml config
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make config
|
|
||||||
```
|
|
||||||
|
|
||||||
`make config` show docker compose yaml config for stack `STACK`
|
|
||||||
`make host-config` show docker compose yaml config for stack `host`
|
|
||||||
`make user-config` show docker compose yaml config for stack `User`
|
|
||||||
`make stack-elastic-config` show docker compose yaml config for stack `elastic`
|
|
||||||
|
|
||||||
* Show debug variables
|
* Show debug variables
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
@ -198,9 +64,6 @@ $ make doc
|
||||||
$ make print-env_args
|
$ make print-env_args
|
||||||
```
|
```
|
||||||
|
|
||||||
* Show user mail
|
## Status
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make print-MAIL
|
|
||||||
```
|
|
||||||
|
|
||||||
|
Beta software, use it at your own risks.
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
playbook.retry
|
||||||
|
inventories/packer-provisioner-ansible*
|
|
@ -0,0 +1,19 @@
|
||||||
|
[defaults]
|
||||||
|
inventory = inventories
|
||||||
|
roles_path = roles
|
||||||
|
filter_plugins = plugins/filter
|
||||||
|
# host_key_checking = False
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
scp_if_ssh = smart
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
changed = purple
|
||||||
|
debug = dark gray
|
||||||
|
deprecate = purple
|
||||||
|
error = bright red
|
||||||
|
ok = green
|
||||||
|
skip = cyan
|
||||||
|
unreachable = red
|
||||||
|
verbose = blue
|
||||||
|
warn = bright purple
|
|
@ -0,0 +1 @@
|
||||||
|
localhost ansible_host=host.docker.internal
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# file: inventories/group_vars/all
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
# file: inventories/host_vars/default
|
||||||
|
|
||||||
|
aws_access_key_id: "{{ lookup('env','ANSIBLE_AWS_ACCESS_KEY_ID') }}"
|
||||||
|
aws_output: "{{ lookup('env','ANSIBLE_AWS_DEFAULT_OUTPUT') or 'json' }}"
|
||||||
|
aws_region: "{{ lookup('env','ANSIBLE_AWS_DEFAULT_REGION') or 'eu-west-1' }}"
|
||||||
|
aws_secret_access_key: "{{ lookup('env','ANSIBLE_AWS_SECRET_ACCESS_KEY') }}"
|
||||||
|
disks_packages:
|
||||||
|
- { "name": "e2fsprogs-extra", "state": "present" }
|
||||||
|
- { "name": "nfs-utils", "state": "present" }
|
||||||
|
hosts_git_repositories:
|
||||||
|
- { "repo": "{{ lookup('env','ANSIBLE_GIT_REPOSITORY') }}", "dest": "{{ lookup('env','ANSIBLE_GIT_DIRECTORY') }}", "key_file": "{{ lookup('env','ANSIBLE_GIT_KEY_FILE') or '~/.ssh/id_rsa' }}", "version": "{{ lookup('env','ANSIBLE_GIT_VERSION') }}" }
|
||||||
|
hosts_packages:
|
||||||
|
- { "name": "ansible-core", "state": "present" }
|
||||||
|
hosts_services:
|
||||||
|
- { "name": "zram", "state": "started", "enabled": "yes" }
|
||||||
|
hosts_update: true
|
||||||
|
hosts_default_env:
|
||||||
|
- ANSIBLE_CONFIG
|
||||||
|
- ANSIBLE_DISKS_NFS_DISK
|
||||||
|
- ANSIBLE_DISKS_NFS_OPTIONS
|
||||||
|
- ANSIBLE_DISKS_NFS_PATH
|
||||||
|
- ANSIBLE_DOCKER_IMAGE_TAG
|
||||||
|
- ANSIBLE_DOCKER_REGISTRY
|
||||||
|
- ANSIBLE_EXTRA_VARS
|
||||||
|
- ANSIBLE_GIT_DIRECTORY
|
||||||
|
- ANSIBLE_GIT_KEY_FILE
|
||||||
|
- ANSIBLE_GIT_REPOSITORY
|
||||||
|
- ANSIBLE_INVENTORY
|
||||||
|
- ANSIBLE_MYOS
|
||||||
|
- ANSIBLE_PLAYBOOK
|
||||||
|
- ENV
|
||||||
|
hosts_user_rc: true
|
||||||
|
hosts_user_rc_functions:
|
||||||
|
- { "path": "10_prompt_set", "state": "touch" }
|
||||||
|
- { "path": "10_ps1_set", "state": "touch" }
|
||||||
|
- { "path": "30_pfetch", "state": "touch" }
|
||||||
|
- { "path": "30_screen_attach", "state": "touch" }
|
||||||
|
- { "path": "40_ssh_add", "state": "touch" }
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
# file: inventories/host_vars/localhost
|
||||||
|
|
||||||
|
disks_packages:
|
||||||
|
- { "name": "btrfs-progs", "state": "present" }
|
||||||
|
- { "name": "xfsprogs", "state": "present" }
|
||||||
|
docker_image_tag: "{{ lookup('env','ANSIBLE_DOCKER_IMAGE_TAG') or 'latest' }}"
|
||||||
|
docker_myos: true
|
||||||
|
docker_registry: "{{ lookup('env','ANSIBLE_DOCKER_REGISTRY') }}"
|
||||||
|
hosts_git_repositories:
|
||||||
|
- { "repo": "{{ lookup('env','ANSIBLE_GIT_REPOSITORY') }}", "dest": "{{ lookup('env','ANSIBLE_GIT_DIRECTORY') }}", "key_file": "{{ lookup('env','ANSIBLE_GIT_KEY_FILE') or '~/.ssh/id_rsa' }}", "version": "{{ lookup('env','ANSIBLE_GIT_VERSION') }}" }
|
||||||
|
hosts_services:
|
||||||
|
- { "name": "myos", "state": "started", "enabled": "yes" }
|
||||||
|
hosts_update: true
|
||||||
|
hosts_default_env:
|
||||||
|
- ANSIBLE_CONFIG
|
||||||
|
- ANSIBLE_DOCKER_IMAGE_TAG
|
||||||
|
- ANSIBLE_DOCKER_REGISTRY
|
||||||
|
- ANSIBLE_EXTRA_VARS
|
||||||
|
- ANSIBLE_GIT_DIRECTORY
|
||||||
|
- ANSIBLE_GIT_KEY_FILE
|
||||||
|
- ANSIBLE_GIT_REPOSITORY
|
||||||
|
- ANSIBLE_INVENTORY
|
||||||
|
- ANSIBLE_MYOS
|
||||||
|
- ANSIBLE_PLAYBOOK
|
||||||
|
- ENV
|
||||||
|
hosts_user_rc: true
|
||||||
|
remotes_myos: true
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
# file: inventories/host_vars/myos
|
||||||
|
|
||||||
|
aws_access_key_id: "{{ lookup('env','ANSIBLE_AWS_ACCESS_KEY_ID') }}"
|
||||||
|
aws_output: "{{ lookup('env','ANSIBLE_AWS_DEFAULT_OUTPUT') or 'json' }}"
|
||||||
|
aws_region: "{{ lookup('env','ANSIBLE_AWS_DEFAULT_REGION') or 'eu-west-1' }}"
|
||||||
|
aws_secret_access_key: "{{ lookup('env','ANSIBLE_AWS_SECRET_ACCESS_KEY') }}"
|
||||||
|
disks_to_mount:
|
||||||
|
- disk: /dev/xvdb
|
||||||
|
disable_periodic_fsck: true
|
||||||
|
fstype: ext4
|
||||||
|
mount_options: defaults
|
||||||
|
mount: /var/lib/docker
|
||||||
|
service: docker
|
||||||
|
- disk: "{{ lookup('env','ANSIBLE_DISKS_NFS_DISK') }}"
|
||||||
|
fstype: nfs
|
||||||
|
mount_options: "{{ lookup('env','ANSIBLE_DISKS_NFS_OPTIONS') }}"
|
||||||
|
mount: "{{ lookup('env','ANSIBLE_DISKS_NFS_PATH') }}"
|
||||||
|
disks_services:
|
||||||
|
- { "name": "rpc.statd", "state": "started", "enabled": "yes" }
|
||||||
|
docker_image_tag: "{{ lookup('env','ANSIBLE_DOCKER_IMAGE_TAG') or 'latest' }}"
|
||||||
|
docker_registry: "{{ lookup('env','ANSIBLE_DOCKER_REGISTRY') }}"
|
||||||
|
hosts_packages:
|
||||||
|
- { "name": "ansible-core", "state": "present" }
|
||||||
|
hosts_services:
|
||||||
|
- { "name": "myos", "state": "started", "enabled": "yes" }
|
||||||
|
- { "name": "zram", "state": "started", "enabled": "yes" }
|
||||||
|
hosts_update: true
|
||||||
|
hosts_default_env:
|
||||||
|
- ANSIBLE_CONFIG
|
||||||
|
- ANSIBLE_DISKS_NFS_DISK
|
||||||
|
- ANSIBLE_DISKS_NFS_OPTIONS
|
||||||
|
- ANSIBLE_DISKS_NFS_PATH
|
||||||
|
- ANSIBLE_DOCKER_IMAGE_TAG
|
||||||
|
- ANSIBLE_DOCKER_REGISTRY
|
||||||
|
- ANSIBLE_EXTRA_VARS
|
||||||
|
- ANSIBLE_GIT_DIRECTORY
|
||||||
|
- ANSIBLE_GIT_KEY_FILE
|
||||||
|
- ANSIBLE_GIT_REPOSITORY
|
||||||
|
- ANSIBLE_INVENTORY
|
||||||
|
- ANSIBLE_MYOS
|
||||||
|
- ANSIBLE_PLAYBOOK
|
||||||
|
- COMPOSE_PROJECT_NAME
|
||||||
|
- ENV
|
||||||
|
- MYOS_TAGS
|
||||||
|
hosts_user_rc: true
|
||||||
|
hosts_user_rc_functions:
|
||||||
|
- { "path": "10_prompt_set", "state": "touch" }
|
||||||
|
- { "path": "10_ps1_set", "state": "touch" }
|
||||||
|
- { "path": "30_pfetch", "state": "touch" }
|
||||||
|
- { "path": "30_screen_attach", "state": "touch" }
|
||||||
|
- { "path": "40_ssh_add", "state": "touch" }
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
# file: playbook.yml
|
||||||
|
|
||||||
|
# bootstrap hosts
|
||||||
|
- hosts: default
|
||||||
|
gather_facts: false
|
||||||
|
pre_tasks:
|
||||||
|
- name: raw - install ansible requirements for alpine linux
|
||||||
|
raw: "[ -f /etc/alpine-release ] && /sbin/apk update && { which python3 >/dev/null 2>&1 || /sbin/apk add python3; } && { /bin/tar --version 2>/dev/null |grep busybox >/dev/null && /sbin/apk add tar; } && { ls /usr/lib/ssh/sftp-server >/dev/null 2>&1 || /sbin/apk add openssh-sftp-server; } || true"
|
||||||
|
tags:
|
||||||
|
- bootstrap
|
||||||
|
|
||||||
|
# install packages and user settings
|
||||||
|
- import_playbook: playbooks/hosts.yml
|
||||||
|
|
||||||
|
# config remotes
|
||||||
|
- import_playbook: playbooks/remotes.yml
|
||||||
|
|
||||||
|
# mount additional disks
|
||||||
|
- import_playbook: playbooks/disks.yml
|
||||||
|
|
||||||
|
# install docker
|
||||||
|
- import_playbook: playbooks/docker.yml
|
||||||
|
|
||||||
|
# launch myos
|
||||||
|
# - import_playbook: playbooks/myos.yml
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# file: playbooks/disks.yml
|
||||||
|
|
||||||
|
- hosts: '{{ target | default("disks") }}'
|
||||||
|
roles:
|
||||||
|
- disks
|
||||||
|
tags:
|
||||||
|
- disks
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# file: playbooks/docker.yml
|
||||||
|
|
||||||
|
- hosts: '{{ target | default("docker") }}'
|
||||||
|
roles:
|
||||||
|
- docker
|
||||||
|
tags:
|
||||||
|
- docker
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# file: playbooks/hosts.yml
|
||||||
|
|
||||||
|
- hosts: '{{ target | default("hosts") }}'
|
||||||
|
roles:
|
||||||
|
- hosts
|
||||||
|
tags:
|
||||||
|
- hosts
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# file: playbooks/remotes.yml
|
||||||
|
|
||||||
|
- hosts: '{{ target | default("remotes") }}'
|
||||||
|
roles:
|
||||||
|
- remotes
|
||||||
|
tags:
|
||||||
|
- remotes
|
|
@ -4,9 +4,9 @@
|
||||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||||
;
|
;
|
||||||
[subrepo]
|
[subrepo]
|
||||||
remote = ssh://git@github.com/aynicos/docker-vsftpd-s3
|
remote = ssh://git@github.com/aynicos/ansible-disks
|
||||||
branch = master
|
branch = master
|
||||||
commit = 6d5b3310525d8cb1be32f0461a8633aba8641b24
|
commit = c0ac6978d715b461fbf20aca719cd5196bc60645
|
||||||
parent = 162fd1a1c05971c62996f6be53522c74559f567b
|
parent = d01cccd9bab3a63d60ba251e3719767635ccd5d2
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.0
|
cmdver = 0.4.0
|
|
@ -0,0 +1,5 @@
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
* **Yann Autissier** - *myos tailoring* - [aya](https://github.com/aya)
|
||||||
|
* **Emilien Kenler** - *initial work* - [milk](https://github.com/milk)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0-alpha - 2021-07-14
|
||||||
|
|
||||||
|
Initial myos release
|
|
@ -0,0 +1,611 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (c) 2014 Wizcorp
|
||||||
|
Copyright (c) 2021 Yann Autissier
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for software
|
||||||
|
and other kinds of works, specifically designed to ensure cooperation with
|
||||||
|
the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed to take
|
||||||
|
away your freedom to share and change the works. By contrast, our General
|
||||||
|
Public Licenses are intended to guarantee your freedom to share and change
|
||||||
|
all versions of a program--to make sure it remains free software for all its
|
||||||
|
users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price. Our
|
||||||
|
General Public Licenses are designed to make sure that you have the freedom
|
||||||
|
to distribute copies of free software (and charge for them if you wish), that
|
||||||
|
you receive source code or can get it if you want it, that you can change
|
||||||
|
the software or use pieces of it in new free programs, and that you know you
|
||||||
|
can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights with two
|
||||||
|
steps: (1) assert copyright on the software, and (2) offer you this License
|
||||||
|
which gives you legal permission to copy, distribute and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that improvements made
|
||||||
|
in alternate versions of the program, if they receive widespread use, become
|
||||||
|
available for other developers to incorporate. Many developers of free software
|
||||||
|
are heartened and encouraged by the resulting cooperation. However, in the
|
||||||
|
case of software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and letting
|
||||||
|
the public access it on a server without ever releasing its source code to
|
||||||
|
the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to ensure that,
|
||||||
|
in such cases, the modified source code becomes available to the community.
|
||||||
|
It requires the operator of a network server to provide the source code of
|
||||||
|
the modified version running there to the users of that server. Therefore,
|
||||||
|
public use of a modified version, on a publicly accessible server, gives the
|
||||||
|
public access to the source code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and published by
|
||||||
|
Affero, was designed to accomplish similar goals. This is a different license,
|
||||||
|
not a version of the Affero GPL, but Affero has released a new version of
|
||||||
|
the Affero GPL which permits relicensing under this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of works,
|
||||||
|
such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this License.
|
||||||
|
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
|
||||||
|
or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work in
|
||||||
|
a fashion requiring copyright permission, other than the making of an exact
|
||||||
|
copy. The resulting work is called a "modified version" of the earlier work
|
||||||
|
or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based on the
|
||||||
|
Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without permission,
|
||||||
|
would make you directly or secondarily liable for infringement under applicable
|
||||||
|
copyright law, except executing it on a computer or modifying a private copy.
|
||||||
|
Propagation includes copying, distribution (with or without modification),
|
||||||
|
making available to the public, and in some countries other activities as
|
||||||
|
well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other parties
|
||||||
|
to make or receive copies. Mere interaction with a user through a computer
|
||||||
|
network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices" to the
|
||||||
|
extent that it includes a convenient and prominently visible feature that
|
||||||
|
(1) displays an appropriate copyright notice, and (2) tells the user that
|
||||||
|
there is no warranty for the work (except to the extent that warranties are
|
||||||
|
provided), that licensees may convey the work under this License, and how
|
||||||
|
to view a copy of this License. If the interface presents a list of user commands
|
||||||
|
or options, such as a menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. "Object code" means any non-source form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official standard
|
||||||
|
defined by a recognized standards body, or, in the case of interfaces specified
|
||||||
|
for a particular programming language, one that is widely used among developers
|
||||||
|
working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other than
|
||||||
|
the work as a whole, that (a) is included in the normal form of packaging
|
||||||
|
a Major Component, but which is not part of that Major Component, and (b)
|
||||||
|
serves only to enable use of the work with that Major Component, or to implement
|
||||||
|
a Standard Interface for which an implementation is available to the public
|
||||||
|
in source code form. A "Major Component", in this context, means a major essential
|
||||||
|
component (kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to produce
|
||||||
|
the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all the source
|
||||||
|
code needed to generate, install, and (for an executable work) run the object
|
||||||
|
code and to modify the work, including scripts to control those activities.
|
||||||
|
However, it does not include the work's System Libraries, or general-purpose
|
||||||
|
tools or generally available free programs which are used unmodified in performing
|
||||||
|
those activities but which are not part of the work. For example, Corresponding
|
||||||
|
Source includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically linked
|
||||||
|
subprograms that the work is specifically designed to require, such as by
|
||||||
|
intimate data communication or control flow between those
|
||||||
|
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users can regenerate
|
||||||
|
automatically from other parts of the Corresponding Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of copyright
|
||||||
|
on the Program, and are irrevocable provided the stated conditions are met.
|
||||||
|
This License explicitly affirms your unlimited permission to run the unmodified
|
||||||
|
Program. The output from running a covered work is covered by this License
|
||||||
|
only if the output, given its content, constitutes a covered work. This License
|
||||||
|
acknowledges your rights of fair use or other equivalent, as provided by copyright
|
||||||
|
law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not convey, without
|
||||||
|
conditions so long as your license otherwise remains in force. You may convey
|
||||||
|
covered works to others for the sole purpose of having them make modifications
|
||||||
|
exclusively for you, or provide you with facilities for running those works,
|
||||||
|
provided that you comply with the terms of this License in conveying all material
|
||||||
|
for which you do not control copyright. Those thus making or running the covered
|
||||||
|
works for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of your copyrighted
|
||||||
|
material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under the conditions
|
||||||
|
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological measure
|
||||||
|
under any applicable law fulfilling obligations under article 11 of the WIPO
|
||||||
|
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
|
||||||
|
or restricting circumvention of such measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid circumvention
|
||||||
|
of technological measures to the extent such circumvention is effected by
|
||||||
|
exercising rights under this License with respect to the covered work, and
|
||||||
|
you disclaim any intention to limit operation or modification of the work
|
||||||
|
as a means of enforcing, against the work's users, your or third parties'
|
||||||
|
legal rights to forbid circumvention of technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you receive
|
||||||
|
it, in any medium, provided that you conspicuously and appropriately publish
|
||||||
|
on each copy an appropriate copyright notice; keep intact all notices stating
|
||||||
|
that this License and any non-permissive terms added in accord with section
|
||||||
|
7 apply to the code; keep intact all notices of the absence of any warranty;
|
||||||
|
and give all recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey, and you
|
||||||
|
may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to produce
|
||||||
|
it from the Program, in the form of source code under the terms of section
|
||||||
|
4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified it, and
|
||||||
|
giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is released under
|
||||||
|
this License and any conditions added under section 7. This requirement modifies
|
||||||
|
the requirement in section 4 to "keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this License to anyone
|
||||||
|
who comes into possession of a copy. This License will therefore apply, along
|
||||||
|
with any applicable section 7 additional terms, to the whole of the work,
|
||||||
|
and all its parts, regardless of how they are packaged. This License gives
|
||||||
|
no permission to license the work in any other way, but it does not invalidate
|
||||||
|
such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display Appropriate
|
||||||
|
Legal Notices; however, if the Program has interactive interfaces that do
|
||||||
|
not display Appropriate Legal Notices, your work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent works,
|
||||||
|
which are not by their nature extensions of the covered work, and which are
|
||||||
|
not combined with it such as to form a larger program, in or on a volume of
|
||||||
|
a storage or distribution medium, is called an "aggregate" if the compilation
|
||||||
|
and its resulting copyright are not used to limit the access or legal rights
|
||||||
|
of the compilation's users beyond what the individual works permit. Inclusion
|
||||||
|
of a covered work in an aggregate does not cause this License to apply to
|
||||||
|
the other parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms of sections
|
||||||
|
4 and 5, provided that you also convey the machine-readable Corresponding
|
||||||
|
Source under the terms of this License, in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by the Corresponding Source fixed
|
||||||
|
on a durable physical medium customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by a written offer, valid for
|
||||||
|
at least three years and valid for as long as you offer spare parts or customer
|
||||||
|
support for that product model, to give anyone who possesses the object code
|
||||||
|
either (1) a copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical medium customarily
|
||||||
|
used for software interchange, for a price no more than your reasonable cost
|
||||||
|
of physically performing this conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the written
|
||||||
|
offer to provide the Corresponding Source. This alternative is allowed only
|
||||||
|
occasionally and noncommercially, and only if you received the object code
|
||||||
|
with such an offer, in accord with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated place (gratis
|
||||||
|
or for a charge), and offer equivalent access to the Corresponding Source
|
||||||
|
in the same way through the same place at no further charge. You need not
|
||||||
|
require recipients to copy the Corresponding Source along with the object
|
||||||
|
code. If the place to copy the object code is a network server, the Corresponding
|
||||||
|
Source may be on a different server (operated by you or a third party) that
|
||||||
|
supports equivalent copying facilities, provided you maintain clear directions
|
||||||
|
next to the object code saying where to find the Corresponding Source. Regardless
|
||||||
|
of what server hosts the Corresponding Source, you remain obligated to ensure
|
||||||
|
that it is available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided you inform
|
||||||
|
other peers where the object code and Corresponding Source of the work are
|
||||||
|
being offered to the general public at no charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded from
|
||||||
|
the Corresponding Source as a System Library, need not be included in conveying
|
||||||
|
the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any tangible
|
||||||
|
personal property which is normally used for personal, family, or household
|
||||||
|
purposes, or (2) anything designed or sold for incorporation into a dwelling.
|
||||||
|
In determining whether a product is a consumer product, doubtful cases shall
|
||||||
|
be resolved in favor of coverage. For a particular product received by a particular
|
||||||
|
user, "normally used" refers to a typical or common use of that class of product,
|
||||||
|
regardless of the status of the particular user or of the way in which the
|
||||||
|
particular user actually uses, or expects or is expected to use, the product.
|
||||||
|
A product is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent the
|
||||||
|
only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods, procedures,
|
||||||
|
authorization keys, or other information required to install and execute modified
|
||||||
|
versions of a covered work in that User Product from a modified version of
|
||||||
|
its Corresponding Source. The information must suffice to ensure that the
|
||||||
|
continued functioning of the modified object code is in no case prevented
|
||||||
|
or interfered with solely because modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or specifically
|
||||||
|
for use in, a User Product, and the conveying occurs as part of a transaction
|
||||||
|
in which the right of possession and use of the User Product is transferred
|
||||||
|
to the recipient in perpetuity or for a fixed term (regardless of how the
|
||||||
|
transaction is characterized), the Corresponding Source conveyed under this
|
||||||
|
section must be accompanied by the Installation Information. But this requirement
|
||||||
|
does not apply if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has been installed
|
||||||
|
in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a requirement
|
||||||
|
to continue to provide support service, warranty, or updates for a work that
|
||||||
|
has been modified or installed by the recipient, or for the User Product in
|
||||||
|
which it has been modified or installed. Access to a network may be denied
|
||||||
|
when the modification itself materially and adversely affects the operation
|
||||||
|
of the network or violates the rules and protocols for communication across
|
||||||
|
the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided, in accord
|
||||||
|
with this section must be in a format that is publicly documented (and with
|
||||||
|
an implementation available to the public in source code form), and must require
|
||||||
|
no special password or key for unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this License
|
||||||
|
by making exceptions from one or more of its conditions. Additional permissions
|
||||||
|
that are applicable to the entire Program shall be treated as though they
|
||||||
|
were included in this License, to the extent that they are valid under applicable
|
||||||
|
law. If additional permissions apply only to part of the Program, that part
|
||||||
|
may be used separately under those permissions, but the entire Program remains
|
||||||
|
governed by this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option remove any
|
||||||
|
additional permissions from that copy, or from any part of it. (Additional
|
||||||
|
permissions may be written to require their own removal in certain cases when
|
||||||
|
you modify the work.) You may place additional permissions on material, added
|
||||||
|
by you to a covered work, for which you have or can give appropriate copyright
|
||||||
|
permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you add
|
||||||
|
to a covered work, you may (if authorized by the copyright holders of that
|
||||||
|
material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the terms of
|
||||||
|
sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or author
|
||||||
|
attributions in that material or in the Appropriate Legal Notices displayed
|
||||||
|
by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or requiring
|
||||||
|
that modified versions of such material be marked in reasonable ways as different
|
||||||
|
from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or authors
|
||||||
|
of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some trade names,
|
||||||
|
trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that material by
|
||||||
|
anyone who conveys the material (or modified versions of it) with contractual
|
||||||
|
assumptions of liability to the recipient, for any liability that these contractual
|
||||||
|
assumptions directly impose on those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further restrictions"
|
||||||
|
within the meaning of section 10. If the Program as you received it, or any
|
||||||
|
part of it, contains a notice stating that it is governed by this License
|
||||||
|
along with a term that is a further restriction, you may remove that term.
|
||||||
|
If a license document contains a further restriction but permits relicensing
|
||||||
|
or conveying under this License, you may add to a covered work material governed
|
||||||
|
by the terms of that license document, provided that the further restriction
|
||||||
|
does not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you must place,
|
||||||
|
in the relevant source files, a statement of the additional terms that apply
|
||||||
|
to those files, or a notice indicating where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the form
|
||||||
|
of a separately written license, or stated as exceptions; the above requirements
|
||||||
|
apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly provided
|
||||||
|
under this License. Any attempt otherwise to propagate or modify it is void,
|
||||||
|
and will automatically terminate your rights under this License (including
|
||||||
|
any patent licenses granted under the third paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your license from
|
||||||
|
a particular copyright holder is reinstated (a) provisionally, unless and
|
||||||
|
until the copyright holder explicitly and finally terminates your license,
|
||||||
|
and (b) permanently, if the copyright holder fails to notify you of the violation
|
||||||
|
by some reasonable means prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is reinstated permanently
|
||||||
|
if the copyright holder notifies you of the violation by some reasonable means,
|
||||||
|
this is the first time you have received notice of violation of this License
|
||||||
|
(for any work) from that copyright holder, and you cure the violation prior
|
||||||
|
to 30 days after your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the licenses
|
||||||
|
of parties who have received copies or rights from you under this License.
|
||||||
|
If your rights have been terminated and not permanently reinstated, you do
|
||||||
|
not qualify to receive new licenses for the same material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or run a copy
|
||||||
|
of the Program. Ancillary propagation of a covered work occurring solely as
|
||||||
|
a consequence of using peer-to-peer transmission to receive a copy likewise
|
||||||
|
does not require acceptance. However, nothing other than this License grants
|
||||||
|
you permission to propagate or modify any covered work. These actions infringe
|
||||||
|
copyright if you do not accept this License. Therefore, by modifying or propagating
|
||||||
|
a covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically receives
|
||||||
|
a license from the original licensors, to run, modify and propagate that work,
|
||||||
|
subject to this License. You are not responsible for enforcing compliance
|
||||||
|
by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an organization,
|
||||||
|
or substantially all assets of one, or subdividing an organization, or merging
|
||||||
|
organizations. If propagation of a covered work results from an entity transaction,
|
||||||
|
each party to that transaction who receives a copy of the work also receives
|
||||||
|
whatever licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the Corresponding
|
||||||
|
Source of the work from the predecessor in interest, if the predecessor has
|
||||||
|
it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the rights
|
||||||
|
granted or affirmed under this License. For example, you may not impose a
|
||||||
|
license fee, royalty, or other charge for exercise of rights granted under
|
||||||
|
this License, and you may not initiate litigation (including a cross-claim
|
||||||
|
or counterclaim in a lawsuit) alleging that any patent claim is infringed
|
||||||
|
by making, using, selling, offering for sale, or importing the Program or
|
||||||
|
any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this License
|
||||||
|
of the Program or a work on which the Program is based. The work thus licensed
|
||||||
|
is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims owned or controlled
|
||||||
|
by the contributor, whether already acquired or hereafter acquired, that would
|
||||||
|
be infringed by some manner, permitted by this License, of making, using,
|
||||||
|
or selling its contributor version, but do not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of the contributor
|
||||||
|
version. For purposes of this definition, "control" includes the right to
|
||||||
|
grant patent sublicenses in a manner consistent with the requirements of this
|
||||||
|
License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
|
||||||
|
license under the contributor's essential patent claims, to make, use, sell,
|
||||||
|
offer for sale, import and otherwise run, modify and propagate the contents
|
||||||
|
of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express agreement
|
||||||
|
or commitment, however denominated, not to enforce a patent (such as an express
|
||||||
|
permission to practice a patent or covenant not to s ue for patent infringement).
|
||||||
|
To "grant" such a patent license to a party means to make such an agreement
|
||||||
|
or commitment not to enforce a patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license, and the
|
||||||
|
Corresponding Source of the work is not available for anyone to copy, free
|
||||||
|
of charge and under the terms of this License, through a publicly available
|
||||||
|
network server or other readily accessible means, then you must either (1)
|
||||||
|
cause the Corresponding Source to be so available, or (2) arrange to deprive
|
||||||
|
yourself of the benefit of the patent license for this particular work, or
|
||||||
|
(3) arrange, in a manner consistent with the requirements of this License,
|
||||||
|
to extend the patent
|
||||||
|
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have actual
|
||||||
|
knowledge that, but for the patent license, your conveying the covered work
|
||||||
|
in a country, or your recipient's use of the covered work in a country, would
|
||||||
|
infringe one or more identifiable patents in that country that you have reason
|
||||||
|
to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or arrangement,
|
||||||
|
you convey, or propagate by procuring conveyance of, a covered work, and grant
|
||||||
|
a patent license to some of the parties receiving the covered work authorizing
|
||||||
|
them to use, propagate, modify or convey a specific copy of the covered work,
|
||||||
|
then the patent license you grant is automatically extended to all recipients
|
||||||
|
of the covered work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within the scope
|
||||||
|
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
|
||||||
|
of one or more of the rights that are specifically granted under this License.
|
||||||
|
You may not convey a covered work if you are a party to an arrangement with
|
||||||
|
a third party that is in the business of distributing software, under which
|
||||||
|
you make payment to the third party based on the extent of your activity of
|
||||||
|
conveying the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory patent
|
||||||
|
license (a) in connection with copies of the covered work conveyed by you
|
||||||
|
(or copies made from those copies), or (b) primarily for and in connection
|
||||||
|
with specific products or compilations that contain the covered work, unless
|
||||||
|
you entered into that arrangement, or that patent license was granted, prior
|
||||||
|
to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting any implied
|
||||||
|
license or other defenses to infringement that may otherwise be available
|
||||||
|
to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||||
|
that contradict the conditions of this License, they do not excuse you from
|
||||||
|
the conditions of this License. If you cannot convey a covered work so as
|
||||||
|
to satisfy simultaneously your obligations under this License and any other
|
||||||
|
pertinent obligations, then as a consequence you may
|
||||||
|
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey the
|
||||||
|
Program, the only way you could satisfy both those terms and this License
|
||||||
|
would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the Program,
|
||||||
|
your modified version must prominently offer all users interacting with it
|
||||||
|
remotely through a computer network (if your version supports such interaction)
|
||||||
|
an opportunity to receive the Corresponding Source of your version by providing
|
||||||
|
access to the Corresponding Source from a network server at no charge, through
|
||||||
|
some standard or customary means of facilitating copying of software. This
|
||||||
|
Corresponding Source shall include the Corresponding Source for any work covered
|
||||||
|
by version 3 of the GNU General Public License that is incorporated pursuant
|
||||||
|
to the following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have permission to
|
||||||
|
link or combine any covered work with a work licensed under version 3 of the
|
||||||
|
GNU General Public License into a single combined work, and to convey the
|
||||||
|
resulting work. The terms of this License will continue to apply to the part
|
||||||
|
which is the covered work, but the work with which it is combined will remain
|
||||||
|
governed by version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of the
|
||||||
|
GNU Affero General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to address
|
||||||
|
new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program specifies
|
||||||
|
that a certain numbered version of the GNU Affero General Public License "or
|
||||||
|
any later version" applies to it, you have the option of following the terms
|
||||||
|
and conditions either of that numbered version or of any later version published
|
||||||
|
by the Free Software Foundation. If the Program does not specify a version
|
||||||
|
number of the GNU Affero General Public License, you may choose any version
|
||||||
|
ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future versions of
|
||||||
|
the GNU Affero General Public License can be used, that proxy's public statement
|
||||||
|
of acceptance of a version permanently authorizes you to choose that version
|
||||||
|
for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different permissions. However,
|
||||||
|
no additional obligations are imposed on any author or copyright holder as
|
||||||
|
a result of your choosing to follow a later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
||||||
|
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
|
||||||
|
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||||
|
CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||||
|
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
|
||||||
|
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
|
||||||
|
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
||||||
|
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||||
|
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided above cannot
|
||||||
|
be given local legal effect according to their terms, reviewing courts shall
|
||||||
|
apply local law that most closely approximates an absolute waiver of all civil
|
||||||
|
liability in connection with the Program, unless a warranty or assumption
|
||||||
|
of liability accompanies a copy of the Program in return for a fee. END OF
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest possible
|
||||||
|
use to the public, the best way to achieve this is to make it free software
|
||||||
|
which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest to attach
|
||||||
|
them to the start of each source file to most effectively state the exclusion
|
||||||
|
of warranty; and each file should have at least the "copyright" line and a
|
||||||
|
pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along
|
||||||
|
with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer network,
|
||||||
|
you should also make sure that it provides a way for users to get its source.
|
||||||
|
For example, if your program is a web application, its interface could display
|
||||||
|
a "Source" link that leads users to an archive of the code. There are many
|
||||||
|
ways you could offer source, and different solutions will be better for different
|
||||||
|
programs; see section 13 for the specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary. For
|
||||||
|
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,94 @@
|
||||||
|
# disks role for Ansible
|
||||||
|
|
||||||
|
Format and mount additional disks
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
### Default Variables
|
||||||
|
|
||||||
|
* `disks_to_mount` - List of disks to mount:
|
||||||
|
* `disable_periodic_fsck` deactivates the periodic ext3/4 filesystem check for the new disk
|
||||||
|
* `disk` is the device, you want to mount
|
||||||
|
* `fstype` allows you to choose the filesystem to use with the new disk
|
||||||
|
* `group` sets group of the mount directory (default: `root`)
|
||||||
|
* `mount` is the directory where the new disk should be mounted
|
||||||
|
* `mount_options` allows you to specify custom mount options
|
||||||
|
* `part` is the first partition name. If not specified, `1` will be appended to the disk name
|
||||||
|
* `user` sets owner of the mount directory (default: `root`)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# inventory/group_vars/GROUP_NAME
|
||||||
|
disks_to_mount:
|
||||||
|
- disk: /dev/sdb
|
||||||
|
fstype: ext4
|
||||||
|
mount_options: defaults
|
||||||
|
mount: /data1
|
||||||
|
user: www-data
|
||||||
|
group: www-data
|
||||||
|
disable_periodic_fsck: false
|
||||||
|
- disk: /dev/nvme0n1
|
||||||
|
part: /dev/nvme0n1p1
|
||||||
|
fstype: xfs
|
||||||
|
mount_options: defaults,noatime
|
||||||
|
mount: /data2
|
||||||
|
- disk: nfs-host:/nfs/export
|
||||||
|
fstype: nfs
|
||||||
|
mount_options: defaults,noatime
|
||||||
|
mount: /data3
|
||||||
|
```
|
||||||
|
|
||||||
|
The following filesystems are currently supported:
|
||||||
|
* [btrfs](http://en.wikipedia.org/wiki/BTRFS) *
|
||||||
|
* [ext2](http://en.wikipedia.org/wiki/Ext2)
|
||||||
|
* [ext3](http://en.wikipedia.org/wiki/Ext3)
|
||||||
|
* [ext4](http://en.wikipedia.org/wiki/Ext4)
|
||||||
|
* [nfs](http://en.wikipedia.org/wiki/Network_File_System) *
|
||||||
|
* [xfs](http://en.wikipedia.org/wiki/XFS) *
|
||||||
|
|
||||||
|
Note: (*) To use these filesystems you have to define and install additional software packages. Please estimate the right package names for your operating system.
|
||||||
|
|
||||||
|
* `disks_packages` - List of packages to install/remove on your hosts
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
disks_packages:
|
||||||
|
- { "name": "xfsprogs", "state": "present" } # package for mkfs.xfs on RedHat / Ubuntu
|
||||||
|
- { "name": "btrfs-progs", "state": "present" } # package for mkfs.btrfs on CentOS / Debian
|
||||||
|
```
|
||||||
|
|
||||||
|
* `disks_services` - List of services to enable/disable on your hosts
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
disks_services:
|
||||||
|
- { "name": "rpc.statd", "state": "started", "enabled": "yes" } # start rpc.statd service for nfs
|
||||||
|
```
|
||||||
|
|
||||||
|
### AWS variables
|
||||||
|
|
||||||
|
* `aws_ebs_discover` - Discover AWS NVMe EBS disks
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
aws_ebs_discover: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example playbook
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
- hosts: 'disks'
|
||||||
|
roles:
|
||||||
|
- role: 'aynicos.disks'
|
||||||
|
disks_to_mount:
|
||||||
|
- disk: /dev/xvdb
|
||||||
|
disable_periodic_fsck: true
|
||||||
|
fstype: ext4
|
||||||
|
mount_options: defaults
|
||||||
|
mount: /var/lib/docker
|
||||||
|
service: docker
|
||||||
|
disks_services:
|
||||||
|
- { "name": "rpc.statd", "state": "started", "enabled": "yes" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
It uses `sfdisk` to partition the disk with a single primary partition spanning the entire disk.
|
||||||
|
It creates the specified filesystem with `mkfs`.
|
||||||
|
It mounts the new filesystem to the specified mount path.
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
# file: default/main.yml
|
||||||
|
|
||||||
|
# discover AWS NVMe EBS disks
|
||||||
|
aws_ebs_discover: false
|
||||||
|
|
||||||
|
# config disks to mount
|
||||||
|
disks_to_mount: []
|
||||||
|
|
||||||
|
# packages to install/remove
|
||||||
|
disks_packages: []
|
||||||
|
|
||||||
|
# services to enable/disable
|
||||||
|
disks_services: []
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
# file: handlers/main.yml
|
||||||
|
|
||||||
|
- name: restart services
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_to_mount_handler_notify.results }}'
|
||||||
|
service:
|
||||||
|
name: "{{item.0.service}}"
|
||||||
|
state: restarted
|
||||||
|
when: item.1.changed and item.0.service is defined
|
||||||
|
|
||||||
|
- name: restart services - nfs
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_to_mount_nfs_handler_notify.results }}'
|
||||||
|
service:
|
||||||
|
name: "{{item.0.service}}"
|
||||||
|
state: restarted
|
||||||
|
when: item.1.changed and item.0.service is defined
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from ctypes import *
|
||||||
|
from fcntl import ioctl
|
||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import *
|
||||||
|
|
||||||
|
module = AnsibleModule(argument_spec=dict(
|
||||||
|
config=dict(required=True, type='list'),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
NVME_ADMIN_IDENTIFY = 0x06
|
||||||
|
NVME_IOCTL_ADMIN_CMD = 0xC0484E41
|
||||||
|
AMZN_NVME_VID = 0x1D0F
|
||||||
|
AMZN_NVME_EBS_MN = "Amazon Elastic Block Store"
|
||||||
|
|
||||||
|
class nvme_admin_command(Structure):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = [("opcode", c_uint8), # op code
|
||||||
|
("flags", c_uint8), # fused operation
|
||||||
|
("cid", c_uint16), # command id
|
||||||
|
("nsid", c_uint32), # namespace id
|
||||||
|
("reserved0", c_uint64),
|
||||||
|
("mptr", c_uint64), # metadata pointer
|
||||||
|
("addr", c_uint64), # data pointer
|
||||||
|
("mlen", c_uint32), # metadata length
|
||||||
|
("alen", c_uint32), # data length
|
||||||
|
("cdw10", c_uint32),
|
||||||
|
("cdw11", c_uint32),
|
||||||
|
("cdw12", c_uint32),
|
||||||
|
("cdw13", c_uint32),
|
||||||
|
("cdw14", c_uint32),
|
||||||
|
("cdw15", c_uint32),
|
||||||
|
("reserved1", c_uint64)]
|
||||||
|
|
||||||
|
class nvme_identify_controller_amzn_vs(Structure):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = [("bdev", c_char * 32), # block device name
|
||||||
|
("reserved0", c_char * (1024 - 32))]
|
||||||
|
|
||||||
|
class nvme_identify_controller_psd(Structure):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = [("mp", c_uint16), # maximum power
|
||||||
|
("reserved0", c_uint16),
|
||||||
|
("enlat", c_uint32), # entry latency
|
||||||
|
("exlat", c_uint32), # exit latency
|
||||||
|
("rrt", c_uint8), # relative read throughput
|
||||||
|
("rrl", c_uint8), # relative read latency
|
||||||
|
("rwt", c_uint8), # relative write throughput
|
||||||
|
("rwl", c_uint8), # relative write latency
|
||||||
|
("reserved1", c_char * 16)]
|
||||||
|
|
||||||
|
class nvme_identify_controller(Structure):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = [("vid", c_uint16), # PCI Vendor ID
|
||||||
|
("ssvid", c_uint16), # PCI Subsystem Vendor ID
|
||||||
|
("sn", c_char * 20), # Serial Number
|
||||||
|
("mn", c_char * 40), # Module Number
|
||||||
|
("fr", c_char * 8), # Firmware Revision
|
||||||
|
("rab", c_uint8), # Recommend Arbitration Burst
|
||||||
|
("ieee", c_uint8 * 3), # IEEE OUI Identifier
|
||||||
|
("mic", c_uint8), # Multi-Interface Capabilities
|
||||||
|
("mdts", c_uint8), # Maximum Data Transfer Size
|
||||||
|
("reserved0", c_uint8 * (256 - 78)),
|
||||||
|
("oacs", c_uint16), # Optional Admin Command Support
|
||||||
|
("acl", c_uint8), # Abort Command Limit
|
||||||
|
("aerl", c_uint8), # Asynchronous Event Request Limit
|
||||||
|
("frmw", c_uint8), # Firmware Updates
|
||||||
|
("lpa", c_uint8), # Log Page Attributes
|
||||||
|
("elpe", c_uint8), # Error Log Page Entries
|
||||||
|
("npss", c_uint8), # Number of Power States Support
|
||||||
|
("avscc", c_uint8), # Admin Vendor Specific Command Configuration
|
||||||
|
("reserved1", c_uint8 * (512 - 265)),
|
||||||
|
("sqes", c_uint8), # Submission Queue Entry Size
|
||||||
|
("cqes", c_uint8), # Completion Queue Entry Size
|
||||||
|
("reserved2", c_uint16),
|
||||||
|
("nn", c_uint32), # Number of Namespaces
|
||||||
|
("oncs", c_uint16), # Optional NVM Command Support
|
||||||
|
("fuses", c_uint16), # Fused Operation Support
|
||||||
|
("fna", c_uint8), # Format NVM Attributes
|
||||||
|
("vwc", c_uint8), # Volatile Write Cache
|
||||||
|
("awun", c_uint16), # Atomic Write Unit Normal
|
||||||
|
("awupf", c_uint16), # Atomic Write Unit Power Fail
|
||||||
|
("nvscc", c_uint8), # NVM Vendor Specific Command Configuration
|
||||||
|
("reserved3", c_uint8 * (704 - 531)),
|
||||||
|
("reserved4", c_uint8 * (2048 - 704)),
|
||||||
|
("psd", nvme_identify_controller_psd * 32), # Power State Descriptor
|
||||||
|
("vs", nvme_identify_controller_amzn_vs)] # Vendor Specific
|
||||||
|
|
||||||
|
class ebs_nvme_device:
|
||||||
|
def __init__(self, device):
|
||||||
|
self.device = device
|
||||||
|
self.ctrl_identify()
|
||||||
|
|
||||||
|
def _nvme_ioctl(self, id_response, id_len):
|
||||||
|
admin_cmd = nvme_admin_command(opcode = NVME_ADMIN_IDENTIFY,
|
||||||
|
addr = id_response,
|
||||||
|
alen = id_len,
|
||||||
|
cdw10 = 1)
|
||||||
|
|
||||||
|
with open(self.device, "w") as nvme:
|
||||||
|
ioctl(nvme, NVME_IOCTL_ADMIN_CMD, admin_cmd)
|
||||||
|
|
||||||
|
def ctrl_identify(self):
|
||||||
|
self.id_ctrl = nvme_identify_controller()
|
||||||
|
self._nvme_ioctl(addressof(self.id_ctrl), sizeof(self.id_ctrl))
|
||||||
|
|
||||||
|
def is_ebs(self):
|
||||||
|
if self.id_ctrl.vid != AMZN_NVME_VID:
|
||||||
|
return False
|
||||||
|
if self.id_ctrl.mn.strip() != AMZN_NVME_EBS_MN:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_volume_id(self):
|
||||||
|
vol = self.id_ctrl.sn.decode('utf-8')
|
||||||
|
|
||||||
|
if vol.startswith("vol") and vol[3] != "-":
|
||||||
|
vol = "vol-" + vol[3:]
|
||||||
|
|
||||||
|
return vol.strip()
|
||||||
|
|
||||||
|
def get_block_device(self, stripped=False):
|
||||||
|
dev = self.id_ctrl.vs.bdev.decode('utf-8')
|
||||||
|
|
||||||
|
if stripped and dev.startswith("/dev/"):
|
||||||
|
dev = dev[5:]
|
||||||
|
|
||||||
|
return dev.strip()
|
||||||
|
|
||||||
|
|
||||||
|
def update_disk(disk, mapping):
|
||||||
|
if 'device_name' not in disk:
|
||||||
|
return disk
|
||||||
|
|
||||||
|
device_name = disk['device_name'][5:]
|
||||||
|
if device_name not in mapping:
|
||||||
|
return disk
|
||||||
|
|
||||||
|
volume_id = mapping[device_name]
|
||||||
|
link_path = '/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol%s' % volume_id[4:]
|
||||||
|
resolved = str(Path(link_path).resolve())
|
||||||
|
|
||||||
|
new_disk = dict(disk)
|
||||||
|
new_disk['disk'] = resolved
|
||||||
|
new_disk['part'] = '%sp1' % resolved
|
||||||
|
return new_disk
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
src_config = module.params['config']
|
||||||
|
|
||||||
|
lsblkOutput = subprocess.check_output(['lsblk', '-J'])
|
||||||
|
lsblk = json.loads(lsblkOutput.decode('utf-8'))
|
||||||
|
mapping = {}
|
||||||
|
for blockdevice in lsblk['blockdevices']:
|
||||||
|
try:
|
||||||
|
dev = ebs_nvme_device('/dev/%s' % blockdevice['name'])
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
except IOError:
|
||||||
|
continue
|
||||||
|
if dev.is_ebs():
|
||||||
|
continue
|
||||||
|
mapping[dev.get_block_device()] = dev.get_volume_id()
|
||||||
|
|
||||||
|
new_config = [
|
||||||
|
update_disk(disk, mapping) for disk in src_config
|
||||||
|
]
|
||||||
|
|
||||||
|
facts = {'blockDeviceMapping': mapping, 'config': new_config, 'source_config': src_config}
|
||||||
|
result = {"changed": False, "ansible_facts": facts}
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
# file: meta/main.yml
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
|
galaxy_info:
|
||||||
|
author: Yann Autissier
|
||||||
|
categories:
|
||||||
|
- system
|
||||||
|
description: Format and mount additional disks
|
||||||
|
license: GPL
|
||||||
|
platforms:
|
||||||
|
- name: Alpine
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Debian
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: EL
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Fedora
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
# file: tasks/config.yml
|
||||||
|
|
||||||
|
- name: config - discover NVMe EBS
|
||||||
|
when: aws_ebs_discover | default(True) | bool
|
||||||
|
disks_ebs_config:
|
||||||
|
config: "{{ disks_to_mount }}"
|
||||||
|
become: yes
|
||||||
|
register: __disks_ebs_config
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
disks_to_mount: "{{ disks_to_mount|defaut([]) + __disks_ebs_config['ansible_facts']['config'] }}"
|
||||||
|
when: __disks_ebs_config is defined and 'ansible_facts' in __disks_ebs_config
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
# file: tasks/disks.yml
|
||||||
|
|
||||||
|
- name: disks - get disk alignment
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
shell: |
|
||||||
|
if
|
||||||
|
[[ -e /sys/block/{{ item.disk | basename }}/queue/optimal_io_size && -e /sys/block/{{ item.disk | basename }}/alignment_offset && -e /sys/block/{{ item.disk | basename }}/queue/physical_block_size ]];
|
||||||
|
then
|
||||||
|
echo $[$(( ($(cat /sys/block/{{ item.disk | basename }}/queue/optimal_io_size) + $(cat /sys/block/{{ item.disk | basename }}/alignment_offset)) / $(cat /sys/block/{{ item.disk | basename }}/queue/physical_block_size) )) | 2048];
|
||||||
|
else
|
||||||
|
echo 2048;
|
||||||
|
fi
|
||||||
|
args:
|
||||||
|
creates: '{{ item.part | default(item.disk + "1") }}'
|
||||||
|
executable: '/bin/bash'
|
||||||
|
register: disks_offset
|
||||||
|
|
||||||
|
- name: disks - stat if the disk exists
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
stat:
|
||||||
|
path: '{{ item.disk }}'
|
||||||
|
changed_when: False
|
||||||
|
register: disks_stat
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
# file: tasks/filesystems.yml
|
||||||
|
|
||||||
|
- name: filesystems - create filesystem on the first partition
|
||||||
|
when: item.1.stat.exists
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_stat.results }}'
|
||||||
|
filesystem:
|
||||||
|
dev: '{{ item.0.part | default(item.0.disk + "1") }}'
|
||||||
|
force: '{{ item.0.force|d(omit) }}'
|
||||||
|
fstype: '{{ item.0.fstype }}'
|
||||||
|
opts: '{{ item.0.fsopts|d(omit) }}'
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: filesystems - disable periodic fsck and reserved space on ext3 or ext4 formatted disks
|
||||||
|
when: "disks_to_mount and ( item.0.fstype == 'ext4' or item.0.fstype == 'ext3' ) and item.0.disable_periodic_fsck|default(false)|bool and item.1.stat.exists"
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_stat.results }}'
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/usr/sbin:/sbin"
|
||||||
|
shell: tune2fs -c0 -i0 -m0 {{ item.0.part | default(item.0.disk + "1") }}
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: filesystems - btrfs
|
||||||
|
when: "disks_to_mount and ansible_cmdline.fstype == 'btrfs'"
|
||||||
|
import_tasks: filesystems_btrfs.yml
|
||||||
|
tags:
|
||||||
|
- btrfs
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# file: tasks/filesystems-btrfs.yml
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
# file: tasks/main.yml
|
||||||
|
|
||||||
|
- import_tasks: vars.yml
|
||||||
|
tags:
|
||||||
|
- vars
|
||||||
|
- import_tasks: config.yml
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
- import_tasks: packages.yml
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- import_tasks: services.yml
|
||||||
|
tags:
|
||||||
|
- services
|
||||||
|
- import_tasks: disks.yml
|
||||||
|
tags:
|
||||||
|
- disks
|
||||||
|
- import_tasks: partitions.yml
|
||||||
|
tags:
|
||||||
|
- partitions
|
||||||
|
- import_tasks: filesystems.yml
|
||||||
|
tags:
|
||||||
|
- filesystems
|
||||||
|
- import_tasks: mount.yml
|
||||||
|
tags:
|
||||||
|
- mount
|
||||||
|
- meta: flush_handlers
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
# file: tasks/mount.yml
|
||||||
|
|
||||||
|
- name: mount - check directory mount exists
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
file:
|
||||||
|
path: '{{ item.mount }}'
|
||||||
|
state: directory
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: mount - mount additional disks
|
||||||
|
when: item.2.stat.exists
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_blkid.results }}'
|
||||||
|
- '{{ disks_stat.results }}'
|
||||||
|
mount:
|
||||||
|
name: '{{ item.0.mount }}'
|
||||||
|
fstype: '{{ item.0.fstype }}'
|
||||||
|
opts: '{{ item.0.mount_options|d(omit) }}'
|
||||||
|
passno: '0'
|
||||||
|
src: 'UUID={{ item.1.stdout }}'
|
||||||
|
state: '{{ item.0.mount_state|d("mounted") }}'
|
||||||
|
become: yes
|
||||||
|
notify:
|
||||||
|
- restart services
|
||||||
|
register: disks_to_mount_handler_notify
|
||||||
|
|
||||||
|
- name: mount - mount additional disks - nfs
|
||||||
|
when: item.fstype == 'nfs'
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
mount:
|
||||||
|
name: '{{ item.mount }}'
|
||||||
|
fstype: '{{ item.fstype }}'
|
||||||
|
opts: '{{ item.mount_options|d(omit) }}'
|
||||||
|
src: '{{ item.disk }}'
|
||||||
|
state: '{{ item.mount_state|d("mounted") }}'
|
||||||
|
become: yes
|
||||||
|
notify:
|
||||||
|
- restart services - nfs
|
||||||
|
register: disks_to_mount_nfs_handler_notify
|
||||||
|
|
||||||
|
- name: mount - set permissions
|
||||||
|
when: item.user is defined or item.group is defined
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
file:
|
||||||
|
path: '{{ item.mount }}'
|
||||||
|
owner: '{{ item.user | default("root") }}'
|
||||||
|
group: '{{ item.group | default("root") }}'
|
||||||
|
state: directory
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
# file: tasks/packages.yml
|
||||||
|
|
||||||
|
- name: packages - install parted
|
||||||
|
when: disks_to_mount is defined
|
||||||
|
package:
|
||||||
|
name: parted
|
||||||
|
state: present
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: packages - install/remove disks packages
|
||||||
|
when: disks_packages is defined
|
||||||
|
with_items: "{{ disks_packages|default([]) }}"
|
||||||
|
package:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
# file: tasks/partitions.yml
|
||||||
|
|
||||||
|
- name: partitions - extend additional disks partitions
|
||||||
|
with_items: '{{ disks_to_mount }}'
|
||||||
|
shell: |
|
||||||
|
if
|
||||||
|
[ -b {{ item.disk }} ]
|
||||||
|
then
|
||||||
|
[ -b {{ item.part | default(item.disk + "1") }} ] || parted -a optimal --script "{{ item.disk }}" mklabel gpt mkpart primary {{ disks_offset.stdout|default("2048") }}s 100% && sleep 5 && partprobe {{ item.disk }}; sleep 5
|
||||||
|
fi
|
||||||
|
args:
|
||||||
|
creates: '{{ item.part | default(item.disk + "1") }}'
|
||||||
|
executable: '/bin/bash'
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: partitions - get UUID
|
||||||
|
when: item.1.stat.exists
|
||||||
|
with_together:
|
||||||
|
- '{{ disks_to_mount }}'
|
||||||
|
- '{{ disks_stat.results }}'
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/usr/sbin:/sbin"
|
||||||
|
command: blkid -s UUID -o value {{ item.0.part | default(item.0.disk + "1") }}
|
||||||
|
changed_when: False
|
||||||
|
check_mode: no
|
||||||
|
become: yes
|
||||||
|
register: disks_blkid
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
# file: tasks/services.yml
|
||||||
|
|
||||||
|
- name: services - enable/disable disks services
|
||||||
|
when: disks_services is defined and ansible_service_mgr|lower != "openrc" and ansible_service_mgr|lower != "runit"
|
||||||
|
with_items: "{{ disks_services|default([]) }}"
|
||||||
|
service:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - enable/disable disks services - openrc
|
||||||
|
when: disks_services is defined and ansible_service_mgr|lower == "openrc"
|
||||||
|
with_items: "{{ disks_services|default([]) }}"
|
||||||
|
service:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
runlevel: boot
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - enable/disable disks services - runit
|
||||||
|
when: disks_services is defined and ansible_service_mgr|lower == "runit"
|
||||||
|
with_items: "{{ disks_services|default([]) }}"
|
||||||
|
sysvinit:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
runlevels:
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# file: tasks/vars.yml
|
||||||
|
|
||||||
|
- name: vars - load per operating system variables
|
||||||
|
include_vars: "{{item}}"
|
||||||
|
with_first_found:
|
||||||
|
- paths:
|
||||||
|
- "vars/"
|
||||||
|
- files:
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_version|lower}}-{{ansible_machine}}.yml" # centos-6.4-i386.yml ubuntu-16.04-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_version|lower}}.yml" # centos-6.4.yml ubuntu-16.04.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_major_version|lower}}-{{ansible_machine}}.yml" # centos-6-i386.yml ubuntu-16-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_major_version|lower}}.yml" # centos-6.yml ubuntu-16.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_version|lower}}-{{ansible_machine}}.yml" # redhat-6.4-i386.yml debian-8.5-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_version|lower}}.yml" # redhat-6.4.yml debian-8.5.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_major_version|lower}}-{{ansible_machine}}.yml" # redhat-6-i386.yml debian-8-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_major_version|lower}}.yml" # redhat-6.yml debian-8.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_machine}}.yml" # centos-i386.yml ubuntu-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}.yml" # centos.yml ubuntu.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_machine}}.yml" # redhat-i386.yml debian-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}.yml" # redhat.yml debian.yml
|
||||||
|
- "{{ansible_system|lower}}-{{ansible_machine}}.yml" # linux-i386.yml linux-x86_64.yml
|
||||||
|
- "{{ansible_system|lower}}.yml" # linux.yml
|
||||||
|
- "default.yml" # default.yml
|
||||||
|
skip: true
|
||||||
|
|
||||||
|
- name: vars - override with local variables
|
||||||
|
include_vars: "{{item}}"
|
||||||
|
with_first_found:
|
||||||
|
- paths:
|
||||||
|
- "vars/"
|
||||||
|
- files:
|
||||||
|
- "local.yml"
|
||||||
|
skip: true
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||||
;
|
;
|
||||||
[subrepo]
|
[subrepo]
|
||||||
remote = ssh://git@github.com/aynicos/docker-pdns-server
|
remote = ssh://git@github.com/aynicos/ansible-docker
|
||||||
branch = master
|
branch = master
|
||||||
commit = 6d3c4ce70cbb38d237be757206bfbf082ce2ba3e
|
commit = 6217a899084cba00447195d1873b211462b60d52
|
||||||
parent = 9de6b77b0d944fe6efa7b020ba7c2dbbba5df4f8
|
parent = 4745dad8cb8a826ee3ac47accda79f96957b5e13
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.0
|
cmdver = 0.4.0
|
|
@ -0,0 +1,4 @@
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
* **Yann Autissier** - *initial work* - [aya](https://github.com/aya)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0-alpha - 2021-07-14
|
||||||
|
|
||||||
|
Initial myos release
|
||||||
|
|
||||||
|
## v0.1.0 - 2016-12-20
|
||||||
|
|
||||||
|
Initial release
|
||||||
|
|
||||||
|
* Install docker daemon
|
||||||
|
* Start and active docker service at boot
|
||||||
|
* Build and run docker images
|
|
@ -0,0 +1,610 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (c) 2016 Yann Autissier
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for software
|
||||||
|
and other kinds of works, specifically designed to ensure cooperation with
|
||||||
|
the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed to take
|
||||||
|
away your freedom to share and change the works. By contrast, our General
|
||||||
|
Public Licenses are intended to guarantee your freedom to share and change
|
||||||
|
all versions of a program--to make sure it remains free software for all its
|
||||||
|
users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price. Our
|
||||||
|
General Public Licenses are designed to make sure that you have the freedom
|
||||||
|
to distribute copies of free software (and charge for them if you wish), that
|
||||||
|
you receive source code or can get it if you want it, that you can change
|
||||||
|
the software or use pieces of it in new free programs, and that you know you
|
||||||
|
can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights with two
|
||||||
|
steps: (1) assert copyright on the software, and (2) offer you this License
|
||||||
|
which gives you legal permission to copy, distribute and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that improvements made
|
||||||
|
in alternate versions of the program, if they receive widespread use, become
|
||||||
|
available for other developers to incorporate. Many developers of free software
|
||||||
|
are heartened and encouraged by the resulting cooperation. However, in the
|
||||||
|
case of software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and letting
|
||||||
|
the public access it on a server without ever releasing its source code to
|
||||||
|
the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to ensure that,
|
||||||
|
in such cases, the modified source code becomes available to the community.
|
||||||
|
It requires the operator of a network server to provide the source code of
|
||||||
|
the modified version running there to the users of that server. Therefore,
|
||||||
|
public use of a modified version, on a publicly accessible server, gives the
|
||||||
|
public access to the source code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and published by
|
||||||
|
Affero, was designed to accomplish similar goals. This is a different license,
|
||||||
|
not a version of the Affero GPL, but Affero has released a new version of
|
||||||
|
the Affero GPL which permits relicensing under this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of works,
|
||||||
|
such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this License.
|
||||||
|
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
|
||||||
|
or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work in
|
||||||
|
a fashion requiring copyright permission, other than the making of an exact
|
||||||
|
copy. The resulting work is called a "modified version" of the earlier work
|
||||||
|
or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based on the
|
||||||
|
Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without permission,
|
||||||
|
would make you directly or secondarily liable for infringement under applicable
|
||||||
|
copyright law, except executing it on a computer or modifying a private copy.
|
||||||
|
Propagation includes copying, distribution (with or without modification),
|
||||||
|
making available to the public, and in some countries other activities as
|
||||||
|
well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other parties
|
||||||
|
to make or receive copies. Mere interaction with a user through a computer
|
||||||
|
network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices" to the
|
||||||
|
extent that it includes a convenient and prominently visible feature that
|
||||||
|
(1) displays an appropriate copyright notice, and (2) tells the user that
|
||||||
|
there is no warranty for the work (except to the extent that warranties are
|
||||||
|
provided), that licensees may convey the work under this License, and how
|
||||||
|
to view a copy of this License. If the interface presents a list of user commands
|
||||||
|
or options, such as a menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. "Object code" means any non-source form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official standard
|
||||||
|
defined by a recognized standards body, or, in the case of interfaces specified
|
||||||
|
for a particular programming language, one that is widely used among developers
|
||||||
|
working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other than
|
||||||
|
the work as a whole, that (a) is included in the normal form of packaging
|
||||||
|
a Major Component, but which is not part of that Major Component, and (b)
|
||||||
|
serves only to enable use of the work with that Major Component, or to implement
|
||||||
|
a Standard Interface for which an implementation is available to the public
|
||||||
|
in source code form. A "Major Component", in this context, means a major essential
|
||||||
|
component (kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to produce
|
||||||
|
the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all the source
|
||||||
|
code needed to generate, install, and (for an executable work) run the object
|
||||||
|
code and to modify the work, including scripts to control those activities.
|
||||||
|
However, it does not include the work's System Libraries, or general-purpose
|
||||||
|
tools or generally available free programs which are used unmodified in performing
|
||||||
|
those activities but which are not part of the work. For example, Corresponding
|
||||||
|
Source includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically linked
|
||||||
|
subprograms that the work is specifically designed to require, such as by
|
||||||
|
intimate data communication or control flow between those
|
||||||
|
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users can regenerate
|
||||||
|
automatically from other parts of the Corresponding Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of copyright
|
||||||
|
on the Program, and are irrevocable provided the stated conditions are met.
|
||||||
|
This License explicitly affirms your unlimited permission to run the unmodified
|
||||||
|
Program. The output from running a covered work is covered by this License
|
||||||
|
only if the output, given its content, constitutes a covered work. This License
|
||||||
|
acknowledges your rights of fair use or other equivalent, as provided by copyright
|
||||||
|
law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not convey, without
|
||||||
|
conditions so long as your license otherwise remains in force. You may convey
|
||||||
|
covered works to others for the sole purpose of having them make modifications
|
||||||
|
exclusively for you, or provide you with facilities for running those works,
|
||||||
|
provided that you comply with the terms of this License in conveying all material
|
||||||
|
for which you do not control copyright. Those thus making or running the covered
|
||||||
|
works for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of your copyrighted
|
||||||
|
material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under the conditions
|
||||||
|
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological measure
|
||||||
|
under any applicable law fulfilling obligations under article 11 of the WIPO
|
||||||
|
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
|
||||||
|
or restricting circumvention of such measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid circumvention
|
||||||
|
of technological measures to the extent such circumvention is effected by
|
||||||
|
exercising rights under this License with respect to the covered work, and
|
||||||
|
you disclaim any intention to limit operation or modification of the work
|
||||||
|
as a means of enforcing, against the work's users, your or third parties'
|
||||||
|
legal rights to forbid circumvention of technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you receive
|
||||||
|
it, in any medium, provided that you conspicuously and appropriately publish
|
||||||
|
on each copy an appropriate copyright notice; keep intact all notices stating
|
||||||
|
that this License and any non-permissive terms added in accord with section
|
||||||
|
7 apply to the code; keep intact all notices of the absence of any warranty;
|
||||||
|
and give all recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey, and you
|
||||||
|
may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to produce
|
||||||
|
it from the Program, in the form of source code under the terms of section
|
||||||
|
4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified it, and
|
||||||
|
giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is released under
|
||||||
|
this License and any conditions added under section 7. This requirement modifies
|
||||||
|
the requirement in section 4 to "keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this License to anyone
|
||||||
|
who comes into possession of a copy. This License will therefore apply, along
|
||||||
|
with any applicable section 7 additional terms, to the whole of the work,
|
||||||
|
and all its parts, regardless of how they are packaged. This License gives
|
||||||
|
no permission to license the work in any other way, but it does not invalidate
|
||||||
|
such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display Appropriate
|
||||||
|
Legal Notices; however, if the Program has interactive interfaces that do
|
||||||
|
not display Appropriate Legal Notices, your work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent works,
|
||||||
|
which are not by their nature extensions of the covered work, and which are
|
||||||
|
not combined with it such as to form a larger program, in or on a volume of
|
||||||
|
a storage or distribution medium, is called an "aggregate" if the compilation
|
||||||
|
and its resulting copyright are not used to limit the access or legal rights
|
||||||
|
of the compilation's users beyond what the individual works permit. Inclusion
|
||||||
|
of a covered work in an aggregate does not cause this License to apply to
|
||||||
|
the other parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms of sections
|
||||||
|
4 and 5, provided that you also convey the machine-readable Corresponding
|
||||||
|
Source under the terms of this License, in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by the Corresponding Source fixed
|
||||||
|
on a durable physical medium customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by a written offer, valid for
|
||||||
|
at least three years and valid for as long as you offer spare parts or customer
|
||||||
|
support for that product model, to give anyone who possesses the object code
|
||||||
|
either (1) a copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical medium customarily
|
||||||
|
used for software interchange, for a price no more than your reasonable cost
|
||||||
|
of physically performing this conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the written
|
||||||
|
offer to provide the Corresponding Source. This alternative is allowed only
|
||||||
|
occasionally and noncommercially, and only if you received the object code
|
||||||
|
with such an offer, in accord with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated place (gratis
|
||||||
|
or for a charge), and offer equivalent access to the Corresponding Source
|
||||||
|
in the same way through the same place at no further charge. You need not
|
||||||
|
require recipients to copy the Corresponding Source along with the object
|
||||||
|
code. If the place to copy the object code is a network server, the Corresponding
|
||||||
|
Source may be on a different server (operated by you or a third party) that
|
||||||
|
supports equivalent copying facilities, provided you maintain clear directions
|
||||||
|
next to the object code saying where to find the Corresponding Source. Regardless
|
||||||
|
of what server hosts the Corresponding Source, you remain obligated to ensure
|
||||||
|
that it is available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided you inform
|
||||||
|
other peers where the object code and Corresponding Source of the work are
|
||||||
|
being offered to the general public at no charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded from
|
||||||
|
the Corresponding Source as a System Library, need not be included in conveying
|
||||||
|
the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any tangible
|
||||||
|
personal property which is normally used for personal, family, or household
|
||||||
|
purposes, or (2) anything designed or sold for incorporation into a dwelling.
|
||||||
|
In determining whether a product is a consumer product, doubtful cases shall
|
||||||
|
be resolved in favor of coverage. For a particular product received by a particular
|
||||||
|
user, "normally used" refers to a typical or common use of that class of product,
|
||||||
|
regardless of the status of the particular user or of the way in which the
|
||||||
|
particular user actually uses, or expects or is expected to use, the product.
|
||||||
|
A product is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent the
|
||||||
|
only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods, procedures,
|
||||||
|
authorization keys, or other information required to install and execute modified
|
||||||
|
versions of a covered work in that User Product from a modified version of
|
||||||
|
its Corresponding Source. The information must suffice to ensure that the
|
||||||
|
continued functioning of the modified object code is in no case prevented
|
||||||
|
or interfered with solely because modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or specifically
|
||||||
|
for use in, a User Product, and the conveying occurs as part of a transaction
|
||||||
|
in which the right of possession and use of the User Product is transferred
|
||||||
|
to the recipient in perpetuity or for a fixed term (regardless of how the
|
||||||
|
transaction is characterized), the Corresponding Source conveyed under this
|
||||||
|
section must be accompanied by the Installation Information. But this requirement
|
||||||
|
does not apply if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has been installed
|
||||||
|
in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a requirement
|
||||||
|
to continue to provide support service, warranty, or updates for a work that
|
||||||
|
has been modified or installed by the recipient, or for the User Product in
|
||||||
|
which it has been modified or installed. Access to a network may be denied
|
||||||
|
when the modification itself materially and adversely affects the operation
|
||||||
|
of the network or violates the rules and protocols for communication across
|
||||||
|
the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided, in accord
|
||||||
|
with this section must be in a format that is publicly documented (and with
|
||||||
|
an implementation available to the public in source code form), and must require
|
||||||
|
no special password or key for unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this License
|
||||||
|
by making exceptions from one or more of its conditions. Additional permissions
|
||||||
|
that are applicable to the entire Program shall be treated as though they
|
||||||
|
were included in this License, to the extent that they are valid under applicable
|
||||||
|
law. If additional permissions apply only to part of the Program, that part
|
||||||
|
may be used separately under those permissions, but the entire Program remains
|
||||||
|
governed by this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option remove any
|
||||||
|
additional permissions from that copy, or from any part of it. (Additional
|
||||||
|
permissions may be written to require their own removal in certain cases when
|
||||||
|
you modify the work.) You may place additional permissions on material, added
|
||||||
|
by you to a covered work, for which you have or can give appropriate copyright
|
||||||
|
permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you add
|
||||||
|
to a covered work, you may (if authorized by the copyright holders of that
|
||||||
|
material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the terms of
|
||||||
|
sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or author
|
||||||
|
attributions in that material or in the Appropriate Legal Notices displayed
|
||||||
|
by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or requiring
|
||||||
|
that modified versions of such material be marked in reasonable ways as different
|
||||||
|
from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or authors
|
||||||
|
of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some trade names,
|
||||||
|
trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that material by
|
||||||
|
anyone who conveys the material (or modified versions of it) with contractual
|
||||||
|
assumptions of liability to the recipient, for any liability that these contractual
|
||||||
|
assumptions directly impose on those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further restrictions"
|
||||||
|
within the meaning of section 10. If the Program as you received it, or any
|
||||||
|
part of it, contains a notice stating that it is governed by this License
|
||||||
|
along with a term that is a further restriction, you may remove that term.
|
||||||
|
If a license document contains a further restriction but permits relicensing
|
||||||
|
or conveying under this License, you may add to a covered work material governed
|
||||||
|
by the terms of that license document, provided that the further restriction
|
||||||
|
does not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you must place,
|
||||||
|
in the relevant source files, a statement of the additional terms that apply
|
||||||
|
to those files, or a notice indicating where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the form
|
||||||
|
of a separately written license, or stated as exceptions; the above requirements
|
||||||
|
apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly provided
|
||||||
|
under this License. Any attempt otherwise to propagate or modify it is void,
|
||||||
|
and will automatically terminate your rights under this License (including
|
||||||
|
any patent licenses granted under the third paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your license from
|
||||||
|
a particular copyright holder is reinstated (a) provisionally, unless and
|
||||||
|
until the copyright holder explicitly and finally terminates your license,
|
||||||
|
and (b) permanently, if the copyright holder fails to notify you of the violation
|
||||||
|
by some reasonable means prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is reinstated permanently
|
||||||
|
if the copyright holder notifies you of the violation by some reasonable means,
|
||||||
|
this is the first time you have received notice of violation of this License
|
||||||
|
(for any work) from that copyright holder, and you cure the violation prior
|
||||||
|
to 30 days after your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the licenses
|
||||||
|
of parties who have received copies or rights from you under this License.
|
||||||
|
If your rights have been terminated and not permanently reinstated, you do
|
||||||
|
not qualify to receive new licenses for the same material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or run a copy
|
||||||
|
of the Program. Ancillary propagation of a covered work occurring solely as
|
||||||
|
a consequence of using peer-to-peer transmission to receive a copy likewise
|
||||||
|
does not require acceptance. However, nothing other than this License grants
|
||||||
|
you permission to propagate or modify any covered work. These actions infringe
|
||||||
|
copyright if you do not accept this License. Therefore, by modifying or propagating
|
||||||
|
a covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically receives
|
||||||
|
a license from the original licensors, to run, modify and propagate that work,
|
||||||
|
subject to this License. You are not responsible for enforcing compliance
|
||||||
|
by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an organization,
|
||||||
|
or substantially all assets of one, or subdividing an organization, or merging
|
||||||
|
organizations. If propagation of a covered work results from an entity transaction,
|
||||||
|
each party to that transaction who receives a copy of the work also receives
|
||||||
|
whatever licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the Corresponding
|
||||||
|
Source of the work from the predecessor in interest, if the predecessor has
|
||||||
|
it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the rights
|
||||||
|
granted or affirmed under this License. For example, you may not impose a
|
||||||
|
license fee, royalty, or other charge for exercise of rights granted under
|
||||||
|
this License, and you may not initiate litigation (including a cross-claim
|
||||||
|
or counterclaim in a lawsuit) alleging that any patent claim is infringed
|
||||||
|
by making, using, selling, offering for sale, or importing the Program or
|
||||||
|
any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this License
|
||||||
|
of the Program or a work on which the Program is based. The work thus licensed
|
||||||
|
is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims owned or controlled
|
||||||
|
by the contributor, whether already acquired or hereafter acquired, that would
|
||||||
|
be infringed by some manner, permitted by this License, of making, using,
|
||||||
|
or selling its contributor version, but do not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of the contributor
|
||||||
|
version. For purposes of this definition, "control" includes the right to
|
||||||
|
grant patent sublicenses in a manner consistent with the requirements of this
|
||||||
|
License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
|
||||||
|
license under the contributor's essential patent claims, to make, use, sell,
|
||||||
|
offer for sale, import and otherwise run, modify and propagate the contents
|
||||||
|
of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express agreement
|
||||||
|
or commitment, however denominated, not to enforce a patent (such as an express
|
||||||
|
permission to practice a patent or covenant not to s ue for patent infringement).
|
||||||
|
To "grant" such a patent license to a party means to make such an agreement
|
||||||
|
or commitment not to enforce a patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license, and the
|
||||||
|
Corresponding Source of the work is not available for anyone to copy, free
|
||||||
|
of charge and under the terms of this License, through a publicly available
|
||||||
|
network server or other readily accessible means, then you must either (1)
|
||||||
|
cause the Corresponding Source to be so available, or (2) arrange to deprive
|
||||||
|
yourself of the benefit of the patent license for this particular work, or
|
||||||
|
(3) arrange, in a manner consistent with the requirements of this License,
|
||||||
|
to extend the patent
|
||||||
|
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have actual
|
||||||
|
knowledge that, but for the patent license, your conveying the covered work
|
||||||
|
in a country, or your recipient's use of the covered work in a country, would
|
||||||
|
infringe one or more identifiable patents in that country that you have reason
|
||||||
|
to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or arrangement,
|
||||||
|
you convey, or propagate by procuring conveyance of, a covered work, and grant
|
||||||
|
a patent license to some of the parties receiving the covered work authorizing
|
||||||
|
them to use, propagate, modify or convey a specific copy of the covered work,
|
||||||
|
then the patent license you grant is automatically extended to all recipients
|
||||||
|
of the covered work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within the scope
|
||||||
|
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
|
||||||
|
of one or more of the rights that are specifically granted under this License.
|
||||||
|
You may not convey a covered work if you are a party to an arrangement with
|
||||||
|
a third party that is in the business of distributing software, under which
|
||||||
|
you make payment to the third party based on the extent of your activity of
|
||||||
|
conveying the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory patent
|
||||||
|
license (a) in connection with copies of the covered work conveyed by you
|
||||||
|
(or copies made from those copies), or (b) primarily for and in connection
|
||||||
|
with specific products or compilations that contain the covered work, unless
|
||||||
|
you entered into that arrangement, or that patent license was granted, prior
|
||||||
|
to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting any implied
|
||||||
|
license or other defenses to infringement that may otherwise be available
|
||||||
|
to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||||
|
that contradict the conditions of this License, they do not excuse you from
|
||||||
|
the conditions of this License. If you cannot convey a covered work so as
|
||||||
|
to satisfy simultaneously your obligations under this License and any other
|
||||||
|
pertinent obligations, then as a consequence you may
|
||||||
|
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey the
|
||||||
|
Program, the only way you could satisfy both those terms and this License
|
||||||
|
would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the Program,
|
||||||
|
your modified version must prominently offer all users interacting with it
|
||||||
|
remotely through a computer network (if your version supports such interaction)
|
||||||
|
an opportunity to receive the Corresponding Source of your version by providing
|
||||||
|
access to the Corresponding Source from a network server at no charge, through
|
||||||
|
some standard or customary means of facilitating copying of software. This
|
||||||
|
Corresponding Source shall include the Corresponding Source for any work covered
|
||||||
|
by version 3 of the GNU General Public License that is incorporated pursuant
|
||||||
|
to the following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have permission to
|
||||||
|
link or combine any covered work with a work licensed under version 3 of the
|
||||||
|
GNU General Public License into a single combined work, and to convey the
|
||||||
|
resulting work. The terms of this License will continue to apply to the part
|
||||||
|
which is the covered work, but the work with which it is combined will remain
|
||||||
|
governed by version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of the
|
||||||
|
GNU Affero General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to address
|
||||||
|
new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program specifies
|
||||||
|
that a certain numbered version of the GNU Affero General Public License "or
|
||||||
|
any later version" applies to it, you have the option of following the terms
|
||||||
|
and conditions either of that numbered version or of any later version published
|
||||||
|
by the Free Software Foundation. If the Program does not specify a version
|
||||||
|
number of the GNU Affero General Public License, you may choose any version
|
||||||
|
ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future versions of
|
||||||
|
the GNU Affero General Public License can be used, that proxy's public statement
|
||||||
|
of acceptance of a version permanently authorizes you to choose that version
|
||||||
|
for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different permissions. However,
|
||||||
|
no additional obligations are imposed on any author or copyright holder as
|
||||||
|
a result of your choosing to follow a later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
||||||
|
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
|
||||||
|
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||||
|
CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||||
|
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
|
||||||
|
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
|
||||||
|
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
||||||
|
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||||
|
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided above cannot
|
||||||
|
be given local legal effect according to their terms, reviewing courts shall
|
||||||
|
apply local law that most closely approximates an absolute waiver of all civil
|
||||||
|
liability in connection with the Program, unless a warranty or assumption
|
||||||
|
of liability accompanies a copy of the Program in return for a fee. END OF
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest possible
|
||||||
|
use to the public, the best way to achieve this is to make it free software
|
||||||
|
which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest to attach
|
||||||
|
them to the start of each source file to most effectively state the exclusion
|
||||||
|
of warranty; and each file should have at least the "copyright" line and a
|
||||||
|
pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along
|
||||||
|
with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer network,
|
||||||
|
you should also make sure that it provides a way for users to get its source.
|
||||||
|
For example, if your program is a web application, its interface could display
|
||||||
|
a "Source" link that leads users to an archive of the code. There are many
|
||||||
|
ways you could offer source, and different solutions will be better for different
|
||||||
|
programs; see section 13 for the specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary. For
|
||||||
|
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,274 @@
|
||||||
|
# docker role for Ansible
|
||||||
|
|
||||||
|
Install and configure the [docker](https://www.docker.com/) daemon
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
### Default Variables
|
||||||
|
|
||||||
|
* `docker_check_kernel` - Minimum kernel version allowed on your hosts to run docker
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_check_kernel: '3.10'
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_daemon_config_directory` - Path to docker daemon configuration files
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_daemon_config_directory: '/etc/docker'
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_daemon_config_file` - Docker daemon configuration file
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_daemon_config_file: "{{docker_daemon_config_directory}}/daemon.json"
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_daemon_config_data_root` - Docker daemon data root directory
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_daemon_config_data_root: '/var/lib/docker'
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_daemon_config_storage_driver` - Docker daemon storage driver
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_daemon_config_storage_driver: 'overlay2'
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_daemon_config` - docker daemon yaml config
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_daemon_config: { "storage-driver": "devicemapper" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_distribution` - Docker package distribution
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_distribution: debian
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_distribution_release` - Docker package distribution release
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_distribution_release: bullseye
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_machine` - Docker package architecture
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_machine: amd64
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_myos` - Register myos tags
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_myos: false
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_package` - Name of the docker package
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_package: docker-ce
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_packages` - List of packages to install/remove before installing the docker package
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_packages:
|
||||||
|
- { "name": "docker", "state": "absent" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_init_config_directory` - Location of the configuration file of the docker daemon init script
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_init_config_directory: "/etc/sysconfig"
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_opts` - Name of the environment variable used to pass options to the docker daemon
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_opts: "OPTIONS"
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_services` - List of services to enable/disable on your hosts
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_services:
|
||||||
|
- { "name": "docker", "state": "started", "enabled": "yes" }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deprecated variables
|
||||||
|
|
||||||
|
* `dockers` - List of docker images to build and run on the docker host with the docker-build and docker-run commands
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
dockers: []
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_cluster` - Optional cluster name to pass to the docker-build and docker-run commands
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_cluster: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_start` - Starts the dockers if set to true
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_start: true
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_restart` - Restarts dockers when their image has been updated, removes current running dockers and start new ones
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_restart: true
|
||||||
|
```
|
||||||
|
|
||||||
|
* `docker_force_restart` - Restart dockers, even if image has not been updated, removes current running dockers and start new ones
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_force_restart: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example playbook
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
- hosts: 'docker'
|
||||||
|
roles:
|
||||||
|
- role: 'aynicos.docker'
|
||||||
|
docker_check_kernel: "3.3"
|
||||||
|
docker_package: "docker-ee"
|
||||||
|
docker_registry: "hub.docker.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
To test this role on your `docker` hosts, run the tests/playbook.yml playbook.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ ansible-playbook tests/playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## DEPRECATED
|
||||||
|
|
||||||
|
Following sections remain of a time where docker compose was borning.
|
||||||
|
|
||||||
|
### Helper scripts
|
||||||
|
|
||||||
|
This role comes with a few helper scripts. Here is a short description.
|
||||||
|
|
||||||
|
* `docker-build` - Build a docker image, reading options to pass to the `docker build` command from a Dockeropts file.
|
||||||
|
|
||||||
|
* `docker-cleanup` - Remove unused dockers.
|
||||||
|
|
||||||
|
* `docker-cleanup-images` - Remove unused docker images.
|
||||||
|
|
||||||
|
* `docker-cleanup-volumes` - Remove unused docker volumes.
|
||||||
|
|
||||||
|
* `docker-get-image` - Return sha256 of the image used by the docker.
|
||||||
|
|
||||||
|
* `docker-get-status` - Return the status of the docker.
|
||||||
|
|
||||||
|
* `docker-log-cleanup` - Empty the file logging the docker output on the docker host.
|
||||||
|
|
||||||
|
* `docker-log-truncate` - Truncate the file logging the docker output on the docker host.
|
||||||
|
|
||||||
|
* `docker-run` - Run a docker, reading options to pass to the `docker run` command from a Dockeropts file.
|
||||||
|
|
||||||
|
### Build a docker image
|
||||||
|
|
||||||
|
On the docker hosts, you'll be able to build docker images and run dockers, based on Dockerfile and Dockeropts files located in the /etc/docker subdirectories.
|
||||||
|
|
||||||
|
To create an `nginx` docker image, create a directory /etc/docker/nginx with a Dockerfile and a Dockeropts files into.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# mkdir -p /etc/docker/nginx
|
||||||
|
# cat << EOF > /etc/docker/nginx/Dockerfile
|
||||||
|
FROM nginx:alpine
|
||||||
|
EOF
|
||||||
|
# cat << EOF > /etc/docker/nginx/Dockeropts
|
||||||
|
DOCKER_ULIMIT="nofile=65536"
|
||||||
|
DOCKER_PORT="80:80"
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Build your `nginx` docker image, then run it ! The docker-run command will read the Dockeropts file to add the --ulimit and --port options to the docker run command.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# docker-build nginx && docker-run nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Override your files
|
||||||
|
|
||||||
|
If you want to copy a file in your Dockerfile, say the default nginx.conf, you can use the DOCKER_BUILD_PREFIX and DOCKER_BUILD_SUFFIX variables to get different versions of this file giving some context.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# cat << EOF > /etc/docker/nginx/Dockerfile
|
||||||
|
FROM nginx:alpine
|
||||||
|
ARG DOCKER_BUILD_PREFIX
|
||||||
|
ARG DOCKER_BUILD_SUFFIX
|
||||||
|
COPY ./\${DOCKER_BUILD_PREFIX}nginx.conf\${DOCKER_BUILD_SUFFIX} /etc/nginx/nginx.conf
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now override the nginx configuration file when you build your image.
|
||||||
|
|
||||||
|
* Without option, the docker-build command will search for the file beside your Dockerfile.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# docker-build nginx && docker-run nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
Both DOCKER_BUILD_PREFIX and DOCKER_BUILD_SUFFIX variables are empty, the Dockerfile will search for a `./nginx.conf` file, ie the /etc/docker/nginx/nginx.conf file.
|
||||||
|
|
||||||
|
* With a -c|--cluster option, the docker-build command will search for the file in a subdirectory below your Dockerfile.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# docker-build -c custom nginx && docker-run -c custom nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
The DOCKER_BUILD_PREFIX variable is populated with 'custom/' to force the Dockerfile to search for a `./custom/nginx.conf` file, ie /etc/docker/nginx/custom/nginx.conf file.
|
||||||
|
|
||||||
|
* With an image name suffixed with a dash, the docker-build command will search for a suffixed file as well.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# docker-build -c custom nginx-develop && docker-run -c custom nginx-develop
|
||||||
|
```
|
||||||
|
|
||||||
|
The DOCKER_BUILD_PREFIX variable is populated with 'custom/' and the DOCKER_BUILD_SUFFIX variable is populated with '-develop' to force the Dockerfile to search for a `./custom/nginx.conf-develop` file, ie /etc/docker/nginx/custom/nginx.conf-develop file.
|
||||||
|
|
||||||
|
### Override your options
|
||||||
|
|
||||||
|
The same override principle can be used for the Dockerfile and the Dockeropts file when using the docker-build and docker-run commands.
|
||||||
|
You can create a /etc/docker/nginx/custom/Dockeropts file that would override your default Dockeropt file, and a /etc/docker/nginx/custom/Dockeropts-develop file overriding both other files too.
|
||||||
|
The Dockeropts file accepts the following options.
|
||||||
|
|
||||||
|
* `SYSCTL` - values to set on the docker host via the sysctl command before running the docker
|
||||||
|
* `DOCKER_ARGS` - values to pass to the docker build command with --build-arg options
|
||||||
|
* `DOCKER_ENV` - values to pass to the docker run command with -e options
|
||||||
|
* `DOCKER_LINK` - values to pass to the docker run command with --link options
|
||||||
|
* `DOCKER_OPT` - values to pass to the docker run command with prefixed by --
|
||||||
|
* `DOCKER_PORT` - values to pass to the docker run command with -p options
|
||||||
|
* `DOCKER_ULIMIT` - values to pass to the docker run command with --ulimit options
|
||||||
|
* `DOCKER_VOLUME` - values to pass to the docker run command with -v options
|
||||||
|
* `HOST_VOLUME` - volumes to allow write access to from the docker on selinux enabled host
|
||||||
|
|
||||||
|
Overriding options is done several times, reading options from the more specific to the more generic file. In our example, files are read in this order :
|
||||||
|
/etc/docker/nginx/custom/Dockeropts-develop
|
||||||
|
/etc/docker/nginx/custom/Dockeropts
|
||||||
|
/etc/docker/nginx/Dockeropts
|
||||||
|
|
||||||
|
### Common configuration
|
||||||
|
|
||||||
|
Following configuration builds and runs the docker image 'nginx-develop' for the 'custom' cluster described in our example.
|
||||||
|
The Dockerfile and Dockeropts files needed in the /etc/docker/nginx directory should be present on the docker host, likely synchronised by an other ansible role.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
docker_cluster: "custom"
|
||||||
|
docker:
|
||||||
|
- nginx-develop
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
This role is known to work on Alpine Linux, Armbian, Centos, Debian, Devuan, Fedora, Raspbian, RedHat and Ubuntu.
|
|
@ -0,0 +1,58 @@
|
||||||
|
---
|
||||||
|
# file: defaults/main.yml
|
||||||
|
|
||||||
|
# minimum kernel version
|
||||||
|
docker_check_kernel: '3.10'
|
||||||
|
|
||||||
|
# location of configuration files of docker daemon
|
||||||
|
# docker_daemon_config_directory: "/etc/docker"
|
||||||
|
|
||||||
|
# configuration files of docker daemon
|
||||||
|
# docker_daemon_config_file: "{{docker_daemon_config_directory}}/daemon.json"
|
||||||
|
|
||||||
|
# configure docker daemon data root directory
|
||||||
|
# docker_daemon_config_data_root: "/var/lib/docker"
|
||||||
|
|
||||||
|
# configure docker daemon storage driver
|
||||||
|
# docker_daemon_config_storage: "overlay2"
|
||||||
|
|
||||||
|
# docker daemon configuration
|
||||||
|
# docker_daemon_config: {}
|
||||||
|
|
||||||
|
# docker package distribution
|
||||||
|
docker_distribution: debian
|
||||||
|
|
||||||
|
# docker package distribution release
|
||||||
|
docker_distribution_release: bullseye
|
||||||
|
|
||||||
|
# docker package architecture
|
||||||
|
docker_machine: amd64
|
||||||
|
|
||||||
|
# register myos tags
|
||||||
|
docker_myos: false
|
||||||
|
|
||||||
|
# docker package name
|
||||||
|
docker_package: docker
|
||||||
|
|
||||||
|
# packages to install/remove
|
||||||
|
docker_packages: []
|
||||||
|
|
||||||
|
# location of configuration files loaded by the init script
|
||||||
|
docker_init_config_directory: "/etc/sysconfig"
|
||||||
|
|
||||||
|
# docker daemon options environment variable
|
||||||
|
docker_opts: "OPTIONS"
|
||||||
|
|
||||||
|
# services to enable/disable
|
||||||
|
docker_services:
|
||||||
|
- { "name": "docker", "state": "started", "enabled": "yes" }
|
||||||
|
|
||||||
|
# start docker
|
||||||
|
docker_start: true
|
||||||
|
|
||||||
|
# stop and remove running docker to start a new one when image has been updated
|
||||||
|
docker_restart: true
|
||||||
|
|
||||||
|
# stop and remove running docker to start a new one even if image has not been updated
|
||||||
|
docker_force_restart: false
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
kernel.pax.softmode=1
|
|
@ -0,0 +1,133 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
DOCKER_IMAGE_REPOSITORY="local"
|
||||||
|
DOCKER_BUILD_DIRECTORY="/etc/docker"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo Usage: $0 [-c cluster] [-f] [-q] [-t] image [image [...]]
|
||||||
|
echo -e "Build a docker image in the '${DOCKER_IMAGE_REPOSITORY}' repository."
|
||||||
|
echo
|
||||||
|
echo -e "image\tis a directory with a Dockerfile, default in '${DOCKER_BUILD_DIRECTORY}/image'."
|
||||||
|
echo -e "\t'image' can contains a dash. The suffixed part after the dash is taken into account"
|
||||||
|
echo -e "\tin the image name but not in the name of the directory containing the Dockerfile."
|
||||||
|
echo -e "\tsuffix will be available in your Dockerfile in the DOCKER_BUILD_SUFFIX build-arg."
|
||||||
|
echo
|
||||||
|
echo -e "Options:"
|
||||||
|
echo -e "\t-c 'cluster'\tAllow to override files in 'image' directory with existing files in"
|
||||||
|
echo -e "\t\t\tthe 'image/cluster' directory. 'cluster' will be available in your"
|
||||||
|
echo -e "\t\t\tDockerfile in the DOCKER_BUILD_PREFIX build-arg."
|
||||||
|
echo -e "\t-f\t\tforce build, do not use cache when building image."
|
||||||
|
echo -e "\t-q\t\tquiet mode, minimal output."
|
||||||
|
echo -e "\t-t\t\ttest mode, do nothing but output the command that would haev been launched."
|
||||||
|
echo
|
||||||
|
echo -e "EXAMPLES"
|
||||||
|
echo
|
||||||
|
echo -e "$0 elk"
|
||||||
|
echo -e "Build a docker image named '${DOCKER_IMAGE_REPOSITORY}/elk' with Dockerfile ${DOCKER_BUILD_DIRECTORY}/elk/Dockerfile"
|
||||||
|
echo
|
||||||
|
echo -e "$0 elk-es01"
|
||||||
|
echo -e "Build a docker image named '${DOCKER_IMAGE_REPOSITORY}/elk-es01' with Dockerfile ${DOCKER_BUILD_DIRECTORY}/elk/Dockerfile"
|
||||||
|
echo -e "and build-arg DOCKER_BUILD_SUFFIX=-es01"
|
||||||
|
echo
|
||||||
|
echo -e "$0 -c custom elk-es01"
|
||||||
|
echo -e "Build a docker image named '${DOCKER_IMAGE_REPOSITORY}/elk-es01' with Dockerfile ${DOCKER_BUILD_DIRECTORY}/elk/Dockerfile,"
|
||||||
|
echo -e "build-arg DOCKER_BUILD_PREFIX=custom/ and build-arg DOCKER_BUILD_SUFFIX=-es01"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
-c|--cluster) shift && CLUSTER="$1"
|
||||||
|
;;
|
||||||
|
-f|--force) FORCE=1
|
||||||
|
;;
|
||||||
|
-t|--test) TEST=1
|
||||||
|
;;
|
||||||
|
-q|--quiet) QUIET=1
|
||||||
|
;;
|
||||||
|
-h|--help) usage
|
||||||
|
;;
|
||||||
|
*) args="${args:-} $1"
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
args="${args# }"
|
||||||
|
done
|
||||||
|
|
||||||
|
# check args
|
||||||
|
[ "${args:0:1}" = "-" ] && usage
|
||||||
|
|
||||||
|
# grsec/pax on alpine linux with docker < 1.12
|
||||||
|
[ -f /etc/alpine-release ] && while read major minor patch; do
|
||||||
|
if [ "${major}" -eq 1 ] && [ "${minor:-0}" -lt 12 ]; then
|
||||||
|
[ "$(sysctl -n kernel.grsecurity.chroot_deny_chmod 2>/dev/null)" = 1 ] && sysctl -w kernel.grsecurity.chroot_deny_chmod=0 2>/dev/null && grsec_disabled_chmod=1
|
||||||
|
[ "$(sysctl -n kernel.grsecurity.chroot_deny_mknod 2>/dev/null)" = 1 ] && sysctl -w kernel.grsecurity.chroot_deny_mknod=0 2>/dev/null && grsec_disabled_mknod=1
|
||||||
|
fi
|
||||||
|
done <<< $(apk version docker |awk -F '-' '/^docker/ {print $2}' |sed 's/\./ /g')
|
||||||
|
|
||||||
|
for arg in $args; do
|
||||||
|
# extract docker image name
|
||||||
|
image="$(basename ${arg})"
|
||||||
|
# keep part before the dash as the directory name
|
||||||
|
dir="$(dirname ${arg})/${image%-*}"
|
||||||
|
# keep part after the dash as an image suffix name
|
||||||
|
[ "${image##*-}" != "${image}" ] && suffix="${image##*-}"
|
||||||
|
|
||||||
|
# default to ${DOCKER_BUILD_DIRECTORY}/${dir} if ${dir} does not exists
|
||||||
|
[ ! -d "${dir}" ] && [ -d "${DOCKER_BUILD_DIRECTORY}/${dir}" ] && dir="${DOCKER_BUILD_DIRECTORY}/${dir#./}"
|
||||||
|
|
||||||
|
# directory exists && contains a Dockerfile
|
||||||
|
[ -d ${dir} ] && [ -f "${dir}/Dockerfile" ] || usage
|
||||||
|
# cluster directory exists
|
||||||
|
[ -n "${CLUSTER}" ] && { [ -d ${dir}/${CLUSTER} ] || usage; }
|
||||||
|
|
||||||
|
# search for Dockeropts files
|
||||||
|
files="${dir}/Dockeropts ${dir}/Dockeropts-${suffix}"
|
||||||
|
[ -n "${CLUSTER}" ] && files="${files} ${dir}/${CLUSTER}/Dockeropts ${dir}/${CLUSTER}/Dockeropts-${suffix}"
|
||||||
|
|
||||||
|
# source the Dockeropts files
|
||||||
|
for dockeropts in ${files}; do
|
||||||
|
[ -f "${dockeropts}" ] && . ${dockeropts}
|
||||||
|
done
|
||||||
|
|
||||||
|
# quiet build
|
||||||
|
[ ${QUIET} ] && DOCKER_BUILD_ARGS="--quiet" || DOCKER_BUILD_ARGS=""
|
||||||
|
|
||||||
|
# do not use cache
|
||||||
|
[ ${FORCE} ] && DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --no-cache"
|
||||||
|
|
||||||
|
# extract DOCKER_ARGS
|
||||||
|
[ -n "${DOCKER_ARGS}" ] && for build_arg in ${DOCKER_ARGS}; do
|
||||||
|
DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --build-arg ${build_arg}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# add DOCKER_BUILD_PREFIX and DOCKER_BUILD_SUFFIX
|
||||||
|
[ -n "${CLUSTER}" ] && DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --build-arg DOCKER_BUILD_PREFIX=${CLUSTER}/"
|
||||||
|
[ -n "${suffix}" ] && DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --build-arg DOCKER_BUILD_SUFFIX=-${suffix}"
|
||||||
|
|
||||||
|
# search for Dockerfile
|
||||||
|
[ -n "${CLUSTER}" ] && files="${dir}/${CLUSTER}/Dockerfile-${suffix} ${dir}/${CLUSTER}/Dockerfile" || files=""
|
||||||
|
files="${files} ${dir}/Dockerfile-${suffix} ${dir}/Dockerfile"
|
||||||
|
|
||||||
|
# build docker image with 1st found Dockerfile
|
||||||
|
for dockerfile in ${files}; do
|
||||||
|
[ -f "${dockerfile}" ] || continue
|
||||||
|
[ ${QUIET} ] && [ ! ${TEST} ] && echo -n "${image} "
|
||||||
|
[ ! ${QUIET} ] && echo "Building image ${image}"
|
||||||
|
if [ ${TEST} ]; then
|
||||||
|
echo docker build ${DOCKER_BUILD_ARGS} -t ${DOCKER_IMAGE_REPOSITORY}/${image} -f ${dockerfile} ${dir}
|
||||||
|
else
|
||||||
|
docker build ${DOCKER_BUILD_ARGS} -t ${DOCKER_IMAGE_REPOSITORY}/${image} -f ${dockerfile} ${dir}
|
||||||
|
result=$?
|
||||||
|
fi
|
||||||
|
[ ${result:-0} -ge ${return:-0} ] && return=${result}
|
||||||
|
break
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# grsec/pax
|
||||||
|
[ ${grsec_disabled_chmod} ] && sysctl -w kernel.grsecurity.chroot_deny_chmod=1 2>/dev/null
|
||||||
|
[ ${grsec_disabled_mknod} ] && sysctl -w kernel.grsecurity.chroot_deny_mknod=1 2>/dev/null
|
||||||
|
|
||||||
|
exit ${return:-1}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
docker ps -q --no-trunc --filter status=exited,status=created,status=dead |while read docker; do docker rm ${docker}; done
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
docker images -q --no-trunc --filter dangling=true |while read image; do docker rmi ${image}; done
|
|
@ -0,0 +1,144 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
set -eou pipefail
|
||||||
|
|
||||||
|
#usage: sudo ./docker-cleanup-volumes.sh [--dry-run]
|
||||||
|
|
||||||
|
docker_bin="$(which docker.io 2> /dev/null || which docker 2> /dev/null)"
|
||||||
|
|
||||||
|
# Default dir
|
||||||
|
dockerdir=/var/lib/docker
|
||||||
|
|
||||||
|
# Look for an alternate docker directory with -g/--graph option
|
||||||
|
dockerpid=$(ps ax | grep "$docker_bin" | grep -v grep | awk '{print $1; exit}') || :
|
||||||
|
if [[ -n "$dockerpid" && $dockerpid -gt 0 ]]; then
|
||||||
|
next_arg_is_dockerdir=false
|
||||||
|
while read -d $'\0' arg
|
||||||
|
do
|
||||||
|
if [[ $arg =~ ^--graph=(.+) ]]; then
|
||||||
|
dockerdir=${BASH_REMATCH[1]}
|
||||||
|
break
|
||||||
|
elif [ $arg = '-g' ]; then
|
||||||
|
next_arg_is_dockerdir=true
|
||||||
|
elif [ $next_arg_is_dockerdir = true ]; then
|
||||||
|
dockerdir=$arg
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done < /proc/$dockerpid/cmdline
|
||||||
|
fi
|
||||||
|
|
||||||
|
dockerdir=$(readlink -f "$dockerdir")
|
||||||
|
|
||||||
|
volumesdir=${dockerdir}/volumes
|
||||||
|
vfsdir=${dockerdir}/vfs/dir
|
||||||
|
allvolumes=()
|
||||||
|
dryrun=false
|
||||||
|
verbose=false
|
||||||
|
|
||||||
|
function log_verbose() {
|
||||||
|
if [ "${verbose}" = true ]; then
|
||||||
|
echo "$1"
|
||||||
|
fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_volumes() {
|
||||||
|
local targetdir=$1
|
||||||
|
echo
|
||||||
|
if [[ ! -d "${targetdir}" || ! "$(ls -A "${targetdir}")" ]]; then
|
||||||
|
echo "Directory ${targetdir} does not exist or is empty, skipping."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "Delete unused volume directories from $targetdir"
|
||||||
|
local dir
|
||||||
|
while read -d $'\0' dir
|
||||||
|
do
|
||||||
|
dir=$(basename "$dir")
|
||||||
|
if [[ -d "${targetdir}/${dir}/_data" || "${dir}" =~ [0-9a-f]{64} ]]; then
|
||||||
|
if [ ${#allvolumes[@]} -gt 0 ] && [[ ${allvolumes[@]} =~ "${dir}" ]]; then
|
||||||
|
echo "In use ${dir}"
|
||||||
|
else
|
||||||
|
if [ "${dryrun}" = false ]; then
|
||||||
|
echo "Deleting ${dir}"
|
||||||
|
rm -rf "${targetdir}/${dir}"
|
||||||
|
else
|
||||||
|
echo "Would have deleted ${dir}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Not a volume ${dir}"
|
||||||
|
fi
|
||||||
|
done < <(find "${targetdir}" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $UID != 0 ]; then
|
||||||
|
echo "You need to be root to use this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$docker_bin" ] ; then
|
||||||
|
echo "Please install docker. You can install docker by running \"wget -qO- https://get.docker.io/ | sh\"."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [[ $# > 0 ]]
|
||||||
|
do
|
||||||
|
key="$1"
|
||||||
|
|
||||||
|
case $key in
|
||||||
|
-n|--dry-run)
|
||||||
|
dryrun=true
|
||||||
|
;;
|
||||||
|
-v|--verbose)
|
||||||
|
verbose=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Cleanup docker volumes: remove unused volumes."
|
||||||
|
echo "Usage: ${0##*/} [--dry-run] [--verbose]"
|
||||||
|
echo " -n, --dry-run: dry run: display what would get removed."
|
||||||
|
echo " -v, --verbose: verbose output."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Make sure that we can talk to docker daemon. If we cannot, we fail here.
|
||||||
|
${docker_bin} version >/dev/null
|
||||||
|
|
||||||
|
container_ids=$(${docker_bin} ps -a -q --no-trunc)
|
||||||
|
|
||||||
|
#All volumes from all containers
|
||||||
|
SAVEIFS=$IFS
|
||||||
|
IFS=$(echo -en "\n\b")
|
||||||
|
for container in $container_ids; do
|
||||||
|
#add container id to list of volumes, don't think these
|
||||||
|
#ever exists in the volumesdir but just to be safe
|
||||||
|
allvolumes+=${container}
|
||||||
|
#add all volumes from this container to the list of volumes
|
||||||
|
log_verbose "Inspecting container ${container}"
|
||||||
|
for volpath in $(
|
||||||
|
${docker_bin} inspect --format='{{range $key, $val := .}}{{if eq $key "Volumes"}}{{range $vol, $path := .}}{{$path}}{{"\n"}}{{end}}{{end}}{{if eq $key "Mounts"}}{{range $mount := $val}}{{$mount.Source}}{{"\n"}}{{end}}{{end}}{{end}}' ${container} \
|
||||||
|
); do
|
||||||
|
log_verbose "Processing volumepath ${volpath}"
|
||||||
|
#try to get volume id from the volume path
|
||||||
|
vid=$(echo "${volpath}" | sed 's|.*/\(.*\)/_data$|\1|;s|.*/\([0-9a-f]\{64\}\)$|\1|')
|
||||||
|
# check for either a 64 character vid or then end of a volumepath containing _data:
|
||||||
|
if [[ "${vid}" =~ ^[0-9a-f]{64}$ || (${volpath} =~ .*/_data$ && ! "${vid}" =~ "/") ]]; then
|
||||||
|
log_verbose "Found volume ${vid}"
|
||||||
|
allvolumes+=("${vid}")
|
||||||
|
else
|
||||||
|
#check if it's a bindmount, these have a config.json file in the ${volumesdir} but no files in ${vfsdir} (docker 1.6.2 and below)
|
||||||
|
for bmv in $(find "${volumesdir}" -name config.json -print | xargs grep -l "\"IsBindMount\":true" | xargs grep -l "\"Path\":\"${volpath}\""); do
|
||||||
|
bmv="$(basename "$(dirname "${bmv}")")"
|
||||||
|
log_verbose "Found bindmount ${bmv}"
|
||||||
|
allvolumes+=("${bmv}")
|
||||||
|
#there should be only one config for the bindmount, delete any duplicate for the same bindmount.
|
||||||
|
break
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
IFS=$SAVEIFS
|
||||||
|
|
||||||
|
delete_volumes "${volumesdir}"
|
||||||
|
delete_volumes "${vfsdir}"
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
[ -n "$1" ] || exit
|
||||||
|
|
||||||
|
for docker in $@; do
|
||||||
|
docker inspect "${docker}" 2>/dev/null |awk '$1 == "\"Image\":" && $2 ~ /^\"sha/ {gsub(/(^\"|\",$)/, "", $2); print "'${docker}' "$2}'
|
||||||
|
done
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
[ -n "$1" ] || exit
|
||||||
|
|
||||||
|
for docker in $@; do
|
||||||
|
docker inspect "${docker}" 2>/dev/null |awk '$1 == "\"Status\":" {gsub(/(^\"|\",$)/, "", $2); print "'${docker}' "$2}'
|
||||||
|
done
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
[ -n "$1" ] && :> $(docker inspect $1 | grep '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g')
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
[ -n "$1" ] && \
|
||||||
|
docker_log=$(docker inspect $1 2>/dev/null | grep '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g') && \
|
||||||
|
[ -f "${docker_log}" ] && \
|
||||||
|
tail -n 100 ${docker_log} > ${docker_log}
|
|
@ -0,0 +1,157 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Author: Yann Autissier <yann.autissier@gmail.com>
|
||||||
|
|
||||||
|
DOCKER_IMAGE_REPOSITORY="local"
|
||||||
|
DOCKER_BUILD_DIRECTORY="/etc/docker"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo Usage: $0 [ -c cluster] [ -i image ] [-f] [-q] [-t] name [name [...]]
|
||||||
|
echo -e "Run a docker from an image in the '${DOCKER_IMAGE_REPOSITORY}' repository."
|
||||||
|
echo
|
||||||
|
echo -e "name\t is a directory with a Dockerfile, default in '${DOCKER_BUILD_DIRECTORY}/name'."
|
||||||
|
echo -e "\t'name' can contains a dash. The directory name will be extracted for the first part"
|
||||||
|
echo -e "\tbefore a dash."
|
||||||
|
echo
|
||||||
|
echo -e "Options:"
|
||||||
|
echo -e "\t-c 'cluster'\tAllow to override files in 'image' directory with existing files in"
|
||||||
|
echo -e "\t\t\tthe 'image/cluster' directory."
|
||||||
|
echo -e "\t -i 'image'\tthe docker image to run, default in '${DOCKER_IMAGE_REPOSITORY}' repository."
|
||||||
|
echo -e "\t -f\t\tforce run, stop and remove existing docker before running a new one."
|
||||||
|
echo -e "\t -q\t\tquiet mode, minimal output."
|
||||||
|
echo -e "\t -t\t\ttest mode, do nothing but output the command that would have been launched."
|
||||||
|
echo
|
||||||
|
echo -e "EXAMPLES"
|
||||||
|
echo
|
||||||
|
echo -e "$0 elk"
|
||||||
|
echo -e "Run a docker named 'elk' from the '${DOCKER_IMAGE_REPOSITORY}/elk' image"
|
||||||
|
echo
|
||||||
|
echo -e "$0 elk-es01"
|
||||||
|
echo -e "Run a docker named 'elk-es01' from the '${DOCKER_IMAGE_REPOSITORY}/elk-es01' image"
|
||||||
|
echo
|
||||||
|
echo -e "$0 -i elk elk-es01"
|
||||||
|
echo -e "Run a docker named 'elk-es01' from the '${DOCKER_IMAGE_REPOSITORY}/elk' image"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
-c|--cluster) shift && CLUSTER="$1"
|
||||||
|
;;
|
||||||
|
-i|--image) shift && IMAGE="$1"
|
||||||
|
;;
|
||||||
|
-h|--help) usage
|
||||||
|
;;
|
||||||
|
-f|--force) FORCE=1
|
||||||
|
;;
|
||||||
|
-q|--quiet) QUIET=1
|
||||||
|
;;
|
||||||
|
-t|--test) TEST=1
|
||||||
|
;;
|
||||||
|
*) args="${args:-} $1"
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
args="${args# }"
|
||||||
|
done
|
||||||
|
|
||||||
|
# check args
|
||||||
|
[ "${args:0:1}" = "-" ] && usage
|
||||||
|
|
||||||
|
for arg in ${args}; do
|
||||||
|
# reset vars
|
||||||
|
image=""; DOCKER_OPT=""
|
||||||
|
# extract docker name
|
||||||
|
name="$(basename ${arg})"
|
||||||
|
# keep part before the dash as the directory name
|
||||||
|
dir="$(dirname ${arg})/${name%-*}"
|
||||||
|
# keep part after the dash as an image suffix name
|
||||||
|
[ "${name##*-}" != "${name}" ] && suffix="${name##*-}"
|
||||||
|
# if provided, set docker image from args
|
||||||
|
if [ -n "${IMAGE}" ]; then
|
||||||
|
# if docker image does not contain a /, add our default repository
|
||||||
|
[ "${IMAGE##*/}" != "${IMAGE}" ] && image="${IMAGE}" || image="${DOCKER_IMAGE_REPOSITORY}/${IMAGE}"
|
||||||
|
# else try to find an image from the docker name
|
||||||
|
else
|
||||||
|
# try docker name, docker name without ending numbers, docker name without suffix
|
||||||
|
for image in ${name} ${name%%[0-9]*} ${name%-*}; do
|
||||||
|
# search for image in ${DOCKER_IMAGE_REPOSITORY}
|
||||||
|
[ -n "$(docker images 2>/dev/null |awk '$1 == "'${DOCKER_IMAGE_REPOSITORY}/${image}'" {print $1}')" ] && image="${DOCKER_IMAGE_REPOSITORY}/${image}" && break
|
||||||
|
image="${name}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
tag="$(docker images |awk '$1 == "'${image}'" {print $2}')"
|
||||||
|
[ -z "${tag}" ] && echo "ERROR: Cannot find image '${image}'" >2 && exit 2
|
||||||
|
|
||||||
|
# default to ${DOCKER_BUILD_DIRECTORY}/${dir} if ${dir} does not exists
|
||||||
|
[ ! -d "${dir}" ] && [ -d "${DOCKER_BUILD_DIRECTORY}/${dir}" ] && dir="${DOCKER_BUILD_DIRECTORY}/${dir#./}"
|
||||||
|
|
||||||
|
# directory exists && contains a Dockerfile
|
||||||
|
[ -d ${dir} ] && [ -f "${dir}/Dockerfile" ] || usage
|
||||||
|
# cluster directory exists
|
||||||
|
[ -n "${CLUSTER}" ] && { [ -d ${dir}/${CLUSTER} ] || usage; }
|
||||||
|
|
||||||
|
# search for Dockeropts files
|
||||||
|
files="${dir}/Dockeropts ${dir}/Dockeropts-${suffix}"
|
||||||
|
[ -n "${CLUSTER}" ] && files="${files} ${dir}/${CLUSTER}/Dockeropts ${dir}/${CLUSTER}/Dockeropts-${suffix}"
|
||||||
|
|
||||||
|
# source the Dockeropts files
|
||||||
|
for dockeropts in ${files}; do
|
||||||
|
[ -f "${dockeropts}" ] && . ${dockeropts}
|
||||||
|
done
|
||||||
|
|
||||||
|
# extract SYSCTL
|
||||||
|
[ -n "${SYSCTL}" ] && for sysctl in ${SYSCTL}; do
|
||||||
|
sysctl -w ${sysctl} 2>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# extract DOCKER_OPT
|
||||||
|
[ -n "${DOCKER_OPT}" ] && DOCKER_OPTS="--${DOCKER_OPT/ / --}" || DOCKER_OPTS=""
|
||||||
|
|
||||||
|
# extract DOCKER_ENV
|
||||||
|
[ -n "${DOCKER_ENV}" ] && DOCKER_OPTS="${DOCKER_OPTS} -e ${DOCKER_ENV//\" /\" -e }"
|
||||||
|
|
||||||
|
# extract DOCKER_LINK
|
||||||
|
[ -n "${DOCKER_LINK}" ] && DOCKER_OPTS="--link ${DOCKER_LINK/ / --link }"
|
||||||
|
|
||||||
|
# extract DOCKER_PORT
|
||||||
|
[ -n "${DOCKER_PORT}" ] && DOCKER_OPTS="${DOCKER_OPTS} -p ${DOCKER_PORT// / -p }"
|
||||||
|
|
||||||
|
# extract DOCKER_ULIMIT
|
||||||
|
[ -n "${DOCKER_ULIMIT}" ] && DOCKER_OPTS="${DOCKER_OPTS} --ulimit ${DOCKER_ULIMIT// / --ulimit }"
|
||||||
|
|
||||||
|
# extract DOCKER_VOLUME
|
||||||
|
[ -n "${DOCKER_VOLUME}" ] && DOCKER_OPTS="${DOCKER_OPTS} -v ${DOCKER_VOLUME// / -v }"
|
||||||
|
|
||||||
|
# enable access to host volumes on selinux
|
||||||
|
for volume in ${HOST_VOLUME}; do
|
||||||
|
chcon -Rt svirt_sandbox_file_t ${volume} 2>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove current docker
|
||||||
|
if [ ${FORCE} ]; then
|
||||||
|
if [ -n "$(docker ps -q --filter status=created,status=restarting,status=running,status=paused,status=exited,status=dead,name=${name})" ]; then
|
||||||
|
[ ! ${QUIET} ] && echo -n "Removing docker ${name}... "
|
||||||
|
if [ ${TEST} ]; then
|
||||||
|
echo docker rm -f ${name}
|
||||||
|
else
|
||||||
|
eval docker rm -f ${name} >/dev/null 2>&1
|
||||||
|
result=$? && [ ${result} -ne 0 ] && echo "ERROR" && { [ ${result:-0} -ge ${return:-0} ] && return=${result}; } && break
|
||||||
|
[ ! ${QUIET} ] && echo "OK"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# launch docker
|
||||||
|
[ ${QUIET} ] && [ ! ${TEST} ] && echo -n "${name} "
|
||||||
|
[ ! ${QUIET} ] && echo -n "Running docker ${name}... "
|
||||||
|
if [ ${TEST} ]; then
|
||||||
|
echo docker run --restart=always ${DOCKER_OPTS} -d --name ${name} ${image} ${DOCKER_RUN:-}
|
||||||
|
else
|
||||||
|
eval docker run --restart=always ${DOCKER_OPTS} -d --name ${name} ${image} ${DOCKER_RUN:-} 2>/dev/null
|
||||||
|
result=$? && [ ${result} -ne 0 ] && echo "ERROR"
|
||||||
|
fi
|
||||||
|
[ ${result:-0} -ge ${return:-0} ] && return=${result}
|
||||||
|
done
|
||||||
|
|
||||||
|
exit ${return:-1}
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
# file: handlers/main.yml
|
||||||
|
|
||||||
|
- name: restart docker
|
||||||
|
with_items: "{{docker_services|default([])}}"
|
||||||
|
service:
|
||||||
|
name: "{{item}}"
|
||||||
|
state: restarted
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
# file: meta/main.yml
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
|
galaxy_info:
|
||||||
|
author: Yann Autissier
|
||||||
|
categories:
|
||||||
|
- system
|
||||||
|
description: Install and configure the docker daemon
|
||||||
|
license: GPL
|
||||||
|
platforms:
|
||||||
|
- name: Alpine
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Centos
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Debian
|
||||||
|
versions:
|
||||||
|
- bookworm
|
||||||
|
- bullseye
|
||||||
|
- buster
|
||||||
|
- stretch
|
||||||
|
- jessie
|
||||||
|
- wheezy
|
||||||
|
- name: Devuan
|
||||||
|
versions:
|
||||||
|
- daedalus
|
||||||
|
- chimaera
|
||||||
|
- beowulf
|
||||||
|
- ascii
|
||||||
|
- jessie
|
||||||
|
- name: EL
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Fedora
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Raspbian
|
||||||
|
versions:
|
||||||
|
- bookworm
|
||||||
|
- bullseye
|
||||||
|
- buster
|
||||||
|
- stretch
|
||||||
|
- jessie
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- impish
|
||||||
|
- hirsute
|
||||||
|
- groovy
|
||||||
|
- focal
|
||||||
|
- eoan
|
||||||
|
- disco
|
||||||
|
- cosmic
|
||||||
|
- bionic
|
||||||
|
- artful
|
||||||
|
- zesty
|
||||||
|
- yakkety
|
||||||
|
- xenial
|
||||||
|
- trusty
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
# file: tasks/build.yml
|
||||||
|
|
||||||
|
- name: build - Build docker image
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "/usr/local/bin/docker-build -q -c {{docker_cluster|default('\"\"')}} {{item}}"
|
||||||
|
register: docker_build_image_command
|
||||||
|
|
||||||
|
- name: build - Register docker_build_image
|
||||||
|
with_items: "{{docker_build_image_command.results}}"
|
||||||
|
set_fact:
|
||||||
|
docker_build_image: "{{docker_build_image |default({}) |combine( {item.item: item.stdout} ) }}"
|
||||||
|
|
||||||
|
- name: build - Debug docker_elk_build_image
|
||||||
|
when: docker_debug|default(false)
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
debug: msg="{{docker_build_image[item]}}"
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
# file: tasks/check.yml
|
||||||
|
|
||||||
|
- name: check - kernel version
|
||||||
|
when: ansible_kernel is version(docker_check_kernel, "<")
|
||||||
|
fail:
|
||||||
|
msg: >
|
||||||
|
docker requires a minimum kernel version of {{docker_check_kernel}}
|
||||||
|
on {{ansible_distribution}} {{ansible_distribution_version}}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
# file: tasks/config.yml
|
||||||
|
|
||||||
|
# - name: config - add docker storage setup
|
||||||
|
# when: docker_package|length > 0 and ansible_service_mgr == "systemd" and ansible_os_family|lower == "redhat"
|
||||||
|
# lineinfile: dest="{{docker_init_config_directory}}/{{docker_package}}-storage-setup" state="present" line="STORAGE_DRIVER=\"\""
|
||||||
|
# become: yes
|
||||||
|
# notify: restart docker
|
||||||
|
|
||||||
|
# - name: config - register docker_daemon_config
|
||||||
|
# set_fact:
|
||||||
|
# docker_daemon_config: "{{ lookup('file',docker_daemon_config_file)|default('{}')|from_json}}"
|
||||||
|
# ignore_errors: true
|
||||||
|
|
||||||
|
# - name: config - add docker daemon storage configuration
|
||||||
|
# when: docker_package|length > 0
|
||||||
|
# template:
|
||||||
|
# src: daemon.json.j2
|
||||||
|
# dest: "{{docker_daemon_config_file}}"
|
||||||
|
# owner: root
|
||||||
|
# group: docker
|
||||||
|
# mode: "0640"
|
||||||
|
# become: yes
|
||||||
|
# notify: restart docker
|
||||||
|
|
||||||
|
# - name: config - disable docker iptables setup
|
||||||
|
# when: docker_package|length > 0 and ansible_service_mgr == "systemd"
|
||||||
|
# lineinfile: dest="/lib/systemd/system/docker.service" state="present" regex="^ExecStart=" line="ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false"
|
||||||
|
# become: yes
|
||||||
|
# notify: restart docker
|
||||||
|
|
||||||
|
- name: config - setup docker mtu on Openstack VMs
|
||||||
|
when: docker_package|length > 0 and ansible_product_name == "OpenStack Nova"
|
||||||
|
lineinfile: dest="{{docker_init_config_directory}}/{{docker_package}}" state="present" backrefs=true regexp='^{{docker_opts}}=(?:\'|\")?((?:\s*[\w=\/\-\.](?<!--mtu=1450)\s*)*)(?:\'|\")?$' line='{{docker_opts}}="\1 --mtu=1450"'
|
||||||
|
become: yes
|
||||||
|
notify: restart docker
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
# file: tasks/files.yml
|
||||||
|
|
||||||
|
- name: files - copy sysctl configuration files
|
||||||
|
with_items:
|
||||||
|
- /etc/sysctl.d/docker.conf
|
||||||
|
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
# file: tasks/groups.yml
|
||||||
|
|
||||||
|
- name: groups - create docker group
|
||||||
|
when: ansible_os_family|lower != "alpine"
|
||||||
|
group: name="docker" state="present" system="yes"
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: groups - add me to the docker group
|
||||||
|
when: ansible_os_family|lower != "alpine" and ansible_user_uid != "0"
|
||||||
|
user: name="{{ansible_user_id}}" groups=docker append=yes
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# file: tasks/main.yml
|
||||||
|
|
||||||
|
- import_tasks: vars.yml
|
||||||
|
tags:
|
||||||
|
- vars
|
||||||
|
- import_tasks: check.yml
|
||||||
|
tags:
|
||||||
|
- check
|
||||||
|
- import_tasks: config.yml
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
- import_tasks: files.yml
|
||||||
|
tags:
|
||||||
|
- files
|
||||||
|
- import_tasks: packages.yml
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- import_tasks: services.yml
|
||||||
|
tags:
|
||||||
|
- services
|
||||||
|
- import_tasks: groups.yml
|
||||||
|
tags:
|
||||||
|
- groups
|
||||||
|
- import_tasks: build.yml
|
||||||
|
tags:
|
||||||
|
- build
|
||||||
|
- import_tasks: run.yml
|
||||||
|
tags:
|
||||||
|
- run
|
||||||
|
- import_tasks: myos.yml
|
||||||
|
when: docker_myos|default(false)
|
||||||
|
tags:
|
||||||
|
- myos
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
# file: tasks/myos.yml
|
||||||
|
|
||||||
|
- name: myos - register myos.tags
|
||||||
|
set_fact:
|
||||||
|
myos_tags: "{{ lookup('env', 'MYOS_TAGS_JSON')|from_json }}"
|
||||||
|
tags: debug
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "{{myos_tags|to_nice_json}}"
|
||||||
|
tags: debug
|
||||||
|
|
||||||
|
- name: myos - check AWS meta-data URI
|
||||||
|
uri:
|
||||||
|
url: http://169.254.169.254/latest/meta-data
|
||||||
|
timeout: 1
|
||||||
|
failed_when: False
|
||||||
|
register: aws_uri_check
|
||||||
|
|
||||||
|
- import_tasks: myos_ec2.yml
|
||||||
|
when: aws_uri_check.status == 200
|
||||||
|
tags:
|
||||||
|
- aws
|
||||||
|
- ec2
|
||||||
|
|
||||||
|
# ansible v2.8
|
||||||
|
# - name: myos - prune docker objects
|
||||||
|
# docker_prune:
|
||||||
|
# containers: yes
|
||||||
|
# images: yes
|
||||||
|
# images_filters:
|
||||||
|
# dangling: false
|
||||||
|
# networks: yes
|
||||||
|
# volumes: yes
|
||||||
|
# builder_cache: yes
|
||||||
|
|
||||||
|
- name: myos - launch docker containers
|
||||||
|
when: myos.tags is defined and myos.tags.env is defined and myos.tags.services is defined and myos.tags.user is defined
|
||||||
|
with_items: '{{myos.tags.services.split(" ")}}'
|
||||||
|
docker_container:
|
||||||
|
image: "{{docker_registry|default(myos.tags.user)}}/{{myos.tags.user}}/{{myos.tags.env}}/{% if ':' in item %}{{item}}{% else %}{{item}}:{{docker_image_tag|default('latest')}}{% endif %}"
|
||||||
|
name: "{{myos.tags.user}}_{{myos.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}}"
|
||||||
|
network_mode: host
|
||||||
|
pull: yes
|
||||||
|
restart_policy: always
|
||||||
|
volumes:
|
||||||
|
- "{{ lookup('env','ANSIBLE_DISKS_NFS_PATH') }}:/shared"
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
|
||||||
|
- name: myos - add docker containers to inventory
|
||||||
|
when: myos.tags is defined and myos.tags.env is defined and myos.tags.services is defined and myos.tags.user is defined
|
||||||
|
with_items: '{{myos.tags.services.split(" ")}}'
|
||||||
|
add_host:
|
||||||
|
name: "{{myos.tags.user}}_{{myos.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}}"
|
||||||
|
ansible_connection: docker
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: myos - run make deploy-hook in docker containers
|
||||||
|
when: myos.tags is defined and myos.tags.env is defined and myos.tags.services is defined and myos.tags.user is defined
|
||||||
|
with_items: '{{myos.tags.services.split(" ")}}'
|
||||||
|
delegate_to: "{{myos.tags.user}}_{{myos.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}}"
|
||||||
|
raw: "command -v make || exit 0 && make deploy-hook CONTAINER={{myos.tags.user}}_{{myos.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}} HOST={{ansible_ec2_local_ipv4}}"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
# file: tasks/myos_ec2.yml
|
||||||
|
|
||||||
|
- name: myos_ec2 - get instance metadata
|
||||||
|
ec2_metadata_facts:
|
||||||
|
|
||||||
|
- name: myos_ec2 - get instance tags
|
||||||
|
when: ansible_ec2_instance_id is defined
|
||||||
|
ec2_tag:
|
||||||
|
aws_access_key: "{{ aws_access_key_id }}"
|
||||||
|
aws_secret_key: "{{ aws_secret_access_key }}"
|
||||||
|
region: "{{ ansible_ec2_placement_region }}"
|
||||||
|
resource: "{{ ansible_ec2_instance_id }}"
|
||||||
|
state: list
|
||||||
|
register: myos
|
||||||
|
|
||||||
|
- name: myos_ec2 - ecr login
|
||||||
|
when: myos.tags is defined
|
||||||
|
shell: "$(aws ecr get-login --no-include-email --region {{ aws_region }})"
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
# file: tasks/packages.yml
|
||||||
|
|
||||||
|
- import_tasks: packages_debian.yml
|
||||||
|
when: ansible_os_family|lower == "debian"
|
||||||
|
tags:
|
||||||
|
- debian
|
||||||
|
|
||||||
|
- name: packages - install/remove docker packages
|
||||||
|
when: docker_packages is defined
|
||||||
|
with_items: "{{ docker_packages|default([]) }}"
|
||||||
|
package: name="{{item.name}}" state="{{item.state}}"
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: packages - add docker package
|
||||||
|
when: docker_package|length > 0
|
||||||
|
package: name="{{docker_package}}" state=present
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
# file: tasks/packages_debian.yml
|
||||||
|
|
||||||
|
- name: packages - add docker GPG key
|
||||||
|
apt_key: url=https://download.docker.com/linux/debian/gpg
|
||||||
|
ignore_errors: true
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: packages - define docker_machine
|
||||||
|
set_fact:
|
||||||
|
docker_machine: "{% if ansible_machine == 'aarch64' %}arm64{% endif %}{% if ansible_machine == 'x86_64' %}amd64{% endif %}"
|
||||||
|
when: docker_machine is undefined
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution
|
||||||
|
set_fact:
|
||||||
|
docker_distribution: "{% if ansible_distribution|lower == 'devuan' %}debian{% else %}{{ansible_distribution|lower}}{% endif %}"
|
||||||
|
when: docker_distribution is undefined
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release - debian bookworm (not yet available)
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "bullseye"
|
||||||
|
when: docker_distribution_release is undefined and ansible_distribution_release|lower == 'bookworm'
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release - devuan daealus
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "bullseye"
|
||||||
|
when: docker_distribution_release is undefined and ansible_distribution_release|lower == 'daedalus/ceres'
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release - devuan chimaera
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "bullseye"
|
||||||
|
when: docker_distribution_release is undefined and ansible_distribution_release|lower == 'chimaera'
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release - devuan beowulf
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "buster"
|
||||||
|
when: docker_distribution_release is undefined and ansible_distribution_release|lower == 'beowulf'
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release - devuan ascii
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "stretch"
|
||||||
|
when: docker_distribution_release is undefined and ansible_distribution_release|lower == 'ascii'
|
||||||
|
|
||||||
|
- name: packages - define docker_distribution_release
|
||||||
|
set_fact:
|
||||||
|
docker_distribution_release: "{{ansible_distribution_release|lower}}"
|
||||||
|
when: docker_distribution_release is undefined
|
||||||
|
|
||||||
|
- name: packages - add docker APT repository
|
||||||
|
apt_repository:
|
||||||
|
repo: deb [arch={{docker_machine}}] https://download.docker.com/linux/{{docker_distribution}} {{docker_distribution_release}} stable
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
# file: tasks/run.yml
|
||||||
|
|
||||||
|
- name: run - Get current docker status
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "/usr/local/bin/docker-get-status {{item}}"
|
||||||
|
register: docker_current_status_command
|
||||||
|
|
||||||
|
- name: run - Register docker_current_status
|
||||||
|
with_items: "{{docker_current_status_command.results}}"
|
||||||
|
set_fact:
|
||||||
|
docker_current_status: "{{docker_current_status |default({}) |combine( {item.item: item.stdout} ) }}"
|
||||||
|
|
||||||
|
- name: run - Debug docker_current_status
|
||||||
|
when: docker_debug|default(false)
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
debug: msg="{{docker_current_status[item]}}"
|
||||||
|
|
||||||
|
- name: run - Get current docker image
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "/usr/local/bin/docker-get-image {{item}}"
|
||||||
|
register: docker_current_image_command
|
||||||
|
|
||||||
|
- name: run - Register docker_current_image
|
||||||
|
with_items: "{{docker_current_image_command.results}}"
|
||||||
|
set_fact:
|
||||||
|
docker_current_image: "{{docker_current_image |default({}) |combine( {item.item: item.stdout} ) }}"
|
||||||
|
|
||||||
|
- name: run - Debug docker_current_image
|
||||||
|
when: docker_debug|default(false)
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
debug: msg="{{docker_current_image[item]}}"
|
||||||
|
|
||||||
|
- name: run - Stop current docker
|
||||||
|
when: ( docker_restart|default(false) and "{{docker_current_image[item]}}" != "{{docker_build_image[item]}}" or docker_force_restart|default(false) ) and "{{docker_current_status[item]}}" == "{{item}} running"
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "docker stop {{item}}"
|
||||||
|
|
||||||
|
- name: run - Remove current docker
|
||||||
|
when: ( docker_restart|default(false) and "{{docker_current_image[item]}}" != "{{docker_build_image[item]}}" or docker_force_restart|default(false) ) and "{{docker_current_status[item]}}" != ""
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "docker rm {{item}}"
|
||||||
|
|
||||||
|
- name: run - Run docker image
|
||||||
|
when: docker_start|default(true) and "{{docker_current_image[item]}}" != "{{docker_build_image[item]}}" or docker_force_restart|default(false)
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "/usr/local/bin/docker-run -q -c {{docker_cluster|default('\"\"')}} {{item}}"
|
||||||
|
|
||||||
|
- name: run - Start docker
|
||||||
|
when: docker_start|default(true) and "{{docker_current_image[item]}}" == "{{docker_build_image[item]}}" and "{{docker_current_status[item]}}" != "{{item}} running"
|
||||||
|
with_items: "{{dockers|default([])}}"
|
||||||
|
command: "docker start {{item}}"
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
# file: tasks/services.yml
|
||||||
|
|
||||||
|
- name: services - enable/disable docker services
|
||||||
|
when: docker_services is defined and ansible_service_mgr|lower != "openrc" and ansible_service_mgr|lower != "runit"
|
||||||
|
with_items: "{{ docker_services|default([]) }}"
|
||||||
|
service:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - force service status - openrc
|
||||||
|
when: docker_services is defined and ansible_service_mgr|lower == "openrc"
|
||||||
|
shell: "kill -0 $(cat /run/{{item.name}}.pid) && [ ! -h /run/openrc/started/{{item.name}} ] && ln -s /etc/init.d/{{item.name}} /run/openrc/started/{{item.name}} && service {{item.name}} restart ||:"
|
||||||
|
with_items: "{{ docker_services|default([]) }}"
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - enable/disable docker services - openrc
|
||||||
|
when: docker_services is defined and ansible_service_mgr|lower == "openrc"
|
||||||
|
with_items: "{{ docker_services|default([]) }}"
|
||||||
|
service:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
runlevel: boot
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - enable/disable docker services - runit
|
||||||
|
when: docker_services is defined and ansible_service_mgr|lower == "runit"
|
||||||
|
with_items: "{{ docker_services|default([]) }}"
|
||||||
|
sysvinit:
|
||||||
|
name: "{{item.name}}"
|
||||||
|
state: "{{item.state}}"
|
||||||
|
enabled: "{{item.enabled}}"
|
||||||
|
runlevels:
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: services - force service restart - openrc
|
||||||
|
when: ansible_service_mgr|lower == "openrc"
|
||||||
|
shell: "[ ! -d /var/lib/docker/tmp ] && service docker restart ||:"
|
||||||
|
become: yes
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# file: tasks/vars.yml
|
||||||
|
|
||||||
|
- name: vars - load per operating system variables
|
||||||
|
include_vars: "{{item}}"
|
||||||
|
with_first_found:
|
||||||
|
- paths:
|
||||||
|
- "vars/"
|
||||||
|
- files:
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_version|lower}}-{{ansible_machine}}.yml" # centos-6.4-i386.yml ubuntu-16.04-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_version|lower}}.yml" # centos-6.4.yml ubuntu-16.04.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_major_version|lower}}-{{ansible_machine}}.yml" # centos-6-i386.yml ubuntu-16-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_distribution_major_version|lower}}.yml" # centos-6.yml ubuntu-16.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_version|lower}}-{{ansible_machine}}.yml" # redhat-6.4-i386.yml debian-8.5-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_version|lower}}.yml" # redhat-6.4.yml debian-8.5.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_major_version|lower}}-{{ansible_machine}}.yml" # redhat-6-i386.yml debian-8-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_distribution_major_version|lower}}.yml" # redhat-6.yml debian-8.yml
|
||||||
|
- "{{ansible_distribution|lower}}-{{ansible_machine}}.yml" # centos-i386.yml ubuntu-x86_64.yml
|
||||||
|
- "{{ansible_distribution|lower}}.yml" # centos.yml ubuntu.yml
|
||||||
|
- "{{ansible_os_family|lower}}-{{ansible_machine}}.yml" # redhat-i386.yml debian-x86_64.yml
|
||||||
|
- "{{ansible_os_family|lower}}.yml" # redhat.yml debian.yml
|
||||||
|
- "{{ansible_system|lower}}-{{ansible_machine}}.yml" # linux-i386.yml linux-x86_64.yml
|
||||||
|
- "{{ansible_system|lower}}.yml" # linux.yml
|
||||||
|
- "default.yml" # default.yml
|
||||||
|
skip: true
|
||||||
|
|
||||||
|
- name: vars - override with local variables
|
||||||
|
include_vars: "{{item}}"
|
||||||
|
with_first_found:
|
||||||
|
- paths:
|
||||||
|
- "vars/"
|
||||||
|
- files:
|
||||||
|
- "local.yml"
|
||||||
|
skip: true
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{{ docker_daemon_config|combine([{ "storage-driver": docker_daemon_config_storage }])|to_nice_json }}
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
# file: tests/goss.yml
|
||||||
|
|
||||||
|
- name: tests - create temporary directory
|
||||||
|
command: mktemp -d
|
||||||
|
register: tests_mktemp
|
||||||
|
|
||||||
|
- name: tests - register goss installation
|
||||||
|
environment:
|
||||||
|
PATH: "/usr/local/bin:{{ansible_env.PATH}}"
|
||||||
|
command: which goss
|
||||||
|
register: tests_goss_installed
|
||||||
|
|
||||||
|
- name: tests - register specific OS goss files
|
||||||
|
set_fact:
|
||||||
|
goss_file:
|
||||||
|
- "goss/main_{{ansible_distribution|lower}}-{{ansible_distribution_major_version|lower}}.yml" # main_centos-6.yml main_centos-7.yml
|
||||||
|
- "goss/main_{{ansible_distribution|lower}}.yml" # main_centos.yml main_ubuntu.yml
|
||||||
|
- "goss/main_{{ansible_os_family|lower}}.yml" # main_redhat.yml main_debian.yml
|
||||||
|
- "goss/main_{{ansible_system|lower}}.yml" # main_linux.yml
|
||||||
|
- "goss/main.yml" # main.yml
|
||||||
|
|
||||||
|
- name: tests - register goss file
|
||||||
|
set_fact:
|
||||||
|
tests_goss_file: "{{lookup('first_found', goss_file)}}"
|
||||||
|
|
||||||
|
- name: tests - copy test files
|
||||||
|
copy: src=goss/ dest="{{tests_mktemp.stdout}}"
|
||||||
|
|
||||||
|
- name: tests - launch tests
|
||||||
|
environment:
|
||||||
|
PATH: "/usr/local/bin:{{ansible_env.PATH}}"
|
||||||
|
goss: path="{{tests_mktemp.stdout}}/{{tests_goss_file|basename}}" format=rspecish
|
||||||
|
register: tests_goss_results
|
||||||
|
ignore_errors: true
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: tests - remove temporary directory
|
||||||
|
file: path="{{tests_mktemp.stdout}}" state=absent
|
||||||
|
|
||||||
|
- name: tests - failure message
|
||||||
|
fail: msg="{{tests_goss_results.msg}}"
|
||||||
|
when: tests_goss_results|failed
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
group:
|
||||||
|
docker:
|
||||||
|
exists: true
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
gossfile:
|
||||||
|
package.yml: {}
|
||||||
|
service.yml: {}
|
||||||
|
group.yml: {}
|
|
@ -0,0 +1,4 @@
|
||||||
|
gossfile:
|
||||||
|
package_centos-6.yml: {}
|
||||||
|
service.yml: {}
|
||||||
|
group.yml: {}
|
|
@ -0,0 +1,4 @@
|
||||||
|
gossfile:
|
||||||
|
package_centos-7.yml: {}
|
||||||
|
service.yml: {}
|
||||||
|
group.yml: {}
|
|
@ -0,0 +1,4 @@
|
||||||
|
gossfile:
|
||||||
|
package_debian.yml: {}
|
||||||
|
service.yml: {}
|
||||||
|
group.yml: {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package:
|
||||||
|
docker:
|
||||||
|
installed: true
|
|
@ -0,0 +1,3 @@
|
||||||
|
package:
|
||||||
|
docker-io:
|
||||||
|
installed: true
|
|
@ -0,0 +1,3 @@
|
||||||
|
package:
|
||||||
|
docker-latest:
|
||||||
|
installed: true
|
|
@ -0,0 +1,3 @@
|
||||||
|
package:
|
||||||
|
docker-engine:
|
||||||
|
installed: true
|
|
@ -0,0 +1,5 @@
|
||||||
|
service:
|
||||||
|
docker:
|
||||||
|
enabled: true
|
||||||
|
running: true
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
from ansible.module_utils.basic import *
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
---
|
||||||
|
module: goss
|
||||||
|
author: Mathieu Corbin
|
||||||
|
short_description: Launch goss (https://github.com/aelsabbahy/goss) test
|
||||||
|
description:
|
||||||
|
- Launch goss test. Always changed = False if success.
|
||||||
|
options:
|
||||||
|
path:
|
||||||
|
required: true
|
||||||
|
description:
|
||||||
|
- Test file to validate. Must be on the remote machine.
|
||||||
|
format:
|
||||||
|
required: false
|
||||||
|
description:
|
||||||
|
- change the output goss format.
|
||||||
|
- Goss format list : goss v --format => [documentation json junit nagios rspecish tap].
|
||||||
|
- Default: rspecish
|
||||||
|
output_file:
|
||||||
|
required: false
|
||||||
|
description:
|
||||||
|
- save the result of the goss command in a file whose path is output_file
|
||||||
|
examples:
|
||||||
|
- name: test goss file
|
||||||
|
goss:
|
||||||
|
path: "/path/to/file.yml"
|
||||||
|
|
||||||
|
- name: test goss files
|
||||||
|
goss:
|
||||||
|
path: "{{ item }}"
|
||||||
|
format: json
|
||||||
|
output_file : /my/output/file-{{ item }}
|
||||||
|
with_items: "{{ goss_files }}"
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
# launch goss validate command on the file
|
||||||
|
def check(module, test_file_path, output_format):
|
||||||
|
cmd = ""
|
||||||
|
if output_format is not None:
|
||||||
|
cmd = "goss -g {0} v --format {1}".format(test_file_path, output_format)
|
||||||
|
else:
|
||||||
|
cmd = "goss -g {0} v".format(test_file_path)
|
||||||
|
return module.run_command(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
# write goss result to output_file_path
|
||||||
|
def output_file(output_file_path, out):
|
||||||
|
if output_file_path is not None:
|
||||||
|
with open(output_file_path, 'w') as output_file:
|
||||||
|
output_file.write(out)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
path=dict(required=True, type='str'),
|
||||||
|
format=dict(required=False, type='str'),
|
||||||
|
output_file=dict(required=False, type='str'),
|
||||||
|
),
|
||||||
|
supports_check_mode=False
|
||||||
|
)
|
||||||
|
|
||||||
|
test_file_path = module.params['path'] # test file path
|
||||||
|
output_format = module.params['format'] # goss output format
|
||||||
|
output_file_path = module.params['output_file']
|
||||||
|
|
||||||
|
if test_file_path is None:
|
||||||
|
module.fail_json(msg="test file path is null")
|
||||||
|
|
||||||
|
test_file_path = os.path.expanduser(test_file_path)
|
||||||
|
|
||||||
|
# test if access to test file is ok
|
||||||
|
|
||||||
|
if not os.access(test_file_path, os.R_OK):
|
||||||
|
module.fail_json(msg="Test file %s not readable" % (test_file_path))
|
||||||
|
|
||||||
|
# test if test file is not a dir
|
||||||
|
if os.path.isdir(test_file_path):
|
||||||
|
module.fail_json(msg="Test file must be a file ! : %s" % (test_file_path))
|
||||||
|
|
||||||
|
(rc, out, err) = check(module, test_file_path, output_format)
|
||||||
|
|
||||||
|
if output_file_path is not None:
|
||||||
|
output_file_path = os.path.expanduser(output_file_path)
|
||||||
|
# check if output_file is a file
|
||||||
|
if output_file_path.endswith(os.sep):
|
||||||
|
module.fail_json(msg="output_file must be a file. Actually : %s "
|
||||||
|
% (output_file_path))
|
||||||
|
|
||||||
|
output_dirname = os.path.dirname(output_file_path)
|
||||||
|
|
||||||
|
# check if output directory exists
|
||||||
|
if not os.path.exists(output_dirname):
|
||||||
|
module.fail_json(msg="directory %s does not exists" % (output_dirname))
|
||||||
|
|
||||||
|
# check if writable
|
||||||
|
if not os.access(os.path.dirname(output_file_path), os.W_OK):
|
||||||
|
module.fail_json(msg="Destination %s not writable" % (os.path.dirname(output_file_path)))
|
||||||
|
# write goss result on the output file
|
||||||
|
output_file(output_file_path, out)
|
||||||
|
|
||||||
|
if rc is not None and rc != 0:
|
||||||
|
error_msg = "err : {0} ; out : {1}".format(err, out)
|
||||||
|
module.fail_json(msg=error_msg)
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result['stdout'] = out
|
||||||
|
result['changed'] = False
|
||||||
|
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
# file: tests/main.yml
|
||||||
|
|
||||||
|
- include: goss.yml
|
||||||
|
tags:
|
||||||
|
- tests
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
# file: tests/playbook.yml
|
||||||
|
|
||||||
|
- hosts: '{{ target | default("all") }}'
|
||||||
|
tasks:
|
||||||
|
- import_tasks: main.yml
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
# file: vars/centos-6.yml
|
||||||
|
|
||||||
|
docker_check_kernel: '2.6.32-431'
|
||||||
|
docker_opts: "other_args"
|
||||||
|
docker_package: docker-io
|
||||||
|
docker_packages: docker
|
||||||
|
- { "name": "docker", "state": "absent" }
|
||||||
|
- { "name": "epel-release", "state": "present" }
|
||||||
|
- { "name": "curl", "state": "present" }
|
||||||
|
- { "name": "device-mapper-libs", "state": "present" }
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
# file: vars/centos-7.yml
|
||||||
|
|
||||||
|
docker_check_kernel: '3.10.0-327'
|
||||||
|
docker_package: docker-latest
|
||||||
|
docker_packages:
|
||||||
|
- { "name": "docker", "state": "absent" }
|
||||||
|
- { "name": "curl", "state": "present" }
|
||||||
|
- { "name": "device-mapper-libs", "state": "present" }
|
||||||
|
docker_services:
|
||||||
|
- { "name": "docker-latest-storage-setup", "state": "started", "enabled": "yes" }
|
||||||
|
- { "name": "docker-latest", "state": "started", "enabled": "yes" }
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
# file: vars/debian.yml
|
||||||
|
|
||||||
|
docker_check_kernel: '3.2'
|
||||||
|
|
||||||
|
docker_package: docker-ce
|
||||||
|
docker_packages:
|
||||||
|
- { "name": "apt-transport-https", "state": "present" }
|
||||||
|
- { "name": "ca-certificates", "state": "present" }
|
||||||
|
- { "name": "curl", "state": "present" }
|
||||||
|
- { "name": "gnupg2", "state": "present" }
|
||||||
|
- { "name": "software-properties-common", "state": "present" }
|
||||||
|
|
||||||
|
docker_init_config_directory: "/etc/default"
|
||||||
|
docker_opts: "DOCKER_OPTS"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
vars/local.yml
|
|
@ -0,0 +1,12 @@
|
||||||
|
; DO NOT EDIT (unless you know what you are doing)
|
||||||
|
;
|
||||||
|
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||||
|
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||||
|
;
|
||||||
|
[subrepo]
|
||||||
|
remote = ssh://git@github.com/aynicos/ansible-hosts
|
||||||
|
branch = master
|
||||||
|
commit = a495a6dbfae1f3c32f8e968c1ff2b3596ab42f27
|
||||||
|
parent = 85a259e1f4db43a63c58b4c8fe39b5d5e3b54053
|
||||||
|
method = merge
|
||||||
|
cmdver = 0.4.0
|
|
@ -0,0 +1,4 @@
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
* **Yann Autissier** - *initial work* - [aya](https://github.com/aya)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0-alpha - 2021-07-14
|
||||||
|
|
||||||
|
Initial myos release
|
||||||
|
|
||||||
|
## v0.1.0 - 2016-12-20
|
||||||
|
|
||||||
|
Initial release
|
|
@ -0,0 +1,610 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (c) 2016 Yann Autissier
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for software
|
||||||
|
and other kinds of works, specifically designed to ensure cooperation with
|
||||||
|
the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed to take
|
||||||
|
away your freedom to share and change the works. By contrast, our General
|
||||||
|
Public Licenses are intended to guarantee your freedom to share and change
|
||||||
|
all versions of a program--to make sure it remains free software for all its
|
||||||
|
users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price. Our
|
||||||
|
General Public Licenses are designed to make sure that you have the freedom
|
||||||
|
to distribute copies of free software (and charge for them if you wish), that
|
||||||
|
you receive source code or can get it if you want it, that you can change
|
||||||
|
the software or use pieces of it in new free programs, and that you know you
|
||||||
|
can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights with two
|
||||||
|
steps: (1) assert copyright on the software, and (2) offer you this License
|
||||||
|
which gives you legal permission to copy, distribute and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that improvements made
|
||||||
|
in alternate versions of the program, if they receive widespread use, become
|
||||||
|
available for other developers to incorporate. Many developers of free software
|
||||||
|
are heartened and encouraged by the resulting cooperation. However, in the
|
||||||
|
case of software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and letting
|
||||||
|
the public access it on a server without ever releasing its source code to
|
||||||
|
the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to ensure that,
|
||||||
|
in such cases, the modified source code becomes available to the community.
|
||||||
|
It requires the operator of a network server to provide the source code of
|
||||||
|
the modified version running there to the users of that server. Therefore,
|
||||||
|
public use of a modified version, on a publicly accessible server, gives the
|
||||||
|
public access to the source code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and published by
|
||||||
|
Affero, was designed to accomplish similar goals. This is a different license,
|
||||||
|
not a version of the Affero GPL, but Affero has released a new version of
|
||||||
|
the Affero GPL which permits relicensing under this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of works,
|
||||||
|
such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this License.
|
||||||
|
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
|
||||||
|
or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work in
|
||||||
|
a fashion requiring copyright permission, other than the making of an exact
|
||||||
|
copy. The resulting work is called a "modified version" of the earlier work
|
||||||
|
or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based on the
|
||||||
|
Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without permission,
|
||||||
|
would make you directly or secondarily liable for infringement under applicable
|
||||||
|
copyright law, except executing it on a computer or modifying a private copy.
|
||||||
|
Propagation includes copying, distribution (with or without modification),
|
||||||
|
making available to the public, and in some countries other activities as
|
||||||
|
well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other parties
|
||||||
|
to make or receive copies. Mere interaction with a user through a computer
|
||||||
|
network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices" to the
|
||||||
|
extent that it includes a convenient and prominently visible feature that
|
||||||
|
(1) displays an appropriate copyright notice, and (2) tells the user that
|
||||||
|
there is no warranty for the work (except to the extent that warranties are
|
||||||
|
provided), that licensees may convey the work under this License, and how
|
||||||
|
to view a copy of this License. If the interface presents a list of user commands
|
||||||
|
or options, such as a menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. "Object code" means any non-source form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official standard
|
||||||
|
defined by a recognized standards body, or, in the case of interfaces specified
|
||||||
|
for a particular programming language, one that is widely used among developers
|
||||||
|
working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other than
|
||||||
|
the work as a whole, that (a) is included in the normal form of packaging
|
||||||
|
a Major Component, but which is not part of that Major Component, and (b)
|
||||||
|
serves only to enable use of the work with that Major Component, or to implement
|
||||||
|
a Standard Interface for which an implementation is available to the public
|
||||||
|
in source code form. A "Major Component", in this context, means a major essential
|
||||||
|
component (kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to produce
|
||||||
|
the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all the source
|
||||||
|
code needed to generate, install, and (for an executable work) run the object
|
||||||
|
code and to modify the work, including scripts to control those activities.
|
||||||
|
However, it does not include the work's System Libraries, or general-purpose
|
||||||
|
tools or generally available free programs which are used unmodified in performing
|
||||||
|
those activities but which are not part of the work. For example, Corresponding
|
||||||
|
Source includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically linked
|
||||||
|
subprograms that the work is specifically designed to require, such as by
|
||||||
|
intimate data communication or control flow between those
|
||||||
|
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users can regenerate
|
||||||
|
automatically from other parts of the Corresponding Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of copyright
|
||||||
|
on the Program, and are irrevocable provided the stated conditions are met.
|
||||||
|
This License explicitly affirms your unlimited permission to run the unmodified
|
||||||
|
Program. The output from running a covered work is covered by this License
|
||||||
|
only if the output, given its content, constitutes a covered work. This License
|
||||||
|
acknowledges your rights of fair use or other equivalent, as provided by copyright
|
||||||
|
law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not convey, without
|
||||||
|
conditions so long as your license otherwise remains in force. You may convey
|
||||||
|
covered works to others for the sole purpose of having them make modifications
|
||||||
|
exclusively for you, or provide you with facilities for running those works,
|
||||||
|
provided that you comply with the terms of this License in conveying all material
|
||||||
|
for which you do not control copyright. Those thus making or running the covered
|
||||||
|
works for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of your copyrighted
|
||||||
|
material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under the conditions
|
||||||
|
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological measure
|
||||||
|
under any applicable law fulfilling obligations under article 11 of the WIPO
|
||||||
|
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
|
||||||
|
or restricting circumvention of such measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid circumvention
|
||||||
|
of technological measures to the extent such circumvention is effected by
|
||||||
|
exercising rights under this License with respect to the covered work, and
|
||||||
|
you disclaim any intention to limit operation or modification of the work
|
||||||
|
as a means of enforcing, against the work's users, your or third parties'
|
||||||
|
legal rights to forbid circumvention of technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you receive
|
||||||
|
it, in any medium, provided that you conspicuously and appropriately publish
|
||||||
|
on each copy an appropriate copyright notice; keep intact all notices stating
|
||||||
|
that this License and any non-permissive terms added in accord with section
|
||||||
|
7 apply to the code; keep intact all notices of the absence of any warranty;
|
||||||
|
and give all recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey, and you
|
||||||
|
may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to produce
|
||||||
|
it from the Program, in the form of source code under the terms of section
|
||||||
|
4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified it, and
|
||||||
|
giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is released under
|
||||||
|
this License and any conditions added under section 7. This requirement modifies
|
||||||
|
the requirement in section 4 to "keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this License to anyone
|
||||||
|
who comes into possession of a copy. This License will therefore apply, along
|
||||||
|
with any applicable section 7 additional terms, to the whole of the work,
|
||||||
|
and all its parts, regardless of how they are packaged. This License gives
|
||||||
|
no permission to license the work in any other way, but it does not invalidate
|
||||||
|
such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display Appropriate
|
||||||
|
Legal Notices; however, if the Program has interactive interfaces that do
|
||||||
|
not display Appropriate Legal Notices, your work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent works,
|
||||||
|
which are not by their nature extensions of the covered work, and which are
|
||||||
|
not combined with it such as to form a larger program, in or on a volume of
|
||||||
|
a storage or distribution medium, is called an "aggregate" if the compilation
|
||||||
|
and its resulting copyright are not used to limit the access or legal rights
|
||||||
|
of the compilation's users beyond what the individual works permit. Inclusion
|
||||||
|
of a covered work in an aggregate does not cause this License to apply to
|
||||||
|
the other parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms of sections
|
||||||
|
4 and 5, provided that you also convey the machine-readable Corresponding
|
||||||
|
Source under the terms of this License, in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by the Corresponding Source fixed
|
||||||
|
on a durable physical medium customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product (including
|
||||||
|
a physical distribution medium), accompanied by a written offer, valid for
|
||||||
|
at least three years and valid for as long as you offer spare parts or customer
|
||||||
|
support for that product model, to give anyone who possesses the object code
|
||||||
|
either (1) a copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical medium customarily
|
||||||
|
used for software interchange, for a price no more than your reasonable cost
|
||||||
|
of physically performing this conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the written
|
||||||
|
offer to provide the Corresponding Source. This alternative is allowed only
|
||||||
|
occasionally and noncommercially, and only if you received the object code
|
||||||
|
with such an offer, in accord with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated place (gratis
|
||||||
|
or for a charge), and offer equivalent access to the Corresponding Source
|
||||||
|
in the same way through the same place at no further charge. You need not
|
||||||
|
require recipients to copy the Corresponding Source along with the object
|
||||||
|
code. If the place to copy the object code is a network server, the Corresponding
|
||||||
|
Source may be on a different server (operated by you or a third party) that
|
||||||
|
supports equivalent copying facilities, provided you maintain clear directions
|
||||||
|
next to the object code saying where to find the Corresponding Source. Regardless
|
||||||
|
of what server hosts the Corresponding Source, you remain obligated to ensure
|
||||||
|
that it is available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided you inform
|
||||||
|
other peers where the object code and Corresponding Source of the work are
|
||||||
|
being offered to the general public at no charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded from
|
||||||
|
the Corresponding Source as a System Library, need not be included in conveying
|
||||||
|
the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any tangible
|
||||||
|
personal property which is normally used for personal, family, or household
|
||||||
|
purposes, or (2) anything designed or sold for incorporation into a dwelling.
|
||||||
|
In determining whether a product is a consumer product, doubtful cases shall
|
||||||
|
be resolved in favor of coverage. For a particular product received by a particular
|
||||||
|
user, "normally used" refers to a typical or common use of that class of product,
|
||||||
|
regardless of the status of the particular user or of the way in which the
|
||||||
|
particular user actually uses, or expects or is expected to use, the product.
|
||||||
|
A product is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent the
|
||||||
|
only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods, procedures,
|
||||||
|
authorization keys, or other information required to install and execute modified
|
||||||
|
versions of a covered work in that User Product from a modified version of
|
||||||
|
its Corresponding Source. The information must suffice to ensure that the
|
||||||
|
continued functioning of the modified object code is in no case prevented
|
||||||
|
or interfered with solely because modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or specifically
|
||||||
|
for use in, a User Product, and the conveying occurs as part of a transaction
|
||||||
|
in which the right of possession and use of the User Product is transferred
|
||||||
|
to the recipient in perpetuity or for a fixed term (regardless of how the
|
||||||
|
transaction is characterized), the Corresponding Source conveyed under this
|
||||||
|
section must be accompanied by the Installation Information. But this requirement
|
||||||
|
does not apply if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has been installed
|
||||||
|
in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a requirement
|
||||||
|
to continue to provide support service, warranty, or updates for a work that
|
||||||
|
has been modified or installed by the recipient, or for the User Product in
|
||||||
|
which it has been modified or installed. Access to a network may be denied
|
||||||
|
when the modification itself materially and adversely affects the operation
|
||||||
|
of the network or violates the rules and protocols for communication across
|
||||||
|
the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided, in accord
|
||||||
|
with this section must be in a format that is publicly documented (and with
|
||||||
|
an implementation available to the public in source code form), and must require
|
||||||
|
no special password or key for unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this License
|
||||||
|
by making exceptions from one or more of its conditions. Additional permissions
|
||||||
|
that are applicable to the entire Program shall be treated as though they
|
||||||
|
were included in this License, to the extent that they are valid under applicable
|
||||||
|
law. If additional permissions apply only to part of the Program, that part
|
||||||
|
may be used separately under those permissions, but the entire Program remains
|
||||||
|
governed by this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option remove any
|
||||||
|
additional permissions from that copy, or from any part of it. (Additional
|
||||||
|
permissions may be written to require their own removal in certain cases when
|
||||||
|
you modify the work.) You may place additional permissions on material, added
|
||||||
|
by you to a covered work, for which you have or can give appropriate copyright
|
||||||
|
permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you add
|
||||||
|
to a covered work, you may (if authorized by the copyright holders of that
|
||||||
|
material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the terms of
|
||||||
|
sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or author
|
||||||
|
attributions in that material or in the Appropriate Legal Notices displayed
|
||||||
|
by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or requiring
|
||||||
|
that modified versions of such material be marked in reasonable ways as different
|
||||||
|
from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or authors
|
||||||
|
of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some trade names,
|
||||||
|
trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that material by
|
||||||
|
anyone who conveys the material (or modified versions of it) with contractual
|
||||||
|
assumptions of liability to the recipient, for any liability that these contractual
|
||||||
|
assumptions directly impose on those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further restrictions"
|
||||||
|
within the meaning of section 10. If the Program as you received it, or any
|
||||||
|
part of it, contains a notice stating that it is governed by this License
|
||||||
|
along with a term that is a further restriction, you may remove that term.
|
||||||
|
If a license document contains a further restriction but permits relicensing
|
||||||
|
or conveying under this License, you may add to a covered work material governed
|
||||||
|
by the terms of that license document, provided that the further restriction
|
||||||
|
does not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you must place,
|
||||||
|
in the relevant source files, a statement of the additional terms that apply
|
||||||
|
to those files, or a notice indicating where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the form
|
||||||
|
of a separately written license, or stated as exceptions; the above requirements
|
||||||
|
apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly provided
|
||||||
|
under this License. Any attempt otherwise to propagate or modify it is void,
|
||||||
|
and will automatically terminate your rights under this License (including
|
||||||
|
any patent licenses granted under the third paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your license from
|
||||||
|
a particular copyright holder is reinstated (a) provisionally, unless and
|
||||||
|
until the copyright holder explicitly and finally terminates your license,
|
||||||
|
and (b) permanently, if the copyright holder fails to notify you of the violation
|
||||||
|
by some reasonable means prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is reinstated permanently
|
||||||
|
if the copyright holder notifies you of the violation by some reasonable means,
|
||||||
|
this is the first time you have received notice of violation of this License
|
||||||
|
(for any work) from that copyright holder, and you cure the violation prior
|
||||||
|
to 30 days after your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the licenses
|
||||||
|
of parties who have received copies or rights from you under this License.
|
||||||
|
If your rights have been terminated and not permanently reinstated, you do
|
||||||
|
not qualify to receive new licenses for the same material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or run a copy
|
||||||
|
of the Program. Ancillary propagation of a covered work occurring solely as
|
||||||
|
a consequence of using peer-to-peer transmission to receive a copy likewise
|
||||||
|
does not require acceptance. However, nothing other than this License grants
|
||||||
|
you permission to propagate or modify any covered work. These actions infringe
|
||||||
|
copyright if you do not accept this License. Therefore, by modifying or propagating
|
||||||
|
a covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically receives
|
||||||
|
a license from the original licensors, to run, modify and propagate that work,
|
||||||
|
subject to this License. You are not responsible for enforcing compliance
|
||||||
|
by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an organization,
|
||||||
|
or substantially all assets of one, or subdividing an organization, or merging
|
||||||
|
organizations. If propagation of a covered work results from an entity transaction,
|
||||||
|
each party to that transaction who receives a copy of the work also receives
|
||||||
|
whatever licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the Corresponding
|
||||||
|
Source of the work from the predecessor in interest, if the predecessor has
|
||||||
|
it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the rights
|
||||||
|
granted or affirmed under this License. For example, you may not impose a
|
||||||
|
license fee, royalty, or other charge for exercise of rights granted under
|
||||||
|
this License, and you may not initiate litigation (including a cross-claim
|
||||||
|
or counterclaim in a lawsuit) alleging that any patent claim is infringed
|
||||||
|
by making, using, selling, offering for sale, or importing the Program or
|
||||||
|
any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this License
|
||||||
|
of the Program or a work on which the Program is based. The work thus licensed
|
||||||
|
is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims owned or controlled
|
||||||
|
by the contributor, whether already acquired or hereafter acquired, that would
|
||||||
|
be infringed by some manner, permitted by this License, of making, using,
|
||||||
|
or selling its contributor version, but do not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of the contributor
|
||||||
|
version. For purposes of this definition, "control" includes the right to
|
||||||
|
grant patent sublicenses in a manner consistent with the requirements of this
|
||||||
|
License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
|
||||||
|
license under the contributor's essential patent claims, to make, use, sell,
|
||||||
|
offer for sale, import and otherwise run, modify and propagate the contents
|
||||||
|
of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express agreement
|
||||||
|
or commitment, however denominated, not to enforce a patent (such as an express
|
||||||
|
permission to practice a patent or covenant not to s ue for patent infringement).
|
||||||
|
To "grant" such a patent license to a party means to make such an agreement
|
||||||
|
or commitment not to enforce a patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license, and the
|
||||||
|
Corresponding Source of the work is not available for anyone to copy, free
|
||||||
|
of charge and under the terms of this License, through a publicly available
|
||||||
|
network server or other readily accessible means, then you must either (1)
|
||||||
|
cause the Corresponding Source to be so available, or (2) arrange to deprive
|
||||||
|
yourself of the benefit of the patent license for this particular work, or
|
||||||
|
(3) arrange, in a manner consistent with the requirements of this License,
|
||||||
|
to extend the patent
|
||||||
|
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have actual
|
||||||
|
knowledge that, but for the patent license, your conveying the covered work
|
||||||
|
in a country, or your recipient's use of the covered work in a country, would
|
||||||
|
infringe one or more identifiable patents in that country that you have reason
|
||||||
|
to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or arrangement,
|
||||||
|
you convey, or propagate by procuring conveyance of, a covered work, and grant
|
||||||
|
a patent license to some of the parties receiving the covered work authorizing
|
||||||
|
them to use, propagate, modify or convey a specific copy of the covered work,
|
||||||
|
then the patent license you grant is automatically extended to all recipients
|
||||||
|
of the covered work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within the scope
|
||||||
|
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
|
||||||
|
of one or more of the rights that are specifically granted under this License.
|
||||||
|
You may not convey a covered work if you are a party to an arrangement with
|
||||||
|
a third party that is in the business of distributing software, under which
|
||||||
|
you make payment to the third party based on the extent of your activity of
|
||||||
|
conveying the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory patent
|
||||||
|
license (a) in connection with copies of the covered work conveyed by you
|
||||||
|
(or copies made from those copies), or (b) primarily for and in connection
|
||||||
|
with specific products or compilations that contain the covered work, unless
|
||||||
|
you entered into that arrangement, or that patent license was granted, prior
|
||||||
|
to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting any implied
|
||||||
|
license or other defenses to infringement that may otherwise be available
|
||||||
|
to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||||
|
that contradict the conditions of this License, they do not excuse you from
|
||||||
|
the conditions of this License. If you cannot convey a covered work so as
|
||||||
|
to satisfy simultaneously your obligations under this License and any other
|
||||||
|
pertinent obligations, then as a consequence you may
|
||||||
|
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey the
|
||||||
|
Program, the only way you could satisfy both those terms and this License
|
||||||
|
would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the Program,
|
||||||
|
your modified version must prominently offer all users interacting with it
|
||||||
|
remotely through a computer network (if your version supports such interaction)
|
||||||
|
an opportunity to receive the Corresponding Source of your version by providing
|
||||||
|
access to the Corresponding Source from a network server at no charge, through
|
||||||
|
some standard or customary means of facilitating copying of software. This
|
||||||
|
Corresponding Source shall include the Corresponding Source for any work covered
|
||||||
|
by version 3 of the GNU General Public License that is incorporated pursuant
|
||||||
|
to the following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have permission to
|
||||||
|
link or combine any covered work with a work licensed under version 3 of the
|
||||||
|
GNU General Public License into a single combined work, and to convey the
|
||||||
|
resulting work. The terms of this License will continue to apply to the part
|
||||||
|
which is the covered work, but the work with which it is combined will remain
|
||||||
|
governed by version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of the
|
||||||
|
GNU Affero General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to address
|
||||||
|
new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program specifies
|
||||||
|
that a certain numbered version of the GNU Affero General Public License "or
|
||||||
|
any later version" applies to it, you have the option of following the terms
|
||||||
|
and conditions either of that numbered version or of any later version published
|
||||||
|
by the Free Software Foundation. If the Program does not specify a version
|
||||||
|
number of the GNU Affero General Public License, you may choose any version
|
||||||
|
ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future versions of
|
||||||
|
the GNU Affero General Public License can be used, that proxy's public statement
|
||||||
|
of acceptance of a version permanently authorizes you to choose that version
|
||||||
|
for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different permissions. However,
|
||||||
|
no additional obligations are imposed on any author or copyright holder as
|
||||||
|
a result of your choosing to follow a later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
||||||
|
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
|
||||||
|
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||||
|
CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||||
|
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
|
||||||
|
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
|
||||||
|
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
||||||
|
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||||
|
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided above cannot
|
||||||
|
be given local legal effect according to their terms, reviewing courts shall
|
||||||
|
apply local law that most closely approximates an absolute waiver of all civil
|
||||||
|
liability in connection with the Program, unless a warranty or assumption
|
||||||
|
of liability accompanies a copy of the Program in return for a fee. END OF
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest possible
|
||||||
|
use to the public, the best way to achieve this is to make it free software
|
||||||
|
which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest to attach
|
||||||
|
them to the start of each source file to most effectively state the exclusion
|
||||||
|
of warranty; and each file should have at least the "copyright" line and a
|
||||||
|
pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along
|
||||||
|
with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer network,
|
||||||
|
you should also make sure that it provides a way for users to get its source.
|
||||||
|
For example, if your program is a web application, its interface could display
|
||||||
|
a "Source" link that leads users to an archive of the code. There are many
|
||||||
|
ways you could offer source, and different solutions will be better for different
|
||||||
|
programs; see section 13 for the specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary. For
|
||||||
|
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,166 @@
|
||||||
|
# hosts role for Ansible
|
||||||
|
|
||||||
|
Bootstrap hosts, installing standard packages and user settings
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
* `hosts_cloudinit` - Install and configure cloud-init
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_cloudinit: false
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_cloudinit_config` - cloud-init yaml config
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_cloudinit_config:
|
||||||
|
preserve_hostname: false
|
||||||
|
datasource_list:
|
||||||
|
- Ec2
|
||||||
|
datasource:
|
||||||
|
Ec2:
|
||||||
|
metadata_urls:
|
||||||
|
- 'http://169.254.169.254'
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_default_env` - List of environment variables to add in file /etc/default/myos
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_default_env:
|
||||||
|
- ENV
|
||||||
|
- DOCKER
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_git_repositories` - Clone git repositories
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_git_repositories:
|
||||||
|
- { "repo": "https://github.com/aynicos/myos", "dest": "/dns/com/github/aynicos/myos", "key_file": "~/.ssh/id_rsa", "version": "master" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_packages` - List of packages to install/remove on your hosts, should be overrided for a specific distro
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_packages: []
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_packages_common` - List of packages to install/remove on your hosts, common to all distros
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_packages_common:
|
||||||
|
- { "name": "bash", "state": "present" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_packages_distro` - List of packages to install/remove on your hosts, specific to a distro
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_packages_distro:
|
||||||
|
- { "name": "vim-nox", "state": "present" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_services` - List of services to enable/disable on your hosts
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_services:
|
||||||
|
# Enable ansible, running ansible pull at boot
|
||||||
|
- { "name": "ansible", "state": "started", "enabled": "yes" }
|
||||||
|
# Enable zram, creating virtual swap devices compressed in RAM, usefull on hosts without physical swap to increase performances
|
||||||
|
- { "name": "zram", "state": "started", "enabled": "yes" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_authorized_keys` - List of urls to add ssh public keys in ~/.ssh/authorized_keys
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_authorized_keys:
|
||||||
|
- https://github.com/aynicos.keys
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_bastion_hostname` - Hostname of ssh bastion added in ~/.ssh/myos/config
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_bastion_hostname: 8.4.2.1
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_bastion_username` - Username of ssh bastion added in ~/.ssh/myos/config
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_bastion_username: root
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_private_ip_range` - Ip range proxified through ssh bastion to add in ~/.ssh/myos/config
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_private_ip_range: 10.* 192.168.42.*
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_private_keys` - List of ssh private keys to copy, default to ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_private_keys:
|
||||||
|
- ~/.ssh/id_rsa
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_public_hosts` - List of host names to add ssh public fingerprints in ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_public_hosts:
|
||||||
|
- github.com
|
||||||
|
- gitlab.com
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_ssh_username` - User to ssh on remote hosts
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_ssh_username: root
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_update` - Update hosts every day
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_update: false
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_user_rc` - Call specific functions on user login, allowing it to customize his session
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_user_rc: false
|
||||||
|
```
|
||||||
|
|
||||||
|
* `hosts_user_rc_functions` - List of specific functions to call on user login, defined in /etc/profile.d/rc_functions.sh
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
hosts_user_rc_functions:
|
||||||
|
# customize PROMPT variable
|
||||||
|
- { "path": "10_prompt_set", "state": "touch" }
|
||||||
|
# customize PS1 variable
|
||||||
|
- { "path": "10_ps1_set", "state": "touch" }
|
||||||
|
# create and/or attach a tmux session
|
||||||
|
- { "path": "20_tmux_attach", "state": "touch" }
|
||||||
|
# display host infos
|
||||||
|
- { "path": "30_pfetch", "state": "touch" }
|
||||||
|
# create and/or attach a screen session
|
||||||
|
- { "path": "30_screen_attach", "state": "touch" }
|
||||||
|
# launch ssh agent and load private keys in ~/.ssh
|
||||||
|
- { "path": "40_ssh_add", "state": "touch" }
|
||||||
|
# remove tmux_attach
|
||||||
|
- { "path": "20_tmux_attach", "state": "absent" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example playbook
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
- hosts: 'hosts'
|
||||||
|
roles:
|
||||||
|
- role: 'aynicos.hosts'
|
||||||
|
hosts_services:
|
||||||
|
- { "name": "zram", "state": "started", "enabled": "yes" }
|
||||||
|
hosts_user_rc: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
To test this role on your `hosts`, run the tests/playbook.yml playbook.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ ansible-playbook tests/playbook.yml
|
||||||
|
```
|
|
@ -0,0 +1,147 @@
|
||||||
|
---
|
||||||
|
# file: defaults/main.yml
|
||||||
|
|
||||||
|
# enable cloud-init
|
||||||
|
hosts_cloudinit: false
|
||||||
|
|
||||||
|
# cloud-init config
|
||||||
|
hosts_cloudinit_config:
|
||||||
|
users:
|
||||||
|
- default
|
||||||
|
disable_root: true
|
||||||
|
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
|
||||||
|
resize_rootfs_tmp: /dev
|
||||||
|
ssh_pwauth: 0
|
||||||
|
preserve_hostname: false
|
||||||
|
datasource_list:
|
||||||
|
- Ec2
|
||||||
|
datasource:
|
||||||
|
Ec2:
|
||||||
|
metadata_urls:
|
||||||
|
- 'http://169.254.169.254'
|
||||||
|
timeout: 5
|
||||||
|
max_wait: 10
|
||||||
|
cloud_init_modules:
|
||||||
|
- migrator
|
||||||
|
- seed_random
|
||||||
|
- bootcmd
|
||||||
|
- write-files
|
||||||
|
- growpart
|
||||||
|
- resizefs
|
||||||
|
- disk_setup
|
||||||
|
- mounts
|
||||||
|
- set_hostname
|
||||||
|
- update_hostname
|
||||||
|
- update_etc_hosts
|
||||||
|
- resolv_conf
|
||||||
|
- ca-certs
|
||||||
|
- rsyslog
|
||||||
|
- users-groups
|
||||||
|
- ssh
|
||||||
|
cloud_config_modules:
|
||||||
|
- ssh-import-id
|
||||||
|
- locale
|
||||||
|
- set-passwords
|
||||||
|
- apk-configure
|
||||||
|
- ntp
|
||||||
|
- timezone
|
||||||
|
- disable-ec2-metadata
|
||||||
|
- runcmd
|
||||||
|
cloud_final_modules:
|
||||||
|
- package-update-upgrade-install
|
||||||
|
- puppet
|
||||||
|
- chef
|
||||||
|
- mcollective
|
||||||
|
- salt-minion
|
||||||
|
- rightscale_userdata
|
||||||
|
- scripts-vendor
|
||||||
|
- scripts-per-once
|
||||||
|
- scripts-per-boot
|
||||||
|
- scripts-per-instance
|
||||||
|
- scripts-user
|
||||||
|
- ssh-authkey-fingerprints
|
||||||
|
- keys-to-console
|
||||||
|
- phone-home
|
||||||
|
- final-message
|
||||||
|
- power-state-change
|
||||||
|
system_info:
|
||||||
|
distro: alpine
|
||||||
|
default_user:
|
||||||
|
name: alpine
|
||||||
|
lock_passwd: True
|
||||||
|
gecos: alpine Cloud User
|
||||||
|
groups: [adm, sudo]
|
||||||
|
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
||||||
|
shell: /bin/ash
|
||||||
|
paths:
|
||||||
|
cloud_dir: /var/lib/cloud/
|
||||||
|
templates_dir: /etc/cloud/templates/
|
||||||
|
ssh_svcname: sshd
|
||||||
|
|
||||||
|
# environment variables to add in /etc/default/myos
|
||||||
|
hosts_default_env: []
|
||||||
|
|
||||||
|
# git repositories to clone
|
||||||
|
hosts_git_repositories: []
|
||||||
|
|
||||||
|
# packages to install/remove
|
||||||
|
hosts_packages: []
|
||||||
|
|
||||||
|
# packages common to all distributions
|
||||||
|
hosts_packages_common:
|
||||||
|
- { "name": "bash", "state": "present" }
|
||||||
|
- { "name": "ca-certificates", "state": "present" }
|
||||||
|
- { "name": "curl", "state": "present" }
|
||||||
|
- { "name": "git", "state": "present" }
|
||||||
|
- { "name": "htop", "state": "present" }
|
||||||
|
- { "name": "less", "state": "present" }
|
||||||
|
- { "name": "lsof", "state": "present" }
|
||||||
|
- { "name": "make", "state": "present" }
|
||||||
|
- { "name": "rsync", "state": "present" }
|
||||||
|
- { "name": "screen", "state": "present" }
|
||||||
|
- { "name": "tmux", "state": "present" }
|
||||||
|
- { "name": "tzdata", "state": "present" }
|
||||||
|
|
||||||
|
# packages specific to a distribution
|
||||||
|
hosts_packages_distro: []
|
||||||
|
|
||||||
|
# services to enable/disable
|
||||||
|
hosts_services:
|
||||||
|
- { "name": "ansible", "state": "stopped", "enabled": "no" }
|
||||||
|
- { "name": "myos", "state": "stopped", "enabled": "no" }
|
||||||
|
- { "name": "zram", "state": "stopped", "enabled": "no" }
|
||||||
|
|
||||||
|
# list of urls to get public keys to add to ~/.ssh/authorized_keys
|
||||||
|
hosts_ssh_authorized_keys: "{{ lookup('env','ANSIBLE_SSH_AUTHORIZED_KEYS').split(' ') }}"
|
||||||
|
|
||||||
|
# hostname of myos-bastion to add in ~/.ssh/myos/config
|
||||||
|
hosts_ssh_bastion_hostname: "{{ lookup('env','ANSIBLE_SSH_BASTION_HOSTNAME') }}"
|
||||||
|
|
||||||
|
# username of myos-bastion to add in ~/.ssh/myos/config
|
||||||
|
hosts_ssh_bastion_username: "{{ lookup('env','ANSIBLE_SSH_BASTION_USERNAME') or ansible_user }}"
|
||||||
|
|
||||||
|
# ip range proxyfied through myos-bastion to add in ~/.ssh/myos/config
|
||||||
|
hosts_ssh_private_ip_range: "{{ lookup('env','ANSIBLE_SSH_PRIVATE_IP_RANGE') }}"
|
||||||
|
|
||||||
|
# list of SSH private keys to copy
|
||||||
|
hosts_ssh_private_keys: "{{ lookup('env','ANSIBLE_SSH_PRIVATE_KEYS').split(' ') }}"
|
||||||
|
|
||||||
|
# list of public hosts to add to known_hosts
|
||||||
|
hosts_ssh_public_hosts: "{{ lookup('env','ANSIBLE_SSH_PUBLIC_HOSTS').split(' ') }}"
|
||||||
|
|
||||||
|
# remote ssh user
|
||||||
|
hosts_ssh_username: "{{ lookup('env','ANSIBLE_SSH_USERNAME') or ansible_user }}"
|
||||||
|
|
||||||
|
# update hosts every hour
|
||||||
|
hosts_update: false
|
||||||
|
|
||||||
|
# run specific functions on user login
|
||||||
|
hosts_user_rc: false
|
||||||
|
|
||||||
|
# list of rc functions to call at user connection
|
||||||
|
hosts_user_rc_functions:
|
||||||
|
- { "path": "10_prompt_set", "state": "touch" }
|
||||||
|
- { "path": "10_ps1_set", "state": "touch" }
|
||||||
|
- { "path": "30_pfetch", "state": "touch" }
|
||||||
|
- { "path": "40_ssh_add", "state": "touch" }
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
@reboot root /etc/init.d/myos ansible-pull > /var/log/ansible.log
|
||||||
|
0 * * * * root /etc/init.d/myos ansible-pull > /var/log/ansible.log
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue