commands

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DriftCommand = cli.Command{
	Name:        "drift",
	Aliases:     []string{"diff"},
	Usage:       "identifies container filesystem changes",
	Description: "identifies container filesystem changes for all containers",
	ArgsUsage:   "[containerID]",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "filter",
			Usage: "comma separated label filter using key=value pair",
		},
		cli.BoolFlag{
			Name:  "mount-support-containers",
			Usage: "mount Kubernetes supporting containers",
		},
	},
	Action: func(clictx *cli.Context) error {

		if runtime.GOOS != "linux" {
			return fmt.Errorf("feature is only supported on Linux")
		}
		output := clictx.GlobalString("output")
		outputfile := clictx.GlobalString("output-file")
		filter := clictx.String("filter")

		// Getting container ID positional arg
		var containerID string
		if clictx.Args().Present() {
			containerID = clictx.Args().First()
		}

		ctx, exp, cancel, err := explorerEnvironment(clictx)
		if err != nil {
			return err
		}
		defer cancel()

		drifts, err := exp.ContainerDrift(ctx, filter, !clictx.Bool("mount-support-containers"), containerID)
		if err != nil {
			log.WithField("message", err).Error("retrieving container drift")
			if output == "json" && outputfile != "" {
				data := []string{}
				writeOutputFile(data, outputfile)
			}
			return nil
		}

		if strings.ToLower(output) == "json" {
			if outputfile != "" {
				writeOutputFile(drifts, outputfile)
			} else {
				printAsJSON(drifts)
			}
			return nil
		}

		tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0)
		defer tw.Flush()

		if output == "table" {

			fmt.Fprintf(tw, "CONTAINER ID\tADDED/MODIFIED\tDELETED\n")
		}

		for _, drift := range drifts {
			switch strings.ToLower(output) {
			case "json_line":
				printAsJSONLine(drift)
			default:
				// Prepare the data for display
				var addedOrModifiedFiles []string
				var inaccessibleFiles []string

				for _, fileinfo := range drift.AddedOrModified {
					if fileinfo.FileType == "executable" {
						addedOrModifiedFiles = append(addedOrModifiedFiles, fileinfo.FullPath+" (executable)")
					} else {
						addedOrModifiedFiles = append(addedOrModifiedFiles, fileinfo.FullPath)
					}
				}

				for _, fileinfo := range drift.InaccessibleFiles {
					inaccessibleFiles = append(inaccessibleFiles, fileinfo.FullPath)
				}

				displayAddedOrModifiedFiles := strings.Join(addedOrModifiedFiles, ", ")
				displayInaccessibleFiles := strings.Join(inaccessibleFiles, ", ")

				displayValues := fmt.Sprintf("%s\t%s\t%s",
					drift.ContainerID,
					displayAddedOrModifiedFiles,
					displayInaccessibleFiles,
				)

				fmt.Fprintf(tw, "%v\n", displayValues)
			}
		}

		return nil
	},
}
View Source
var ExportAllCommand = cli.Command{
	Name:        "export-all",
	Aliases:     []string{"export_all"},
	Usage:       "export all containers as image or archive",
	Description: "export all containers as image or archive",
	ArgsUsage:   "OUTPUTDIR",
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "image",
			Usage: "output container as raw image",
		},
		cli.BoolFlag{
			Name:  "archive",
			Usage: "output container as archive",
		},
		cli.StringFlag{
			Name:  "filter",
			Usage: "comma separated label filter using key=value",
		},
		cli.BoolFlag{
			Name:  "export-support-containers",
			Usage: "export Kubernetes supporting containers",
		},
	},
	Action: func(clictx *cli.Context) error {

		if runtime.GOOS != "linux" {
			return fmt.Errorf("exporting containers is only supported on Linux")
		}

		if clictx.NArg() < 1 {
			return fmt.Errorf("output directory is required")
		}
		outputDir := clictx.Args().First()

		exportAsImage := clictx.Bool("image")
		exportAsArchive := clictx.Bool("archive")

		if !exportAsArchive && !exportAsImage {
			exportAsImage = true
		}

		exportOptions := make(map[string]bool)
		exportOptions["image"] = exportAsImage
		exportOptions["archive"] = exportAsArchive

		filterString := clictx.String("filter")
		filterMap := getFilterMap(filterString)

		exportSupportContainers := clictx.Bool("export-support-containers")

		ctx, runtimeConfig, err := parseRuntimeConfig(clictx)
		if err != nil {
			return err
		}

		namespace := runtimeConfig["namespace"].(string)
		imageRootDir := runtimeConfig["imageRootDir"].(string)
		containerdRootDir := runtimeConfig["containerdRootDir"].(string)
		dockerRootDir := runtimeConfig["dockerRootDir"].(string)
		metadataFile := runtimeConfig["metadataFile"].(string)
		snapshotFile := runtimeConfig["snapshotFile"].(string)
		layercache := runtimeConfig["layerCache"].(string)
		sc := runtimeConfig["supportContainer"].(*explorers.SupportContainer)

		log.WithFields(log.Fields{
			"namespace":       namespace,
			"outputDir":       outputDir,
			"exportAsImage":   exportAsImage,
			"exportAsArchive": exportAsArchive,
		}).Debug("Processing export-all request")

		cXplr, err := containerd.NewExplorer(imageRootDir, containerdRootDir, metadataFile, snapshotFile, layercache, sc)
		if err == nil {
			if err := cXplr.ExportAllContainers(ctx, outputDir, exportOptions, filterMap, exportSupportContainers); err != nil {
				log.Errorf("exporting all containerd containers as image or archive: %v", err)
			}
		} else {
			log.Errorf("getting containerd explorer: %v", err)
		}

		dXplr, err := docker.NewExplorer(dockerRootDir, containerdRootDir, metadataFile, snapshotFile, sc)
		if err == nil {
			if err := dXplr.ExportAllContainers(ctx, outputDir, exportOptions, filterMap, exportSupportContainers); err != nil {
				log.Errorf("exporting all Docker containers as image or archive: %v", err)
			}
		} else {
			log.Errorf("getting Docker explorer: %v", err)
		}

		return nil
	},
}
View Source
var ExportCommand = cli.Command{
	Name:        "export",
	Usage:       "export a container as image or archive",
	Description: "export a container as image or archive",
	ArgsUsage:   "ID OUTPUTDIR",
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "image",
			Usage: "output container as raw image",
		},
		cli.BoolFlag{
			Name:  "archive",
			Usage: "output container as archive",
		},
	},
	Action: func(clictx *cli.Context) error {

		if runtime.GOOS != "linux" {
			return fmt.Errorf("exporting a container is only supported on Linux")
		}

		if clictx.NArg() < 2 {
			return fmt.Errorf("container ID and output directory are required")
		}

		containerID := clictx.Args().First()
		outputDir := clictx.Args().Get(1)

		exportAsImage := clictx.Bool("image")
		exportAsArchive := clictx.Bool("archive")

		if !exportAsArchive && !exportAsImage {
			exportAsImage = true
		}

		exportOptions := make(map[string]bool)
		exportOptions["image"] = exportAsImage
		exportOptions["archive"] = exportAsArchive

		ctx, runtimeConfig, err := parseRuntimeConfig(clictx)
		if err != nil {
			return err
		}

		namespace := runtimeConfig["namespace"].(string)
		imageRootDir := runtimeConfig["imageRootDir"].(string)
		containerdRootDir := runtimeConfig["containerdRootDir"].(string)
		dockerRootDir := runtimeConfig["dockerRootDir"].(string)
		metadataFile := runtimeConfig["metadataFile"].(string)
		snapshotFile := runtimeConfig["snapshotFile"].(string)
		layercache := runtimeConfig["layerCache"].(string)
		sc := runtimeConfig["supportContainer"].(*explorers.SupportContainer)

		log.WithFields(log.Fields{
			"namespace":       namespace,
			"containerID":     containerID,
			"outputDir":       outputDir,
			"exportAsImage":   exportAsImage,
			"exportAsArchive": exportAsArchive,
		}).Debug("Processing export request")

		cXplr, err := containerd.NewExplorer(imageRootDir, containerdRootDir, metadataFile, snapshotFile, layercache, sc)
		if err == nil {
			if err := cXplr.ExportContainer(ctx, containerID, outputDir, exportOptions); err != nil {
				log.Errorf("exporting %s as containerd container: %v", containerID, err)
			}
		} else {
			log.Errorf("getting containerd explorer: %v", err)
		}

		dXplr, err := docker.NewExplorer(dockerRootDir, containerdRootDir, metadataFile, snapshotFile, sc)
		if err == nil {
			if err := dXplr.ExportContainer(ctx, containerID, outputDir, exportOptions); err != nil {
				log.Errorf("exporting %s as Docker container: %v", containerID, err)
			}
		} else {
			log.Errorf("getting Docker explorer: %v", err)
		}

		return nil
	},
}
View Source
var InfoCommand = cli.Command{
	Name:        "info",
	Usage:       "show internal information",
	Description: "show internal information",
	Subcommands: cli.Commands{
		infoContainer,
	},
}
View Source
var ListCommand = cli.Command{
	Name:    "list",
	Aliases: []string{"ls"},
	Usage:   "lists container related information",
	Subcommands: cli.Commands{
		listNamespaces,
		listContainers,
		listContent,
		listImages,
		listSnapshots,
		listTasks,
	},
}
View Source
var MountAllCommand = cli.Command{
	Name:        "mount-all",
	Aliases:     []string{"mount_all"},
	Usage:       "mount all containers",
	Description: "mount all containers to subdirectories with the specified mount point",
	ArgsUsage:   "[flag] MOUNT_POINT",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "filter",
			Usage: "comma separated label filter using key=value pair",
		},
		cli.BoolFlag{
			Name:  "mount-support-containers",
			Usage: "mount Kubernetes supporting containers",
		},
	},
	Action: func(clictx *cli.Context) error {

		if runtime.GOOS != "linux" {
			return fmt.Errorf("mounting a container is only supported on Linux")
		}

		if clictx.NArg() < 1 {
			return fmt.Errorf("mount point is required")
		}

		mountpoint := clictx.Args().First()
		filter := clictx.String("filter")

		ctx, exp, cancel, err := explorerEnvironment(clictx)
		if err != nil {
			return err
		}
		defer cancel()

		if err := exp.MountAllContainers(ctx, mountpoint, filter, !clictx.Bool("mount-support-containers")); err != nil {
			return err
		}

		return nil
	},
}
View Source
var MountCommand = cli.Command{
	Name:        "mount",
	Usage:       "mount a container to a mount point",
	Description: "mount a container to a mount point",
	ArgsUsage:   "ID MOUNTPOINT",
	Action: func(clictx *cli.Context) error {

		if runtime.GOOS != "linux" {
			return fmt.Errorf("mounting a container is only supported on Linux")
		}

		if clictx.NArg() < 2 {
			return fmt.Errorf("container id and mount point are required")
		}

		namespace := clictx.GlobalString("namespace")
		containerid := clictx.Args().First()
		mountpoint := clictx.Args().Get(1)

		log.WithFields(log.Fields{
			"namespace":   namespace,
			"containerid": containerid,
			"mountpoint":  mountpoint,
		}).Debug("user provided mount options")

		ctx, exp, cancel, err := explorerEnvironment(clictx)
		if err != nil {
			return err
		}
		defer cancel()

		ctx = namespaces.WithNamespace(ctx, namespace)

		if err := exp.MountContainer(ctx, containerid, mountpoint); err != nil {
			return err
		}

		return nil
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

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