diff --git a/cmd/etcd.go b/cmd/etcd.go index 747476ad7..168a36546 100644 --- a/cmd/etcd.go +++ b/cmd/etcd.go @@ -125,8 +125,8 @@ func EtcdRestoreCmdFunc(cmd *cobra.Command, args []string) { logger.Info("Start kube-apiserver kube-controller-manager kube-scheduler") // start kube-apiserver e.StartPod(tmpdir) + logger.Info("Wait 60s to health check for etcd") time.Sleep(time.Second * 60) - logger.Info("health check for etcd") e.HealthCheck() logger.Info("restore kubernetes yourself glad~") } diff --git a/install/etcd_restore.go b/install/etcd_restore.go index 4f0b60e5e..58dcbfd77 100644 --- a/install/etcd_restore.go +++ b/install/etcd_restore.go @@ -1,12 +1,10 @@ package install import ( - "archive/zip" "fmt" "github.com/wonderivan/logger" "go.etcd.io/etcd/clientv3/snapshot" "go.uber.org/zap" - "io" "math/rand" "os" "path/filepath" @@ -83,6 +81,9 @@ func (e *EtcdFlags) StopPod() (string, error) { func (e *EtcdFlags) RestoreAll() { for _, host := range e.EtcdHosts { hostname := SSHConfig.CmdToString(host, "hostname", "") + // remove first + cmd := fmt.Sprintf("rm -rf %s-%s", e.RestoreDir, hostname) + CmdWork(host, cmd, TMPDIR) e.restore(hostname) } } @@ -122,19 +123,21 @@ func (e *EtcdFlags) AfterRestore() error { // first to mv every for _, host := range e.EtcdHosts { hostname := SSHConfig.CmdToString(host, "hostname", "") + // /opt/sealos/ectd-restore-dev-k8s-master location := fmt.Sprintf("%s-%s", e.RestoreDir, hostname) - tmpFlie := fmt.Sprintf("/tmp/%s.zip", filepath.Base(location)) - + // + tmpFile := fmt.Sprintf("/tmp/%s.tar", filepath.Base(location)) + sdtTmpTar := fmt.Sprintf("/var/lib/%s.tar", filepath.Base(location)) // 压缩已经已经restore的文件 - err := Compress(location, tmpFlie) + err := CompressTar(location, tmpFile) if err != nil { return err } logger.Info("compress file") // 复制并解压到相应目录 - // todo - AfterHook := fmt.Sprintf(`cd %s && unzip %s.zip && rm -rf %s.zip`, ETCDDATADIR, filepath.Base(location), filepath.Base(location)) - SendPackage(tmpFlie, []string{host}, ETCDDATADIR, nil, &AfterHook) + // use quiet to tar + AfterHook := fmt.Sprintf(`tar xf %s -C /var/lib/ && mv /var/lib/%s %s && rm -rf %s`, sdtTmpTar, filepath.Base(location), ETCDDATADIR, sdtTmpTar) + SendPackage(tmpFile, []string{host}, "/var/lib", nil, &AfterHook) //logger.Info("send etcd.zip to hosts") } @@ -206,38 +209,3 @@ func CmdWork(node, cmd, workdir string) error { // not safe when use etcdctl to backup return SSHConfig.CmdAsyncEctd(node, command) } - -// Compress is compress all file in fileDir , and zip to outputPath -func Compress(fileDir string, outputPath string) error { - outFile, err := os.Create(outputPath) - if err != nil { - return err - } - defer outFile.Close() - w := zip.NewWriter(outFile) - defer w.Close() - - return filepath.Walk(fileDir, func(path string, f os.FileInfo, err error) error { - if f == nil { - return err - } - if f.IsDir() { - return nil - } - rel, _ := filepath.Rel(fileDir, path) - fmt.Println(rel, path) - compress(rel, path, w) - return nil - }) - -} - -func compress(rel string, path string, zw *zip.Writer) { - file, _ := os.Open(path) - info, _ := file.Stat() - header, _ := zip.FileInfoHeader(info) - header.Name = rel - writer, _ := zw.CreateHeader(header) - io.Copy(writer, file) - defer file.Close() -} diff --git a/install/utils.go b/install/utils.go index 5a57d9673..d9b809fc0 100644 --- a/install/utils.go +++ b/install/utils.go @@ -1,15 +1,20 @@ package install import ( + "archive/tar" + "archive/zip" + "compress/gzip" "crypto/tls" "fmt" "github.com/wonderivan/logger" + "io" "math/big" "math/rand" "net" "net/http" "net/url" "os" + "path" "path/filepath" "strconv" "strings" @@ -283,3 +288,152 @@ func FetchSealosAbsPath() string { exPath := filepath.Dir(ex) return exPath + string(os.PathSeparator) + os.Args[0] } + +func CompressTar(srcDirPath string, destFilePath string) error { + fw, err := os.Create(destFilePath) + if err != nil { + return err + } + defer fw.Close() + + + gw := gzip.NewWriter(fw) + defer gw.Close() + + + tw := tar.NewWriter(gw) + defer tw.Close() + + + f, err := os.Open(srcDirPath) + if err != nil { + return err + } + fi, err := f.Stat() + if err != nil { + return err + } + if fi.IsDir() { + err = compressDir(srcDirPath, path.Base(srcDirPath), tw) + if err != nil { + return err + } + } else { + err := compressFile(srcDirPath, fi.Name(), tw, fi) + if err != nil { + return err + } + } + return nil +} + +func compressDir(srcDirPath string, recPath string, tw *tar.Writer) error { + dir, err := os.Open(srcDirPath) + if err != nil { + return err + } + defer dir.Close() + + + fis, err := dir.Readdir(0) + if err != nil { + return err + } + for _, fi := range fis { + curPath := srcDirPath + "/" + fi.Name() + + + if fi.IsDir() { + err = compressDir(curPath, recPath+"/"+fi.Name(), tw) + if err != nil { + return err + } + } + + + err = compressFile(curPath, recPath+"/"+fi.Name(), tw, fi) + if err != nil { + return err + } + } + return nil +} + +func compressFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) error { + if fi.IsDir() { + hdr := new(tar.Header) + hdr.Name = recPath + "/" + hdr.Typeflag = tar.TypeDir + hdr.Size = 0 + hdr.Mode = int64(fi.Mode()) + hdr.ModTime = fi.ModTime() + + + err := tw.WriteHeader(hdr) + if err != nil { + return err + } + } else { + fr, err := os.Open(srcFile) + if err != nil { + return err + } + defer fr.Close() + + + hdr := new(tar.Header) + hdr.Name = recPath + hdr.Size = fi.Size() + hdr.Mode = int64(fi.Mode()) + hdr.ModTime = fi.ModTime() + + + err = tw.WriteHeader(hdr) + if err != nil { + return err + } + + + _, err = io.Copy(tw, fr) + if err != nil { + return err + } + } + return nil +} + + +// CompressZip is compress all file in fileDir , and zip to outputPath like unix zip ./ -r a.zip +func CompressZip(fileDir string, outputPath string) error { + outFile, err := os.Create(outputPath) + if err != nil { + return err + } + defer outFile.Close() + w := zip.NewWriter(outFile) + defer w.Close() + + return filepath.Walk(fileDir, func(path string, f os.FileInfo, err error) error { + if f == nil { + return err + } + if f.IsDir() { + return nil + } + rel, _ := filepath.Rel(fileDir, path) + fmt.Println(rel, path) + compress(rel, path, w) + return nil + }) + +} + +func compress(rel string, path string, zw *zip.Writer) { + file, _ := os.Open(path) + info, _ := file.Stat() + header, _ := zip.FileInfoHeader(info) + header.Name = rel + writer, _ := zw.CreateHeader(header) + io.Copy(writer, file) + defer file.Close() +}