[REV] handle statefulset app volume when restore.(#72)

This commit is contained in:
barnettZQG 2018-05-30 10:49:17 +08:00
parent 1c706c8c4a
commit 8bdf6d9e1f
5 changed files with 75 additions and 0 deletions

View File

@ -144,6 +144,13 @@ func (b *BackupAPPNew) Run(timeout time.Duration) error {
} }
} }
} }
if app.Service.HostPath != "" && !util.DirIsEmpty(app.Service.HostPath) {
dstDir := fmt.Sprintf("%s/data_%s/%s_common.zip", b.SourceDir, app.ServiceID, app.ServiceID)
if err := util.Zip(app.Service.HostPath, dstDir); err != nil {
logrus.Errorf("backup service(%s) common data error.%s", app.ServiceID, err.Error())
return err
}
}
b.Logger.Info(fmt.Sprintf("完成备份应用(%s)持久化数据", app.Service.ServiceAlias), map[string]string{"step": "backup_builder", "status": "success"}) b.Logger.Info(fmt.Sprintf("完成备份应用(%s)持久化数据", app.Service.ServiceAlias), map[string]string{"step": "backup_builder", "status": "success"})
//TODO:backup relation volume data? //TODO:backup relation volume data?
} }

View File

@ -152,6 +152,14 @@ func (b *BackupAPPRestore) Run(timeout time.Duration) error {
b.saveResult("success", "") b.saveResult("success", "")
return nil return nil
} }
func (b *BackupAPPRestore) getServiceType(labels []*dbmodel.TenantServiceLable) string {
for _, l := range labels {
if l.LabelKey == dbmodel.LabelKeyServiceType {
return l.LabelValue
}
}
return util.StatelessServiceType
}
func (b *BackupAPPRestore) restoreVersionAndData(backup *dbmodel.AppBackup, appSnapshots []*RegionServiceSnapshot) error { func (b *BackupAPPRestore) restoreVersionAndData(backup *dbmodel.AppBackup, appSnapshots []*RegionServiceSnapshot) error {
for _, app := range appSnapshots { for _, app := range appSnapshots {
//backup app image or code slug file //backup app image or code slug file
@ -181,6 +189,26 @@ func (b *BackupAPPRestore) restoreVersionAndData(backup *dbmodel.AppBackup, appS
logrus.Errorf("restore service(%s) volume(%s) data error.%s", app.ServiceID, volume.VolumeName, err.Error()) logrus.Errorf("restore service(%s) volume(%s) data error.%s", app.ServiceID, volume.VolumeName, err.Error())
return err return err
} }
//if app type is statefulset, change pod hostpath
if b.getServiceType(app.ServiceLabel) == util.StatefulServiceType {
list, err := util.GetDirList(volume.HostPath)
if err != nil {
logrus.Errorf("restore statefulset service(%s) volume(%s) data error.%s", app.ServiceID, volume.VolumeName, err.Error())
return err
}
for _, podName := range list {
newNameTmp := strings.Split(podName, "-")
newNameTmp[0] = b.serviceChange[b.getOldServiceID(app.ServiceID)].ServiceAlias
newName := strings.Join(newNameTmp, "-")
err := util.Rename(filepath.Join(tmpDir, podName), filepath.Join(tmpDir, newName))
if err != nil {
return err
}
if err := os.Chmod(filepath.Join(tmpDir, newName), 0777); err != nil {
return err
}
}
}
err := util.Rename(tmpDir, util.GetParentDirectory(volume.HostPath)) err := util.Rename(tmpDir, util.GetParentDirectory(volume.HostPath))
if err != nil { if err != nil {
return err return err
@ -190,6 +218,21 @@ func (b *BackupAPPRestore) restoreVersionAndData(backup *dbmodel.AppBackup, appS
} }
} }
} }
if app.Service.HostPath != "" {
dstDir := fmt.Sprintf("%s/data_%s/%s_common.zip", b.cacheDir, b.getOldServiceID(app.ServiceID), b.getOldServiceID(app.ServiceID))
tmpDir := fmt.Sprintf("/grdata/tmp/%s_%s", app.ServiceID, app.ServiceID)
if err := util.Unzip(dstDir, tmpDir); err != nil {
logrus.Errorf("restore service(%s) common data error.%s", app.ServiceID, err.Error())
return err
}
err := util.Rename(tmpDir, util.GetParentDirectory(app.Service.HostPath))
if err != nil {
return err
}
if err := os.Chmod(app.Service.HostPath, 0777); err != nil {
return err
}
}
b.Logger.Info(fmt.Sprintf("完成恢复应用(%s)持久化数据", app.Service.ServiceAlias), map[string]string{"step": "restore_builder", "status": "success"}) b.Logger.Info(fmt.Sprintf("完成恢复应用(%s)持久化数据", app.Service.ServiceAlias), map[string]string{"step": "restore_builder", "status": "success"})
//TODO:relation relation volume data? //TODO:relation relation volume data?
} }

View File

@ -156,6 +156,7 @@ func (n *Cluster) handleNodeStatus(v *model.HostNode) {
if v.NodeStatus != nil { if v.NodeStatus != nil {
if v.Unschedulable { if v.Unschedulable {
v.Status = "unschedulable" v.Status = "unschedulable"
return
} }
if v.AvailableCPU == 0 { if v.AvailableCPU == 0 {
v.AvailableCPU = v.NodeStatus.Allocatable.Cpu().Value() v.AvailableCPU = v.NodeStatus.Allocatable.Cpu().Value()
@ -285,6 +286,7 @@ func (n *Cluster) loadAndWatchK8sNodes() {
if cn, ok := n.nodes[node.Name]; ok { if cn, ok := n.nodes[node.Name]; ok {
cn.NodeStatus = &node.Status cn.NodeStatus = &node.Status
cn.NodeStatus.Images = nil cn.NodeStatus.Images = nil
cn.Unschedulable = node.Spec.Unschedulable
cn.UpdataK8sCondition(node.Status.Conditions) cn.UpdataK8sCondition(node.Status.Conditions)
n.UpdateNode(cn) n.UpdateNode(cn)
} else { } else {

View File

@ -519,3 +519,18 @@ func CreateVersionByTime() string {
re := fmt.Sprintf("%d%d%d%d%d%d%d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond()) re := fmt.Sprintf("%d%d%d%d%d%d%d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond())
return re return re
} }
// GetDirList get all lower level dir
func GetDirList(dirpath string) ([]string, error) {
var dirlist []string
list, err := ioutil.ReadDir(dirpath)
if err != nil {
return nil, err
}
for _, f := range list {
if f.IsDir() {
dirlist = append(dirlist, f.Name())
}
}
return dirlist, nil
}

View File

@ -66,3 +66,11 @@ func TestCreateVersionByTime(t *testing.T) {
t.Log(re) t.Log(re)
} }
} }
func TestGetDirList(t *testing.T) {
list, err := GetDirList("/tmp/back")
if err != nil {
t.Fatal(err)
}
t.Log(list)
}