support k3s artifact

Signed-off-by: 24sama <leo@kubesphere.io>
This commit is contained in:
24sama 2022-02-16 13:56:12 +08:00
parent 3290db9fb3
commit 1b9af3e7b0
6 changed files with 157 additions and 3 deletions

View File

@ -64,3 +64,58 @@ func K3sFilesDownloadHTTP(kubeConf *common.KubeConf, path, version, arch string,
pipelineCache.Set(common.KubeBinaries+"-"+arch, binariesMap)
return nil
}
func K3sArtifactBinariesDownload(manifest *common.ArtifactManifest, path, arch, version string) error {
m := manifest.Spec
etcd := files.NewKubeBinary("etcd", arch, m.Components.ETCD.Version, path, manifest.Arg.DownloadCommand)
kubecni := files.NewKubeBinary("kubecni", arch, m.Components.CNI.Version, path, manifest.Arg.DownloadCommand)
helm := files.NewKubeBinary("helm", arch, m.Components.Helm.Version, path, manifest.Arg.DownloadCommand)
k3s := files.NewKubeBinary("k3s", arch, version, path, manifest.Arg.DownloadCommand)
crictl := files.NewKubeBinary("crictl", arch, m.Components.Crictl.Version, path, manifest.Arg.DownloadCommand)
binaries := []*files.KubeBinary{k3s, helm, kubecni, etcd}
dockerArr := make([]*files.KubeBinary, 0, 0)
dockerVersionMap := make(map[string]struct{})
for _, c := range m.Components.ContainerRuntimes {
var dockerVersion string
if c.Type == common.Docker {
dockerVersion = c.Version
} else {
dockerVersion = kubekeyapiv1alpha2.DefaultDockerVersion
}
if _, ok := dockerVersionMap[dockerVersion]; !ok {
dockerVersionMap[dockerVersion] = struct{}{}
docker := files.NewKubeBinary("docker", arch, dockerVersion, path, manifest.Arg.DownloadCommand)
dockerArr = append(dockerArr, docker)
}
}
binaries = append(binaries, dockerArr...)
if m.Components.Crictl.Version != "" {
binaries = append(binaries, crictl)
}
for _, binary := range binaries {
if err := binary.CreateBaseDir(); err != nil {
return errors.Wrapf(errors.WithStack(err), "create file %s base dir failed", binary.FileName)
}
logger.Log.Messagef(common.LocalHost, "downloading %s %s %s ...", arch, binary.ID, binary.Version)
if util.IsExist(binary.Path()) {
// download it again if it's incorrect
if err := binary.SHA256Check(); err != nil {
_ = exec.Command("/bin/sh", "-c", fmt.Sprintf("rm -f %s", binary.Path())).Run()
} else {
continue
}
}
if err := binary.Download(); err != nil {
return fmt.Errorf("Failed to download %s binary: %s error: %w ", binary.ID, binary.GetCmd(), err)
}
}
return nil
}

View File

@ -80,6 +80,25 @@ func (a *ArtifactBinariesModule) Init() {
}
}
type K3sArtifactBinariesModule struct {
common.ArtifactModule
}
func (a *K3sArtifactBinariesModule) Init() {
a.Name = "K3sArtifactBinariesModule"
a.Desc = "Download artifact binaries"
download := &task.LocalTask{
Name: "K3sDownloadBinaries",
Desc: "Download k3s manifest expect binaries",
Action: new(K3sArtifactDownload),
}
a.Tasks = []task.Interface{
download,
}
}
type RegistryPackageModule struct {
common.KubeModule
}

View File

@ -139,6 +139,51 @@ func (a *ArtifactDownload) Execute(runtime connector.Runtime) error {
return nil
}
type K3sArtifactDownload struct {
common.ArtifactAction
}
func (a *K3sArtifactDownload) Execute(runtime connector.Runtime) error {
manifest := a.Manifest.Spec
archMap := make(map[string]bool)
for _, arch := range manifest.Arches {
switch arch {
case "amd64":
archMap["amd64"] = true
case "arm64":
archMap["arm64"] = true
default:
return errors.New(fmt.Sprintf("Unsupported architecture: %s", arch))
}
}
kubernetesSet := mapset.NewThreadUnsafeSet()
for _, k := range manifest.KubernetesDistributions {
kubernetesSet.Add(k)
}
kubernetesVersions := make([]string, 0, kubernetesSet.Cardinality())
for _, k := range kubernetesSet.ToSlice() {
k8s := k.(kubekeyapiv1alpha2.KubernetesDistribution)
kubernetesVersions = append(kubernetesVersions, k8s.Version)
}
basePath := filepath.Join(runtime.GetWorkDir(), common.Artifact)
for arch := range archMap {
for _, version := range kubernetesVersions {
if err := K3sArtifactBinariesDownload(a.Manifest, basePath, arch, version); err != nil {
return err
}
}
if err := RegistryBinariesDownload(a.Manifest, basePath, arch); err != nil {
return err
}
}
return nil
}
type RegistryPackageDownload struct {
common.KubeAction
}

