예제 #1
0
    def _ProcessImage(self):
        fs_layers = []
        self._layer_map = {}
        for layer_id in self._v1_image.ancestry(self._v1_image.top()):
            blob = self._v1_image.layer(layer_id)
            digest = 'sha256:' + hashlib.sha256(blob).hexdigest()
            fs_layers += [{'blobSum': digest}]
            self._layer_map[digest] = layer_id

        self._manifest = util.Sign(
            json.dumps(
                {
                    'schemaVersion':
                    1,
                    'name':
                    'unused',
                    'tag':
                    'unused',
                    'architecture':
                    'amd64',
                    'fsLayers':
                    fs_layers,
                    'history': [{
                        'v1Compatibility':
                        self._v1_image.json(layer_id)
                    } for layer_id in self._v1_image.ancestry(
                        self._v1_image.top())],
                },
                sort_keys=True))
예제 #2
0
  def __init__(self, base, tar_gz,
               port, *envs):
    """Creates a new layer on top of a base with optional tar.gz, port or envs.

    Args:
      base: a base DockerImage for a new layer.
      tar_gz: an optional gzipped tarball passed as a string with filesystem
          changeset.
      port: an optional port to be exposed, passed as a string. For example:
          '8080/tcp'.
      *envs: environment variables passed as strings in the format:
          'ENV_ONE=val', 'ENV_TWO=val2'.
    """
    self._base = base

    unsigned_manifest, unused_signatures = util.DetachSignatures(
        self._base.manifest())
    manifest = json.loads(unsigned_manifest)
    v1_compat = json.loads(manifest['history'][0]['v1Compatibility'])

    if tar_gz:
      if isinstance(tar_gz, six.text_type):
        self._blob = tar_gz.encode()
      else:
        self._blob = tar_gz
      self._blob_sum = 'sha256:' + hashlib.sha256(self._blob).hexdigest()
      v1_compat['throwaway'] = False
    else:
      self._blob_sum = _EMPTY_LAYER_TAR_ID
      self._blob = ''
      v1_compat['throwaway'] = True

    manifest['fsLayers'].insert(0, {'blobSum': self._blob_sum})
    v1_compat['parent'] = v1_compat['id']
    v1_compat['id'] = binascii.hexlify(os.urandom(32)).decode('ascii')

    config = v1_compat.get('config', {}) or {}
    envs = list(envs)
    if envs:
      env_keys = [env.split('=')[0] for env in envs]
      old_envs = config.get('Env', []) or []
      old_envs = [env for env in old_envs if env.split('=')[0] not in env_keys]
      config['Env'] = old_envs + envs
    if port is not None:
      old_ports = config.get('ExposedPorts', {}) or {}
      old_ports[port] = {}
      config['ExposedPorts'] = old_ports
    v1_compat['config'] = config

    manifest['history'].insert(
        0, {'v1Compatibility': json.dumps(v1_compat, sort_keys=True)})
    self._manifest = util.Sign(json.dumps(manifest, sort_keys=True))
예제 #3
0
    def _ProcessImage(self):
        """Constructs schema 1 manifest from schema 2 manifest and config file."""
        manifest_schema2 = json.loads(self._v2_2_image.manifest())
        raw_config = self._v2_2_image.config_file()
        config = json.loads(raw_config)

        parent = ''

        histories = config.get('history', {})
        layer_count = len(histories)
        v2_layer_index = 0
        layers = manifest_schema2.get('layers', {})

        # from base to top
        fs_layers = []
        v1_histories = []
        for v1_layer_index, history in enumerate(histories):
            digest, media_type, v2_layer_index = self._GetSchema1LayerDigest(
                history, layers, v1_layer_index, v2_layer_index)

            if v1_layer_index != layer_count - 1:
                layer_id = self._GenerateV1LayerId(digest, parent)
                v1_compatibility = self._BuildV1Compatibility(
                    layer_id, parent, history)
            else:
                layer_id = self._GenerateV1LayerId(digest, parent, raw_config)
                v1_compatibility = self._BuildV1CompatibilityForTopLayer(
                    layer_id, parent, history, config)
            parent = layer_id
            fs_layers = [{
                'blobSum': digest,
                'mediaType': media_type
            }] + fs_layers
            v1_histories = [{
                'v1Compatibility': v1_compatibility
            }] + v1_histories

        manifest_schema1 = {
            'schemaVersion': 1,
            'name': 'unused',
            'tag': 'unused',
            'fsLayers': fs_layers,
            'history': v1_histories
        }
        if 'architecture' in config:
            manifest_schema1['architecture'] = config['architecture']
        self._manifest = v2_util.Sign(
            json.dumps(manifest_schema1, sort_keys=True))
예제 #4
0
    def _ProcessImage(self):
        """Constructs schema 1 manifest from schema 2 manifest and config file."""
        manifest_schema2 = json.loads(self._v2_2_image.manifest())
        raw_config = self._v2_2_image.config_file()
        config = json.loads(raw_config)

        parent = ''

        histories = config['history']
        layer_count = len(histories)
        v2_layer_index = 0
        layers = manifest_schema2['layers']

        # from base to top
        fs_layers = []
        v1_histories = []
        for v1_layer_index, history in enumerate(histories):
            digest, v2_layer_index = self._GetSchema1LayerDigest(
                history, layers, v1_layer_index, v2_layer_index)

            if v1_layer_index != layer_count - 1:
                layer_id = self._GenerateV1LayerId(digest, parent)
                v1_compatibility = self._BuildV1Compatibility(
                    layer_id, parent, history)
            else:
                layer_id = self._GenerateV1LayerId(digest, parent, raw_config)
                v1_compatibility = self._BuildV1CompatibilityForTopLayer(
                    layer_id, parent, history, config)
            parent = layer_id
            fs_layers = [{'blobSum': digest}] + fs_layers
            v1_histories = [{
                'v1Compatibility': v1_compatibility
            }] + v1_histories

        manifest_schema1 = {
            'schemaVersion': 1,
            'architecture': config['architecture'],
            'fsLayers': fs_layers,
            'history': v1_histories
        }
        self._manifest = v2_util.Sign(json.dumps(manifest_schema1))