mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
add images push command
Signed-off-by: 24sama <jacksama@foxmail.com>
This commit is contained in:
parent
5702163f78
commit
48f5f90c98
|
|
@ -17,6 +17,7 @@
|
|||
package artifact
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/cmd/ctl/artifact/images"
|
||||
"github.com/kubesphere/kubekey/cmd/ctl/options"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -31,7 +32,7 @@ func NewArtifactOptions() *ArtifactOptions {
|
|||
}
|
||||
}
|
||||
|
||||
// NewCmdArtifact creates a new create command
|
||||
// NewCmdArtifact creates a new cobra.Command for `kubekey artifact`
|
||||
func NewCmdArtifact() *cobra.Command {
|
||||
o := NewArtifactOptions()
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -41,6 +42,7 @@ func NewCmdArtifact() *cobra.Command {
|
|||
|
||||
o.CommonOptions.AddCommonFlag(cmd)
|
||||
|
||||
cmd.AddCommand(NewCmdCreateCluster())
|
||||
cmd.AddCommand(NewCmdArtifactExport())
|
||||
cmd.AddCommand(images.NewCmdArtifactImages())
|
||||
return cmd
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ func NewArtifactExportOptions() *ArtifactExportOptions {
|
|||
}
|
||||
}
|
||||
|
||||
// NewCmdCreateCluster creates a new create cluster command
|
||||
func NewCmdCreateCluster() *cobra.Command {
|
||||
// NewCmdArtifactExport creates a new `kubekey artifact export` command
|
||||
func NewCmdArtifactExport() *cobra.Command {
|
||||
o := NewArtifactExportOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "export",
|
||||
|
|
@ -60,7 +60,7 @@ func NewCmdCreateCluster() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func (o *ArtifactExportOptions) Complete(cmd *cobra.Command, args []string) error {
|
||||
func (o *ArtifactExportOptions) Complete(_ *cobra.Command, _ []string) error {
|
||||
var err error
|
||||
if o.Output == "" {
|
||||
o.Output = "kubekey-artifact.tar.gz"
|
||||
|
|
@ -74,7 +74,7 @@ func (o *ArtifactExportOptions) Complete(cmd *cobra.Command, args []string) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *ArtifactExportOptions) Validate(args []string) error {
|
||||
func (o *ArtifactExportOptions) Validate(_ []string) error {
|
||||
if o.ManifestFile == "" {
|
||||
return fmt.Errorf("--manifest can not be an empty string")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2022 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package images
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/cmd/ctl/options"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type ArtifactImagesOptions struct {
|
||||
CommonOptions *options.CommonOptions
|
||||
}
|
||||
|
||||
func NewArtifactImagesOptions() *ArtifactImagesOptions {
|
||||
return &ArtifactImagesOptions{
|
||||
CommonOptions: options.NewCommonOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
// NewCmdArtifactImages creates a new `kubekey artifact image` command
|
||||
func NewCmdArtifactImages() *cobra.Command {
|
||||
o := NewArtifactImagesOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "images",
|
||||
Aliases: []string{"image", "i"},
|
||||
Short: "manage KubeKey artifact image",
|
||||
}
|
||||
|
||||
o.CommonOptions.AddCommonFlag(cmd)
|
||||
cmd.AddCommand(NewCmdArtifactImagesPush())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
Copyright 2022 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package images
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/cmd/ctl/options"
|
||||
"github.com/kubesphere/kubekey/cmd/ctl/util"
|
||||
"github.com/kubesphere/kubekey/pkg/artifact"
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/precheck"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/module"
|
||||
"github.com/kubesphere/kubekey/pkg/core/pipeline"
|
||||
"github.com/kubesphere/kubekey/pkg/filesystem"
|
||||
"github.com/kubesphere/kubekey/pkg/images"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type ArtifactImagesPushOptions struct {
|
||||
CommonOptions *options.CommonOptions
|
||||
|
||||
ImageDirPath string
|
||||
Artifact string
|
||||
ClusterCfgFile string
|
||||
}
|
||||
|
||||
func NewArtifactImagesPushOptions() *ArtifactImagesPushOptions {
|
||||
return &ArtifactImagesPushOptions{
|
||||
CommonOptions: options.NewCommonOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
// NewCmdArtifactImagesPush creates a new `kubekey artifacts images push` command
|
||||
func NewCmdArtifactImagesPush() *cobra.Command {
|
||||
o := NewArtifactImagesPushOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "push",
|
||||
Short: "push images to a registry from an artifact",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
util.CheckErr(o.Complete(cmd, args))
|
||||
util.CheckErr(o.Validate(args))
|
||||
util.CheckErr(o.Run())
|
||||
},
|
||||
}
|
||||
|
||||
o.CommonOptions.AddCommonFlag(cmd)
|
||||
o.AddFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (o *ArtifactImagesPushOptions) Complete(_ *cobra.Command, _ []string) error {
|
||||
if o.ImageDirPath == "" && o.Artifact == "" {
|
||||
currentDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get current directory")
|
||||
}
|
||||
o.ImageDirPath = filepath.Join(currentDir, "kubekey", "images")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArtifactImagesPushOptions) Validate(_ []string) error {
|
||||
if o.ClusterCfgFile == "" {
|
||||
return errors.New("kubekey config file is required")
|
||||
}
|
||||
if o.ImageDirPath != "" && o.Artifact != "" {
|
||||
return errors.New("only one of --image-dir or --artifact can be specified")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArtifactImagesPushOptions) Run() error {
|
||||
arg := common.Argument{
|
||||
ImagesDir: o.ImageDirPath,
|
||||
Artifact: o.Artifact,
|
||||
FilePath: o.ClusterCfgFile,
|
||||
Debug: o.CommonOptions.Verbose,
|
||||
IgnoreErr: o.CommonOptions.IgnoreErr,
|
||||
}
|
||||
return runPush(arg)
|
||||
}
|
||||
|
||||
func (o *ArtifactImagesPushOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.ImageDirPath, "images-dir", "", "", "Path to a KubeKey artifact images directory")
|
||||
cmd.Flags().StringVarP(&o.Artifact, "artifact", "a", "", "Path to a KubeKey artifact")
|
||||
cmd.Flags().StringVarP(&o.ClusterCfgFile, "filename", "f", "", "Path to a configuration file")
|
||||
}
|
||||
|
||||
func runPush(arg common.Argument) error {
|
||||
runtime, err := common.NewKubeRuntime(common.File, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := newImagesPushPipeline(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newImagesPushPipeline(runtime *common.KubeRuntime) error {
|
||||
noArtifact := runtime.Arg.Artifact == ""
|
||||
|
||||
m := []module.Module{
|
||||
&precheck.CRIPreCheckModule{},
|
||||
&artifact.UnArchiveModule{Skip: noArtifact},
|
||||
&images.PushModule{ImagePath: runtime.Arg.ImagesDir},
|
||||
&filesystem.ChownWorkDirModule{},
|
||||
}
|
||||
|
||||
p := pipeline.Pipeline{
|
||||
Name: "ArtifactImagesPushPipeline",
|
||||
Modules: m,
|
||||
Runtime: runtime,
|
||||
}
|
||||
|
||||
if err := p.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -139,3 +139,22 @@ func (c *ClusterPreCheckModule) Init() {
|
|||
getKubernetesNodesStatus,
|
||||
}
|
||||
}
|
||||
|
||||
type CRIPreCheckModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (c *CRIPreCheckModule) Init() {
|
||||
c.Name = "CRIPreCheckModule"
|
||||
c.Desc = "Do CRI pre-check on local node"
|
||||
|
||||
criCheck := &task.LocalTask{
|
||||
Name: "CRIPreCheck",
|
||||
Desc: "Check CRI",
|
||||
Action: new(CRIPreCheck),
|
||||
}
|
||||
|
||||
c.Tasks = []task.Interface{
|
||||
criCheck,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/kubesphere/kubekey/pkg/version/kubesphere"
|
||||
"github.com/pkg/errors"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -275,3 +276,14 @@ func (g *GetKubernetesNodesStatus) Execute(runtime connector.Runtime) error {
|
|||
g.PipelineCache.Set(common.ClusterNodeStatus, nodeStatus)
|
||||
return nil
|
||||
}
|
||||
|
||||
type CRIPreCheck struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (c *CRIPreCheck) Execute(_ connector.Runtime) error {
|
||||
if _, err := exec.Command("/bin/bash", "-c", "which ctr").CombinedOutput(); err != nil {
|
||||
return errors.New("containerd is not installed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ type Argument struct {
|
|||
Artifact string
|
||||
InstallPackages bool
|
||||
CertificatesDir string
|
||||
ImagesDir string
|
||||
}
|
||||
|
||||
func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ func (c *ChownModule) Init() {
|
|||
}
|
||||
|
||||
type ChownWorkDirModule struct {
|
||||
common.ArtifactModule
|
||||
module.BaseTaskModule
|
||||
}
|
||||
|
||||
func (c *ChownWorkDirModule) Init() {
|
||||
c.Name = "ChownWorkDirModule"
|
||||
c.Desc = "Change file and dir owner"
|
||||
c.Name = "ChownWorkerModule"
|
||||
c.Desc = "Change kubekey work dir mode and owner"
|
||||
|
||||
userKubeDir := &task.LocalTask{
|
||||
Name: "ChownFileAndDir",
|
||||
|
|
@ -57,6 +57,19 @@ func (c *ChownWorkDirModule) Init() {
|
|||
Action: &LocalTaskChown{Path: c.Runtime.GetWorkDir()},
|
||||
}
|
||||
|
||||
c.Tasks = []task.Interface{
|
||||
userKubeDir,
|
||||
}
|
||||
}
|
||||
|
||||
type ChownOutputModule struct {
|
||||
common.ArtifactModule
|
||||
}
|
||||
|
||||
func (c *ChownOutputModule) Init() {
|
||||
c.Name = "ChownOutputModule"
|
||||
c.Desc = "Change file and dir owner"
|
||||
|
||||
output := &task.LocalTask{
|
||||
Name: "Chown output file",
|
||||
Desc: "Chown output file",
|
||||
|
|
@ -64,7 +77,6 @@ func (c *ChownWorkDirModule) Init() {
|
|||
}
|
||||
|
||||
c.Tasks = []task.Interface{
|
||||
userKubeDir,
|
||||
output,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ func (p *PullModule) Init() {
|
|||
|
||||
type PushModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
Skip bool
|
||||
ImagePath string
|
||||
}
|
||||
|
||||
func (p *PushModule) IsSkip() bool {
|
||||
|
|
@ -87,7 +88,7 @@ func (p *PushModule) Init() {
|
|||
push := &task.LocalTask{
|
||||
Name: "PushImages",
|
||||
Desc: "Push images to private registry",
|
||||
Action: new(PushImage),
|
||||
Action: &PushImage{ImagesPath: p.ImagePath},
|
||||
}
|
||||
|
||||
p.Tasks = []task.Interface{
|
||||
|
|
|
|||
|
|
@ -136,10 +136,17 @@ func GetImage(runtime connector.ModuleRuntime, kubeConf *common.KubeConf, name s
|
|||
|
||||
type PushImage struct {
|
||||
common.KubeAction
|
||||
ImagesPath string
|
||||
}
|
||||
|
||||
func (p *PushImage) Execute(runtime connector.Runtime) error {
|
||||
imagesPath := filepath.Join(runtime.GetWorkDir(), "images")
|
||||
var imagesPath string
|
||||
if p.ImagesPath != "" {
|
||||
imagesPath = p.ImagesPath
|
||||
} else {
|
||||
imagesPath = filepath.Join(runtime.GetWorkDir(), "images")
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(imagesPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(errors.WithStack(err), "read %s dir faied", imagesPath)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ func NewArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
|
|||
&binaries.ArtifactBinariesModule{},
|
||||
&artifact.RepositoryModule{},
|
||||
&artifact.ArchiveModule{},
|
||||
&filesystem.ChownOutputModule{},
|
||||
&filesystem.ChownWorkDirModule{},
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +59,7 @@ func NewK3sArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
|
|||
&binaries.K3sArtifactBinariesModule{},
|
||||
&artifact.RepositoryModule{},
|
||||
&artifact.ArchiveModule{},
|
||||
&filesystem.ChownOutputModule{},
|
||||
&filesystem.ChownWorkDirModule{},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue