diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 33dd163b6..64ebff7cd 100755 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -77,3 +77,13 @@ jobs: with: name: sealos-arm64 path: dist/sealos_linux_arm64/sealos + - name: Save build binaries linux-amd64 sealctl + uses: actions/upload-artifact@v2 + with: + name: sealctl-amd64 + path: dist/sealctl_linux_amd64/sealctl + - name: Save build binaries linux-arm64 + uses: actions/upload-artifact@v2 + with: + name: sealctl-arm64 + path: dist/sealctl_linux_arm64/sealctl diff --git a/cmd/sealctl/cmd/cert.go b/cmd/sealctl/cmd/cert.go index 521da6d5e..6b2e60dc0 100755 --- a/cmd/sealctl/cmd/cert.go +++ b/cmd/sealctl/cmd/cert.go @@ -21,17 +21,7 @@ import ( "os" ) -type Flag struct { - AltNames []string - NodeName string - ServiceCIDR string - NodeIP string - DNSDomain string - CertPath string - CertEtcdPath string -} -var config *Flag // certCmd represents the cert command var certCmd = &cobra.Command{ @@ -39,7 +29,7 @@ var certCmd = &cobra.Command{ Short: "generate certs", Long: `you can specify expire time`, Run: func(cmd *cobra.Command, args []string) { - err := cert.GenerateCert(config.CertPath, config.CertEtcdPath, config.AltNames, config.NodeIP, config.NodeName, config.ServiceCIDR, config.DNSDomain) + err := cert.GenerateCert(flag.Cert.CertPath, flag.Cert.CertEtcdPath, flag.Cert.AltNames, flag.Cert.NodeIP, flag.Cert.NodeName, flag.Cert.ServiceCIDR, flag.Cert.DNSDomain) if err != nil { logger.Error(err) os.Exit(-1) @@ -48,14 +38,13 @@ var certCmd = &cobra.Command{ } func init() { - config = &Flag{} rootCmd.AddCommand(certCmd) - certCmd.Flags().StringSliceVar(&config.AltNames, "alt-names", []string{}, "like sealyun.com or 10.103.97.2") - certCmd.Flags().StringVar(&config.NodeName, "node-name", "", "like master0") - certCmd.Flags().StringVar(&config.ServiceCIDR, "service-cidr", "", "like 10.103.97.2/24") - certCmd.Flags().StringVar(&config.NodeIP, "node-ip", "", "like 10.103.97.2") - certCmd.Flags().StringVar(&config.DNSDomain, "dns-domain", "cluster.local", "cluster dns domain") - certCmd.Flags().StringVar(&config.CertPath, "cert-path", "/etc/kubernetes/pki", "kubernetes cert file path") - certCmd.Flags().StringVar(&config.CertEtcdPath, "cert-etcd-path", "/etc/kubernetes/pki/etcd", "kubernetes etcd cert file path") + certCmd.Flags().StringSliceVar(&flag.Cert.AltNames, "alt-names", []string{}, "like sealyun.com or 10.103.97.2") + certCmd.Flags().StringVar(&flag.Cert.NodeName, "node-name", "", "like master0") + certCmd.Flags().StringVar(&flag.Cert.ServiceCIDR, "service-cidr", "", "like 10.103.97.2/24") + certCmd.Flags().StringVar(&flag.Cert.NodeIP, "node-ip", "", "like 10.103.97.2") + certCmd.Flags().StringVar(&flag.Cert.DNSDomain, "dns-domain", "cluster.local", "cluster dns domain") + certCmd.Flags().StringVar(&flag.Cert.CertPath, "cert-path", "/etc/kubernetes/pki", "kubernetes cert file path") + certCmd.Flags().StringVar(&flag.Cert.CertEtcdPath, "cert-etcd-path", "/etc/kubernetes/pki/etcd", "kubernetes etcd cert file path") } diff --git a/cmd/sealctl/cmd/cri.go b/cmd/sealctl/cmd/cri.go new file mode 100644 index 000000000..15e6feca5 --- /dev/null +++ b/cmd/sealctl/cmd/cri.go @@ -0,0 +1,244 @@ +/* +Copyright 2022 cuisongliu@qq.com. + +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 cmd + +import ( + "fmt" + "github.com/fanux/sealos/pkg/cri" + "github.com/fanux/sealos/pkg/utils/logger" + "github.com/spf13/cobra" + utilsexec "k8s.io/utils/exec" + "os" + "strconv" + "strings" +) + +func NewCRICmd() *cobra.Command { + var cmd = &cobra.Command{ + Use: "cri", + Short: "cri manager", + //Run: func(cmd *cobra.Command, args []string) { + // + //}, + } + cmd.AddCommand(NewIsDockerCmd()) + cmd.AddCommand(NewIsRunningCmd()) + cmd.AddCommand(NewListKubeContainersCmd()) + cmd.AddCommand(NewRemoveContainersCmd()) + cmd.AddCommand(NewPullImageCmd()) + cmd.AddCommand(NewImageExistsCmd()) + cmd.AddCommand(NewCGroupDriverCmd()) + cmd.PersistentFlags().StringVar(&flag.CRI.socketPath, "socket-path", "", "cri socket path") + cmd.PersistentFlags().StringVar(&flag.CRI.configPath, "config", "", "cri config file") + + return cmd +} + +func NewIsDockerCmd() *cobra.Command { + var cmd = &cobra.Command{ + Use: "is-docker", + Short: "cri manager is-docker", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + isDocker := runtime.IsDocker() + println(strconv.FormatBool(isDocker)) + }, + } + return cmd +} +func NewIsRunningCmd() *cobra.Command { + var shortPrint bool + var cmd = &cobra.Command{ + Use: "is-running", + Short: "cri manager is-running", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + err := runtime.IsRunning() + if shortPrint { + println(strconv.FormatBool(err == nil)) + return + } + if err != nil { + logger.Error(err) + return + } + logger.Info("container runtime is running") + }, + } + cmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print just result.") + return cmd +} +func NewListKubeContainersCmd() *cobra.Command { + var shortPrint bool + var cmd = &cobra.Command{ + Use: "list-containers", + Short: "cri manager list-containers", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + containers, err := runtime.ListKubeContainers() + if err != nil { + logger.Error(err) + os.Exit(1) + } + if shortPrint { + println(fmt.Sprintf("%s", strings.Join(containers, ","))) + return + } + logger.Info("container runtime cgroup-driver is %+v", containers) + }, + } + cmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print just result.") + return cmd +} +func NewRemoveContainersCmd() *cobra.Command { + var containers []string + var cmd = &cobra.Command{ + Use: "remove-containers", + Short: "cri manager remove-containers", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + if len(containers) == 0 { + logger.Error("container runtime containers is empty.") + os.Exit(1) + } + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + err := runtime.RemoveContainers(containers) + if err != nil { + logger.Error(err) + return + } + logger.Info("container runtime remove containers %+v success.", containers) + }, + } + cmd.Flags().StringSliceVar(&containers, "containers", []string{}, "containers name list") + return cmd +} +func NewPullImageCmd() *cobra.Command { + var imageName string + var cmd = &cobra.Command{ + Use: "pull-image", + Short: "cri manager pull-image", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + if imageName == "" { + logger.Error("container runtime pull image name is empty.", imageName) + os.Exit(1) + } + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + err := runtime.PullImage(imageName) + if err != nil { + logger.Error(err) + return + } + logger.Info("container runtime pull image %s success.", imageName) + }, + } + cmd.Flags().StringVar(&imageName, "image", "", "image name") + return cmd +} +func NewImageExistsCmd() *cobra.Command { + var shortPrint bool + var imageName string + var cmd = &cobra.Command{ + Use: "image-exists", + Short: "cri manager image-exists", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + if imageName == "" { + logger.Error("container runtime image exists name is empty.", imageName) + os.Exit(1) + } + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + b := runtime.ImageExists(imageName) + if shortPrint { + println(strconv.FormatBool(b)) + return + } + if !b { + logger.Warn("container runtime image name %s is not exists", imageName) + return + } + logger.Info("container runtime image name %s is exists", imageName) + }, + } + cmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print just result.") + return cmd +} +func NewCGroupDriverCmd() *cobra.Command { + var shortPrint bool + var cmd = &cobra.Command{ + Use: "cgroup-driver", + Short: "cri manager cgroup-driver", + PreRun: func(cmd *cobra.Command, args []string) { + criCheck() + }, + Run: func(cmd *cobra.Command, args []string) { + runtime := criRuntime() + driver, err := runtime.CGroupDriver() + if err != nil { + logger.Error(err) + os.Exit(1) + } + if shortPrint { + println(driver) + return + } + logger.Info("container runtime cgroup-driver is %s", driver) + }, + } + cmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print just result.") + return cmd +} + + + +func criCheck() { + var err error + if flag.CRI.socketPath == "" { + flag.CRI.socketPath, err = cri.DetectCRISocket() + } + if err != nil { + logger.Error(err) + os.Exit(1) + } +} +func criRuntime() cri.ContainerRuntime { + rt, err := cri.NewContainerRuntime(utilsexec.New(), flag.CRI.socketPath, flag.CRI.configPath) + if err != nil { + logger.Error(err) + os.Exit(1) + } + return rt +} +func init() { + rootCmd.AddCommand(NewCRICmd()) +} diff --git a/cmd/sealctl/cmd/flags.go b/cmd/sealctl/cmd/flags.go new file mode 100644 index 000000000..c43cbc72a --- /dev/null +++ b/cmd/sealctl/cmd/flags.go @@ -0,0 +1,51 @@ +/* +Copyright 2022 cuisongliu@qq.com. + +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 cmd + +import "github.com/sealyun/lvscare/care" + +type Flag struct { + Cert struct { + AltNames []string + NodeName string + ServiceCIDR string + NodeIP string + DNSDomain string + CertPath string + CertEtcdPath string + } + Hosts struct { + HostsPath string + } + Ipvs care.LvsCare + Route struct { + host string + gatewayIP string + } + StaticPod struct{ + staticPodPath string + } + Version struct{ + shortPrint bool + } + CRI struct{ + socketPath string + configPath string + } +} + +var flag Flag diff --git a/cmd/sealctl/cmd/hosts.go b/cmd/sealctl/cmd/hosts.go index aa900d120..43a51a9b3 100644 --- a/cmd/sealctl/cmd/hosts.go +++ b/cmd/sealctl/cmd/hosts.go @@ -22,8 +22,6 @@ import ( "github.com/spf13/cobra" ) -var hostsPath string - func NewHostsCmd() *cobra.Command { var cmd = &cobra.Command{ Use: "hosts", @@ -36,7 +34,7 @@ func NewHostsCmd() *cobra.Command { cmd.AddCommand(NewHostsListCmd()) cmd.AddCommand(NewHostsAddCmd()) cmd.AddCommand(NewHostsDeleteCmd()) - cmd.PersistentFlags().StringVar(&hostsPath, "path", "/etc/hosts", "default hosts path") + cmd.PersistentFlags().StringVar(&flag.Hosts.HostsPath, "path", "/etc/hosts", "default hosts path") return cmd } @@ -45,7 +43,7 @@ func NewHostsListCmd() *cobra.Command { Use: "list", Short: "hosts manager list", Run: func(cmd *cobra.Command, args []string) { - hf := &hosts.HostFile{Path: hostsPath} + hf := &hosts.HostFile{Path: flag.Hosts.HostsPath} hf.ListCurrentHosts() }, } @@ -67,7 +65,7 @@ func NewHostsAddCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - hf := &hosts.HostFile{Path: hostsPath} + hf := &hosts.HostFile{Path: flag.Hosts.HostsPath} hf.AppendHost(domain, ip) }, } @@ -88,7 +86,7 @@ func NewHostsDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - hf := &hosts.HostFile{Path: hostsPath} + hf := &hosts.HostFile{Path: flag.Hosts.HostsPath} hf.DeleteDomain(domain) }, } diff --git a/cmd/sealctl/cmd/ipvs.go b/cmd/sealctl/cmd/ipvs.go index ef37051db..465ac340a 100644 --- a/cmd/sealctl/cmd/ipvs.go +++ b/cmd/sealctl/cmd/ipvs.go @@ -15,18 +15,15 @@ package cmd import ( - "github.com/sealyun/lvscare/care" "github.com/spf13/cobra" ) -var Ipvs care.LvsCare - // ipvsCmd represents the ipvs command var ipvsCmd = &cobra.Command{ Use: "ipvs", Short: "sealos create or care local ipvs lb", Run: func(cmd *cobra.Command, args []string) { - Ipvs.VsAndRsCare() + flag.Ipvs.VsAndRsCare() }, } @@ -34,14 +31,14 @@ func init() { rootCmd.AddCommand(ipvsCmd) // Here you will define your flags and configuration settings. - ipvsCmd.Flags().BoolVar(&Ipvs.RunOnce, "run-once", false, "is run once mode") - ipvsCmd.Flags().BoolVarP(&Ipvs.Clean, "clean", "c", true, " clean Vip ipvs rule before join node, if Vip has no ipvs rule do nothing.") - ipvsCmd.Flags().StringVar(&Ipvs.VirtualServer, "vs", "", "virturl server like 10.54.0.2:6443") - ipvsCmd.Flags().StringSliceVar(&Ipvs.RealServer, "rs", []string{}, "virturl server like 192.168.0.2:6443") + ipvsCmd.Flags().BoolVar(&flag.Ipvs.RunOnce, "run-once", false, "is run once mode") + ipvsCmd.Flags().BoolVarP(&flag.Ipvs.Clean, "clean", "c", true, " clean Vip ipvs rule before join node, if Vip has no ipvs rule do nothing.") + ipvsCmd.Flags().StringVar(&flag.Ipvs.VirtualServer, "vs", "", "virturl server like 10.54.0.2:6443") + ipvsCmd.Flags().StringSliceVar(&flag.Ipvs.RealServer, "rs", []string{}, "virturl server like 192.168.0.2:6443") - ipvsCmd.Flags().StringVar(&Ipvs.HealthPath, "health-path", "/healthz", "health check path") - ipvsCmd.Flags().StringVar(&Ipvs.HealthSchem, "health-schem", "https", "health check schem") - ipvsCmd.Flags().Int32Var(&Ipvs.Interval, "interval", 5, "health check interval, unit is sec.") + ipvsCmd.Flags().StringVar(&flag.Ipvs.HealthPath, "health-path", "/healthz", "health check path") + ipvsCmd.Flags().StringVar(&flag.Ipvs.HealthSchem, "health-schem", "https", "health check schem") + ipvsCmd.Flags().Int32Var(&flag.Ipvs.Interval, "interval", 5, "health check interval, unit is sec.") // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // ipvsCmd.PersistentFlags().String("foo", "", "A help for foo") diff --git a/cmd/sealctl/cmd/route.go b/cmd/sealctl/cmd/route.go index 448ab4167..f6e9cb34b 100644 --- a/cmd/sealctl/cmd/route.go +++ b/cmd/sealctl/cmd/route.go @@ -15,14 +15,10 @@ package cmd import ( - "github.com/fanux/sealos/pkg/install" + "github.com/fanux/sealos/pkg/route" "github.com/spf13/cobra" ) -var ( - host string - gatewayIP string -) func NewRouteCmd() *cobra.Command { // routeCmd represents the route command @@ -32,7 +28,7 @@ func NewRouteCmd() *cobra.Command { Run: RouteCmdFunc, } // check route for host - cmd.Flags().StringVar(&host, "host", "", "route host ip address for iFace") + cmd.Flags().StringVar(&flag.Route.host, "host", "", "route host ip address for iFace") cmd.AddCommand(NewDelRouteCmd()) cmd.AddCommand(NewAddRouteCmd()) return cmd @@ -49,8 +45,8 @@ func NewAddRouteCmd() *cobra.Command { Run: RouteAddCmdFunc, } // manually to set host via gateway - cmd.Flags().StringVar(&host, "host", "", "route host ,ex ip route add host via gateway") - cmd.Flags().StringVar(&gatewayIP, "gateway", "", "route gateway ,ex ip route add host via gateway") + cmd.Flags().StringVar(&flag.Route.host, "host", "", "route host ,ex ip route add host via gateway") + cmd.Flags().StringVar(&flag.Route.gatewayIP, "gateway", "", "route gateway ,ex ip route add host via gateway") return cmd } @@ -61,22 +57,22 @@ func NewDelRouteCmd() *cobra.Command { Run: RouteDelCmdFunc, } // manually to set host via gateway - cmd.Flags().StringVar(&host, "host", "", "route host ,ex ip route del host via gateway") - cmd.Flags().StringVar(&gatewayIP, "gateway", "", "route gateway ,ex ip route del host via gateway") + cmd.Flags().StringVar(&flag.Route.host, "host", "", "route host ,ex ip route del host via gateway") + cmd.Flags().StringVar(&flag.Route.gatewayIP, "gateway", "", "route gateway ,ex ip route del host via gateway") return cmd } func RouteCmdFunc(cmd *cobra.Command, args []string) { - r := install.GetRouteFlag(host, gatewayIP) + r := route.GetRouteFlag(flag.Route.host, flag.Route.gatewayIP) r.CheckRoute() } func RouteAddCmdFunc(cmd *cobra.Command, args []string) { - r := install.GetRouteFlag(host, gatewayIP) + r := route.GetRouteFlag(flag.Route.host, flag.Route.gatewayIP) r.SetRoute() } func RouteDelCmdFunc(cmd *cobra.Command, args []string) { - r := install.GetRouteFlag(host, gatewayIP) + r := route.GetRouteFlag(flag.Route.host, flag.Route.gatewayIP) r.DelRoute() } diff --git a/cmd/sealctl/cmd/static_pod.go b/cmd/sealctl/cmd/static_pod.go index 5e688d3cf..6de3303e2 100755 --- a/cmd/sealctl/cmd/static_pod.go +++ b/cmd/sealctl/cmd/static_pod.go @@ -26,7 +26,6 @@ import ( "path" ) -var staticPodPath string func NewStaticPodCmd() *cobra.Command { var cmd = &cobra.Command{ @@ -38,7 +37,7 @@ func NewStaticPodCmd() *cobra.Command { } // check route for host cmd.AddCommand(NewLvscareCmd()) - cmd.PersistentFlags().StringVar(&staticPodPath, "path", "/etc/kubernetes/manifests", "default kubernetes static pod path") + cmd.PersistentFlags().StringVar(&flag.StaticPod.staticPodPath, "path", "/etc/kubernetes/manifests", "default kubernetes static pod path") return cmd } @@ -67,11 +66,11 @@ func NewLvscareCmd() *cobra.Command { return } logger.Debug("lvscare static pod yaml is %s", yaml) - if err = boot.InitRootDirectory([]string{staticPodPath}); err != nil { + if err = boot.InitRootDirectory([]string{flag.StaticPod.staticPodPath}); err != nil { logger.Error("init dir is error: %v", err) os.Exit(1) } - err = ioutil.WriteFile(path.Join(staticPodPath, fileName), []byte(yaml), 0755) + err = ioutil.WriteFile(path.Join(flag.StaticPod.staticPodPath, fileName), []byte(yaml), 0755) if err != nil { logger.Error(err) os.Exit(1) diff --git a/cmd/sealctl/cmd/token.go b/cmd/sealctl/cmd/token.go index 458f665a7..5dd6cd87a 100755 --- a/cmd/sealctl/cmd/token.go +++ b/cmd/sealctl/cmd/token.go @@ -16,8 +16,10 @@ package cmd import ( "github.com/fanux/sealos/pkg/utils/kubernetes/token" + "github.com/fanux/sealos/pkg/utils/logger" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/util/json" + "os" ) func NewTokenCmd() *cobra.Command { @@ -27,10 +29,15 @@ func NewTokenCmd() *cobra.Command { Short: "token generator", Run: func(cmd *cobra.Command, args []string) { var t *token.Token + var err error if master { - t = token.Master() + t, err = token.Master() } else { - t = token.Node() + t, err = token.Node() + } + if err != nil { + logger.Error("exec token error: " + err.Error()) + os.Exit(1) } data, _ := json.Marshal(t) println(string(data)) diff --git a/cmd/sealctl/cmd/version.go b/cmd/sealctl/cmd/version.go index f38e2a7d8..1b9e32a9c 100644 --- a/cmd/sealctl/cmd/version.go +++ b/cmd/sealctl/cmd/version.go @@ -22,8 +22,6 @@ import ( "github.com/spf13/cobra" ) -var shortPrint bool - var versionCmd = &cobra.Command{ Use: "version", Short: "version", @@ -34,7 +32,7 @@ var versionCmd = &cobra.Command{ if err != nil { return err } - if shortPrint { + if flag.Version.shortPrint { fmt.Println(version.Get().String()) } else { fmt.Println(string(marshalled)) @@ -46,5 +44,5 @@ var versionCmd = &cobra.Command{ func init() { rootCmd.AddCommand(versionCmd) - versionCmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print just the version number.") + versionCmd.Flags().BoolVar(&flag.Version.shortPrint, "short", false, "if true, print just the version number.") } diff --git a/go.mod b/go.mod index 2de831492..245501286 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.7.0 + github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.11.0 github.com/schollz/progressbar/v3 v3.8.5 diff --git a/go.sum b/go.sum index 77c0ee217..c215e8dcb 100644 --- a/go.sum +++ b/go.sum @@ -354,6 +354,7 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/pkg/config/config.go b/pkg/config/config.go index 5928dc622..f7687e2a0 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -17,6 +17,7 @@ package config import ( "bytes" "fmt" + "github.com/fanux/sealos/pkg/cri" "strings" "text/template" @@ -26,8 +27,6 @@ import ( "github.com/fanux/sealos/pkg/utils/logger" - "github.com/fanux/sealos/pkg/utils/cri" - v1 "github.com/fanux/sealos/pkg/types/v1alpha1" "sigs.k8s.io/yaml" ) diff --git a/pkg/utils/cri/cri.go b/pkg/cri/cri.go similarity index 80% rename from pkg/utils/cri/cri.go rename to pkg/cri/cri.go index a4fa02579..023f37493 100644 --- a/pkg/utils/cri/cri.go +++ b/pkg/cri/cri.go @@ -17,12 +17,13 @@ limitations under the License. package cri import ( + "github.com/fanux/sealos/pkg/utils/file" + "github.com/pelletier/go-toml" + "io/ioutil" "path/filepath" goruntime "runtime" "strings" - strings2 "github.com/fanux/sealos/pkg/utils/strings" - "github.com/pkg/errors" errorsutil "k8s.io/apimachinery/pkg/util/errors" @@ -45,7 +46,7 @@ type ContainerRuntime interface { ListKubeContainers() ([]string, error) RemoveContainers(containers []string) error PullImage(image string) error - ImageExists(image string) (bool, error) + ImageExists(image string) bool CGroupDriver() (string, error) } @@ -53,6 +54,7 @@ type ContainerRuntime interface { type ContainerdRuntime struct { exec utilsexec.Interface criSocket string + config string } // DockerRuntime is a struct that interfaces with the Docker daemon @@ -61,7 +63,7 @@ type DockerRuntime struct { } // NewContainerRuntime sets up and returns a ContainerRuntime struct -func NewContainerRuntime(execer utilsexec.Interface, criSocket string) (ContainerRuntime, error) { +func NewContainerRuntime(execer utilsexec.Interface, criSocket string, config string) (ContainerRuntime, error) { var toolName string var runtime ContainerRuntime @@ -73,7 +75,7 @@ func NewContainerRuntime(execer utilsexec.Interface, criSocket string) (Containe if filepath.IsAbs(criSocket) && goruntime.GOOS != "windows" { criSocket = "unix://" + criSocket } - runtime = &ContainerdRuntime{execer, criSocket} + runtime = &ContainerdRuntime{execer, criSocket, config} } else { toolName = "docker" runtime = &DockerRuntime{execer} @@ -128,15 +130,59 @@ func (runtime *ContainerdRuntime) CGroupDriver() (string, error) { if err := runtime.IsRunning(); err != nil { return "", err } - var err error - var out []byte - if out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "info", "-o", "go-template", "--template", "{{.config.systemdCgroup}}").CombinedOutput(); err != nil { - return "", errors.Wrapf(err, "container runtime is not running: output: %s, error", string(out)) + runtime.configFile() + return runtime.processConfigFile() +} + +func (runtime *ContainerdRuntime) configFile() { + const defaultConfig = "/etc/containerd/config.toml" + if !file.IsExist(runtime.config) { + runtime.config = defaultConfig } - if strings2.TrimWS(string(out)) == "false" { - return DefaultCgroupDriver, nil +} + +func (runtime *ContainerdRuntime) processConfigFile() (string, error) { + // Config is a wrapper of server config for printing out. + type Config struct { + Version int `toml:"version"` + Root string `toml:"root"` + Plugins struct { + IoContainerdGrpcV1Cri struct { + SandboxImage string `toml:"sandbox_image"` + MaxContainerLogLineSize int `toml:"max_container_log_line_size"` + MaxConcurrentDownloads int `toml:"max_concurrent_downloads"` + Containerd struct { + Snapshotter string `toml:"snapshotter"` + DefaultRuntimeName string `toml:"default_runtime_name"` + Runtimes struct { + Runc struct { + RuntimeType string `toml:"runtime_type"` + RuntimeEngine string `toml:"runtime_engine"` + RuntimeRoot string `toml:"runtime_root"` + Options struct { + SystemdCgroup bool `toml:"SystemdCgroup"` + } `toml:"options"` + } `toml:"runc"` + } `toml:"runtimes"` + } `toml:"containerd"` + } `toml:"io.containerd.grpc.v1.cri"` + } `toml:"plugins"` } - return DefaultSystemdCgroupDriver, nil + config := &Config{} + if file.IsExist(runtime.config) { + data, err := ioutil.ReadFile(runtime.config) + if err != nil { + return "", err + } + err = toml.Unmarshal(data, config) + if err != nil { + return "", err + } + if config.Plugins.IoContainerdGrpcV1Cri.Containerd.Runtimes.Runc.Options.SystemdCgroup { + return DefaultSystemdCgroupDriver, nil + } + } + return DefaultCgroupDriver, nil } // ListKubeContainers lists running k8s CRI pods @@ -219,15 +265,15 @@ func (runtime *DockerRuntime) PullImage(image string) error { } // ImageExists checks to see if the image exists on the system -func (runtime *ContainerdRuntime) ImageExists(image string) (bool, error) { +func (runtime *ContainerdRuntime) ImageExists(image string) bool { err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "inspecti", image).Run() - return err == nil, nil + return err == nil } // ImageExists checks to see if the image exists on the system -func (runtime *DockerRuntime) ImageExists(image string) (bool, error) { +func (runtime *DockerRuntime) ImageExists(image string) bool { err := runtime.exec.Command("docker", "inspect", image).Run() - return err == nil, nil + return err == nil } // detectCRISocketImpl is separated out only for test purposes, DON'T call it directly, use DetectCRISocket instead diff --git a/pkg/cri/cri_test.go b/pkg/cri/cri_test.go new file mode 100644 index 000000000..7029dab82 --- /dev/null +++ b/pkg/cri/cri_test.go @@ -0,0 +1,31 @@ +/* +Copyright 2018 The Kubernetes 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 cri + +import ( + "fmt" + "testing" +) + + +func TestNewContainerRuntime(t *testing.T) { + //cr:=&ContainerdRuntime{config: "/Users/cuisongliu/Workspaces/go/src/github.com/sealyun/cloud-kernel/runtime/containerd/etc/config.toml"} + //driver,_:=cr.processConfigFile() + //t.Log(driver) + cc:=[]string{"aa","bb","cc"} + println(fmt.Sprintf("%+v",cc)) +} diff --git a/pkg/utils/cri/cri_unix.go b/pkg/cri/cri_unix.go similarity index 100% rename from pkg/utils/cri/cri_unix.go rename to pkg/cri/cri_unix.go diff --git a/pkg/install/route.go b/pkg/route/route.go similarity index 99% rename from pkg/install/route.go rename to pkg/route/route.go index 040c0cc23..9bf36da05 100644 --- a/pkg/install/route.go +++ b/pkg/route/route.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package install +package route import ( "fmt" diff --git a/pkg/utils/cri/cri_test.go b/pkg/utils/cri/cri_test.go deleted file mode 100644 index dc12fd559..000000000 --- a/pkg/utils/cri/cri_test.go +++ /dev/null @@ -1,463 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 cri - -import ( - "io/ioutil" - "net" - "os" - "reflect" - "runtime" - "testing" - - "github.com/pkg/errors" - - "k8s.io/utils/exec" - fakeexec "k8s.io/utils/exec/testing" -) - -const crlctlBin = "/usr/bin/crictl" - -func TestNewContainerRuntime(t *testing.T) { - execLookPathOK := fakeexec.FakeExec{ - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - execLookPathErr := fakeexec.FakeExec{ - LookPathFunc: func(cmd string) (string, error) { return "", errors.Errorf("%s not found", cmd) }, - } - cases := []struct { - name string - execer fakeexec.FakeExec - criSocket string - isDocker bool - isError bool - }{ - {"valid: default cri socket", execLookPathOK, DefaultDockerCRISocket, true, false}, - {"valid: cri-o socket url", execLookPathOK, "unix:///var/run/crio/crio.sock", false, false}, - {"valid: cri-o socket path", execLookPathOK, "/var/run/crio/crio.sock", false, false}, - {"invalid: no crictl", execLookPathErr, "unix:///var/run/crio/crio.sock", false, true}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&tc.execer, tc.criSocket) - if err != nil { - if !tc.isError { - t.Fatalf("unexpected NewContainerRuntime error. criSocket: %s, error: %v", tc.criSocket, err) - } - return // expected error occurs, impossible to test runtime further - } - if tc.isError && err == nil { - t.Fatalf("unexpected NewContainerRuntime success. criSocket: %s", tc.criSocket) - } - isDocker := runtime.IsDocker() - if tc.isDocker != isDocker { - t.Fatalf("unexpected isDocker() result %v for the criSocket %s", isDocker, tc.criSocket) - } - }) - } -} - -func genFakeActions(fcmd *fakeexec.FakeCmd, num int) []fakeexec.FakeCommandAction { - var actions []fakeexec.FakeCommandAction - for i := 0; i < num; i++ { - actions = append(actions, func(cmd string, args ...string) exec.Cmd { - return fakeexec.InitFakeCmd(fcmd, cmd, args...) - }) - } - return actions -} - -func TestIsRunning(t *testing.T) { - fcmd := fakeexec.FakeCmd{ - CombinedOutputScript: []fakeexec.FakeAction{ - func() ([]byte, []byte, error) { return nil, nil, nil }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return nil, nil, nil }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - }, - } - - criExecer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)), - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - - dockerExecer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)), - LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/docker", nil }, - } - - cases := []struct { - name string - criSocket string - execer fakeexec.FakeExec - isError bool - }{ - {"valid: CRI-O is running", "unix:///var/run/crio/crio.sock", criExecer, false}, - {"invalid: CRI-O is not running", "unix:///var/run/crio/crio.sock", criExecer, true}, - {"valid: docker is running", DefaultDockerCRISocket, dockerExecer, false}, - {"invalid: docker is not running", DefaultDockerCRISocket, dockerExecer, true}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&tc.execer, tc.criSocket) - if err != nil { - t.Fatalf("unexpected NewContainerRuntime error: %v", err) - } - isRunning := runtime.IsRunning() - if tc.isError && isRunning == nil { - t.Error("unexpected IsRunning() success") - } - if !tc.isError && isRunning != nil { - t.Error("unexpected IsRunning() error") - } - }) - } -} - -func TestListKubeContainers(t *testing.T) { - fcmd := fakeexec.FakeCmd{ - CombinedOutputScript: []fakeexec.FakeAction{ - func() ([]byte, []byte, error) { return []byte("k8s_p1\nk8s_p2"), nil, nil }, - func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("k8s_p1\nk8s_p2"), nil, nil }, - }, - } - execer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)), - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - - cases := []struct { - name string - criSocket string - isError bool - }{ - {"valid: list containers using CRI socket url", "unix:///var/run/crio/crio.sock", false}, - {"invalid: list containers using CRI socket url", "unix:///var/run/crio/crio.sock", true}, - {"valid: list containers using docker", DefaultDockerCRISocket, false}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&execer, tc.criSocket) - if err != nil { - t.Fatalf("unexpected NewContainerRuntime error: %v", err) - } - - containers, err := runtime.ListKubeContainers() - if tc.isError { - if err == nil { - t.Errorf("unexpected ListKubeContainers success") - } - return - } else if err != nil { - t.Errorf("unexpected ListKubeContainers error: %v", err) - } - - if !reflect.DeepEqual(containers, []string{"k8s_p1", "k8s_p2"}) { - t.Errorf("unexpected ListKubeContainers output: %v", containers) - } - }) - } -} - -func TestRemoveContainers(t *testing.T) { - fakeOK := func() ([]byte, []byte, error) { return nil, nil, nil } - fakeErr := func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} } - fcmd := fakeexec.FakeCmd{ - CombinedOutputScript: []fakeexec.FakeAction{ - fakeOK, fakeOK, fakeOK, fakeOK, fakeOK, fakeOK, // Test case 1 - fakeOK, fakeOK, fakeOK, fakeErr, fakeOK, fakeOK, - fakeErr, fakeOK, fakeOK, fakeErr, fakeOK, - fakeOK, fakeOK, fakeOK, fakeOK, fakeOK, fakeOK, - fakeOK, fakeOK, fakeOK, fakeErr, fakeOK, fakeOK, - fakeErr, fakeOK, fakeOK, fakeErr, fakeOK, - }, - } - execer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)), - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - - cases := []struct { - name string - criSocket string - containers []string - isError bool - }{ - {"valid: remove containers using CRI", "unix:///var/run/crio/crio.sock", []string{"k8s_p1", "k8s_p2", "k8s_p3"}, false}, // Test case 1 - {"invalid: CRI rmp failure", "unix:///var/run/crio/crio.sock", []string{"k8s_p1", "k8s_p2", "k8s_p3"}, true}, - {"invalid: CRI stopp failure", "unix:///var/run/crio/crio.sock", []string{"k8s_p1", "k8s_p2", "k8s_p3"}, true}, - {"valid: remove containers using docker", DefaultDockerCRISocket, []string{"k8s_c1", "k8s_c2", "k8s_c3"}, false}, - {"invalid: docker rm failure", DefaultDockerCRISocket, []string{"k8s_c1", "k8s_c2", "k8s_c3"}, true}, - {"invalid: docker stop failure", DefaultDockerCRISocket, []string{"k8s_c1", "k8s_c2", "k8s_c3"}, true}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&execer, tc.criSocket) - if err != nil { - t.Fatalf("unexpected NewContainerRuntime error: %v, criSocket: %s", err, tc.criSocket) - } - - err = runtime.RemoveContainers(tc.containers) - if !tc.isError && err != nil { - t.Errorf("unexpected RemoveContainers errors: %v, criSocket: %s, containers: %v", err, tc.criSocket, tc.containers) - } - if tc.isError && err == nil { - t.Errorf("unexpected RemoveContainers success, criSocket: %s, containers: %v", tc.criSocket, tc.containers) - } - }) - } -} - -func TestPullImage(t *testing.T) { - fcmd := fakeexec.FakeCmd{ - CombinedOutputScript: []fakeexec.FakeAction{ - func() ([]byte, []byte, error) { return nil, nil, nil }, - // If the pull fails, it will be retried 5 times (see PullImageRetry in constants/constants.go) - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return nil, nil, nil }, - // If the pull fails, it will be retried 5 times (see PullImageRetry in constants/constants.go) - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }, - }, - } - execer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)), - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - - cases := []struct { - name string - criSocket string - image string - isError bool - }{ - {"valid: pull image using CRI", "unix:///var/run/crio/crio.sock", "image1", false}, - {"invalid: CRI pull error", "unix:///var/run/crio/crio.sock", "image2", true}, - {"valid: pull image using docker", DefaultDockerCRISocket, "image1", false}, - {"invalid: docker pull error", DefaultDockerCRISocket, "image2", true}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&execer, tc.criSocket) - if err != nil { - t.Fatalf("unexpected NewContainerRuntime error: %v, criSocket: %s", err, tc.criSocket) - } - - err = runtime.PullImage(tc.image) - if !tc.isError && err != nil { - t.Errorf("unexpected PullImage error: %v, criSocket: %s, image: %s", err, tc.criSocket, tc.image) - } - if tc.isError && err == nil { - t.Errorf("unexpected PullImage success, criSocket: %s, image: %s", tc.criSocket, tc.image) - } - }) - } -} - -func TestImageExists(t *testing.T) { - fcmd := fakeexec.FakeCmd{ - RunScript: []fakeexec.FakeAction{ - func() ([]byte, []byte, error) { return nil, nil, nil }, - func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, - func() ([]byte, []byte, error) { return nil, nil, nil }, - func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} }, - }, - } - execer := fakeexec.FakeExec{ - CommandScript: genFakeActions(&fcmd, len(fcmd.RunScript)), - LookPathFunc: func(cmd string) (string, error) { return crlctlBin, nil }, - } - - cases := []struct { - name string - criSocket string - image string - result bool - }{ - {"valid: test if image exists using CRI", "unix:///var/run/crio/crio.sock", "image1", false}, - {"invalid: CRI inspecti failure", "unix:///var/run/crio/crio.sock", "image2", true}, - {"valid: test if image exists using docker", DefaultDockerCRISocket, "image1", false}, - {"invalid: docker inspect failure", DefaultDockerCRISocket, "image2", true}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - runtime, err := NewContainerRuntime(&execer, tc.criSocket) - if err != nil { - t.Fatalf("unexpected NewContainerRuntime error: %v, criSocket: %s", err, tc.criSocket) - } - - result, err := runtime.ImageExists(tc.image) - if !tc.result != result { - t.Errorf("unexpected ImageExists result: %t, criSocket: %s, image: %s, expected result: %t", err, tc.criSocket, tc.image, tc.result) - } - }) - } -} - -func TestIsExistingSocket(t *testing.T) { - // this test is not expected to work on Windows - if runtime.GOOS == "windows" { - return - } - - const tempPrefix = "test.kubeadm.runtime.isExistingSocket." - tests := []struct { - name string - proc func(*testing.T) - }{ - { - name: "Valid domain socket is detected as such", - proc: func(t *testing.T) { - tmpFile, err := ioutil.TempFile("", tempPrefix) - if err != nil { - t.Fatalf("unexpected error by TempFile: %v", err) - } - theSocket := tmpFile.Name() - os.Remove(theSocket) - tmpFile.Close() - - con, err := net.Listen("unix", theSocket) - if err != nil { - t.Fatalf("unexpected error while dialing a socket: %v", err) - } - defer con.Close() - - if !isExistingSocket(theSocket) { - t.Fatalf("isExistingSocket(%q) gave unexpected result. Should have been true, instead of false", theSocket) - } - }, - }, - { - name: "Regular file is not a domain socket", - proc: func(t *testing.T) { - tmpFile, err := ioutil.TempFile("", tempPrefix) - if err != nil { - t.Fatalf("unexpected error by TempFile: %v", err) - } - theSocket := tmpFile.Name() - defer os.Remove(theSocket) - tmpFile.Close() - - if isExistingSocket(theSocket) { - t.Fatalf("isExistingSocket(%q) gave unexpected result. Should have been false, instead of true", theSocket) - } - }, - }, - { - name: "Non existent socket is not a domain socket", - proc: func(t *testing.T) { - const theSocket = "/non/existent/socket" - if isExistingSocket(theSocket) { - t.Fatalf("isExistingSocket(%q) gave unexpected result. Should have been false, instead of true", theSocket) - } - }, - }, - } - - for _, test := range tests { - t.Run(test.name, test.proc) - } -} - -func TestDetectCRISocketImpl(t *testing.T) { - tests := []struct { - name string - existingSockets []string - expectedError bool - expectedSocket string - }{ - { - name: "No existing sockets, use Docker", - existingSockets: []string{}, - expectedError: false, - expectedSocket: DefaultDockerCRISocket, - }, - { - name: "One valid CRI socket leads to success", - existingSockets: []string{"/var/run/crio/crio.sock"}, - expectedError: false, - expectedSocket: "/var/run/crio/crio.sock", - }, - { - name: "Correct Docker CRI socket is returned", - existingSockets: []string{"/var/run/docker.sock"}, - expectedError: false, - expectedSocket: DefaultDockerCRISocket, - }, - { - name: "CRI and Docker sockets lead to an error", - existingSockets: []string{ - "/var/run/docker.sock", - "/var/run/crio/crio.sock", - }, - expectedError: true, - }, - { - name: "Docker and containerd lead to Docker being used", - existingSockets: []string{ - "/var/run/docker.sock", - "/run/containerd/containerd.sock", - }, - expectedError: false, - expectedSocket: DefaultDockerCRISocket, - }, - { - name: "A couple of CRI sockets lead to an error", - existingSockets: []string{ - "/var/run/crio/crio.sock", - "/run/containerd/containerd.sock", - }, - expectedError: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - socket, err := detectCRISocketImpl(func(path string) bool { - for _, existing := range test.existingSockets { - if path == existing { - return true - } - } - - return false - }) - if (err != nil) != test.expectedError { - t.Fatalf("detectCRISocketImpl returned unexpected result\n\tExpected error: %t\n\tGot error: %t", test.expectedError, err != nil) - } - if !test.expectedError && socket != test.expectedSocket { - t.Fatalf("detectCRISocketImpl returned unexpected CRI socket\n\tExpected socket: %s\n\tReturned socket: %s", - test.expectedSocket, socket) - } - }) - } -} diff --git a/pkg/utils/file/file_v2.go b/pkg/utils/file/file_v2.go index a34438910..2f3a18131 100644 --- a/pkg/utils/file/file_v2.go +++ b/pkg/utils/file/file_v2.go @@ -119,16 +119,6 @@ func MkTmpFile(path string) (*os.File, error) { return ioutil.TempFile(path, ".FTmp-") } -func IsFileExist(filename string) bool { - _, err := os.Stat(filename) - if !os.IsNotExist(err) { - if err == nil { - return true - } - logger.Warn(err) - } - return false -} func WriteFile(fileName string, content []byte) error { dir := filepath.Dir(fileName) diff --git a/pkg/utils/kubernetes/token/token.go b/pkg/utils/kubernetes/token/token.go index 6969c5b90..237e13c15 100644 --- a/pkg/utils/kubernetes/token/token.go +++ b/pkg/utils/kubernetes/token/token.go @@ -18,6 +18,7 @@ package token import ( "encoding/json" + "errors" "fmt" "github.com/fanux/sealos/pkg/utils/exec" "github.com/fanux/sealos/pkg/utils/file" @@ -32,12 +33,11 @@ type Token struct { DiscoveryTokenCaCertHash []string `json:"discovery-token-ca-cert-hash,omitempty"` CertificateKey string `json:"certificate-key,omitempty"` Command string `json:"command,omitempty"` - Message string `json:"message,omitempty"` } const defaultAdminConf = "/etc/kubernetes/admin.conf" -func Master() *Token { +func Master() (*Token, error) { token := &Token{} if _, ok := exec.CheckCmdIsExist("kubeadm"); ok && file.IsExist(defaultAdminConf) { key, _ := CreateCertificateKey() @@ -53,21 +53,18 @@ func Master() *Token { token.JoinToken = diff.List()[0] hashs, err := discoveryTokenCaCertHash() if err != nil { - token.Message = err.Error() - return token + return nil, err } token.DiscoveryTokenCaCertHash = hashs - return token + return token, nil } - token.Message = fmt.Sprintf("token list found more than one") - } else { - token.Message = fmt.Sprintf("kubeadm command not found or /etc/kubernetes/admin.conf not exist") + return nil, fmt.Errorf("token list found more than one") } - return token + return nil, fmt.Errorf("kubeadm command not found or /etc/kubernetes/admin.conf not exist") } -func Node() *Token { +func Node() (*Token, error) { token := &Token{} if _, ok := exec.CheckCmdIsExist("kubeadm"); ok && file.IsExist(defaultAdminConf) { tokens := ListToken() @@ -75,15 +72,13 @@ func Node() *Token { token.JoinToken = tokens[0].Token.String() hashs, err := discoveryTokenCaCertHash() if err != nil { - token.Message = err.Error() - return token + return nil, err } - return &Token{JoinToken: tokens[0].Token.String(), DiscoveryTokenCaCertHash: hashs} + return &Token{JoinToken: tokens[0].Token.String(), DiscoveryTokenCaCertHash: hashs}, nil } - token.Message = fmt.Sprintf("token not found") + return nil, errors.New("token not found") } - token.Message = fmt.Sprintf("kubeadm command not found or /etc/kubernetes/admin.conf not exist") - return token + return nil, errors.New("kubeadm command not found or /etc/kubernetes/admin.conf not exist") } func ListToken() BootstrapTokens {