image

package
v0.0.0-...-3e0e934 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2026 License: Apache-2.0, BSD-2-Clause Imports: 62 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Fix = &cli.Command{
	Name:        "fix",
	Usage:       "CUBEMNT=1 cubecli image fix",
	UsageText:   "CUBEMNT=1 cubecli image fix, fix broken image.",
	Description: "fix broken image",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:  "skip-cfs",
			Usage: "skip to fix cfs image",
		},
		&cli.StringFlag{
			Name:  "cubelet-path",
			Usage: "cubelet work path",
			Value: "/data/cubelet",
		},
	},
	Action: func(context *cli.Context) error {
		_, ok := os.LookupEnv("CUBEMNT")
		if !ok {
			return fmt.Errorf("env CUBEMNT=1 not set")
		}
		cubeletPath = context.String("cubelet-path")
		statePath = path.Join(cubeletPath, "state", "io.cubelet.internal.v1.images")
		var (
			db  *utils.CubeStore
			err error
		)

		dbspath := filepath.Join(statePath, "db")
		dbdpath := filepath.Join(statePath, "db-tmp")
		err = exec.Command("cp", "-rf", dbspath, dbdpath).Run()
		if err != nil {
			return fmt.Errorf("cp db failed %s", err.Error())
		}
		defer os.RemoveAll(dbdpath)

		dbopt := &bbolt.Options{
			Timeout:   30 * time.Second,
			ReadOnly:  true,
			MmapFlags: syscall.MAP_SHARED,
		}
		if db, err = utils.NewCubeStoreExt(dbdpath, "meta.db", 10, dbopt); err != nil {
			return fmt.Errorf("init db %s failed %s", dbdpath, err.Error())
		}
		nfsImageMap, err := db.ReadAll(nfsImageBucketName)
		if err != nil {
			return fmt.Errorf("read nfs image failed %s", err.Error())
		}
		fmt.Printf("read nfs image success, total %d\n", len(nfsImageMap))

		for _, data := range nfsImageMap {
			img := &imagestore.Image{}
			err = jsoniter.Unmarshal(data, img)
			if err != nil {
				fmt.Printf("unmarshal nfs image failed %s\n", err.Error())
				continue
			}
			err = fixCfsImage(img)
			if err != nil {
				fmt.Printf("fix cfs image %s failed %s\n", img.ID, err.Error())
				continue
			}
		}
		fmt.Println("fix cfs image success")

		return err
	},
}
View Source
var GlobalListImageCommand = &cli.Command{
	Name:   "images",
	Usage:  "Warning: List images is deprecated, use 'cube image ls' instead.",
	Action: ListImageCommand.Action,
	Flags:  ListImageCommand.Flags,
}
View Source
var Inspect = &cli.Command{
	Name:  "inspect",
	Usage: "inspect image",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:  "mode,m",
			Value: "native",
			Usage: "Inspect mode, 'dockercompat' for Docker-compatible output, 'native' for containerd-native output",
		},
		&cli.StringFlag{
			Name:  "platform",
			Value: "amd64",
			Usage: "Inspect a specific platform",
		},
	},
	Action: func(context *cli.Context) error {
		mode := context.String("mode")
		f := &imageInspector{
			mode: mode,
		}

		var clientOpts []containerd.Opt
		if context.String("platform") != "" {
			platformParsed, err := platforms.Parse(context.String("platform"))
			if err != nil {
				return err
			}
			platformM := platforms.Only(platformParsed)
			clientOpts = append(clientOpts, containerd.WithDefaultPlatform(platformM))
		}

		cntdClient, err := containerd.New(context.String("address"), clientOpts...)
		if err != nil {
			return fmt.Errorf("init containerd connect failed.%s", err)
		}
		cntCtx := namespaces.WithNamespace(gocontext.Background(), context.String("namespace"))
		cntCtx, cntCancel := gocontext.WithTimeout(cntCtx, context.Duration("timeout"))
		defer cntCancel()

		walker := &ImageWalker{
			Client: cntdClient,
			OnFound: func(ctx gocontext.Context, found Found) error {
				ctx, cancel := gocontext.WithTimeout(ctx, 5*time.Second)
				defer cancel()

				n, err := InspectImge(ctx, cntdClient, found.Image)
				if err != nil {
					return err
				}
				switch f.mode {
				case "native":
					f.entries = append(f.entries, n)
				default:
					return fmt.Errorf("unknown mode %q", f.mode)
				}
				return nil
			},
		}
		var errs []error
		for _, req := range context.Args().Slice() {
			n, err := walker.Walk(cntCtx, req)
			if err != nil {
				errs = append(errs, err)
			} else if n == 0 {
				errs = append(errs, fmt.Errorf("no such object: %s", req))
			}
		}
		if len(errs) > 0 {
			return fmt.Errorf("%d errors: %v", len(errs), errs)
		}

		b, err := json.MarshalIndent(f.entries, "", "    ")
		if err != nil {
			return err
		}

		fmt.Fprintln(os.Stdout, string(b))
		return nil
	},
}
View Source
var ListImageCommand = &cli.Command{
	Name:                   "ls",
	Usage:                  "List images",
	ArgsUsage:              "[REPOSITORY[:TAG]]",
	UseShortOptionHandling: true,
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Show verbose info for images",
		},
		&cli.BoolFlag{
			Name:    "quiet",
			Aliases: []string{"q"},
			Usage:   "Only show image IDs",
		},
		&cli.StringSliceFlag{
			Name:    "filter",
			Aliases: []string{"f"},
			Usage:   "Filter output based on provided conditions.\nAvailable filters: \n* dangling=(boolean - true or false)\n* reference=/regular expression/\n* before=<image-name>[:<tag>]|<image id>|<image@digest>\n* since=<image-name>[:<tag>]|<image id>|<image@digest>\nMultiple filters can be combined together.",
		},
		&cli.StringFlag{
			Name:    "output",
			Aliases: []string{"o"},
			Usage:   "Output format, One of: json|yaml|table",
		},
		&cli.BoolFlag{
			Name:  "digests",
			Usage: "Show digests",
		},
		&cli.BoolFlag{
			Name:  "no-trunc",
			Usage: "Show output without truncating the ID",
		},
		&cli.BoolFlag{
			Name:  "pinned",
			Usage: "Show whether the image is pinned or not",
		},
	},
	Action: func(c *cli.Context) error {
		conn, ctx, cancel, err := commands.NewGrpcConn(c)
		if err != nil {
			return err
		}
		defer conn.Close()
		defer cancel()
		iClient := runtime.NewImageServiceClient(conn)
		r, err := ListImages(ctx, iClient, c.Args().First(), c.StringSlice("filter"))
		if err != nil {
			return fmt.Errorf("listing images: %w", err)
		}

		switch c.String("output") {
		case outputTypeJSON:
			return outputProtobufObjAsJSON(r)
		case outputTypeYAML:
			return outputProtobufObjAsYAML(r)
		}

		display := newDefaultTableDisplay()
		verbose := c.Bool("verbose")
		showDigest := c.Bool("digests")
		showPinned := c.Bool("pinned")
		quiet := c.Bool("quiet")
		noTrunc := c.Bool("no-trunc")
		if !verbose && !quiet {
			row := []string{columnImage, columnTag}
			if showDigest {
				row = append(row, columnDigest)
			}
			row = append(row, columnImageID, columnSize, columnMedia)
			if showPinned {
				row = append(row, columnPinned)
			}
			display.AddRow(row)
		}
		for _, image := range r.Images {
			if quiet {
				fmt.Printf("%s\n", image.Id)

				continue
			}
			if !verbose {
				imageName, repoDigest := utils.NormalizeRepoDigest(image.RepoDigests)
				repoTagPairs := utils.NormalizeRepoTagPair(image.RepoTags, imageName)
				size := units.HumanSizeWithPrecision(float64(image.GetSize_()), 3)
				media := "docker"
				if image.Spec != nil && image.Spec.Image != "" {
					media = image.Spec.Image
				}
				id := image.Id
				if !noTrunc {
					id = utils.GetTruncatedID(id, "sha256:")
					repoDigest = utils.GetTruncatedID(repoDigest, "sha256:")
				}
				for _, repoTagPair := range repoTagPairs {
					row := []string{repoTagPair[0], repoTagPair[1]}
					if showDigest {
						row = append(row, repoDigest)
					}
					row = append(row, id, size, media)
					if showPinned {
						row = append(row, strconv.FormatBool(image.Pinned))
					}
					display.AddRow(row)
				}

				continue
			}
			fmt.Printf("ID: %s\n", image.Id)
			for _, tag := range image.RepoTags {
				fmt.Printf("RepoTags: %s\n", tag)
			}
			for _, digest := range image.RepoDigests {
				fmt.Printf("RepoDigests: %s\n", digest)
			}
			if image.Size_ != 0 {
				fmt.Printf("Size: %d\n", image.Size_)
			}
			if image.Uid != nil {
				fmt.Printf("Uid: %v\n", image.Uid)
			}
			if image.Username != "" {
				fmt.Printf("Username: %v\n", image.Username)
			}
			if image.Pinned {
				fmt.Printf("Pinned: %v\n", image.Pinned)
			}
			fmt.Printf("\n")
		}
		display.Flush()

		return nil
	},
}
View Source
var Load = &cli.Command{
	Name:  "load",
	Usage: "Warning: load image is deprecated, `cubecli image pull` instead",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:  "snapshotter",
			Value: "overlayfs",
			Usage: "snapshotter format",
		},
		&cli.StringFlag{
			Name:    "input",
			Aliases: []string{"i"},
			Value:   "",
			Usage:   "Read from tar archive file, instead of STDIN",
		},
	},
	Action: func(context *cli.Context) error {
		input := context.String("input")
		if input == "" {
			log.Printf("should provide input")
			return nil
		}

		f, err := os.Open(input)
		if err != nil {
			return err
		}
		defer f.Close()

		platMC := platforms.DefaultStrict()
		cntdClient, err := containerd.New(context.String("address"),
			containerd.WithDefaultPlatform(platMC))
		if err != nil {
			return fmt.Errorf("init containerd connect failed.%s", err)
		}
		cntCtx := namespaces.WithNamespace(gocontext.Background(), context.String("namespace"))
		cntCtx, cntCancel := gocontext.WithTimeout(cntCtx, context.Duration("timeout"))
		defer cntCancel()

		imgs, err := cntdClient.Import(cntCtx, f,
			containerd.WithDigestRef(archive.DigestTranslator("cube-import/"+context.String("snapshotter"))),
			containerd.WithSkipDigestRef(func(name string) bool { return name != "" }),
			containerd.WithImportPlatform(platMC),
			containerd.WithImageLabels(map[string]string{
				constants.LabelImageCreateBy: constants.LabelImageCreateByImport,
			}))

		if err != nil {
			if errors.Is(err, images.ErrEmptyWalk) {
				err = fmt.Errorf("%w (Hint: set `--platform=PLATFORM` or `--all-platforms`)", err)
			}
			return err
		}
		for _, img := range imgs {
			image := containerd.NewImageWithPlatform(cntdClient, img, platMC)

			fmt.Fprintf(os.Stdout, "unpacking %s (%s)...", img.Name, img.Target.Digest)
			err = image.Unpack(cntCtx, context.String("snapshotter"))
			if err != nil {
				return err
			}
			fmt.Fprintf(os.Stdout, "done\n")
		}

		return nil
	},
}

