Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ConvertCommand = cli.Command{ Name: "convert", Usage: "convert an image", ArgsUsage: "[flags] <source_ref> <target_ref>...", Description: `Convert an image format. e.g., 'ctr-remote convert --estargz --oci example.com/foo:orig example.com/foo:esgz' Use '--platform' to define the output platform. When '--all-platforms' is given all images in a manifest list must be available. `, Flags: []cli.Flag{ cli.BoolFlag{ Name: "estargz", Usage: "convert legacy tar(.gz) layers to eStargz for lazy pulling. Should be used in conjunction with '--oci'", }, cli.StringFlag{ Name: "estargz-record-in", Usage: "Read 'ctr-remote optimize --record-out=<FILE>' record file", }, cli.IntFlag{ Name: "estargz-compression-level", Usage: "eStargz compression level", Value: gzip.BestCompression, }, cli.IntFlag{ Name: "estargz-chunk-size", Usage: "eStargz chunk size", Value: 0, }, cli.BoolFlag{ Name: "zstdchunked", Usage: "use zstd compression instead of gzip (a.k.a zstd:chunked). Must be used in conjunction with '--oci'.", }, cli.BoolFlag{ Name: "uncompress", Usage: "convert tar.gz layers to uncompressed tar layers", }, cli.BoolFlag{ Name: "oci", Usage: "convert Docker media types to OCI media types", }, cli.StringSliceFlag{ Name: "platform", Usage: "Convert content for a specific platform", Value: &cli.StringSlice{}, }, cli.BoolFlag{ Name: "all-platforms", Usage: "Convert content for all platforms", }, }, Action: func(context *cli.Context) error { var ( convertOpts = []converter.Opt{} ) srcRef := context.Args().Get(0) targetRef := context.Args().Get(1) if srcRef == "" || targetRef == "" { return errors.New("src and target image need to be specified") } var platformMC platforms.MatchComparer if context.Bool("all-platforms") { platformMC = platforms.All } else { if pss := context.StringSlice("platform"); len(pss) > 0 { var all []ocispec.Platform for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return errors.Wrapf(err, "invalid platform %q", ps) } all = append(all, p) } platformMC = platforms.Ordered(all...) } else { platformMC = platforms.DefaultStrict() } } convertOpts = append(convertOpts, converter.WithPlatform(platformMC)) var layerConvertFunc converter.ConvertFunc if context.Bool("estargz") { esgzOpts, err := getESGZConvertOpts(context) if err != nil { return err } layerConvertFunc = estargzconvert.LayerConvertFunc(esgzOpts...) if !context.Bool("oci") { logrus.Warn("option --estargz should be used in conjunction with --oci") } if context.Bool("uncompress") { return errors.New("option --estargz conflicts with --uncompress") } if context.Bool("zstdchunked") { return errors.New("option --estargz conflicts with --zstdchunked") } } if context.Bool("zstdchunked") { esgzOpts, err := getESGZConvertOpts(context) if err != nil { return err } layerConvertFunc = zstdchunkedconvert.LayerConvertFunc(esgzOpts...) if !context.Bool("oci") { return errors.New("option --zstdchunked must be used in conjunction with --oci") } if context.Bool("uncompress") { return errors.New("option --zstdchunked conflicts with --uncompress") } } if context.Bool("uncompress") { layerConvertFunc = uncompress.LayerConvertFunc } if layerConvertFunc == nil { return errors.New("specify layer converter") } convertOpts = append(convertOpts, converter.WithLayerConvertFunc(layerConvertFunc)) if context.Bool("oci") { convertOpts = append(convertOpts, converter.WithDockerToOCI(true)) } client, ctx, cancel, err := commands.NewClient(context) if err != nil { return err } defer cancel() newImg, err := converter.Convert(ctx, client, targetRef, srcRef, convertOpts...) if err != nil { return err } fmt.Fprintln(context.App.Writer, newImg.Target.Digest.String()) return nil }, }
ConvertCommand converts an image
View Source
var FanotifyCommand = cli.Command{ Name: "fanotify", Hidden: true, Action: func(context *cli.Context) error { target := context.Args().Get(0) if target == "" { return fmt.Errorf("target must be specified") } return service.Serve(target, os.Stdin, os.Stdout) }, }
FanotifyCommand notifies filesystem event under the specified directory.
View Source
var GetTOCDigestCommand = cli.Command{ Name: "get-toc-digest", Usage: "get the digest of TOC of a layer", ArgsUsage: "<layer digest>", Flags: []cli.Flag{ cli.BoolFlag{ Name: "zstdchunked", Usage: "parse layer as zstd:chunked", }, cli.BoolFlag{ Name: "dump-toc", Usage: "dump TOC instead of digest. Note that the dumped TOC might be formatted with indents so may have different digest against the original in the layer", }, }, Action: func(clicontext *cli.Context) error { layerDgstStr := clicontext.Args().Get(0) if layerDgstStr == "" { return errors.New("layer digest need to be specified") } client, ctx, cancel, err := commands.NewClient(clicontext) if err != nil { return err } defer cancel() layerDgst, err := digest.Parse(layerDgstStr) if err != nil { return err } ra, err := client.ContentStore().ReaderAt(ctx, ocispec.Descriptor{Digest: layerDgst}) if err != nil { return err } defer ra.Close() footerSize := estargz.FooterSize if clicontext.Bool("zstdchunked") { footerSize = zstdchunked.FooterSize } footer := make([]byte, footerSize) if _, err := ra.ReadAt(footer, ra.Size()-int64(footerSize)); err != nil { return errors.Wrapf(err, "error reading footer") } var decompressor estargz.Decompressor decompressor = new(estargz.GzipDecompressor) if clicontext.Bool("zstdchunked") { decompressor = new(zstdchunked.Decompressor) } _, tocOff, tocSize, err := decompressor.ParseFooter(footer) if err != nil { return errors.Wrapf(err, "error parsing footer") } if tocSize <= 0 { tocSize = ra.Size() - tocOff - int64(footerSize) } toc, tocDgst, err := decompressor.ParseTOC(io.NewSectionReader(ra, tocOff, tocSize)) if err != nil { return errors.Wrapf(err, "error parsing TOC") } if clicontext.Bool("dump-toc") { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return errors.Wrapf(err, "failed to marshal toc") } fmt.Println(string(tocJSON)) return nil } fmt.Println(tocDgst.String()) return nil }, }
GetTOCDigestCommand outputs TOC info of a layer
View Source
var OptimizeCommand = cli.Command{ Name: "optimize", Usage: "optimize an image with user-specified workload", ArgsUsage: "[flags] <source_ref> <target_ref>...", Flags: append([]cli.Flag{ cli.BoolFlag{ Name: "reuse", Usage: "reuse eStargz (already optimized) layers without further conversion", }, cli.StringSliceFlag{ Name: "platform", Usage: "Pull content from a specific platform", Value: &cli.StringSlice{}, }, cli.BoolFlag{ Name: "all-platforms", Usage: "targeting all platform of the source image", }, cli.BoolFlag{ Name: "wait-on-signal", Usage: "ignore context cancel and keep the container running until it receives SIGINT (Ctrl + C) sent manually", }, cli.BoolFlag{ Name: "no-optimize", Usage: "convert image without optimization", }, cli.StringFlag{ Name: "record-out", Usage: "record the monitor log to the specified file", }, cli.BoolFlag{ Name: "oci", Usage: "convert Docker media types to OCI media types", }, cli.IntFlag{ Name: "estargz-compression-level", Usage: "eStargz compression level (only applied to gzip as of now)", Value: gzip.BestCompression, }, cli.BoolFlag{ Name: "zstdchunked", Usage: "use zstd compression instead of gzip (a.k.a zstd:chunked)", }, }, samplerFlags...), Action: func(clicontext *cli.Context) error { convertOpts := []converter.Opt{} srcRef := clicontext.Args().Get(0) targetRef := clicontext.Args().Get(1) if srcRef == "" || targetRef == "" { return errors.New("src and target image need to be specified") } var platformMC platforms.MatchComparer if clicontext.Bool("all-platforms") { platformMC = platforms.All } else { if pss := clicontext.StringSlice("platform"); len(pss) > 0 { var all []ocispec.Platform for _, ps := range pss { p, err := platforms.Parse(ps) if err != nil { return errors.Wrapf(err, "invalid platform %q", ps) } all = append(all, p) } platformMC = platforms.Ordered(all...) } else { platformMC = platforms.DefaultStrict() } } convertOpts = append(convertOpts, converter.WithPlatform(platformMC)) if clicontext.Bool("oci") { convertOpts = append(convertOpts, converter.WithDockerToOCI(true)) } else if clicontext.Bool("zstdchunked") { return errors.New("option --zstdchunked must be used in conjunction with --oci") } client, ctx, cancel, err := commands.NewClient(clicontext) if err != nil { return err } defer cancel() ctx, done, err := client.WithLease(ctx) if err != nil { return err } defer done(ctx) recordOut, esgzOptsPerLayer, wrapper, err := analyze(ctx, clicontext, client, srcRef) if err != nil { return err } if recordOutFile := clicontext.String("record-out"); recordOutFile != "" { if err := writeContentFile(ctx, client, recordOut, recordOutFile); err != nil { return errors.Wrapf(err, "failed output record file") } } var f converter.ConvertFunc if clicontext.Bool("zstdchunked") { f = zstdchunkedconvert.LayerConvertWithLayerOptsFunc(esgzOptsPerLayer) } else { f = estargzconvert.LayerConvertWithLayerAndCommonOptsFunc(esgzOptsPerLayer, estargz.WithCompressionLevel(clicontext.Int("estargz-compression-level"))) } if wrapper != nil { f = wrapper(f) } layerConvertFunc := logWrapper(f) convertOpts = append(convertOpts, converter.WithLayerConvertFunc(layerConvertFunc)) newImg, err := converter.Convert(ctx, client, targetRef, srcRef, convertOpts...) if err != nil { return err } fmt.Fprintln(clicontext.App.Writer, newImg.Target.Digest.String()) return nil }, }
OptimizeCommand converts and optimizes an image
View Source
var RpullCommand = cli.Command{ Name: "rpull", Usage: "pull an image from a registry levaraging stargz snapshotter", ArgsUsage: "[flags] <ref>", Description: `Fetch and prepare an image for use in containerd levaraging stargz snapshotter. After pulling an image, it should be ready to use the same reference in a run command. `, Flags: append(commands.RegistryFlags, commands.LabelFlag, cli.BoolFlag{ Name: skipContentVerifyOpt, Usage: "Skip content verification for layers contained in this image.", }, ), Action: func(context *cli.Context) error { var ( ref = context.Args().First() config = &rPullConfig{} ) if ref == "" { return fmt.Errorf("please provide an image reference to pull") } client, ctx, cancel, err := commands.NewClient(context) if err != nil { return err } defer cancel() ctx, done, err := client.WithLease(ctx) if err != nil { return err } defer done(ctx) fc, err := content.NewFetchConfig(ctx, context) if err != nil { return err } config.FetchConfig = fc if context.Bool(skipContentVerifyOpt) { config.skipVerify = true } return pull(ctx, client, ref, config) }, }
RpullCommand is a subcommand to pull an image from a registry levaraging stargz snapshotter
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.