github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/docker/image.go (about)

     1  package docker
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/telepresenceio/telepresence/v2/pkg/proc"
    13  )
    14  
    15  // BuildImage builds an image from source. Stdout is silenced during those operations. The
    16  // image ID is returned.
    17  func BuildImage(ctx context.Context, context string, buildArgs []string) (string, error) {
    18  	args := append([]string{"build", "--quiet"}, buildArgs...)
    19  	st, err := os.Stat(context)
    20  	if err != nil {
    21  		return "", err
    22  	}
    23  	if st.Mode().IsRegular() {
    24  		var fn string
    25  		dir := filepath.Dir(context)
    26  		if dir == "." {
    27  			fn = context
    28  		} else {
    29  			fn, err = filepath.Abs(context)
    30  			if err != nil {
    31  				return "", err
    32  			}
    33  		}
    34  		context = dir
    35  		args = append(args, "--file", fn)
    36  	}
    37  	cmd := proc.StdCommand(ctx, "docker", append(args, context)...)
    38  	var out bytes.Buffer
    39  	cmd.Stdout = &out
    40  	if err := cmd.Run(); err != nil {
    41  		return "", err
    42  	}
    43  	return strings.TrimSpace(out.String()), nil
    44  }
    45  
    46  // PullImage checks if the given image exists locally by doing docker image inspect. A docker pull is
    47  // performed if no local image is found. Stdout is silenced during those operations.
    48  func PullImage(ctx context.Context, image string) error {
    49  	cli, err := GetClient(ctx)
    50  	if err != nil {
    51  		return err
    52  	}
    53  	_, _, err = cli.ImageInspectWithRaw(ctx, image)
    54  	if err == nil {
    55  		// Image exists in the local cache, so don't bother pulling it.
    56  		return nil
    57  	}
    58  	cmd := proc.StdCommand(ctx, "docker", "pull", image)
    59  	// Docker run will put the pull logs in stderr, but docker pull will put them in stdout.
    60  	// We discard them here, so they don't spam the user. They'll get errors through stderr if it comes to it.
    61  	cmd.Stdout = io.Discard
    62  
    63  	// Only print stderr if the return code is non-zero
    64  	var stderr bytes.Buffer
    65  	cmd.Stderr = &stderr
    66  
    67  	err = cmd.Run()
    68  	if err != nil {
    69  		fmt.Fprint(os.Stderr, stderr.String())
    70  		return err
    71  	}
    72  
    73  	return nil
    74  }