Functions

func ImageCommand

func ImageCommand() *cli.Command

func ImageStatus

func ImageStatus(ctx context.Context, client runtime.ImageServiceClient, image string, verbose bool) (*runtime.ImageStatusResponse, error)

func InspectImge

func InspectImge(ctx context.Context, client *containerd.Client, image images.Image) (*nativeImage, error)

func ListImages

func ListImages(ctx context.Context, client runtime.ImageServiceClient, nameFilter string, conditionFilters []string) (*runtime.ListImagesResponse, error)

func ParseDockerRef

func ParseDockerRef(rawRef string) (reference.Named, error)

func ParseIPFSRefWithScheme

func ParseIPFSRefWithScheme(name string) (scheme, ref string, err error)

func ParseRepoTag

func ParseRepoTag(imgName string) (string, string)

func RemoveImage

func RemoveImage(ctx context.Context, client runtime.ImageServiceClient, image string) error

func TimeSinceInHuman

func TimeSinceInHuman(since time.Time) string

Types

type Flusher

type Flusher interface {
	Flush() error
}

type Found

type Found struct {
	Image      images.Image
	Req        string
	MatchIndex int
	MatchCount int
}

type ImageWalker

type ImageWalker struct {
	Client  *containerd.Client
	OnFound OnFound
}

func (*ImageWalker) Walk

func (w *ImageWalker) Walk(ctx gocontext.Context, req string) (int, error)

type OnFound

type OnFound func(ctx gocontext.Context, found Found) error

type Reference

type Reference interface {
	String() string
}

func ParseAny

func ParseAny(rawRef string) (Reference, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL