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 }