github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/filesystem/cloudfilesystem/nydus.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cloudfilesystem 16 17 import ( 18 "context" 19 "fmt" 20 "path/filepath" 21 22 "github.com/alibaba/sealer/utils/platform" 23 24 "golang.org/x/sync/errgroup" 25 26 "github.com/alibaba/sealer/logger" 27 "github.com/alibaba/sealer/pkg/env" 28 29 "github.com/alibaba/sealer/pkg/runtime" 30 v2 "github.com/alibaba/sealer/types/api/v2" 31 32 "github.com/alibaba/sealer/common" 33 "github.com/alibaba/sealer/utils" 34 "github.com/alibaba/sealer/utils/ssh" 35 ) 36 37 const ( 38 RemoteNydusdInit = "cd %s && chmod +x *.sh && bash start.sh %s" 39 RemoteNydusdStop = "if [ -f \"%[1]s\" ];then sh %[1]s;fi && rm -rf %s" 40 ) 41 42 type nydusFileSystem struct { 43 } 44 45 func (n *nydusFileSystem) MountRootfs(cluster *v2.Cluster, hosts []string, initFlag bool) error { 46 clusterRootfsDir := common.DefaultTheClusterRootfsDir(cluster.Name) 47 //scp roofs to all Masters and Nodes,then do init.sh 48 if err := mountNydusRootfs(hosts, clusterRootfsDir, cluster, initFlag); err != nil { 49 return fmt.Errorf("mount rootfs failed %v", err) 50 } 51 52 return nil 53 } 54 55 func (n *nydusFileSystem) UnMountRootfs(cluster *v2.Cluster, hosts []string) error { 56 var ( 57 nydusdFileDir = common.DefaultTheClusterNydusdFileDir(cluster.Name) 58 nydusdServerClean = filepath.Join(nydusdFileDir, "serverfile", "serverclean.sh") 59 ) 60 //do clean.sh,then remove all Masters and Nodes roofs 61 if err := unmountRootfs(hosts, cluster); err != nil { 62 return err 63 } 64 65 if utils.IsExist(nydusdServerClean) { 66 cleanCmd := fmt.Sprintf("sh %s", nydusdServerClean) 67 _, err := utils.RunSimpleCmd(cleanCmd) 68 if err != nil { 69 return fmt.Errorf("failed to stop nydusdserver %v", err) 70 } 71 } else { 72 logger.Info("%s not found", nydusdServerClean) 73 } 74 return nil 75 } 76 77 func mountNydusRootfs(ipList []string, target string, cluster *v2.Cluster, initFlag bool) error { 78 clusterPlatform, err := ssh.GetClusterPlatform(cluster) 79 if err != nil { 80 return err 81 } 82 localIP, err := utils.GetLocalIP(cluster.GetMaster0IP() + ":22") 83 if err != nil { 84 return fmt.Errorf("failed to get local address, %v", err) 85 } 86 var ( 87 nydusdfileSrc = filepath.Join(platform.DefaultMountCloudImageDir(cluster.Name), "nydusdfile") 88 nydusdFileDir = common.DefaultTheClusterNydusdFileDir(cluster.Name) 89 nydusdserverDir = filepath.Join(nydusdFileDir, "serverfile") 90 nydusdfileCpCmd = fmt.Sprintf("rm -rf %s && cp -r %s %s", nydusdFileDir, nydusdfileSrc, nydusdFileDir) 91 nydusdDir = common.DefaultTheClusterNydusdDir(cluster.Name) 92 nydusdInitCmd = fmt.Sprintf(RemoteNydusdInit, nydusdDir, target) 93 nydusdCleanCmd = fmt.Sprintf(RemoteNydusdStop, filepath.Join(nydusdDir, "clean.sh"), nydusdDir) 94 cleanCmd = fmt.Sprintf("echo '%s' >> "+common.DefaultClusterClearBashFile, nydusdCleanCmd, cluster.Name) 95 envProcessor = env.NewEnvProcessor(cluster) 96 config = runtime.GetRegistryConfig(platform.DefaultMountCloudImageDir(cluster.Name), runtime.GetMaster0Ip(cluster)) 97 initCmd = fmt.Sprintf(RemoteChmod, target, config.Domain, config.Port) 98 ) 99 _, err = utils.RunSimpleCmd(nydusdfileCpCmd) 100 if err != nil { 101 return fmt.Errorf("cp nydusdfile failed %v", err) 102 } 103 //dirs need be converted 104 mountDirs := make(map[string]bool) 105 dirlist := "" 106 for _, IP := range ipList { 107 ip := IP 108 src := platform.GetMountCloudImagePlatformDir(cluster.Name, clusterPlatform[ip]) 109 if !mountDirs[src] { 110 mountDirs[src] = true 111 dirlist = dirlist + fmt.Sprintf(",%s", src) 112 clientfileSrc := filepath.Join(src, "nydusdfile", "clientfile") 113 clientfileDest := filepath.Join(nydusdFileDir, filepath.Base(src)) 114 nydusdCpCmd := fmt.Sprintf("cp -r %s %s", clientfileSrc, clientfileDest) 115 _, err = utils.RunSimpleCmd(nydusdCpCmd) 116 if err != nil { 117 return fmt.Errorf("cp nydusdclinetfile failed %v", err) 118 } 119 } 120 } 121 startNydusdServer := fmt.Sprintf("cd %s && chmod +x serverstart.sh && ./serverstart.sh -d %s -i %s", nydusdserverDir, dirlist, localIP) 122 //convert image and start nydusd http server 123 _, err = utils.RunSimpleCmd(startNydusdServer) 124 if err != nil { 125 return fmt.Errorf("nydusdserver start fail %v", err) 126 } 127 logger.Info("nydus images converted and nydusd http server started") 128 129 eg, _ := errgroup.WithContext(context.Background()) 130 for _, IP := range ipList { 131 ip := IP 132 eg.Go(func() error { 133 src := platform.GetMountCloudImagePlatformDir(cluster.Name, clusterPlatform[ip]) 134 src = filepath.Join(nydusdFileDir, filepath.Base(src)) 135 sshClient, err := ssh.GetHostSSHClient(ip, cluster) 136 if err != nil { 137 return fmt.Errorf("get host ssh client failed %v", err) 138 } 139 err = copyFiles(sshClient, ip, src, nydusdDir) 140 if err != nil { 141 return fmt.Errorf("scp nydusd failed %v", err) 142 } 143 if initFlag { 144 err = sshClient.CmdAsync(ip, envProcessor.WrapperShell(ip, nydusdInitCmd)) 145 if err != nil { 146 return fmt.Errorf("init nydusd failed %v", err) 147 } 148 err = sshClient.CmdAsync(ip, envProcessor.WrapperShell(ip, initCmd)) 149 if err != nil { 150 return fmt.Errorf("exec init.sh failed %v", err) 151 } 152 err = sshClient.CmdAsync(ip, envProcessor.WrapperShell(ip, cleanCmd)) 153 if err != nil { 154 return fmt.Errorf("echo nydusdcleancmd to clean.sh failed %v", err) 155 } 156 } 157 return err 158 }) 159 } 160 if err = eg.Wait(); err != nil { 161 return err 162 } 163 if !utils.InList(config.IP, ipList) { 164 return nil 165 } 166 return nil 167 } 168 169 func NewNydusFileSystem() (Interface, error) { 170 return &nydusFileSystem{}, nil 171 }