diff --git a/cmd/app/server.go b/cmd/app/server.go index 5e992e4..68afb33 100644 --- a/cmd/app/server.go +++ b/cmd/app/server.go @@ -2,8 +2,6 @@ package app import ( "context" - metrics "github.com/labring/cri-shim/pkg/metric" - "go.opentelemetry.io/otel" "log/slog" "net/http" "os" @@ -11,10 +9,13 @@ import ( "syscall" "time" + "github.com/spf13/cobra" + "go.opentelemetry.io/otel" + imageutil "github.com/labring/cri-shim/pkg/image" + metrics "github.com/labring/cri-shim/pkg/metric" "github.com/labring/cri-shim/pkg/server" "github.com/labring/cri-shim/pkg/types" - "github.com/spf13/cobra" ) var cfg *types.Config @@ -39,6 +40,7 @@ func run(cfg *types.Config) { CRISocket: cfg.RuntimeSocket, ContainerdNamespace: cfg.ContainerdNamespace, PoolSize: cfg.PoolSize, + Estargz: cfg.Estargz, MetricFlag: cfg.MetricsConfig.Metric, }, imageutil.RegistryOptions{ diff --git a/pkg/image/interface.go b/pkg/image/interface.go index e31f4ee..bff260d 100644 --- a/pkg/image/interface.go +++ b/pkg/image/interface.go @@ -29,6 +29,7 @@ type ImageInterface interface { Pull(context.Context, string, string, string) error Commit(ctx context.Context, imageName, containerID string, pause bool) error Login(ctx context.Context, serverAddress, username, password string) error + ConvertToEstargz(ctx context.Context, srcRawRef, destRawRef string) error Squash(ctx context.Context, SourceImageRef, TargetImageName string) error Remove(ctx context.Context, args string, force, async bool) error Tag(ctx context.Context, src, dest string) error @@ -94,11 +95,12 @@ func (impl *imageInterfaceImpl) Commit(ctx context.Context, imageName, container // convert converts an image to the specified format // srcRawRef: the source image reference // destRawRef: the destination image reference -func (impl *imageInterfaceImpl) convert(ctx context.Context, srcRawRef, destRawRef string) error { +func (impl *imageInterfaceImpl) ConvertToEstargz(ctx context.Context, srcRawRef, destRawRef string) error { slog.Info("Converting image", "Source", srcRawRef, "Destination", destRawRef) opt := types.ImageConvertOptions{ GOptions: impl.GlobalOptions, Oci: true, + Estargz: true, Stdout: impl.Stdout, } return image.Convert(ctx, impl.Client, srcRawRef, destRawRef, opt) diff --git a/pkg/server/server.go b/pkg/server/server.go index 9261c6e..c896707 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -2,7 +2,6 @@ package server import ( "context" - "go.opentelemetry.io/otel/metric" "log/slog" "net" "os" @@ -10,6 +9,8 @@ import ( "strings" "time" + "go.opentelemetry.io/otel/metric" + "github.com/labring/cri-shim/pkg/container" imageutil "github.com/labring/cri-shim/pkg/image" netutil "github.com/labring/cri-shim/pkg/net" @@ -38,6 +39,7 @@ type Options struct { // PoolSize is the size of the pool of goroutines. PoolSize int + Estargz bool MetricFlag bool } @@ -416,8 +418,8 @@ func (s *Server) CommitContainer(task types.Task) error { if err = s.imageClient.Pull(ctx, info.ImageRef, registry.UserName, registry.Password); err != nil { slog.Error("failed to pull image", "image name", imageName, "error", err) } - - if err := s.imageClient.Commit(ctx, initialImageName, statusResp.Status.Id, false); err != nil { + currentImageName := initialImageName + if err := s.imageClient.Commit(ctx, currentImageName, statusResp.Status.Id, false); err != nil { slog.Error("failed to commit container after retries", "containerId", statusResp.Status.Id, "image name", initialImageName, "error", err) s.pool.SetCommitStatus(task.ContainerID, types.ErrorCommit) if s.options.MetricFlag { @@ -433,17 +435,27 @@ func (s *Server) CommitContainer(task types.Task) error { defer s.imageClient.Remove(ctx, initialImageName, false, false) if info.SquashEnabled { - if err = s.imageClient.Squash(ctx, initialImageName, imageName); err != nil { + slog.Info("squash enabled, start squash image") + if err = s.imageClient.Squash(ctx, currentImageName, currentImageName+"-squashed"); err != nil { slog.Error("failed to squash image", "image name", imageName, "error", err) s.pool.SetCommitStatus(task.ContainerID, types.ErrorCommit) return err } - } else { - if err = s.imageClient.Tag(ctx, initialImageName, imageName); err != nil { - slog.Error("failed to tag image", "image name", imageName, "error", err) + currentImageName = currentImageName + "-squashed" + } + if s.options.Estargz { + slog.Info("estargz enabled, start convert to estargz image") + if err = s.imageClient.ConvertToEstargz(ctx, currentImageName, currentImageName+"-converted"); err != nil { + slog.Error("failed to convert image to estargz", "image name", imageName, "error", err) s.pool.SetCommitStatus(task.ContainerID, types.ErrorCommit) return err } + currentImageName = currentImageName + "-converted" + } + if err = s.imageClient.Tag(ctx, currentImageName, imageName); err != nil { + slog.Error("failed to tag image", "image name", imageName, "error", err) + s.pool.SetCommitStatus(task.ContainerID, types.ErrorCommit) + return err } } diff --git a/pkg/types/config.go b/pkg/types/config.go index c591dd8..c38a992 100644 --- a/pkg/types/config.go +++ b/pkg/types/config.go @@ -21,6 +21,7 @@ type Config struct { GlobalRegistryRepo string ContainerdNamespace string PoolSize int + Estargz bool Debug bool Trace bool MetricsConfig MetricsConfig @@ -48,6 +49,7 @@ func BindOptions(cmd *cobra.Command) *Config { cmd.Flags().IntVar(&cfg.PoolSize, "pool-size", 10, "Pool size") cmd.Flags().BoolVar(&cfg.Debug, "debug", false, "enable debug logging") cmd.Flags().BoolVar(&cfg.Trace, "trace", false, "enable pprof to trace") + cmd.Flags().BoolVar(&cfg.Estargz, "estargz", false, "enable estargz image") cmd.Flags().BoolVar(&cfg.MetricsConfig.Metric, "metric", false, "enable otel to metric") cmd.Flags().StringVar(&cfg.MetricsConfig.Endpoint, "metric-endpoint", "localhost:8428", "VictoriaMetrics endpoint - host:port") cmd.Flags().StringVar(&cfg.MetricsConfig.IngestPath, "metric-ingestPath", "/opentelemetry/api/v1/push", "url path for ingestion path")