Browse Source

Merge branch 'feature/create-docker-user' of ansible-roles/deploy-docker into master

tags/v1.2.0^2^2
Lyz 1 year ago
parent
commit
d9b2201358

+ 8
- 1
README.md View File

@@ -26,6 +26,8 @@ Role Variables
26 26
 * `docker_registry_read`: Domain of the registry with read access.
27 27
 * `registry_user`: User used to authenticate with the registry.
28 28
 * `registry_password`: Password used to authenticate with the registry.
29
+* `docker_user`: User that will run the service
30
+* `docker_group`: Group of the user that will run the service
29 31
 * `docker_image`: If you want to download a docker image and not a git repository
30 32
 * `docker_image_tag`: Docker tag.
31 33
 * `docker_command`: Docker command used to launch the container.
@@ -92,9 +94,14 @@ enough to test the other case, please make a new molecule scenery. Both in this
92 94
 role and in the ui-registry one.
93 95
 
94 96
 ```bash
95
-molecule test
97
+molecule test --all
96 98
 ```
97 99
 
100
+Right now we've got two sceneries:
101
+* *default*: Tests the creation of a service with root user
102
+* *nginx-user*: Tests the creation of a service with a user specified in the var
103
+  `docker_user`
104
+
98 105
 License
99 106
 -------
100 107
 

+ 2
- 0
defaults/main.yml View File

@@ -9,5 +9,7 @@ docker_registry_url:
9 9
 docker_registry_read:
10 10
 registry_user:
11 11
 registry_password:
12
+docker_user: root
13
+docker_group: "{{ docker_user }}"
12 14
 docker_image_tag: "{{ git_repository_tag }}"
13 15
 docker_command:

+ 1
- 1
molecule/default/requirements.yml View File

@@ -1,4 +1,4 @@
1 1
 - src: git+https://git.digitales.cslabrecha.org/ansible-roles/docker.git
2 2
   version: v1.0.1
3 3
 - src: git+https://git.digitales.cslabrecha.org/ansible-roles/docker-registry.git
4
-  version: feature/26
4
+  version: v1.0.0

+ 17
- 0
molecule/nginx-user/INSTALL.rst View File

@@ -0,0 +1,17 @@
1
+*******
2
+Install
3
+*******
4
+
5
+Requirements
6
+============
7
+
8
+* Vagrant
9
+* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop
10
+* python-vagrant
11
+
12
+Install
13
+=======
14
+
15
+.. code-block:: bash
16
+
17
+  $ sudo pip install python-vagrant

+ 56
- 0
molecule/nginx-user/create.yml View File

@@ -0,0 +1,56 @@
1
+---
2
+- name: Create
3
+  hosts: localhost
4
+  connection: local
5
+  gather_facts: False
6
+  no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
7
+  vars:
8
+    molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
9
+    molecule_instance_config: "{{ lookup('env', 'MOLECULE_INSTANCE_CONFIG') }}"
10
+    molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
11
+  tasks:
12
+    - name: Create molecule instance(s)
13
+      molecule_vagrant:
14
+        instance_name: "{{ item.name }}"
15
+        instance_interfaces: "{{ item.interfaces | default(omit) }}"
16
+        instance_raw_config_args: "{{ item.instance_raw_config_args | default(omit) }}"
17
+
18
+        platform_box: "{{ item.box }}"
19
+        platform_box_version: "{{ item.box_version | default(omit) }}"
20
+        platform_box_url: "{{ item.box_url | default(omit) }}"
21
+
22
+        provider_name: "{{ molecule_yml.driver.provider.name }}"
23
+        provider_memory: "{{ item.memory | default(omit) }}"
24
+        provider_cpus: "{{ item.cpus | default(omit) }}"
25
+        provider_raw_config_args: "{{ item.raw_config_args | default(omit) }}"
26
+
27
+        state: up
28
+      register: server
29
+      with_items: "{{ molecule_yml.platforms }}"
30
+
31
+    # Mandatory configuration for Molecule to function.
32
+
33
+    - name: Populate instance config dict
34
+      set_fact:
35
+        instance_conf_dict: {
36
+          'instance': "{{ item.Host }}",
37
+          'address': "{{ item.HostName }}",
38
+          'user': "{{ item.User }}",
39
+          'port': "{{ item.Port }}",
40
+          'identity_file': "{{ item.IdentityFile }}", }
41
+      with_items: "{{ server.results }}"
42
+      register: instance_config_dict
43
+      when: server.changed | bool
44
+
45
+    - name: Convert instance config dict to a list
46
+      set_fact:
47
+        instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}"
48
+      when: server.changed | bool
49
+
50
+    - name: Dump instance config
51
+      copy:
52
+        # NOTE(retr0h): Workaround for Ansible 2.2.
53
+        #               https://github.com/ansible/ansible/issues/20885
54
+        content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
55
+        dest: "{{ molecule_instance_config }}"
56
+      when: server.changed | bool

