"Fossies" - the Fresh Open Source Software Archive

Member "buildah-1.27.2/cmd/buildah/addcopy.go" (20 Sep 2022, 9917 Bytes) of package /linux/misc/buildah-1.27.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "addcopy.go": 1.26.4_vs_1.27.0.

    1 package main
    2 
    3 import (
    4     "errors"
    5     "fmt"
    6     "os"
    7     "path/filepath"
    8     "strings"
    9 
   10     "github.com/containers/buildah"
   11     "github.com/containers/buildah/internal/util"
   12     buildahcli "github.com/containers/buildah/pkg/cli"
   13     "github.com/containers/buildah/pkg/parse"
   14     "github.com/containers/common/pkg/auth"
   15     "github.com/containers/storage"
   16     "github.com/sirupsen/logrus"
   17     "github.com/spf13/cobra"
   18     "github.com/spf13/pflag"
   19 )
   20 
   21 type addCopyResults struct {
   22     addHistory       bool
   23     chmod            string
   24     chown            string
   25     quiet            bool
   26     ignoreFile       string
   27     contextdir       string
   28     from             string
   29     blobCache        string
   30     decryptionKeys   []string
   31     removeSignatures bool
   32     signaturePolicy  string
   33     authfile         string
   34     creds            string
   35     tlsVerify        bool
   36     certDir          string
   37 }
   38 
   39 func createCommand(addCopy string, desc string, short string, opts *addCopyResults) *cobra.Command {
   40     return &cobra.Command{
   41         Use:   addCopy,
   42         Short: short,
   43         Long:  desc,
   44         RunE: func(cmd *cobra.Command, args []string) error {
   45             return addAndCopyCmd(cmd, args, strings.ToUpper(addCopy), *opts)
   46         },
   47         Example: `buildah ` + addCopy + ` containerID '/myapp/app.conf'
   48   buildah ` + addCopy + ` containerID '/myapp/app.conf' '/myapp/app.conf'`,
   49         Args: cobra.MinimumNArgs(1),
   50     }
   51 }
   52 
   53 func applyFlagVars(flags *pflag.FlagSet, opts *addCopyResults) {
   54     flags.SetInterspersed(false)
   55     flags.BoolVar(&opts.addHistory, "add-history", false, "add an entry for this operation to the image's history.  Use BUILDAH_HISTORY environment variable to override. (default false)")
   56     flags.StringVar(&opts.authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
   57     if err := flags.MarkHidden("authfile"); err != nil {
   58         panic(fmt.Sprintf("error marking authfile as hidden: %v", err))
   59     }
   60     flags.StringVar(&opts.blobCache, "blob-cache", "", "store copies of pulled image blobs in the specified directory")
   61     if err := flags.MarkHidden("blob-cache"); err != nil {
   62         panic(fmt.Sprintf("error marking blob-cache as hidden: %v", err))
   63     }
   64     flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access registries")
   65     if err := flags.MarkHidden("cert-dir"); err != nil {
   66         panic(fmt.Sprintf("error marking cert-dir as hidden: %v", err))
   67     }
   68     flags.StringVar(&opts.chown, "chown", "", "set the user and group ownership of the destination content")
   69     flags.StringVar(&opts.chmod, "chmod", "", "set the access permissions of the destination content")
   70     flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing registries when pulling images")
   71     if err := flags.MarkHidden("creds"); err != nil {
   72         panic(fmt.Sprintf("error marking creds as hidden: %v", err))
   73     }
   74     flags.StringVar(&opts.from, "from", "", "use the specified container's or image's root directory as the source root directory")
   75     flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", nil, "key needed to decrypt a pulled image")
   76     if err := flags.MarkHidden("decryption-key"); err != nil {
   77         panic(fmt.Sprintf("error marking decryption-key as hidden: %v", err))
   78     }
   79     flags.StringVar(&opts.ignoreFile, "ignorefile", "", "path to .containerignore file")
   80     flags.StringVar(&opts.contextdir, "contextdir", "", "context directory path")
   81     flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output a digest of the newly-added/copied content")
   82     flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing registries when pulling images. TLS verification cannot be used when talking to an insecure registry.")
   83     if err := flags.MarkHidden("tls-verify"); err != nil {
   84         panic(fmt.Sprintf("error marking tls-verify as hidden: %v", err))
   85     }
   86     flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pulling image")
   87     if err := flags.MarkHidden("remove-signatures"); err != nil {
   88         panic(fmt.Sprintf("error marking remove-signatures as hidden: %v", err))
   89     }
   90     flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
   91     if err := flags.MarkHidden("signature-policy"); err != nil {
   92         panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
   93     }
   94 }
   95 
   96 func init() {
   97     var (
   98         addDescription  = "\n  Adds the contents of a file, URL, or directory to a container's working\n  directory.  If a local file appears to be an archive, its contents are\n  extracted and added instead of the archive file itself."
   99         copyDescription = "\n  Copies the contents of a file, URL, or directory into a container's working\n  directory."
  100         shortAdd        = "Add content to the container"
  101         shortCopy       = "Copy content into the container"
  102         addOpts         addCopyResults
  103         copyOpts        addCopyResults
  104     )
  105     addCommand := createCommand("add", addDescription, shortAdd, &addOpts)
  106     addCommand.SetUsageTemplate(UsageTemplate())
  107 
  108     copyCommand := createCommand("copy", copyDescription, shortCopy, &copyOpts)
  109     copyCommand.SetUsageTemplate(UsageTemplate())
  110 
  111     addFlags := addCommand.Flags()
  112     applyFlagVars(addFlags, &addOpts)
  113 
  114     copyFlags := copyCommand.Flags()
  115     applyFlagVars(copyFlags, &copyOpts)
  116 
  117     rootCmd.AddCommand(addCommand)
  118     rootCmd.AddCommand(copyCommand)
  119 }
  120 
  121 func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyResults) error {
  122     if len(args) == 0 {
  123         return errors.New("container ID must be specified")
  124     }
  125     name := args[0]
  126     args = Tail(args)
  127     if len(args) == 0 {
  128         return errors.New("src must be specified")
  129     }
  130 
  131     if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
  132         return err
  133     }
  134 
  135     // If list is greater than one, the last item is the destination
  136     dest := ""
  137     size := len(args)
  138     if size > 1 {
  139         dest = args[size-1]
  140         args = args[:size-1]
  141     }
  142 
  143     store, err := getStore(c)
  144     if err != nil {
  145         return err
  146     }
  147 
  148     var from *buildah.Builder
  149     unmountFrom := false
  150     removeFrom := false
  151     var idMappingOptions *buildah.IDMappingOptions
  152     contextdir := iopts.contextdir
  153     if iopts.ignoreFile != "" && contextdir == "" {
  154         return errors.New("--ignorefile option requires that you specify a context dir using --contextdir")
  155     }
  156 
  157     if iopts.from != "" {
  158         if from, err = openBuilder(getContext(), store, iopts.from); err != nil && errors.Is(err, storage.ErrContainerUnknown) {
  159             systemContext, err2 := parse.SystemContextFromOptions(c)
  160             if err2 != nil {
  161                 return fmt.Errorf("error building system context: %w", err2)
  162             }
  163 
  164             decryptConfig, err2 := util.DecryptConfig(iopts.decryptionKeys)
  165             if err2 != nil {
  166                 return fmt.Errorf("unable to obtain decrypt config: %w", err2)
  167             }
  168             options := buildah.BuilderOptions{
  169                 FromImage:           iopts.from,
  170                 BlobDirectory:       iopts.blobCache,
  171                 SignaturePolicyPath: iopts.signaturePolicy,
  172                 SystemContext:       systemContext,
  173                 MaxPullRetries:      buildahcli.MaxPullPushRetries,
  174                 PullRetryDelay:      buildahcli.PullPushRetryDelay,
  175                 OciDecryptConfig:    decryptConfig,
  176             }
  177             if !iopts.quiet {
  178                 options.ReportWriter = os.Stderr
  179             }
  180             if from, err = buildah.NewBuilder(getContext(), store, options); err != nil {
  181                 return fmt.Errorf("no container named %q, error copying content from image %q: %w", iopts.from, iopts.from, err)
  182             }
  183             removeFrom = true
  184             defer func() {
  185                 if !removeFrom {
  186                     return
  187                 }
  188                 if err := from.Delete(); err != nil {
  189                     logrus.Errorf("error deleting %q temporary working container %q", iopts.from, from.Container)
  190                 }
  191             }()
  192         }
  193         if err != nil {
  194             return fmt.Errorf("error reading build container %q: %w", iopts.from, err)
  195         }
  196         fromMountPoint, err := from.Mount(from.MountLabel)
  197         if err != nil {
  198             return fmt.Errorf("error mounting %q container %q: %w", iopts.from, from.Container, err)
  199         }
  200         unmountFrom = true
  201         defer func() {
  202             if !unmountFrom {
  203                 return
  204             }
  205             if err := from.Unmount(); err != nil {
  206                 logrus.Errorf("error unmounting %q container %q", iopts.from, from.Container)
  207             }
  208             if err := from.Save(); err != nil {
  209                 logrus.Errorf("error saving information about %q container %q", iopts.from, from.Container)
  210             }
  211         }()
  212         idMappingOptions = &from.IDMappingOptions
  213         contextdir = filepath.Join(fromMountPoint, iopts.contextdir)
  214         for i := range args {
  215             args[i] = filepath.Join(fromMountPoint, args[i])
  216         }
  217     }
  218 
  219     builder, err := openBuilder(getContext(), store, name)
  220     if err != nil {
  221         return fmt.Errorf("error reading build container %q: %w", name, err)
  222     }
  223 
  224     builder.ContentDigester.Restart()
  225 
  226     options := buildah.AddAndCopyOptions{
  227         Chmod:            iopts.chmod,
  228         Chown:            iopts.chown,
  229         ContextDir:       contextdir,
  230         IDMappingOptions: idMappingOptions,
  231     }
  232     if iopts.contextdir != "" {
  233         var excludes []string
  234 
  235         excludes, options.IgnoreFile, err = parse.ContainerIgnoreFile(options.ContextDir, iopts.ignoreFile)
  236         if err != nil {
  237             return err
  238         }
  239         options.Excludes = excludes
  240     }
  241 
  242     extractLocalArchives := verb == "ADD"
  243     err = builder.Add(dest, extractLocalArchives, options, args...)
  244     if err != nil {
  245         return fmt.Errorf("error adding content to container %q: %w", builder.Container, err)
  246     }
  247     if unmountFrom {
  248         if err := from.Unmount(); err != nil {
  249             return fmt.Errorf("error unmounting %q container %q: %w", iopts.from, from.Container, err)
  250         }
  251         if err := from.Save(); err != nil {
  252             return fmt.Errorf("error saving information about %q container %q: %w", iopts.from, from.Container, err)
  253         }
  254         unmountFrom = false
  255     }
  256     if removeFrom {
  257         if err := from.Delete(); err != nil {
  258             return fmt.Errorf("error deleting %q temporary working container %q: %w", iopts.from, from.Container, err)
  259         }
  260         removeFrom = false
  261     }
  262 
  263     contentType, digest := builder.ContentDigester.Digest()
  264     if !iopts.quiet {
  265         fmt.Printf("%s\n", digest.Hex())
  266     }
  267     if contentType != "" {
  268         contentType = contentType + ":"
  269     }
  270     conditionallyAddHistory(builder, c, "/bin/sh -c #(nop) %s %s%s", verb, contentType, digest.Hex())
  271     return builder.Save()
  272 }