Add docker image publishing

Change-Id: I6a09b73ffd0af6d2d23963b99c436b43410b1a46
This commit is contained in:
Mark Burnett 2018-05-22 11:09:40 -05:00
parent 4d65082663
commit 57466a94bf
4 changed files with 232 additions and 2 deletions

View File

@ -14,11 +14,72 @@
check:
jobs:
- airship-promenade-linter
- airship-docker-build-gate
gate:
jobs:
- airship-promenade-linter
- airship-docker-build-gate
post:
jobs:
- airship-docker-build-post
- job:
name: airship-promenade-linter
run: tools/gate/playbooks/zuul-linter.yaml
nodeset: openstack-helm-single-node
- job:
name: airship-docker-build-base
run: tools/gate/playbooks/docker-image-build.yaml
nodeset: ubuntu-xenial
- job:
name: airship-docker-build-gate
parent: airship-docker-build-base
vars:
publish: false
tags:
dynamic:
patch_set: true
- job:
name: airship-docker-build-post
parent: airship-docker-build-base
secrets:
- airship_dockerhub_creds
vars:
publish: true
tags:
dynamic:
branch: true
commit: true
static:
- latest
- secret:
name: airship_dockerhub_creds
data:
username: !encrypted/pkcs1-oaep
- KIl1I3Ki2tvGCCqlRNE0BPgkJo5Fw8St5eX9gCr9TncYtnvZuusDjlbvJS5jFd4o0Coj8
4LniBnmitm+mQiaPrWvM0Op4w8fA12oFA2bF6ZG/R2ZhzDzRSC7ucpoHoNDuZWeSh2v38
/rNPTRw4wgm6p3tPHeNLelBOkE8WbN/v6Wj03pKGBQC5Z1Ua1BD2DoNZqAfH2mnxrgEs1
r7jvc3Livw3qvJVqtleRBldxN89GOlH9uU6XUdlUVUBecEv03SfgrRXU5njGa16KunyOE
cs3VdLqh65EXrrx4vc7RPOx+Ql6wshDtD6vhF4zEthEfRdYUK+6rY368b9O5WdOSHJTL5
yMQwItXYn+4AzPKPwf4dHeJmbHhXp3q7aI57WlMip71ReJNGpS2S2WekNGrPrl/5Fp/Ns
XdpEZwoq2wAVDZe9nsfSAOLICxurQVawpOrJBcCot8zCe/7xYPHVBnvktV08oTIyykMOx
LYtl7Vq/0VwI+aoMfEUPBjuzApvgRIRi0IbkzrEJvD6Y17nrJ7uGbimyYhz76g2GrCPex
mCDZ7DReoX/ECIwpsurib51O7KH4uQh3fX5yrbnuXCQzfdCrX12b5uRPWnfFDMcj6rq4+
36N7tof6O6ooTl0fbQSGHK38Smaz7lWt69WW2FjT6IfNiI7rEV3aeACtfbG6JU=
password: !encrypted/pkcs1-oaep
- PleEYq7618O5ujy1Hy3a3nT2WLjYC46PPWnGwra2KKKfvoDSB/wfwLhZ9p9M9OODb5xHJ
Me0V+7bD0xBPK9VQIpOlj1BA3PXcyX6zzVvbCSJKmILFhg81++aGBUnSDuKe+Y7qPTgjI
l5hW69LJkyHtj6WVKWGo+7Le3kjbtEMZt7lqhtdhWlWfFNWoTDfpAzvj/14yRp5xTZPFt
zWYdj2grjjDmFjUHRbdbyUnfNEI+WZeXM5U+0F7jyAEkW3yqBeQV9InM1dhwNFqpGFflk
XXIamyjhf/DpT0e7kBDd8NKvb6m+ubPUE8HG+TLEqcSN0mOxfTYWHx4okrkAXrSDhYyi5
DWj0lfrr/YE7XE5NnPfmDEgo53lx8yiFmiQ4iz4UtAhjSftUm99EOrL2vFCRawKVW+liw
9nExTVGUexLiy+DcIAShVWEVwQPtIr/HcleuO4zLfaljNS9NHBke9lHrU+QZ3AZnkd0/A
wcA8OJdGauWiAMvSLqvQEWP3xRBiZe63OATtaWQTmOxzn+9crmIf1eVhCpiNEQNTlmTNe
fB0SPYANzVkAF8+ZAmcGBt24Ivc+uSBqrqzR7lFkbDaEbBrTjddKcfbUCoul0yye+qfPj
cow63ecH56++tyGyfMKpNL5WJ2GpbCPwiB8ZwDQZv7iQD0TpinhJxAmvt5qhcs=

View File

