def discover_image_tag(self, image, tag_from_label=None):
        dockerc = Client(base_url='unix://var/run/docker.sock', version='auto')

        image_name, colon, tag = image.partition(':')
        if not tag:
            tag = 'latest'
        image = '%s:%s' % (image_name, tag)

        self._pull_retry(dockerc, image)
        i = dockerc.inspect_image(image)
        labels = i['Config']['Labels']

        label_keys = ', '.join(labels.keys())

        if not tag_from_label:
            raise ImageUploaderException(
                'No label specified. Available labels: %s' % label_keys)

        tag_label = labels.get(tag_from_label)
        if tag_label is None:
            raise ImageUploaderException(
                'Image %s has no label %s. Available labels: %s' %
                (image, tag_from_label, label_keys))

        # confirm the tag exists by pulling it, which should be fast
        # because that image has just been pulled
        versioned_image = '%s:%s' % (image_name, tag_label)
        self._pull_retry(dockerc, versioned_image)
        return tag_label
    def _inspect(image, insecure=False):

        cmd = ['skopeo', 'inspect']

        if insecure:
            cmd.append('--tls-verify=false')
        cmd.append(image)

        LOG.info('Running %s' % ' '.join(cmd))
        env = os.environ.copy()
        process = subprocess.Popen(cmd,
                                   env=env,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        out, err = process.communicate()
        if process.returncode != 0:
            not_found_msgs = (
                u'manifest unknown',
                # returned by docker.io
                u'requested access to the resource is denied')
            if any(n in err for n in not_found_msgs):
                raise ImageNotFoundException('Not found image: %s\n%s' %
                                             (image, err))
            raise ImageUploaderException('Error inspecting image: %s\n%s' %
                                         (image, err))
        return json.loads(out)
Beispiel #3
0
    def _push(dockerc, image, tag=None):
        LOG.debug('Pushing %s' % image)

        for line in dockerc.push(image, tag=tag, stream=True):
            status = json.loads(line)
            if 'error' in status:
                LOG.warning('docker push failed: %s' % status['error'])
                raise ImageUploaderException('Could not push image %s' % image)
Beispiel #4
0
    def _discover_tag_from_inspect(i, image, tag_from_label=None,
                                   fallback_tag=None):
        labels = i.get('Labels', {})

        label_keys = ', '.join(labels.keys())

        if not tag_from_label:
            raise ImageUploaderException(
                'No label specified. Available labels: %s' % label_keys
            )

        if "{" in tag_from_label:
            try:
                tag_label = tag_from_label.format(**labels)
            except ValueError as e:
                raise ImageUploaderException(e)
            except KeyError as e:
                if fallback_tag:
                    tag_label = fallback_tag
                else:
                    raise ImageUploaderException(
                        'Image %s %s. Available labels: %s' %
                        (image, e, label_keys)
                    )
        else:
            tag_label = labels.get(tag_from_label)
            if tag_label is None:
                if fallback_tag:
                    tag_label = fallback_tag
                else:
                    raise ImageUploaderException(
                        'Image %s has no label %s. Available labels: %s' %
                        (image, tag_from_label, label_keys)
                    )

        # confirm the tag exists by checking for an entry in RepoTags
        repo_tags = i.get('RepoTags', [])
        if tag_label not in repo_tags:
            raise ImageUploaderException(
                'Image %s has no tag %s.\nAvailable tags: %s' %
                (image, tag_label, ', '.join(repo_tags))
            )
        return tag_label
 def _pull_retry(self, dockerc, image, tag=None):
     retval = -1
     count = 0
     while retval != 0:
         if count >= 5:
             raise ImageUploaderException('Could not pull image %s' % image)
         count += 1
         retval = self._pull(dockerc, image, tag)
         if retval != 0:
             time.sleep(3)
             self.logger.warning('retrying pulling image: %s' % image)
Beispiel #6
0
    def test_images_match(self, mock_inspect):
        mock_inspect.side_effect = [{'Digest': 'a'}, {'Digest': 'b'}]
        self.assertFalse(self.uploader._images_match('foo', 'bar', set()))

        mock_inspect.side_effect = [{'Digest': 'a'}, {'Digest': 'a'}]
        self.assertTrue(self.uploader._images_match('foo', 'bar', set()))

        mock_inspect.side_effect = [{}, {'Digest': 'b'}]
        self.assertFalse(self.uploader._images_match('foo', 'bar', set()))

        mock_inspect.side_effect = [{'Digest': 'a'}, {}]
        self.assertFalse(self.uploader._images_match('foo', 'bar', set()))

        mock_inspect.side_effect = [None, None]
        self.assertFalse(self.uploader._images_match('foo', 'bar', set()))

        mock_inspect.side_effect = ImageUploaderException()
        self.assertFalse(self.uploader._images_match('foo', 'bar', set()))
Beispiel #7
0
    def _inspect(image, insecure=False):

        cmd = ['skopeo', 'inspect']

        if insecure:
            cmd.append('--tls-verify=false')
        cmd.append(image)

        LOG.info('Running %s' % ' '.join(cmd))
        env = os.environ.copy()
        process = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        out, err = process.communicate()
        if process.returncode != 0:
            raise ImageUploaderException('Error inspecting image: %s\n%s' %
                                         (image, err))
        return json.loads(out)
 def run_modify_playbook(modify_role, modify_vars, source_image,
                         target_image, append_tag):
     vars = {}
     if modify_vars:
         vars.update(modify_vars)
     vars['source_image'] = source_image
     vars['target_image'] = target_image
     vars['modified_append_tag'] = append_tag
     LOG.info('Playbook variables: \n%s' %
              yaml.safe_dump(vars, default_flow_style=False))
     playbook = [{
         'hosts':
         'localhost',
         'tasks': [{
             'name': 'Import role %s' % modify_role,
             'import_role': {
                 'name': modify_role
             },
             'vars': vars
         }]
     }]
     LOG.info('Playbook: \n%s' %
              yaml.safe_dump(playbook, default_flow_style=False))
     work_dir = tempfile.mkdtemp(prefix='tripleo-modify-image-playbook-')
     try:
         action = ansible.AnsiblePlaybookAction(playbook=playbook,
                                                work_dir=work_dir,
                                                verbosity=3)
         result = action.run(None)
         log_path = result.get('log_path')
         if log_path and os.path.isfile(log_path):
             with open(log_path) as f:
                 LOG.info(f.read())
         shutil.rmtree(work_dir)
     except processutils.ProcessExecutionError as e:
         LOG.error('%s\nError running playbook in directory: %s' %
                   (e.stdout, work_dir))
         raise ImageUploaderException('Modifying image %s failed' %
                                      target_image)
 def get_uploader(uploader):
     if uploader == 'docker':
         return DockerImageUploader()
     raise ImageUploaderException('Unknown image uploader type')