From 58077cea2c87c88950997e35e1f85239f23df689 Mon Sep 17 00:00:00 2001 From: Cory Hawkless Date: Fri, 2 Oct 2020 15:37:29 +0930 Subject: [PATCH] first commit --- dockerContainer.yml | 239 ++++++++++++++++++++++++++++++++++++++++ dockerVolume.yml | 143 ++++++++++++++++++++++++ dockerVolumeWrapper.yml | 7 ++ 3 files changed, 389 insertions(+) create mode 100644 dockerContainer.yml create mode 100644 dockerVolume.yml create mode 100644 dockerVolumeWrapper.yml diff --git a/dockerContainer.yml b/dockerContainer.yml new file mode 100644 index 0000000..393f55c --- /dev/null +++ b/dockerContainer.yml @@ -0,0 +1,239 @@ +# Define an empty list for the mappings to be assigned to +- set_fact: + mappings: [] + tags: always + + +# Container name always equals the Dict name +- set_fact: container_Name="{{item.value.name | default(item.key)}}" + tags: always +# Container hostname is the container name by default but can be overridden by setting 'hostname' +- set_fact: container_hostname="{{item.value.hostname | default (container_Name)}}" + tags: always +- set_fact: container_configDir="{{containerConfigDir}}/container-configs/{{container_Name}}/" + tags: always +# Create the config storage directory if it doesnt already exist +- name: "Create config dir" + file: + path: "{{container_configDir}}" + state: directory + tags: always + +#----------------------------------Check NETWORK---------------------------------- + #If the network varibale isnt defined then dont error out, set the network variable to an empty list +- name: Setup a blank network variable + set_fact: net_checked=[] + when: item.value.networks is not defined + tags: always +- name: Copy network variables into config + set_fact: net_checked="{{item.value.networks}}" + when: item.value.networks is defined + tags: always + +#- name: Show IP +# debug: msg="{{item.value.networks[0].ipv4_address | default(item.value.hostIP)}}" +#----------------------------------/Check NETWORK---------------------------------- + + + +#----------------------------------VOLUMES---------------------------------- +#Do all of the defined mappings exist? +#Create them if not +- set_fact: volumes_Defined=0 + tags: always +- name: Check if volumes have been defined or not + set_fact: + volumes_Defined: 1 + when: item.value.mappings.volumes is defined + tags: always +- name: "Volume mappings for {{container_Name}}" + include: dockerVolume.yml + with_dict: "{{item.value.mappings.volumes}}" + when: volumes_Defined == 1 + tags: always +#Note, the volume gets added to the mapping list in the dockerVolume.yml file becuase in there it knows the actual name of the volume +#----------------------------------/VOLUMES---------------------------------- + + + +#----------------------------------TEMPLATES---------------------------------- +#Only copy template files if there are templates defined in the incoming defintion dict +- set_fact: templates_Defined=0 + tags: always +- name: Check if templates have been defined or not + set_fact: + templates_Defined: 1 + when: item.value.mappings.templates is defined + tags: always +#- debug: msg="Templates not defined" +# when: templates_Defined is not defined +# +#- debug: msg="{{item.value.mappings.templates}}" + + #Copy all of the defined templates to the container host into the {{container_configDir}} ready for mapping to the container later +- name: "Template mappings for {{container_Name}}" + #Files will be copied to the 'config' dir as defined by container_configDir, they will be stored using their template file name but with the '.j2' stripped + #Need to ensure you dont have duplicate files names here + template: src="{{container_Name}}/{{outer_item.value.src}}" dest="{{container_configDir}}/{{outer_item.value.src.split(".j2")[0]}}" mode=0644 + with_dict: "{{item.value.mappings.templates}}" + loop_control: + loop_var: outer_item + when: templates_Defined ==1 and outer_item.value.generic is not defined + tags: always + + #Copy templates form a generic dir, allow ansible to search +- name: "Generic template mappings for {{container_Name}}" + #Files will be copied to the 'config' dir as defined by container_configDir, they will be stored using their template file name but with the '.j2' stripped + #Need to ensure you dont have duplicate files names here + template: src="{{outer_item.value.src}}" dest="{{container_configDir}}/{{outer_item.value.src.split(".j2")[0]}}" mode=0644 + with_dict: "{{item.value.mappings.templates}}" + loop_control: + loop_var: outer_item + when: templates_Defined ==1 and outer_item.value.generic is defined + tags: always + +- name: Append templated files to the mapping list + set_fact: + #build a list to pass to docker containing the source of the file(As on disk on the host) and the destination mount within the container + #Also allows the passing of 'params' which is rw or ro, defaults to rw + #mappings: "{{ mappings + ['type=\"bind\", source=\"' + container_configDir + item.value.src.split('.j2')[0] + '\",target=\"' + item.value.dest + '\",readonly=\"' + item.value.readonly | default('false') +'\"'] }}" + mappings: "{{ mappings + [ container_configDir + outer_item.value.src.split('.j2')[0] + ':' + outer_item.value.dest + ':' + outer_item.value.params | default('rw') ] }}" + with_dict: "{{item.value.mappings.templates}}" + loop_control: + loop_var: outer_item + when: templates_Defined ==1 + tags: always + + #type = "bind",target = "/usr/share/nginx/html",source = "/home/bfnadmin/www",readonly = false + + +#----------------------------------/TEMPLATES---------------------------------- + + + + + +#----------------------------------FILES---------------------------------- +- set_fact: files_Defined=0 + tags: always +#Only copy files if there are templates defined in the incoming defintion dict +- name: Check if Files have been defined or not + set_fact: + files_Defined: 1 + when: item.value.mappings.files is defined + tags: always +#Copy all of the defined files to the container host into the {{container_configDir}} ready for mapping to the container later +- name: "File mappings for {{container_Name}}" + #Files will be copied to the 'config' dir as defined by container_configDir, they will be stored using their file name + #Need to ensure you dont have duplicate files names here + copy: src="{{container_Name}}/{{outer_item.value.src}}" dest="{{container_configDir}}/{{outer_item.key}}" mode=0644 + with_dict: "{{item.value.mappings.files}}" + loop_control: + loop_var: outer_item + when: files_Defined == 1 and outer_item.value.generic is not defined and outer_item.value.src_text is not defined + tags: always +#Copy files from a generic dir, allow ansible to search +- name: "Generic File mappings for {{container_Name}}" + #Files will be copied to the 'config' dir as defined by container_configDir, they will be stored using their file name + #Need to ensure you dont have duplicate files names here + copy: src="{{outer_item.value.src}}" dest="{{container_configDir}}/{{outer_item.key}}" mode=0644 + with_dict: "{{item.value.mappings.files}}" + loop_control: + loop_var: outer_item + when: files_Defined == 1 and outer_item.value.generic is defined and outer_item.value.src_text is not defined + tags: always +#Create files based on the suplied src_text param +- name: "Text based file creation for {{container_Name}}" + #Files will be copied to the 'config' dir as defined by container_configDir, they will be stored using their file name + #Need to ensure you dont have duplicate files names here + copy: content="{{outer_item.value.src_text}}" dest="{{container_configDir}}/{{outer_item.key}}" mode=0644 + with_dict: "{{item.value.mappings.files}}" + loop_control: + loop_var: outer_item + when: files_Defined == 1 and outer_item.value.src_text is defined + tags: always + +- name: Append static remote files to the mapping list + set_fact: + #build a list to pass to docker containing the source of the file(As on disk on the host) and the destination mount within the container + #Also allows the passing of 'params' which is rw or ro, defaults to rw + mappings: "{{ mappings + [ container_configDir + outer_item.key + ':' + outer_item.value.dest + ':' + outer_item.value.params | default('rw') ] }}" + with_dict: "{{item.value.mappings.files}}" + loop_control: + loop_var: outer_item + when: files_Defined == 1 + tags: always +#----------------------------------/FILES---------------------------------- + + + + +#----------------------------------LOCAL---------------------------------- +#Local files alreeady exist on the host, commonly local time and or netns for namespace, could also be locl disk drives? +#Nothing gets copied for local mappings, just defintiions added to the mapping list +#Only copy files if there are local files defined in the incoming defintion dict +- set_fact: local_Defined=0 + tags: always +- name: Check if Local files have been defined or not + set_fact: + local_Defined: 1 + when: item.value.mappings.local is defined + tags: always +#- debug: msg="local not defined" +# when: local_Defined is not defined + +- name: Append static local files to the mapping list + set_fact: + #build a list to pass to docker containing the source of the file(As on disk on the host) and the destination mount within the container + #Also allows the passing of 'params' which is rw or ro, defaults to rw + #mappings: "{{ mappings + ['type=\"bind\", source=\"' + item.value.src + '\",target=\"' + item.value.dest + '\",readonly=\"' + item.value.readonly | default('false') +'\"'] }}" + mappings: "{{ mappings + [ outer_item.value.src + ':' + outer_item.value.dest + ':' + outer_item.value.params | default('rw') ] }}" + with_dict: "{{item.value.mappings.local}}" + loop_control: + loop_var: outer_item + when: local_Defined == 1 + tags: always +#----------------------------------/LOCAL---------------------------------- + + +#----------------------------------Check ENV---------------------------------- +#If the env varibale isnt defined then dont error out, set the network variable to an empty list +- name: Setup a blank env variable + set_fact: env_checked={} + when: item.value.env is not defined + tags: always +- name: Copy env variables into config + set_fact: env_checked="{{item.value.env}}" + when: item.value.env is defined + tags: always +#----------------------------------/Check ENV---------------------------------- + + + + +- name: "Container {{container_Name}}" + become: yes + docker_container: + name: "{{container_Name}}" + hostname: "{{item.value.hostname | default(container_Name)}}" + command: "{{item.value.command | default('') }}" + pull: "{{item.value.pull | default('false') }}" + recreate: "{{item.value.recreate | default('false') }}" + image: "{{item.value.image}}" + state: "{{item.value.start | default ('started')}}" + restart: "{{item.value.restart | default ('no')}}" + restart_policy: "{{item.value.restart_policy | default ('always')}}" + purge_networks: "{{item.value.purge_networks | default ('yes')}}" + networks: "{{net_checked}}" + volumes: "{{mappings}}" + env: "{{env_checked}}" + privileged: "{{item.value.privileged | default ('no')}}" + network_mode: "{{item.value.network_mode | default ('default')}}" + shm_size: "{{item.value.shm_size | default ('64M')}}" + ports: "{{item.value.ports | default ([])}}" + #log_driver: fluentd + #"{{item.value.ports | default ([json-file])}}" + #log_options: + # fluentd-sub-second-precision: true + # tag: myservice + tags: always diff --git a/dockerVolume.yml b/dockerVolume.yml new file mode 100644 index 0000000..c2701cb --- /dev/null +++ b/dockerVolume.yml @@ -0,0 +1,143 @@ +#- name: "Checking docker volume {{working_volume_name}}" +# debug: msg="Checking docker volume {{working_volume_name}}" + + +#----------------------------------CephFS Volume---------------------------------- +- set_fact: base_volume_name="cephFS_" + tags: always + +- name: Set working_volume_name(staticName not defined) + set_fact: working_volume_name="{{base_volume_name+container_Name + '_' + item.value.volumeName}}" + when: item.value.staticName is not defined + tags: always + +- name: Set working_volume_name(staticName IS defined) + set_fact: working_volume_name={{item.value.staticName}} + when: item.value.staticName is defined + tags: always + +- name: "Create {{ containerConfigDir }}/docker/cephFS" + file: + path: "{{containerConfigDir}}/docker/cephFS" + state: directory + recurse: no + when: item.value.type=="cephfs" + tags: always + +- name: "Create {{ containerConfigDir }}/docker/configs" + file: + path: "{{containerConfigDir}}/docker/configs" + state: directory + recurse: no + when: item.value.type=="cephfs" + tags: always + +- name: Add CephFS mount to fstab + lineinfile: + dest=/etc/fstab + backup=yes + state=present + line='none {{containerConfigDir}}/docker/cephFS fuse.ceph ceph.id=admin,_netdev,defaults 0 0' + register: fstab + tags: mount,always + when: item.value.type=="cephfs" + + +- name: Mount FSTab + shell: "mount -a" + args: + warn: false + when: fstab.changed + tags: mount,always + +- name: "Checking docker volume " + debug: msg="CephFS user {{ cephFS_user }} secret {{ cephFS_secret }}" + when: item.value.type=="cephfs" + tags: always + +- name: "Create docker volume - {{ working_volume_name }}" + docker_volume: + name: "{{ working_volume_name }}" + driver: n0r1skcom/docker-volume-cephfs + driver_options: + name="{{cephFS_user}}" + path="/container/{{working_volume_name}}" + secret="{{cephFS_secret}}" + monitors="{{ceph_Mons}}" + register: dockerVolume + tags: volume,always + when: item.value.type=="cephfs" + +# This is needed so that when Docker goes to mount the volume, the folder it's looking for actually exists +- name: Create {{containerConfigDir}}/docker/cephFS/container/{{working_volume_name}} + file: + path: "{{containerConfigDir}}/docker/cephFS/container/{{working_volume_name}}" + state: directory + recurse: no + when: dockerVolume.changed + tags: volume,always + when: item.value.type=="cephfs" + +- name: Append the volume to the container mapping list(mappings var defined in dockerContainer.yml) + set_fact: + mappings: "{{ mappings + [ working_volume_name + ':' + item.value.dest + ':' + item.value.params | default('rw') ] }}" + when: item.value.type=="cephfs" + tags: always +#----------------------------------/CephFS Volume---------------------------------- + +#----------------------------------Local Volume---------------------------------- +- set_fact: base_volume_name="local_" +- name: Set working_volume_name(staticName not defined) + set_fact: working_volume_name="{{base_volume_name+container_Name + '_' + item.value.volumeName}}" + when: item.value.staticName is not defined + tags: always + +- name: Set working_volume_name(staticName IS defined) + set_fact: working_volume_name={{item.value.staticName}} + when: item.value.staticName is defined + tags: always + +- name: "Create {{ containerConfigDir }}/docker/local" + file: + path: "{{containerConfigDir}}/docker/local" + state: directory + recurse: no + when: item.value.type=="local" + tags: always + +- name: "Create {{ containerConfigDir }}/docker/configs" + file: + path: "{{containerConfigDir}}/docker/configs" + state: directory + recurse: no + when: item.value.type=="local" + tags: always + +- name: "Create docker volume - {{ working_volume_name }}" + docker_volume: + name: "{{ working_volume_name }}" + driver: "local" + driver_options: + o: "bind" + device: "{{containerConfigDir}}/docker/local/container/{{working_volume_name}}" + type: "none" + register: dockerVolume + tags: volume,always + when: item.value.type=="local" + +# This is needed so that when Docker goes to mount the volume, the folder it's looking for actually exists +- name: Create {{containerConfigDir}}/docker/local/container/{{working_volume_name}} + file: + path: "{{containerConfigDir}}/docker/local/container/{{working_volume_name}}" + state: directory + recurse: no + when: dockerVolume.changed + tags: volume,always + when: item.value.type=="local" + +- name: Append the volume to the container mapping list(mappings var defined in dockerContainer.yml) + set_fact: + mappings: "{{ mappings + [ working_volume_name + ':' + item.value.dest + ':' + item.value.params | default('rw') ] }}" + when: item.value.type=="local" + tags: always +#----------------------------------/Local Volume---------------------------------- diff --git a/dockerVolumeWrapper.yml b/dockerVolumeWrapper.yml new file mode 100644 index 0000000..24df2bb --- /dev/null +++ b/dockerVolumeWrapper.yml @@ -0,0 +1,7 @@ +- debug: msg="{{item.value.mappings.volumes}}" + tags: always + +- name: "Volume mappings for {{container_Name}}" + include: dockerVolume.yml + with_dict: "{{item.value.mappings.volumes}}" + tags: always