github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/domain/infra/tunnel/images.go (about)

     1  package tunnel
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"os"
     7  
     8  	"github.com/containers/common/pkg/config"
     9  	"github.com/containers/image/v5/docker/reference"
    10  	images "github.com/containers/libpod/pkg/bindings/images"
    11  	"github.com/containers/libpod/pkg/domain/entities"
    12  	"github.com/containers/libpod/pkg/domain/utils"
    13  	utils2 "github.com/containers/libpod/utils"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
    18  	found, err := images.Exists(ir.ClientCxt, nameOrId)
    19  	return &entities.BoolReport{Value: found}, err
    20  }
    21  
    22  func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
    23  	report := entities.ImageDeleteReport{}
    24  
    25  	for _, id := range nameOrId {
    26  		results, err := images.Remove(ir.ClientCxt, id, &opts.Force)
    27  		if err != nil {
    28  			return nil, err
    29  		}
    30  		for _, e := range results {
    31  			if a, ok := e["Deleted"]; ok {
    32  				report.Deleted = append(report.Deleted, a)
    33  			}
    34  
    35  			if a, ok := e["Untagged"]; ok {
    36  				report.Untagged = append(report.Untagged, a)
    37  			}
    38  		}
    39  	}
    40  	return &report, nil
    41  }
    42  
    43  func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
    44  	images, err := images.List(ir.ClientCxt, &opts.All, opts.Filters)
    45  
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	is := make([]*entities.ImageSummary, len(images))
    51  	for i, img := range images {
    52  		hold := entities.ImageSummary{}
    53  		if err := utils.DeepCopy(&hold, img); err != nil {
    54  			return nil, err
    55  		}
    56  		is[i] = &hold
    57  	}
    58  	return is, nil
    59  }
    60  
    61  func (ir *ImageEngine) History(ctx context.Context, nameOrId string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) {
    62  	results, err := images.History(ir.ClientCxt, nameOrId)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	history := entities.ImageHistoryReport{
    68  		Layers: make([]entities.ImageHistoryLayer, len(results)),
    69  	}
    70  
    71  	for i, layer := range results {
    72  		hold := entities.ImageHistoryLayer{}
    73  		_ = utils.DeepCopy(&hold, layer)
    74  		history.Layers[i] = hold
    75  	}
    76  	return &history, nil
    77  }
    78  
    79  func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
    80  	results, err := images.Prune(ir.ClientCxt, &opts.All, opts.Filters)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	report := entities.ImagePruneReport{
    86  		Report: entities.Report{
    87  			Id:  results,
    88  			Err: nil,
    89  		},
    90  		Size: 0,
    91  	}
    92  	return &report, nil
    93  }
    94  
    95  func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
    96  	pulledImages, err := images.Pull(ir.ClientCxt, rawImage, options)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	return &entities.ImagePullReport{Images: pulledImages}, nil
   101  }
   102  
   103  func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
   104  	for _, newTag := range tags {
   105  		var (
   106  			tag, repo string
   107  		)
   108  		ref, err := reference.Parse(newTag)
   109  		if err != nil {
   110  			return err
   111  		}
   112  		if t, ok := ref.(reference.Tagged); ok {
   113  			tag = t.Tag()
   114  		}
   115  		if r, ok := ref.(reference.Named); ok {
   116  			repo = r.Name()
   117  		}
   118  		if len(repo) < 1 {
   119  			return errors.Errorf("invalid image name %q", nameOrId)
   120  		}
   121  		if err := images.Tag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
   122  			return err
   123  		}
   124  	}
   125  	return nil
   126  }
   127  
   128  func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
   129  	for _, newTag := range tags {
   130  		var (
   131  			tag, repo string
   132  		)
   133  		ref, err := reference.Parse(newTag)
   134  		if err != nil {
   135  			return err
   136  		}
   137  		if t, ok := ref.(reference.Tagged); ok {
   138  			tag = t.Tag()
   139  		}
   140  		if r, ok := ref.(reference.Named); ok {
   141  			repo = r.Name()
   142  		}
   143  		if len(repo) < 1 {
   144  			return errors.Errorf("invalid image name %q", nameOrId)
   145  		}
   146  		if err := images.Untag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
   147  			return err
   148  		}
   149  	}
   150  	return nil
   151  }
   152  
   153  func (ir *ImageEngine) Inspect(_ context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
   154  	report := entities.ImageInspectReport{}
   155  	for _, id := range names {
   156  		r, err := images.GetImage(ir.ClientCxt, id, &opts.Size)
   157  		if err != nil {
   158  			report.Errors[id] = err
   159  		}
   160  		report.Images = append(report.Images, r)
   161  	}
   162  	return &report, nil
   163  }
   164  
   165  func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) {
   166  	f, err := os.Open(opts.Input)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  	defer f.Close()
   171  	return images.Load(ir.ClientCxt, f, &opts.Name)
   172  }
   173  
   174  func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
   175  	var (
   176  		err       error
   177  		sourceURL *string
   178  		f         *os.File
   179  	)
   180  	if opts.SourceIsURL {
   181  		sourceURL = &opts.Source
   182  	} else {
   183  		f, err = os.Open(opts.Source)
   184  		if err != nil {
   185  			return nil, err
   186  		}
   187  	}
   188  	return images.Import(ir.ClientCxt, opts.Changes, &opts.Message, &opts.Reference, sourceURL, f)
   189  }
   190  
   191  func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error {
   192  	return images.Push(ir.ClientCxt, source, destination, options)
   193  }
   194  
   195  func (ir *ImageEngine) Save(ctx context.Context, nameOrId string, tags []string, options entities.ImageSaveOptions) error {
   196  	var (
   197  		f   *os.File
   198  		err error
   199  	)
   200  
   201  	switch options.Format {
   202  	case "oci-dir", "docker-dir":
   203  		f, err = ioutil.TempFile("", "podman_save")
   204  		if err == nil {
   205  			defer func() { _ = os.Remove(f.Name()) }()
   206  		}
   207  	default:
   208  		f, err = os.Create(options.Output)
   209  	}
   210  	if err != nil {
   211  		return err
   212  	}
   213  
   214  	exErr := images.Export(ir.ClientCxt, nameOrId, f, &options.Format, &options.Compress)
   215  	if err := f.Close(); err != nil {
   216  		return err
   217  	}
   218  	if exErr != nil {
   219  		return exErr
   220  	}
   221  
   222  	if options.Format != "oci-dir" && options.Format != "docker-dir" {
   223  		return nil
   224  	}
   225  
   226  	f, err = os.Open(f.Name())
   227  	if err != nil {
   228  		return err
   229  	}
   230  	info, err := os.Stat(options.Output)
   231  	switch {
   232  	case err == nil:
   233  		if info.Mode().IsRegular() {
   234  			return errors.Errorf("%q already exists as a regular file", options.Output)
   235  		}
   236  	case os.IsNotExist(err):
   237  		if err := os.Mkdir(options.Output, 0755); err != nil {
   238  			return err
   239  		}
   240  	default:
   241  		return err
   242  	}
   243  	return utils2.UntarToFileSystem(options.Output, f, nil)
   244  }
   245  
   246  // Diff reports the changes to the given image
   247  func (ir *ImageEngine) Diff(ctx context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) {
   248  	changes, err := images.Diff(ir.ClientCxt, nameOrId)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	return &entities.DiffReport{Changes: changes}, nil
   253  }
   254  
   255  func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
   256  	return images.Search(ir.ClientCxt, term, opts)
   257  }
   258  
   259  func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) {
   260  	return config.Default()
   261  }