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))
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))
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))
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))