+ 36
- 0
molecule/nginx-user/destroy.yml View File

@@ -0,0 +1,36 @@
1
+---
2
+
3
+- name: Destroy
4
+  hosts: localhost
5
+  connection: local
6
+  gather_facts: False
7
+  no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
8
+  vars:
9
+    molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
10
+    molecule_instance_config: "{{ lookup('env',' MOLECULE_INSTANCE_CONFIG') }}"
11
+    molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
12
+  tasks:
13
+    - name: Destroy molecule instance(s)
14
+      molecule_vagrant:
15
+        instance_name: "{{ item.name }}"
16
+        platform_box: "{{ item.box }}"
17
+        provider_name: "{{ molecule_yml.driver.provider.name }}"
18
+        force_stop: "{{ item.force_stop | default(True) }}"
19
+
20
+        state: destroy
21
+      register: server
22
+      with_items: "{{ molecule_yml.platforms }}"
23
+
24
+    # Mandatory configuration for Molecule to function.
25
+
26
+    - name: Populate instance config
27
+      set_fact:
28
+        instance_conf: {}
29
+
30
+    - name: Dump instance config
31
+      copy:
32
+        # NOTE(retr0h): Workaround for Ansible 2.2.
33
+        #               https://github.com/ansible/ansible/issues/20885
34
+        content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
35
+        dest: "{{ molecule_instance_config }}"
36
+      when: server.changed | bool

+ 2
- 0
molecule/nginx-user/files/htpasswd View File

@@ -0,0 +1,2 @@
1
+testuser:$2y$05$vXnk299Xwr1RjEcwhJvHC.w7UnxuucId7y3wb5iOgSjkKCYaPZeFq
2
+

+ 36
- 0
molecule/nginx-user/molecule.yml View File

@@ -0,0 +1,36 @@
1
+---
2
+dependency:
3
+  name: galaxy
4
+driver:
5
+  name: vagrant
6
+  provider:
7
+    name: libvirt
8
+lint:
9
+  name: yamllint
10
+platforms:
11
+  - name: deploy-docker-nginx-user
12
+    box: debian/stretch64
13
+    instance_raw_config_args:
14
+      - "vm.synced_folder '.', '/vagrant', disabled: true"
15
+provisioner:
16
+  name: ansible
17
+  lint:
18
+    name: ansible-lint
19
+scenario:
20
+  name: nginx-user
21
+  test_sequence:
22
+    - destroy
23
+    - lint
24
+    - dependency
25
+    - syntax
26
+    - create
27
+    - prepare
28
+    - converge
29
+    - idempotence
30
+    - side_effect
31
+    - verify
32
+    - destroy
33
+verifier:
34
+  name: testinfra
35
+  lint:
36
+    name: flake8

+ 92
- 0
molecule/nginx-user/playbook.yml View File

@@ -0,0 +1,92 @@
1
+---
2
+- name: '[Pretask] Install pip, and curl'
3
+  hosts: all
4
+  tasks:
5
+    - name: Install required packages
6
+      become: true
7
+      package:
8
+        name: "{{ item }}"
9
+        state: present
10
+      with_items:
11
+        - python-pip
12
+        - curl
13
+
14
+- name: '[Pretask] Install docker'
15
+  hosts: all
16
+  roles:
17
+    - role: docker
18
+
19
+- name: '[Pretask] Configure docker-registry on /etc/hosts'
20
+  hosts: all
21
+  tasks:
22
+    - name: Configure docker-registry on /etc/hosts
23
+      become: True
24
+      lineinfile:
25
+        path: /etc/hosts
26
+        state: present
27
+        line: '127.0.0.1  docker-registry'
28
+
29
+- name: '[Pretask] Configure docker basic authentication'
30
+  hosts: all
31
+  tasks:
32
+    - name: Create registry/auth directory
33
+      become: True
34
+      file:
35
+        path: /root/docker/registry/auth/
36
+        state: directory
37
+
38
+    - name: Copy the htpasswd
39
+      become: True
40
+      copy:
41
+        src: htpasswd
42
+        dest: /root/docker/registry/auth/htpasswd
43
+
44
+
45
+- name: '[Pretask] Install registry on the registry instance'
46
+  hosts: all
47
+  vars:
48
+    docker_command: /usr/bin/docker run -i --name {{ registry_service_name }} -p 127.0.0.1:5000:5000 --rm -v {{ registry_data }}:/var/lib/registry -v {{ registry_auth }}:/var/lib/auth -v {{ registry_config }}/:/etc/docker/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/var/lib/auth/htpasswd registry:2
49
+  roles:
50
+    - role: docker-registry
51
+
52
+
53
+- name: Build nginx from image
54
+  hosts: all
55
+  vars:
56
+    remote_build: True
57
+    docker_image: nginx
58
+    service_name: image-nginx
59
+    docker_data_directories:
60
+      - "/root/docker/image-nginx/data"
61
+      - "/root/docker/image-nginx/auth"
62
+    docker_registry: "docker-registry:5000"
63
+    docker_registry_read: "{{ docker_registry }}"
64
+    registry_user: testuser
65
+    registry_password: testpassword
66
+    docker_user: nginx
67
+    docker_image_tag: latest
68
+    docker_command: /usr/bin/docker run --rm -i --name "{{ service_name }}" -p 8080:80 "{{ docker_registry_read }}/{{ service_name }}"
69
+  roles:
70
+    - role: deploy-docker
71
+
72
+- name: Build nginx from git
73
+  hosts: all
74
+  vars:
75
+    remote_build: True
76
+    git_repository: https://github.com/nginxinc/docker-nginx
77
+    git_repository_destination: /tmp/docker-nginx
78
+    git_repository_extra_path: stable/stretch
79
+    git_repository_tag: master
80
+    service_name: git-nginx
81
+    docker_data_directories:
82
+      - "/root/docker/git-nginx/data"
83
+      - "/root/docker/git-nginx/auth"
84
+    docker_registry: "docker-registry:5000"
85
+    docker_registry_read: "{{ docker_registry }}"
86
+    registry_user: testuser
87
+    registry_password: testpassword
88
+    docker_user: nginx
89
+    docker_image_tag: latest
90
+    docker_command: /usr/bin/docker run --rm -i --name "{{ service_name }}" -p 8081:80 "{{ docker_registry_read }}/{{ service_name }}"
91
+  roles:
92
+    - role: deploy-docker

+ 9
- 0
molecule/nginx-user/prepare.yml View File

@@ -0,0 +1,9 @@
1
+---
2
+- name: Prepare
3
+  hosts: all
4
+  gather_facts: False
5
+  tasks:
6
+    - name: Install python for Ansible
7
+      raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
8
+      become: True
9
+      changed_when: False