@ -0,0 +1,56 @@
- hosts: all
tasks:
- name: Install Docker (Debian)
block:
- apt:
name: "{{ item }}"
with_items:
- docker.io
- python-pip
when: ansible_os_family == 'Debian'
- pip:
name: docker
version: 2.7.0
become: True
- name: Debug tag generation inputs
block:
- debug:
var: publish
- debug:
var: tags
- debug:
var: zuul
- debug:
msg: "{{ tags | to_json }}"
- name: Determine tags
shell: echo '{{ tags | to_json }}' | python {{ zuul.project.src_dir }}/tools/image_tags.py
environment:
BRANCH: "{{ zuul.branch }}"
CHANGE: "{{ zuul.change }}"
COMMIT: "{{ zuul.newrev }}"
PATCHSET: "{{ zuul.patchset }}"
register: image_tags
- name: Debug computed tags
debug:
var: image_tags
- name: Build images
docker_image:
name: airshipit/promenade
dockerfile: "Dockerfile"
path: "{{ zuul.project.src_dir }}"
pull: false
tag: "{{ item }}"
with_items: "{{ image_tags.stdout_lines }}"
become: True
- name: Push to Docker Hub
block:
- command: docker login -u {{ airship_dockerhub_creds.username }} -p {{ airship_dockerhub_creds.password }}
no_log: True
- command: docker push docker.io/airshipit/promenade:{{ item }}
with_items: "{{ image_tags.stdout_lines }}"
when: publish

113
tools/image_tags.py Normal file
View File

@ -0,0 +1,113 @@
#!/bin/python
import json
import logging
import os
import sys
LOG = logging.getLogger(__name__)
LOG_FORMAT = '%(asctime)s %(levelname)-8s %(name)s:%(funcName)s [%(lineno)3d] %(message)s' # noqa
class TagGenExeception(Exception):
pass
def read_config(stream, env):
config = {}
try:
config['tags'] = json.load(stream)
except ValueError:
LOG.exception('Failed to decode JSON from input stream')
config['tags'] = {}
LOG.debug('Configuration after reading stream: %s', config)
config['context'] = {
'branch': env.get('BRANCH'),
'change': env.get('CHANGE'),
'commit': env.get('COMMIT'),
'ps': env.get('PATCHSET'),
}
LOG.info('Final configuration: %s', config)
return config
def build_tags(config):
tags = config.get('tags', {}).get('static', [])
LOG.debug('Dynamic tags: %s', tags)
tags.extend(build_dynamic_tags(config))
LOG.info('All tags: %s', tags)
return tags
def build_dynamic_tags(config):
dynamic_tags = []
dynamic_tags.extend(_build_branch_tag(config))
dynamic_tags.extend(_build_commit_tag(config))
dynamic_tags.extend(_build_ps_tag(config))
return dynamic_tags
def _build_branch_tag(config):
if _valid_dg(config, 'branch'):
return [config['context']['branch']]
else:
return []
def _build_commit_tag(config):
if _valid_dg(config, 'commit'):
return [config['context']['commit']]
else:
return []
def _build_ps_tag(config):
if _valid_dg(config, 'patch_set', 'change') and _valid_dg(
config, 'patch_set', 'ps'):
return [
'%s-%s' % (config['context']['change'], config['context']['ps'])
]
else:
return []
def _valid_dg(config, dynamic_tag, context_name=None):
if context_name is None:
context_name = dynamic_tag
if config.get('tags', {}).get('dynamic', {}).get(dynamic_tag):
if config.get('context', {}).get(context_name):
return True
else:
raise TagGenExeception('Dynamic tag "%s" requested, but "%s"'
' not found in context' % (dynamic_tag,
context_name))
else:
return False
def main():
config = read_config(sys.stdin, os.environ)
tags = build_tags(config)
for tag in tags:
print(tag)
if __name__ == '__main__':
logging.basicConfig(format=LOG_FORMAT, level=logging.WARNING)
try:
main()
except TagGenExeception:
LOG.exception('Failed to generate tags')
sys.exit(1)
except:
LOG.exception('Unexpected exception')
sys.exit(2)

View File

@ -31,7 +31,7 @@ commands =
[testenv:fmt]
deps = yapf==0.20.0
commands =
yapf -ir {toxinidir}/promenade {toxinidir}/tests
yapf -ir {toxinidir}/promenade {toxinidir}/tests {toxinidir}/tools/image_tags.py
[testenv:freeze]
deps = -r{toxinidir}/requirements-direct.txt
@ -52,5 +52,5 @@ deps =
yapf==0.20.0
flake8==3.5.0
commands =
yapf -rd {toxinidir}/promenade {toxinidir}/tests
yapf -rd {toxinidir}/promenade {toxinidir}/tests {toxinidir}/tools/image_tags.py
flake8 {toxinidir}/promenade