package service import ( "aps_crm/pkg/logx" "aps_crm/utils" "errors" "fmt" "io/ioutil" "os" "os/exec" ) /* 管理dir类型的container的生命周期的管理器 */ type DirContainerImpl struct{} // Image 获取容器化用户一整套运行环境的基础目录 func (slf *DirContainerImpl) Image() string { return "/var/data/aps/sys" } // GetContainerRoot 获取容器目录的根路径地址 func (slf *DirContainerImpl) GetContainerRoot() string { return "/var/data/aps/container" } /* 将生成的用户id写入到新分配的container(配置文件)中,container中所有进程启动后注册到etcd 时,内部服务的key都包含有此主账号的id。container内部中的服务调用时,只会调用到内部注册有此用户id的 key的服务,所有container对外部来说是隔离的。 */ func (slf *DirContainerImpl) Init(cId string) error { logx.Infof("DirContainerImpl Init cId:", cId) root := slf.GetContainerRoot() uDir := root + "/" + cId if !utils.DirExists(uDir) { if err := os.MkdirAll(uDir, os.ModePerm); err != nil { logx.Errorf("mkdir container Root err:", err) return err } } else { logx.Errorf("container ", cId, " exist") return errors.New("container " + cId + " exist") } if !utils.DirExists(slf.Image()) { logx.Errorf("saas 系统运行环境文件不存在,请检查") return errors.New("saas 系统运行环境文件不存在,请检查") } var err error defer func() { if err != nil { logx.Errorf("rollback err:", err) os.RemoveAll(uDir) } }() _, err = utils.CopyDirByCmd(slf.Image()+"/*", uDir) if err != nil { logx.Errorf("CopyDirByCmd err:", err) return err } //将创建容器的主账号id写入到容器中 err = ioutil.WriteFile(uDir+"/bin/container.txt", []byte(cId), os.ModePerm) if err != nil { logx.Errorf("ioutil.WriteFile err:", err) return err } //配置开机启动 //启动容器 err = slf.Start(cId) if err != nil { logx.Errorf("start container err:", err, " id:", cId) return err } return nil } // Start 启动指定的用户容器 func (slf *DirContainerImpl) Start(cId string) error { uroot := slf.GetContainerRoot() + "/" + cId sh := fmt.Sprintf("%s %s &", uroot+"/start.sh", uroot) cmd := exec.Command("sh", "-C", sh) ret, e := cmd.Output() if e != nil { return e } logx.Infof("start container "+cId+", ret: ", ret) return nil } // Stop 停止指定的用户容器 func (slf *DirContainerImpl) Stop(cId string) error { uroot := slf.GetContainerRoot() + "/" + cId sh := fmt.Sprintf("%s %s", uroot+"/stop.sh", uroot) cmd := exec.Command("sh", "-C", sh) ret, e := cmd.Output() if e != nil { return e } logx.Infof("stop container "+cId+", ret: ", ret) return nil } // Restart 重新启动指定的用户容器 func (slf *DirContainerImpl) Restart(cId string) error { err := slf.Stop(cId) if err != nil { return err } err = slf.Start(cId) if err != nil { return err } return nil } // BakData 备份容器中的用户数据 func (slf *DirContainerImpl) BakData(cId string) error { bdir := slf.GetContainerRoot() + "/bak" if !utils.DirExists(bdir) { err := os.MkdirAll(bdir, os.ModePerm) if err != nil { return err } } ret, err := utils.CopyDirByCmd(slf.GetContainerRoot()+"/"+cId, bdir) if err != nil { return err } logx.Infof("Bake container:", cId, " ret:", ret) return nil } // Destroy 删除指定的用户容器 func (slf *DirContainerImpl) Destroy(cId string) error { if err := slf.BakData(cId); err != nil { return err } err := slf.Stop(cId) if err != nil { return err } uroot := slf.GetContainerRoot() + "/" + cId if utils.DirExists(uroot) { os.RemoveAll(uroot) } return nil } func (slf *DirContainerImpl) watch() { return }