github.com/containers/podman/v4@v4.9.4/pkg/bindings/images/images.go (about) 1 package images 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 "net/url" 10 "strconv" 11 12 imageTypes "github.com/containers/image/v5/types" 13 "github.com/containers/podman/v4/pkg/api/handlers/types" 14 "github.com/containers/podman/v4/pkg/auth" 15 "github.com/containers/podman/v4/pkg/bindings" 16 "github.com/containers/podman/v4/pkg/domain/entities" 17 "github.com/containers/podman/v4/pkg/domain/entities/reports" 18 ) 19 20 // Exists a lightweight way to determine if an image exists in local storage. It returns a 21 // boolean response. 22 func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, error) { 23 conn, err := bindings.GetClient(ctx) 24 if err != nil { 25 return false, err 26 } 27 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/exists", nil, nil, nameOrID) 28 if err != nil { 29 return false, err 30 } 31 defer response.Body.Close() 32 33 return response.IsSuccess(), nil 34 } 35 36 // List returns a list of images in local storage. The all boolean and filters parameters are optional 37 // ways to alter the image query. 38 func List(ctx context.Context, options *ListOptions) ([]*entities.ImageSummary, error) { 39 if options == nil { 40 options = new(ListOptions) 41 } 42 var imageSummary []*entities.ImageSummary 43 conn, err := bindings.GetClient(ctx) 44 if err != nil { 45 return nil, err 46 } 47 params, err := options.ToParams() 48 if err != nil { 49 return nil, err 50 } 51 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/json", params, nil) 52 if err != nil { 53 return imageSummary, err 54 } 55 defer response.Body.Close() 56 57 return imageSummary, response.Process(&imageSummary) 58 } 59 60 // Get performs an image inspect. To have the on-disk size of the image calculated, you can 61 // use the optional size parameter. 62 func GetImage(ctx context.Context, nameOrID string, options *GetOptions) (*entities.ImageInspectReport, error) { 63 if options == nil { 64 options = new(GetOptions) 65 } 66 conn, err := bindings.GetClient(ctx) 67 if err != nil { 68 return nil, err 69 } 70 params, err := options.ToParams() 71 if err != nil { 72 return nil, err 73 } 74 inspectedData := entities.ImageInspectReport{} 75 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/json", params, nil, nameOrID) 76 if err != nil { 77 return &inspectedData, err 78 } 79 defer response.Body.Close() 80 81 return &inspectedData, response.Process(&inspectedData) 82 } 83 84 // Tree retrieves a "tree" based representation of the given image 85 func Tree(ctx context.Context, nameOrID string, options *TreeOptions) (*entities.ImageTreeReport, error) { 86 if options == nil { 87 options = new(TreeOptions) 88 } 89 var report entities.ImageTreeReport 90 conn, err := bindings.GetClient(ctx) 91 if err != nil { 92 return nil, err 93 } 94 params, err := options.ToParams() 95 if err != nil { 96 return nil, err 97 } 98 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/tree", params, nil, nameOrID) 99 if err != nil { 100 return nil, err 101 } 102 defer response.Body.Close() 103 104 return &report, response.Process(&report) 105 } 106 107 // History returns the parent layers of an image. 108 func History(ctx context.Context, nameOrID string, options *HistoryOptions) ([]*types.HistoryResponse, error) { 109 if options == nil { 110 options = new(HistoryOptions) 111 } 112 _ = options 113 var history []*types.HistoryResponse 114 conn, err := bindings.GetClient(ctx) 115 if err != nil { 116 return nil, err 117 } 118 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/history", nil, nil, nameOrID) 119 if err != nil { 120 return history, err 121 } 122 defer response.Body.Close() 123 124 return history, response.Process(&history) 125 } 126 127 func Load(ctx context.Context, r io.Reader) (*entities.ImageLoadReport, error) { 128 var report entities.ImageLoadReport 129 conn, err := bindings.GetClient(ctx) 130 if err != nil { 131 return nil, err 132 } 133 response, err := conn.DoRequest(ctx, r, http.MethodPost, "/images/load", nil, nil) 134 if err != nil { 135 return nil, err 136 } 137 defer response.Body.Close() 138 139 return &report, response.Process(&report) 140 } 141 142 // Export saves images from local storage as a tarball or image archive. The optional format 143 // parameter is used to change the format of the output. 144 func Export(ctx context.Context, nameOrIDs []string, w io.Writer, options *ExportOptions) error { 145 if options == nil { 146 options = new(ExportOptions) 147 } 148 conn, err := bindings.GetClient(ctx) 149 if err != nil { 150 return err 151 } 152 params, err := options.ToParams() 153 if err != nil { 154 return err 155 } 156 for _, ref := range nameOrIDs { 157 params.Add("references", ref) 158 } 159 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/export", params, nil) 160 if err != nil { 161 return err 162 } 163 defer response.Body.Close() 164 165 if response.StatusCode/100 == 2 || response.StatusCode/100 == 3 { 166 _, err = io.Copy(w, response.Body) 167 return err 168 } 169 return response.Process(nil) 170 } 171 172 // Prune removes unused images from local storage. The optional filters can be used to further 173 // define which images should be pruned. 174 func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, error) { 175 var ( 176 deleted []*reports.PruneReport 177 ) 178 if options == nil { 179 options = new(PruneOptions) 180 } 181 conn, err := bindings.GetClient(ctx) 182 if err != nil { 183 return nil, err 184 } 185 params, err := options.ToParams() 186 if err != nil { 187 return nil, err 188 } 189 response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/prune", params, nil) 190 if err != nil { 191 return deleted, err 192 } 193 defer response.Body.Close() 194 195 return deleted, response.Process(&deleted) 196 } 197 198 // Tag adds an additional name to locally-stored image. Both the tag and repo parameters are required. 199 func Tag(ctx context.Context, nameOrID, tag, repo string, options *TagOptions) error { 200 if options == nil { 201 options = new(TagOptions) 202 } 203 _ = options 204 conn, err := bindings.GetClient(ctx) 205 if err != nil { 206 return err 207 } 208 params := url.Values{} 209 params.Set("tag", tag) 210 params.Set("repo", repo) 211 response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/%s/tag", params, nil, nameOrID) 212 if err != nil { 213 return err 214 } 215 defer response.Body.Close() 216 217 return response.Process(nil) 218 } 219 220 // Untag removes a name from locally-stored image. Both the tag and repo parameters are required. 221 func Untag(ctx context.Context, nameOrID, tag, repo string, options *UntagOptions) error { 222 if options == nil { 223 options = new(UntagOptions) 224 } 225 _ = options 226 conn, err := bindings.GetClient(ctx) 227 if err != nil { 228 return err 229 } 230 params := url.Values{} 231 params.Set("tag", tag) 232 params.Set("repo", repo) 233 response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/%s/untag", params, nil, nameOrID) 234 if err != nil { 235 return err 236 } 237 defer response.Body.Close() 238 239 return response.Process(nil) 240 } 241 242 // Import adds the given image to the local image store. This can be done by file and the given reader 243 // or via the url parameter. Additional metadata can be associated with the image by using the changes and 244 // message parameters. The image can also be tagged given a reference. One of url OR r must be provided. 245 func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities.ImageImportReport, error) { 246 if options == nil { 247 options = new(ImportOptions) 248 } 249 var report entities.ImageImportReport 250 if r != nil && options.URL != nil { 251 return nil, errors.New("url and r parameters cannot be used together") 252 } 253 conn, err := bindings.GetClient(ctx) 254 if err != nil { 255 return nil, err 256 } 257 params, err := options.ToParams() 258 if err != nil { 259 return nil, err 260 } 261 response, err := conn.DoRequest(ctx, r, http.MethodPost, "/images/import", params, nil) 262 if err != nil { 263 return nil, err 264 } 265 defer response.Body.Close() 266 267 return &report, response.Process(&report) 268 } 269 270 // Search is the binding for libpod's v2 endpoints for Search images. 271 func Search(ctx context.Context, term string, options *SearchOptions) ([]entities.ImageSearchReport, error) { 272 if options == nil { 273 options = new(SearchOptions) 274 } 275 conn, err := bindings.GetClient(ctx) 276 if err != nil { 277 return nil, err 278 } 279 params, err := options.ToParams() 280 if err != nil { 281 return nil, err 282 } 283 params.Set("term", term) 284 285 // SkipTLSVerify is special. It's not being serialized by ToParams() 286 // because we need to flip the boolean. 287 if options.SkipTLSVerify != nil { 288 params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify())) 289 } 290 291 header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword()) 292 if err != nil { 293 return nil, err 294 } 295 296 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/search", params, header) 297 if err != nil { 298 return nil, err 299 } 300 defer response.Body.Close() 301 302 results := []entities.ImageSearchReport{} 303 if err := response.Process(&results); err != nil { 304 return nil, err 305 } 306 307 return results, nil 308 } 309 310 func Scp(ctx context.Context, source, destination *string, options ScpOptions) (reports.ScpReport, error) { 311 rep := reports.ScpReport{} 312 313 conn, err := bindings.GetClient(ctx) 314 if err != nil { 315 return rep, err 316 } 317 params, err := options.ToParams() 318 if err != nil { 319 return rep, err 320 } 321 response, err := conn.DoRequest(ctx, nil, http.MethodPost, fmt.Sprintf("/images/scp/%s", *source), params, nil) 322 if err != nil { 323 return rep, err 324 } 325 defer response.Body.Close() 326 327 return rep, response.Process(&rep) 328 }