mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
121 lines
3.8 KiB
Go
121 lines
3.8 KiB
Go
/*
|
|
Copyright 2021 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 customscripts
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/cmd/kk/apis/kubekey/v1alpha2"
|
|
"github.com/kubesphere/kubekey/cmd/kk/pkg/common"
|
|
"github.com/kubesphere/kubekey/cmd/kk/pkg/core/action"
|
|
"github.com/kubesphere/kubekey/cmd/kk/pkg/core/connector"
|
|
"github.com/kubesphere/kubekey/cmd/kk/pkg/core/util"
|
|
)
|
|
|
|
type CustomScriptTask struct {
|
|
action.BaseAction
|
|
taskDir string
|
|
script kubekeyapiv1alpha2.CustomScripts
|
|
}
|
|
|
|
|
|
|
|
func (t *CustomScriptTask) Execute(runtime connector.Runtime) error {
|
|
|
|
if len(t.script.Bash) <= 0 {
|
|
return errors.Errorf("custom script %s Bash is empty", t.script.Name)
|
|
}
|
|
|
|
remoteTaskHome := common.TmpDir + t.taskDir
|
|
|
|
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s", remoteTaskHome), false); err != nil {
|
|
return errors.Wrapf(err, "create remoteTaskHome: %s err:%s", remoteTaskHome, err)
|
|
}
|
|
|
|
// dilver the dependency materials to the remotehost
|
|
for idx, localPath := range t.script.Materials {
|
|
|
|
if !util.IsExist(localPath) {
|
|
return errors.Errorf("Not found Path: %s", localPath)
|
|
}
|
|
|
|
targetPath := filepath.Join(remoteTaskHome, filepath.Base(localPath))
|
|
|
|
// first clean the target to makesure target path always is the lastest.
|
|
cleanCmd := fmt.Sprintf("rm -fr %s", targetPath)
|
|
if _, err := runtime.GetRunner().SudoCmd(cleanCmd, false); err != nil {
|
|
return errors.Wrapf(err, "Can not remove target found Path: %s", targetPath)
|
|
}
|
|
|
|
start := time.Now()
|
|
err := runtime.GetRunner().SudoScp(localPath, targetPath)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "Can not Scp -fr %s root@%s:%s", localPath, runtime.RemoteHost().GetAddress(), targetPath)
|
|
}
|
|
|
|
fmt.Printf("Copy %d/%d materials: Scp -fr %s root@%s:%s done, take %s\n",
|
|
idx, len(t.script.Materials), localPath, runtime.RemoteHost().GetAddress(), targetPath, time.Since(start))
|
|
}
|
|
|
|
// wrap use bash file if shell has many lines.
|
|
RunBash := t.script.Bash
|
|
if strings.Index(RunBash, "\n") > 0 {
|
|
tmpFile, err := ioutil.TempFile(os.TempDir(), t.taskDir)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "create tmp Bash: %s/%s in local node, err:%s", os.TempDir(), t.taskDir, err)
|
|
}
|
|
defer os.Remove(tmpFile.Name())
|
|
|
|
if _, err := tmpFile.WriteString(RunBash); err != nil {
|
|
return errors.Wrapf(err, "write to tmp:%s in local node, err:%s", tmpFile.Name(), err)
|
|
}
|
|
|
|
targetPath := filepath.Join(remoteTaskHome, "task.sh")
|
|
if err := runtime.GetRunner().SudoScp(tmpFile.Name(), targetPath); err != nil {
|
|
return errors.Wrapf(err, "Can not Scp -fr %s root@%s:%s", tmpFile.Name(), runtime.RemoteHost().GetAddress(), targetPath)
|
|
}
|
|
|
|
RunBash = "/bin/bash " + targetPath
|
|
}
|
|
|
|
start := time.Now()
|
|
out, err := runtime.GetRunner().SudoCmd(RunBash, false)
|
|
if err != nil {
|
|
return errors.Errorf("Exec Bash: %s err:%s", RunBash, err)
|
|
}
|
|
|
|
if !runtime.GetRunner().Debug {
|
|
fmt.Printf("Exec Bash:%s done, take %s", RunBash, time.Since(start))
|
|
cleanCmd := fmt.Sprintf("rm -fr %s", remoteTaskHome)
|
|
if _, err := runtime.GetRunner().SudoCmd(cleanCmd, false); err != nil {
|
|
return errors.Wrapf(err, "Exec cmd:%s err:%s", cleanCmd, err)
|
|
}
|
|
}else {
|
|
// keep the Materials for debug
|
|
fmt.Printf("Exec Bash:%s done, take %s, output:\n%s", RunBash, time.Since(start), out)
|
|
}
|
|
|
|
return nil
|
|
}
|