...

Source file src/github.com/google/go-containerregistry/pkg/v1/daemon/write.go

Documentation: github.com/google/go-containerregistry/pkg/v1/daemon

     1  // Copyright 2018 Google LLC All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package daemon
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  
    21  	"github.com/google/go-containerregistry/pkg/name"
    22  	v1 "github.com/google/go-containerregistry/pkg/v1"
    23  	"github.com/google/go-containerregistry/pkg/v1/tarball"
    24  )
    25  
    26  // Tag adds a tag to an already existent image.
    27  func Tag(src, dest name.Tag, options ...Option) error {
    28  	o, err := makeOptions(options...)
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	return o.client.ImageTag(o.ctx, src.String(), dest.String())
    34  }
    35  
    36  // Write saves the image into the daemon as the given tag.
    37  func Write(tag name.Tag, img v1.Image, options ...Option) (string, error) {
    38  	o, err := makeOptions(options...)
    39  	if err != nil {
    40  		return "", err
    41  	}
    42  
    43  	// If we already have this image by this image ID, we can skip loading it.
    44  	id, err := img.ConfigName()
    45  	if err != nil {
    46  		return "", fmt.Errorf("computing image ID: %w", err)
    47  	}
    48  	if resp, _, err := o.client.ImageInspectWithRaw(o.ctx, id.String()); err == nil {
    49  		want := tag.String()
    50  
    51  		// If we already have this tag, we can skip tagging it.
    52  		for _, have := range resp.RepoTags {
    53  			if have == want {
    54  				return "", nil
    55  			}
    56  		}
    57  
    58  		return "", o.client.ImageTag(o.ctx, id.String(), want)
    59  	}
    60  
    61  	pr, pw := io.Pipe()
    62  	go func() {
    63  		pw.CloseWithError(tarball.Write(tag, img, pw))
    64  	}()
    65  
    66  	// write the image in docker save format first, then load it
    67  	resp, err := o.client.ImageLoad(o.ctx, pr, false)
    68  	if err != nil {
    69  		return "", fmt.Errorf("error loading image: %w", err)
    70  	}
    71  	defer resp.Body.Close()
    72  	b, err := io.ReadAll(resp.Body)
    73  	response := string(b)
    74  	if err != nil {
    75  		return response, fmt.Errorf("error reading load response body: %w", err)
    76  	}
    77  	return response, nil
    78  }
    79  

View as plain text