|  | {% from "docker/map.jinja" import client with context %} | 
|  |  | 
|  | include: | 
|  | - docker.client | 
|  |  | 
|  | {%- for app, compose in client.stack.iteritems() %} | 
|  | {%- if compose.service is defined %} | 
|  | {%- if compose.secrets is defined %} | 
|  | {%- for secret, values in compose.secrets.iteritems() %} | 
|  | {%- if values['external'] is defined and values['external'] == true %} | 
|  | docker_secret_{{ secret }}: | 
|  | cmd.run: | 
|  | - name: > | 
|  | retry=5 | 
|  | i=1; | 
|  | while [[ $i -lt $retry ]]; do | 
|  | echo "{{ values['value'] }}" | docker secret create {{ secret }} -; | 
|  | ret=$?; | 
|  | if [[ $ret -eq 0 ]]; then echo 'Secret created'; break; | 
|  | else | 
|  | echo "Secret creation failed, retrying in 3 seconds.." >&2; | 
|  | sleep 3; | 
|  | i=$(( i + 1 )); | 
|  | fi; | 
|  | if [[ $i -ge $retry ]]; then | 
|  | echo "Secret creation failed!"; exit 1; | 
|  | fi; | 
|  | done; | 
|  | - shell: /bin/bash | 
|  | - user: {{ compose.user|default("root") }} | 
|  | - unless: "docker secret inspect {{ secret }}" | 
|  | - output_loglevel: quiet | 
|  | - require_in: | 
|  | - cmd: docker_stack_{{ app }} | 
|  | - cmd: docker_stack_{{ app }}_update | 
|  | {%- endif %} | 
|  | {%- endfor %} | 
|  | {%- endif %} | 
|  |  | 
|  | docker_{{ app }}_dir: | 
|  | file.directory: | 
|  | - name: {{ client.compose.base }}/{{ app }} | 
|  | - makedirs: true | 
|  |  | 
|  | docker_{{ app }}_compose: | 
|  | file.managed: | 
|  | - name: {{ client.compose.base }}/{{ app }}/docker-compose.yml | 
|  | - source: salt://docker/files/docker-compose.yml | 
|  | - template: jinja | 
|  | - mode: 600 | 
|  | - defaults: | 
|  | compose: {{ compose }} | 
|  | volume: {{ compose.volume|default({}) }} | 
|  | service: {{ compose.service }} | 
|  | network: {{ compose.network|default({}) }} | 
|  | secrets: {{ compose.secrets|default({}) }} | 
|  | - require: | 
|  | - file: docker_{{ app }}_dir | 
|  |  | 
|  | {%- if compose.environment is defined %} | 
|  |  | 
|  | docker_{{ app }}_env: | 
|  | file.managed: | 
|  | - name: {{ client.compose.base }}/{{ app }}/.env | 
|  | - source: salt://docker/files/docker-env | 
|  | - template: jinja | 
|  | - user: {{ compose.user|default("root") }} | 
|  | - mode: 640 | 
|  | - defaults: | 
|  | env: {{ compose.environment }} | 
|  | - require: | 
|  | - file: docker_{{ app }}_dir | 
|  |  | 
|  | {%- else %} | 
|  |  | 
|  | docker_{{ app }}_env: | 
|  | file.absent: | 
|  | - name: {{ client.compose.base }}/{{ app }}/.env | 
|  |  | 
|  | {%- endif %} | 
|  |  | 
|  | {%- for name, service in compose.service.iteritems() %} | 
|  | {%- for volume in service.get('volumes', []) %} | 
|  | {%- if volume is string and ':' in volume %} | 
|  | {%- set path = volume.split(':')[0] %} | 
|  | {%- elif volume is mapping and volume.get('type', 'bind') == 'bind' %} | 
|  | {%- set path = volume.source %} | 
|  | {%- else %} | 
|  | {%- set path = None %} | 
|  | {%- endif %} | 
|  |  | 
|  | {%- if path != None and path not in compose.get('volume', {}).keys() %} | 
|  | docker_{{ app }}_{{ name }}_volume_{{ path }}: | 
|  | file.directory: | 
|  | - name: {{ path }} | 
|  | - makedirs: true | 
|  | - unless: "test -e {{ path }}" | 
|  | {%- endif %} | 
|  | {%- endfor %} | 
|  | {%- endfor %} | 
|  |  | 
|  | {%- if compose.enabled|default(True) %} | 
|  |  | 
|  | docker_stack_{{ app }}: | 
|  | cmd.run: | 
|  | - name: > | 
|  | retry=5 | 
|  | i=1; | 
|  | while [[ $i -lt $retry ]]; do | 
|  | {%- if compose.registry_auth|default(False) %} | 
|  | docker stack deploy --with-registry-auth --compose-file docker-compose.yml {{ app }}; | 
|  | {%- else %} | 
|  | docker stack deploy --compose-file docker-compose.yml {{ app }}; | 
|  | {%- endif %} | 
|  | ret=$?; | 
|  | if [[ $ret -eq 0 ]]; then echo 'Stack created'; break; | 
|  | else | 
|  | echo "Stack creation failed, retrying in 3 seconds.." >&2; | 
|  | sleep 3; | 
|  | i=$(( i + 1 )); | 
|  | fi; | 
|  | if [[ $i -ge $retry ]]; then | 
|  | echo "Stack creation failed!"; exit 1; | 
|  | fi; | 
|  | done; | 
|  | - shell: /bin/bash | 
|  | - cwd: {{ client.compose.base }}/{{ app }} | 
|  | - user: {{ compose.user|default("root") }} | 
|  | - unless: "docker stack ls | grep '{{ app }}'" | 
|  | - require: | 
|  | - file: docker_{{ app }}_env | 
|  | - file: docker_{{ app }}_compose | 
|  |  | 
|  | docker_stack_{{ app }}_update: | 
|  | cmd.wait: | 
|  | - name: > | 
|  | retry=5 | 
|  | i=1; | 
|  | while [[ $i -lt $retry ]]; do | 
|  | {%- if compose.registry_auth|default(False) %} | 
|  | docker stack deploy --with-registry-auth --compose-file docker-compose.yml {{ app }}; | 
|  | {%- else %} | 
|  | docker stack deploy --compose-file docker-compose.yml {{ app }}; | 
|  | {%- endif %} | 
|  | ret=$?; | 
|  | if [[ $ret -eq 0 ]]; then echo 'Stack updated'; break; | 
|  | else | 
|  | echo "Stack update failed, retrying in 3 seconds.." >&2; | 
|  | sleep 3; | 
|  | i=$(( i + 1 )); | 
|  | fi; | 
|  | if [[ $i -ge $retry ]]; then | 
|  | echo "Stack update failed!"; exit 1; | 
|  | fi; | 
|  | done; | 
|  | - shell: /bin/bash | 
|  | - cwd: {{ client.compose.base }}/{{ app }} | 
|  | - user: {{ compose.user|default("root") }} | 
|  | - require: | 
|  | - cmd: docker_stack_{{ app }} | 
|  | - watch: | 
|  | - file: docker_{{ app }}_env | 
|  | - file: docker_{{ app }}_compose | 
|  |  | 
|  | {%- else %} | 
|  |  | 
|  | docker_remove_{{ app }}: | 
|  | cmd.run: | 
|  | - name: docker stack rm {{ app }} | 
|  | - user: {{ compose.user|default("root") }} | 
|  | - onlyif: "docker stack ls | grep '{{ app }}'" | 
|  |  | 
|  | {%- endif %} | 
|  |  | 
|  | {%- else %} | 
|  |  | 
|  | {#- | 
|  | No stack.service is defined so we can add support for deploying using | 
|  | bundle file, etc. | 
|  | #} | 
|  |  | 
|  | {%- endif %} | 
|  | {%- endfor %} |