Added to vendor

This commit is contained in:
Priya Wadhwa
2018-02-28 12:22:10 -08:00
parent 3ce3dca56d
commit 66bb59ff12
602 changed files with 230607 additions and 5 deletions
@@ -0,0 +1,168 @@
/*
Copyright 2017 Google, Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package image
import (
"bytes"
"compress/gzip"
"encoding/json"
"io"
"io/ioutil"
"time"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
digest "github.com/opencontainers/go-digest"
)
type MutableSource struct {
ProxySource
mfst *manifest.Schema2
cfg *manifest.Schema2Image
extraBlobs map[string][]byte
extraLayers []digest.Digest
}
func NewMutableSource(r types.ImageReference) (*MutableSource, error) {
src, err := r.NewImageSource(nil)
if err != nil {
return nil, err
}
img, err := r.NewImage(nil)
if err != nil {
return nil, err
}
ms := &MutableSource{
ProxySource: ProxySource{
Ref: r,
ImageSource: src,
img: img,
},
extraBlobs: make(map[string][]byte),
}
if err := ms.populateManifestAndConfig(); err != nil {
return nil, err
}
return ms, nil
}
// Manifest marshals the stored manifest to the byte format.
func (m *MutableSource) GetManifest(_ *digest.Digest) ([]byte, string, error) {
if err := m.saveConfig(); err != nil {
return nil, "", err
}
s, err := json.Marshal(m.mfst)
if err != nil {
return nil, "", err
}
return s, manifest.DockerV2Schema2MediaType, err
}
// populateManifestAndConfig parses the raw manifest and configs, storing them on the struct.
func (m *MutableSource) populateManifestAndConfig() error {
mfstBytes, _, err := m.ProxySource.GetManifest(nil)
if err != nil {
return err
}
m.mfst, err = manifest.Schema2FromManifest(mfstBytes)
if err != nil {
return err
}
bi := types.BlobInfo{Digest: m.mfst.ConfigDescriptor.Digest}
r, _, err := m.GetBlob(bi)
if err != nil {
return err
}
cfgBytes, err := ioutil.ReadAll(r)
if err != nil {
return err
}
return json.Unmarshal(cfgBytes, &m.cfg)
}
// GetBlob first checks the stored "extra" blobs, then proxies the call to the original source.
func (m *MutableSource) GetBlob(bi types.BlobInfo) (io.ReadCloser, int64, error) {
if b, ok := m.extraBlobs[bi.Digest.String()]; ok {
return ioutil.NopCloser(bytes.NewReader(b)), int64(len(b)), nil
}
return m.ImageSource.GetBlob(bi)
}
func gzipBytes(b []byte) ([]byte, error) {
buf := bytes.NewBuffer([]byte{})
w := gzip.NewWriter(buf)
_, err := w.Write(b)
w.Close()
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// appendLayer appends an uncompressed blob to the image, preserving the invariants required across the config and manifest.
func (m *MutableSource) AppendLayer(content []byte) error {
compressedBlob, err := gzipBytes(content)
if err != nil {
return err
}
dgst := digest.FromBytes(compressedBlob)
// Add the layer to the manifest.
descriptor := manifest.Schema2Descriptor{
MediaType: manifest.DockerV2Schema2LayerMediaType,
Size: int64(len(content)),
Digest: dgst,
}
m.mfst.LayersDescriptors = append(m.mfst.LayersDescriptors, descriptor)
m.extraBlobs[dgst.String()] = compressedBlob
m.extraLayers = append(m.extraLayers, dgst)
// Also add it to the config.
diffID := digest.FromBytes(content)
m.cfg.RootFS.DiffIDs = append(m.cfg.RootFS.DiffIDs, diffID)
history := manifest.Schema2History{
Created: time.Now(),
Author: "container-diff",
}
m.cfg.History = append(m.cfg.History, history)
return nil
}
// saveConfig marshals the stored image config, and updates the references to it in the manifest.
func (m *MutableSource) saveConfig() error {
cfgBlob, err := json.Marshal(m.cfg)
if err != nil {
return err
}
cfgDigest := digest.FromBytes(cfgBlob)
m.extraBlobs[cfgDigest.String()] = cfgBlob
m.mfst.ConfigDescriptor = manifest.Schema2Descriptor{
MediaType: manifest.DockerV2Schema2ConfigMediaType,
Size: int64(len(cfgBlob)),
Digest: cfgDigest,
}
return nil
}
@@ -0,0 +1,63 @@
/*
Copyright 2017 Google, Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package image
import (
"github.com/containers/image/types"
)
// ProxySource is a type that implements types.ImageSource by proxying all calls to an underlying implementation.
type ProxySource struct {
Ref types.ImageReference
types.ImageSource
img types.Image
}
func NewProxySource(ref types.ImageReference) (*ProxySource, error) {
src, err := ref.NewImageSource(nil)
if err != nil {
return nil, err
}
img, err := ref.NewImage(nil)
if err != nil {
return nil, err
}
return &ProxySource{
Ref: ref,
img: img,
ImageSource: src,
}, nil
}
func (p *ProxySource) Reference() types.ImageReference {
return p.Ref
}
func (p *ProxySource) LayerInfosForCopy() []types.BlobInfo {
return nil
}
// ProxyReference implements types.Reference by proxying calls to an underlying implementation.
type ProxyReference struct {
types.ImageReference
Src types.ImageSource
}
func (p *ProxyReference) NewImageSource(ctx *types.SystemContext) (types.ImageSource, error) {
return p.Src, nil
}