+ 4
- 0
molecule/nginx-user/requirements.yml View File

@@ -0,0 +1,4 @@
1
+- src: git+https://git.digitales.cslabrecha.org/ansible-roles/docker.git
2
+  version: v1.0.1
3
+- src: git+https://git.digitales.cslabrecha.org/ansible-roles/docker-registry.git
4
+  version: v1.0.0

+ 3
- 0
molecule/nginx-user/templates/daemon.json.j2 View File

@@ -0,0 +1,3 @@
1
+{
2
+  "insecure-registries" : ["{{ hostvars['ui-registry-registry-instance'].ansible_default_ipv4.address }}:5000"]
3
+}

+ 9
- 0
molecule/nginx-user/templates/main.yml.j2 View File

@@ -0,0 +1,9 @@
1
+- name: Converge
2
+  hosts: all
3
+  vars:
4
+    docker_registry: "{{ hostvars['ui-registry-registry-debian-stretch64'].ansible_default_ipv4.address }}:5000"
5
+    docker_registry_read: "{{ hostvars['ui-registry-registry-debian-stretch64'].ansible_default_ipv4.address }}:5000"
6
+    docker_command: /usr/bin/docker run --rm --name "{{ service_name }}" -i -p 127.0.0.1:8080:8080 "{{ docker_registry_read }}/{{ service_name }}" --registry "{{ docker_registry_read }}"
7
+  roles:
8
+    - role: ui-registry
9
+

+ 99
- 0
molecule/nginx-user/tests/test_default.py View File

@@ -0,0 +1,99 @@
1
+import os
2
+import pytest
3
+import testinfra.utils.ansible_runner
4
+
5
+testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
6
+    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
7
+
8
+
9
+@pytest.mark.parametrize("package", [
10
+    ("docker-ce"),
11
+    ("python-pip"),
12
+])
13
+def test_required_packages_exist(host, package):
14
+    pkg = host.package(package)
15
+    assert pkg.is_installed
16
+
17
+
18
+@pytest.mark.parametrize("pip_package", [
19
+    ("docker-py"),
20
+])
21
+def test_required_pip_packages_exist(host, pip_package):
22
+    pip_packages = host.pip_package.get_packages()
23
+    assert pip_package in pip_packages
24
+
25
+
26
+def test_user_nginx_exist(host):
27
+    assert host.user('nginx').name == 'nginx'
28
+    assert host.user('nginx').shell == '/usr/sbin/nologin'
29
+
30
+# Test remotely build from image
31
+
32
+
33
+@pytest.mark.parametrize("directories", [
34
+    ("/root/docker/image-nginx/data"),
35
+    ("/root/docker/image-nginx/auth"),
36
+])
37
+def test_required_directories_exist(host, directories):
38
+    with host.sudo():
39
+        directory = host.file(directories)
40
+        assert directory.exists
41
+        assert directory.user == 'nginx'
42
+        assert directory.group == 'nginx'
43
+        assert oct(directory.mode) == '0700'
44
+
45
+
46
+def test_build_nginx_image_is_downloaded(host):
47
+    with host.sudo():
48
+        registry_exist = host.check_output(
49
+            'docker inspect --type=image docker-registry:5000/image-nginx',
50
+        )
51
+        assert not registry_exist == 'Error: No such image: ' + \
52
+                                     'docker-registry:5000/image-nginx'
53
+
54
+
55
+def test_build_nginx_is_enabled_and_running(host):
56
+    service = host.service('image-nginx')
57
+    assert service.is_enabled
58
+    assert service.is_running
59
+
60
+
61
+def test_build_nginx_is_working(host):
62
+    build_nginx_exist = host.check_output('curl localhost:8080')
63
+    assert '<h1>Welcome to nginx!</h1>' in build_nginx_exist
64
+
65
+
66
+# Test remotely build from git
67
+
68
+
69
+@pytest.mark.parametrize("directories", [
70
+    ("/root/docker/git-nginx/data"),
71
+    ("/root/docker/git-nginx/auth"),
72
+])
73
+def test_required_directories_exist_for_git_build(host, directories):
74
+    with host.sudo():
75
+        directory = host.file(directories)
76
+        assert directory.exists
77
+        assert directory.user == 'nginx'
78
+        assert directory.group == 'nginx'
79
+        assert oct(directory.mode) == '0700'
80
+
81
+
82
+def test_image_nginx_image_is_downloaded(host):
83
+    with host.sudo():
84
+        registry_exist = host.check_output(
85
+            'docker inspect --type=image docker-registry:5000/git-nginx',
86
+        )
87
+        assert not registry_exist == 'Error: No such image: ' + \
88
+                                     'docker-registry:5000/git-nginx'
89
+
90
+
91
+def test_image_nginx_is_enabled_and_running(host):
92
+    service = host.service('git-nginx')
93
+    assert service.is_enabled
94
+    assert service.is_running
95
+
96
+
97
+def test_image_nginx_is_working(host):
98
+    build_nginx_exist = host.check_output('curl localhost:8081')
99
+    assert '<h1>Welcome to nginx!</h1>' in build_nginx_exist

