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
|
}
|