View File

@ -141,13 +141,17 @@ func CmdPush(fileName string, prePath string, kubeConf *common.KubeConf, arches
fullPath := filepath.Join(prePath, fileName)
oldName := fmt.Sprintf("%s/%s/%s:%s", registry, namespace, imageName, tag)
ctrCmd := "sudo ctr"
if kubeConf.Cluster.Kubernetes.Type == common.K3s {
ctrCmd = "k3s ctr"
}
if out, err := exec.Command("/bin/bash", "-c",
fmt.Sprintf("sudo ctr images import --base-name %s %s", oldName, fullPath)).CombinedOutput(); err != nil {
fmt.Sprintf("%s images import --base-name %s %s", ctrCmd, oldName, fullPath)).CombinedOutput(); err != nil {
return errors.Wrapf(err, "import image %s failed: %s", oldName, out)
}
pushCmd := fmt.Sprintf("sudo ctr images push %s %s --platform %s -k",
image.ImageName(), oldName, strings.Join(arches, " "))
pushCmd := fmt.Sprintf("%s images push %s %s --platform %s -k", ctrCmd, image.ImageName(), oldName, strings.Join(arches, " "))
if kubeConf.Cluster.Registry.PlainHTTP {
pushCmd = fmt.Sprintf("%s --plain-http", pushCmd)
}

View File

@ -51,6 +51,29 @@ func NewArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
return nil
}
func NewK3sArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
m := []module.Module{
&confirm.CheckFileExistModule{FileName: runtime.Arg.Output},
&artifact.ImagesModule{},
&binaries.K3sArtifactBinariesModule{},
&artifact.RepositoryModule{},
&artifact.ArchiveModule{},
&filesystem.ChownWorkDirModule{},
}
p := pipeline.Pipeline{
Name: "K3sArtifactExportPipeline",
Modules: m,
Runtime: runtime,
ModulePostHooks: nil,
}
if err := p.Start(); err != nil {
return err
}
return nil
}
func ArtifactExport(args common.ArtifactArgument, downloadCmd string) error {
args.DownloadCommand = func(path, url string) string {
// this is an extension point for downloading tools, for example users can set the timeout, proxy or retry under
@ -77,6 +100,9 @@ func ArtifactExport(args common.ArtifactArgument, downloadCmd string) error {
switch runtime.Spec.KubernetesDistributions[0].Type {
case common.K3s:
if err := NewK3sArtifactExportPipeline(runtime); err != nil {
return err
}
case common.Kubernetes:
if err := NewArtifactExportPipeline(runtime); err != nil {
return err

View File

@ -143,6 +143,8 @@ Please check the result using the command:
}
func NewK3sCreateClusterPipeline(runtime *common.KubeRuntime) error {
noArtifact := runtime.Arg.Artifact == ""
skipPushImages := runtime.Arg.SKipPushImages || noArtifact || (!noArtifact && runtime.Cluster.Registry.PrivateRegistry == "")
skipLocalStorage := true
if runtime.Arg.DeployLocalStorage != nil {
skipLocalStorage = !*runtime.Arg.DeployLocalStorage
@ -151,6 +153,8 @@ func NewK3sCreateClusterPipeline(runtime *common.KubeRuntime) error {
}
m := []module.Module{
&artifact.UnArchiveModule{Skip: noArtifact},
&os.RepositoryModule{Skip: noArtifact || !runtime.Arg.InstallPackages},
&binaries.K3sNodeBinariesModule{},
&os.ConfigureOSModule{},
&k3s.StatusModule{},
@ -163,6 +167,7 @@ func NewK3sCreateClusterPipeline(runtime *common.KubeRuntime) error {
&k3s.InitClusterModule{},
&k3s.StatusModule{},
&k3s.JoinNodesModule{},
&images.PushModule{Skip: skipPushImages},
&loadbalancer.K3sHaproxyModule{Skip: !runtime.Cluster.ControlPlaneEndpoint.IsInternalLBEnabled()},
&network.DeployNetworkPluginModule{},
&filesystem.ChownModule{},