+ 31
- 2
tasks/main.yml View File

@@ -1,11 +1,29 @@
1 1
 ---
2
+- name: Create docker service group
3
+  become: True
4
+  group:
5
+    name: "{{ docker_group }}"
6
+    state: present
7
+  when:
8
+    - docker_group != 'root'
9
+
10
+- name: Create docker service user
11
+  become: True
12
+  user:
13
+    name: "{{ docker_user }}"
14
+    group: "{{ docker_group }}"
15
+    shell: /usr/sbin/nologin
16
+  when:
17
+    - docker_user != 'root'
18
+    - docker_group != 'root'
19
+
2 20
 - name: Create docker data directories
3 21
   become: True
4 22
   file:
5 23
     path: "{{ item }}"
6 24
     state: directory
7
-    owner: root
8
-    group: root
25
+    owner: "{{ docker_user }}"
26
+    group: "{{ docker_group }}"
9 27
     mode: 0700
10 28
   with_items: "{{ docker_data_directories}}"
11 29
 
@@ -98,6 +116,13 @@
98 116
     password: "{{ registry_password }}"
99 117
   when: remote_build == True
100 118
 
119
+- name: Test if image exists
120
+  become: True
121
+  command: docker inspect --type=image "{{ docker_registry }}/{{ service_name }}"
122
+  register: image_exists
123
+  changed_when: false
124
+  failed_when: false
125
+
101 126
 - name: Clone git repository remotely
102 127
   git:
103 128
     repo: "{{ git_repository }}"
@@ -105,6 +130,7 @@
105 130
     version: "{{ git_repository_tag }}"
106 131
   when:
107 132
     - docker_image is not defined
133
+    - image_exists.rc != '0'
108 134
     - remote_build == True
109 135
 
110 136
 - name: Build docker image remotely and push it to a registry with tag latest
@@ -116,6 +142,7 @@
116 142
     push: yes
117 143
   when:
118 144
     - docker_image is not defined
145
+    - image_exists.rc != 0
119 146
     - remote_build == True
120 147
 
121 148
 - name: Build docker image remotely and push it to a registry with real tag
@@ -127,6 +154,7 @@
127 154
     push: yes
128 155
   when:
129 156
     - docker_image is not defined
157
+    - image_exists.rc != 0
130 158
     - remote_build == True
131 159
 
132 160
 - name: Build docker image remotely and push it to a registry
@@ -137,6 +165,7 @@
137 165
     push: yes
138 166
   when:
139 167
     - docker_image is not defined
168
+    - image_exists.rc != 0
140 169
     - remote_build == True
141 170
 
142 171
 - name: Download image remotely from public registry

Loading…
Cancel
Save