Skip to content

Instantly share code, notes, and snippets.

@abitrolly
Last active April 30, 2019 11:13
Show Gist options
  • Save abitrolly/24ddc1c05db2239d4689e7479d0b063f to your computer and use it in GitHub Desktop.
Save abitrolly/24ddc1c05db2239d4689e7479d0b063f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
Pull images for `docker-compose build` with ignore filter.
https://github.com/docker/compose/issues/6668
The code is placed into public domain.
"""
import argparse
from subprocess import run
# parsing yaml in sorted way
import oyaml as yaml
def get_image_heir(composefile, debug=print):
debug('Parsing ' + composefile)
pose = yaml.safe_load(open(composefile, 'r'))
# pairs [level, image, locality]
# level - hierarchy starting from 0 (like indentation)
# image - image name to pull
# locality - None, 'local', `remote` - tested during run
imagestack = []
images = []
for key, val in pose['services'].items():
# --- val format ---
# app:
# image: registry.example.com/dev/backend_app:latest
# build:
# context: .
# dockerfile: ./srv/app/Dockerfile
# target: dev
# service = key
if 'build' not in val:
continue
dockerfile = val['build']['dockerfile']
debug('Found Dockerfile: ' + dockerfile)
# if 'target' in val['build']:
# target = val['build']['target']
# else:
# target = None
level = 0
with open(dockerfile, 'r') as dockery:
for line in dockery:
if line.startswith('FROM'):
# FROM python
image = line.split()[1]
debug(' Found image: ' + image)
if image not in images:
images.append(image)
imagestack.append([level, image, None])
return imagestack
def pull_images(imagestack, ignore=[], debug=print):
for level, image, locality in imagestack:
if image in ignore:
debug('Ignoring ' + image)
else:
debug('Pulling ' + image)
cmd = 'docker pull {}'.format(image)
run(cmd, shell=True, check=True)
if __name__ == '__main__':
desc = 'Pull images for `docker-compose build` with ignore filter.'
parser = argparse.ArgumentParser(description=desc)
parser.add_argument('composefile', metavar='<docker-compose.yml>',
help='docker-compose.yml with build sections')
parser.add_argument('-i', '--ignore', metavar='image1,image2,...',
help='images to ignore while pulling')
args = parser.parse_args()
composefile = args.composefile
ignore = [] if args.ignore is None else args.ignore.split(',')
imagestack = get_image_heir(composefile)
# for level, image, locality in imagestack:
# print("{}{} - {}".format(" "*level, image, locality))
pull_images(imagestack, ignore=ignore)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment