From 2ca38206048e3dc5b44b00fe5032c021bdfc2e00 Mon Sep 17 00:00:00 2001 From: fengxsong Date: Mon, 19 Dec 2022 16:28:48 +0800 Subject: [PATCH] refactor buildah interface, arguments as flagsetters (#2281) Signed-off-by: fengxsong Signed-off-by: fengxsong --- pkg/apply/processor/create.go | 3 +- pkg/apply/processor/install.go | 3 +- pkg/buildah/create.go | 31 ++++++++++++-- pkg/buildah/interface.go | 77 +++++++++++++++++++++++++--------- 4 files changed, 90 insertions(+), 24 deletions(-) diff --git a/pkg/apply/processor/create.go b/pkg/apply/processor/create.go index 173a929fa..9eaee0bcc 100644 --- a/pkg/apply/processor/create.go +++ b/pkg/apply/processor/create.go @@ -108,7 +108,8 @@ func (c *CreateProcessor) CheckImageType(cluster *v2.Cluster) error { func (c *CreateProcessor) PreProcess(cluster *v2.Cluster) error { logger.Info("Executing pipeline PreProcess in CreateProcessor.") - err := c.Buildah.Pull(buildah.DefaultPlatform(), buildah.PullIfMissing.String(), cluster.Spec.Image...) + err := c.Buildah.Pull(cluster.Spec.Image, buildah.WithPlatformOption(buildah.DefaultPlatform()), + buildah.WithPullPolicyOption(buildah.PullIfMissing.String())) if err != nil { return err } diff --git a/pkg/apply/processor/install.go b/pkg/apply/processor/install.go index 8fb6da655..1cefe6f6b 100644 --- a/pkg/apply/processor/install.go +++ b/pkg/apply/processor/install.go @@ -114,7 +114,8 @@ func (c *InstallProcessor) SyncStatusAndCheck(cluster *v2.Cluster) error { } func (c *InstallProcessor) PreProcess(cluster *v2.Cluster) error { - if err := c.Buildah.Pull(buildah.DefaultPlatform(), buildah.PullIfMissing.String(), c.NewImages...); err != nil { + if err := c.Buildah.Pull(c.NewImages, buildah.WithPlatformOption(buildah.DefaultPlatform()), + buildah.WithPullPolicyOption(buildah.PullIfMissing.String())); err != nil { return err } imageTypes := sets.NewString() diff --git a/pkg/buildah/create.go b/pkg/buildah/create.go index 82287ae90..add87f96d 100644 --- a/pkg/buildah/create.go +++ b/pkg/buildah/create.go @@ -18,24 +18,49 @@ import ( "os" "os/exec" + "github.com/containers/buildah/pkg/parse" "github.com/containers/storage/pkg/unshare" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/labring/sealos/pkg/utils/logger" ) +type createOptions struct { + name string + platform string +} + +func newDefaultCreateOptions() *createOptions { + return &createOptions{ + name: "default", + platform: parse.DefaultPlatform(), + } +} + +func (opts *createOptions) RegisterFlags(fs *pflag.FlagSet) { + fs.StringVarP(&opts.name, "cluster", "c", opts.name, "name of cluster to be created but not actually run") + fs.StringVar(&opts.platform, "platform", opts.platform, "set the OS/ARCH/VARIANT of the image to the provided value instead of the current operating system and architecture of the host (for example `linux/arm`)") +} + func newCreateCmd() *cobra.Command { - var clusterName string + opts := newDefaultCreateOptions() var createCmd = &cobra.Command{ Use: "create", Short: "Create a cluster without running the CMD, for inspecting image", Args: cobra.MinimumNArgs(1), RunE: func(c *cobra.Command, args []string) error { + oss, arch, variant, err := parse.Platform(opts.platform) + if err != nil { + return err + } bder, err := New("") if err != nil { return err } - info, err := bder.Create(clusterName, args[0]) + info, err := bder.Create(opts.name, args[0], + WithPlatformOption(v1.Platform{OS: oss, Architecture: arch, Variant: variant})) if err != nil { return err } @@ -68,6 +93,6 @@ func newCreateCmd() *cobra.Command { return nil }, } - createCmd.Flags().StringVarP(&clusterName, "cluster", "c", "default", "name of cluster to be created but not actually run") + opts.RegisterFlags(createCmd.Flags()) return createCmd } diff --git a/pkg/buildah/interface.go b/pkg/buildah/interface.go index 68070a4f7..0402c9309 100644 --- a/pkg/buildah/interface.go +++ b/pkg/buildah/interface.go @@ -25,17 +25,18 @@ import ( storagetypes "github.com/containers/storage/types" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/labring/sealos/pkg/utils/logger" ) type Interface interface { - Pull(v1.Platform, string, ...string) error - Load(string) (string, error) - InspectImage(string) (v1.Image, error) - Create(string, string) (buildah.BuilderInfo, error) - Delete(string) error - InspectContainer(string) (buildah.BuilderInfo, error) + Pull(imageNames []string, opts ...FlagSetter) error + Load(input string) (string, error) + InspectImage(name string) (v1.Image, error) + Create(name string, image string, opts ...FlagSetter) (buildah.BuilderInfo, error) + Delete(name string) error + InspectContainer(name string) (buildah.BuilderInfo, error) ListContainers() ([]JSONContainer, error) } @@ -61,14 +62,47 @@ type realImpl struct { systemContext *types.SystemContext } -func (impl *realImpl) Pull(pf v1.Platform, pullPolicy string, imageNames ...string) error { +type FlagSetter func(*pflag.FlagSet) error + +func newFlagSetter(k string, v string) FlagSetter { + return func(fs *pflag.FlagSet) error { + if f := fs.Lookup(k); f != nil { + return fs.Set(k, v) + } + return nil + } +} + +func WithPlatformOption(pf v1.Platform) FlagSetter { + return func(fs *pflag.FlagSet) error { + for _, fn := range []FlagSetter{ + newFlagSetter("os", pf.OS), + newFlagSetter("arch", pf.Architecture), + newFlagSetter("variant", pf.Variant), + } { + if err := fn(fs); err != nil { + return err + } + } + return nil + } +} + +func WithPullPolicyOption(policy string) FlagSetter { + return func(fs *pflag.FlagSet) error { + return newFlagSetter("policy", policy)(fs) + } +} + +func (impl *realImpl) Pull(imageNames []string, opts ...FlagSetter) error { cmd := impl.mockCmd() iopt := newDefaultPullOptions() - iopt.os = pf.OS - iopt.arch = pf.Architecture - iopt.variant = pf.Variant - iopt.pullPolicy = pullPolicy _ = iopt.RegisterFlags(cmd.Flags()) + for i := range opts { + if err := opts[i](cmd.Flags()); err != nil { + return err + } + } if err := setDefaultFlags(cmd); err != nil { return err } @@ -89,11 +123,11 @@ func (impl *realImpl) InspectImage(name string) (v1.Image, error) { return out.OCIv1, nil } -func (impl *realImpl) Create(name string, image string) (buildah.BuilderInfo, error) { +func (impl *realImpl) Create(name string, image string, opts ...FlagSetter) (buildah.BuilderInfo, error) { if err := impl.Delete(impl.finalizeName(name)); err != nil { return buildah.BuilderInfo{}, fmt.Errorf("failed to delete: %v", err) } - if _, err := impl.from(impl.finalizeName(name), image); err != nil { + if _, err := impl.from(impl.finalizeName(name), image, opts...); err != nil { return buildah.BuilderInfo{}, fmt.Errorf("failed to from: %v", err) } if _, err := impl.mount(impl.finalizeName(name)); err != nil { @@ -113,16 +147,21 @@ func (impl *realImpl) Delete(name string) error { return builder.Delete() } -func (impl *realImpl) from(name, image string) (*buildah.Builder, error) { +func (impl *realImpl) from(name, image string, opts ...FlagSetter) (*buildah.Builder, error) { cmd := impl.mockCmd() - opts := newDefaultFromReply() - opts.name = impl.finalizeName(name) - opts.pull = "" - opts.RegisterFlags(cmd.Flags()) + iopts := newDefaultFromReply() + iopts.name = impl.finalizeName(name) + iopts.pull = "" + iopts.RegisterFlags(cmd.Flags()) + for i := range opts { + if err := opts[i](cmd.Flags()); err != nil { + return nil, err + } + } if err := setDefaultFlags(cmd); err != nil { return nil, err } - return doFrom(cmd, image, opts, impl.store, nil) + return doFrom(cmd, image, iopts, impl.store, nil) } func (impl *realImpl) mount(name string) (jsonMount, error) {