github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/cmd/umoci/unpack.go (about) 1 /* 2 * umoci: Umoci Modifies Open Containers' Images 3 * Copyright (C) 2016-2020 SUSE LLC 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package main 19 20 import ( 21 "github.com/opencontainers/umoci" 22 "github.com/opencontainers/umoci/oci/cas/dir" 23 "github.com/opencontainers/umoci/oci/casext" 24 "github.com/opencontainers/umoci/oci/layer" 25 "github.com/pkg/errors" 26 "github.com/urfave/cli" 27 ) 28 29 var unpackCommand = uxRemap(cli.Command{ 30 Name: "unpack", 31 Usage: "unpacks a reference into an OCI runtime bundle", 32 ArgsUsage: `--image <image-path>[:<tag>] <bundle> 33 34 Where "<image-path>" is the path to the OCI image, "<tag>" is the name of the 35 tagged image to unpack (if not specified, defaults to "latest") and "<bundle>" 36 is the destination to unpack the image to. 37 38 It should be noted that this is not the same as oci-create-runtime-bundle, 39 because this command also will create an mtree specification to allow for layer 40 creation with umoci-repack(1).`, 41 42 // unpack reads manifest information. 43 Category: "image", 44 45 Flags: []cli.Flag{ 46 cli.BoolFlag{ 47 Name: "keep-dirlinks", 48 Usage: "don't clobber underlying symlinks to directories", 49 }, 50 }, 51 52 Action: unpack, 53 54 Before: func(ctx *cli.Context) error { 55 if ctx.NArg() != 1 { 56 return errors.Errorf("invalid number of positional arguments: expected <bundle>") 57 } 58 if ctx.Args().First() == "" { 59 return errors.Errorf("bundle path cannot be empty") 60 } 61 ctx.App.Metadata["bundle"] = ctx.Args().First() 62 return nil 63 }, 64 }) 65 66 func unpack(ctx *cli.Context) error { 67 imagePath := ctx.App.Metadata["--image-path"].(string) 68 fromName := ctx.App.Metadata["--image-tag"].(string) 69 bundlePath := ctx.App.Metadata["bundle"].(string) 70 71 var unpackOptions layer.UnpackOptions 72 var meta umoci.Meta 73 meta.Version = umoci.MetaVersion 74 75 // Parse and set up the mapping options. 76 err := umoci.ParseIdmapOptions(&meta, ctx) 77 if err != nil { 78 return err 79 } 80 81 unpackOptions.KeepDirlinks = ctx.Bool("keep-dirlinks") 82 unpackOptions.MapOptions = meta.MapOptions 83 84 // Get a reference to the CAS. 85 engine, err := dir.Open(imagePath) 86 if err != nil { 87 return errors.Wrap(err, "open CAS") 88 } 89 engineExt := casext.NewEngine(engine) 90 defer engine.Close() 91 return umoci.Unpack(engineExt, fromName, bundlePath, unpackOptions) 92 }