* Copyright (c) 2025 Bocloud Technologies Co., Ltd.
* installer is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain n copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
******************************************************************/
package global
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"gopkg.openfuyao.cn/bkeadm/pkg/executor/containerd"
"gopkg.openfuyao.cn/bkeadm/pkg/executor/docker"
"gopkg.openfuyao.cn/bkeadm/pkg/executor/exec"
"gopkg.openfuyao.cn/bkeadm/pkg/executor/k8s"
"gopkg.openfuyao.cn/bkeadm/utils"
"gopkg.openfuyao.cn/bkeadm/utils/log"
)
var (
Docker docker.DockerClient
Containerd containerd.ContainerdClient
K8s k8s.KubernetesClient
Command exec.Executor
Workspace string
CustomExtra map[string]string
)
func init() {
Command = &exec.CommandExecutor{}
if utils.IsFile("/opt/BKE_WORKSPACE") {
f, err := os.ReadFile("/opt/BKE_WORKSPACE")
if err == nil {
Workspace = string(f)
Workspace = strings.TrimSpace(Workspace)
Workspace = strings.TrimRight(Workspace, "\n")
Workspace = strings.TrimRight(Workspace, "\r")
Workspace = strings.TrimRight(Workspace, "\t")
Workspace = filepath.Join(Workspace, "bke")
}
}
if os.Getenv("BKE_WORKSPACE") != "" {
Workspace = filepath.Join(os.Getenv("BKE_WORKSPACE"), "bke")
}
if Workspace == "" {
Workspace = "/bke"
}
if !utils.Exists(Workspace + "/tmpl") {
if err := os.MkdirAll(Workspace+"/tmpl", utils.DefaultDirPermission); err != nil {
log.Warnf("Create tmpl directory %s failed: %v", Workspace+"/tmpl", err)
}
}
if !utils.Exists(Workspace + "/volumes") {
if err := os.MkdirAll(Workspace+"/volumes", utils.DefaultDirPermission); err != nil {
log.Warnf("Create volumes directory %s failed: %v", Workspace+"/volumes", err)
}
}
if !utils.Exists(Workspace + "/mount") {
if err := os.MkdirAll(Workspace+"/mount", utils.DefaultDirPermission); err != nil {
log.Warnf("Create mount directory %s failed: %v", Workspace+"/mount", err)
}
}
CustomExtra = make(map[string]string)
}
func TarGZ(prefix, target string) error {
output, err := Command.ExecuteCommandWithOutput("sh", "-c", fmt.Sprintf("cd %s && tar --use-compress-program=pigz -cf %s .", prefix, target))
if err != nil {
return fmt.Errorf("tar failed, output: %s, error: %v", output, err)
}
return nil
}
func TarGZWithDir(prefix, dir, target string) error {
output, err := Command.ExecuteCommandWithOutput("sh", "-c", fmt.Sprintf("cd %s && tar "+
"--use-compress-program=pigz -cf %s ./%s", prefix, target, dir))
if err != nil {
return fmt.Errorf("tar failed, output: %s, error: %v", output, err)
}
return nil
}
func TaeGZWithoutChangeFile(prefix, target string) error {
cmd := fmt.Sprintf("cd %s && tar --use-compress-program=pigz -cf %s . --warning=no-file-changed --ignore-failed-read",
prefix, target)
output, err := Command.ExecuteCommandWithOutput("sh", "-c", cmd)
if err != nil {
return fmt.Errorf("tar failed, output: %s, error: %v", output, err)
}
return nil
}
func UnTarGZ(dataFile, target string) error {
output, err := Command.ExecuteCommandWithOutput("sh", "-c", fmt.Sprintf("tar -xzf %s -C %s", dataFile, target))
if err != nil {
return fmt.Errorf("untar failed, output: %s, error: %v", output, err)
}
return nil
}
func ListK8sResources(gvr schema.GroupVersionResource, target interface{}) error {
var workloadUnstructured *unstructured.UnstructuredList
var err error
dynamicClient := K8s.GetDynamicClient()
workloadUnstructured, err = dynamicClient.Resource(gvr).List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Errorf("List k8s resources %s failed: %v", gvr.Resource, err)
return err
}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(workloadUnstructured.UnstructuredContent(), target)
if err != nil {
log.Errorf("Convert k8s resources %s failed: %v", gvr.Resource, err)
return err
}
return nil
}
func ExecuteManifestCommands(target, manifestCreateCmd string, manifestAnnotate []string) error {
manifestEnv := append(os.Environ(), "DOCKER_CLI_EXPERIMENTAL=enabled")
if err := Command.ExecuteCommandWithEnv(manifestEnv, "/bin/sh", "-c", manifestCreateCmd); err != nil {
log.Errorf("%s, %v", manifestCreateCmd, err)
return err
}
log.Infof("Execute manifest create command: %s", manifestCreateCmd)
for _, cmd := range manifestAnnotate {
if err := Command.ExecuteCommandWithEnv(manifestEnv, "/bin/sh", "-c", cmd); err != nil {
log.Errorf("%s, %v", cmd, err)
return err
}
log.Debugf("Execute manifest annotate command: %s", cmd)
}
manifestPushCmd := fmt.Sprintf("docker manifest push --purge --insecure %s", target)
if err := Command.ExecuteCommandWithEnv(manifestEnv, "/bin/sh", "-c", manifestPushCmd); err != nil {
log.Errorf("%s, %v", manifestPushCmd, err)
return err
}
log.Infof("Execute manifest push command: %s", manifestPushCmd)
return nil
}