2018-03-05 03:41:08 +00:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/coreos/etcd/clientv3"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
mgo "gopkg.in/mgo.v2"
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
|
|
|
|
|
|
|
"github.com/shunfei/cronsun"
|
|
|
|
"github.com/shunfei/cronsun/conf"
|
|
|
|
)
|
|
|
|
|
|
|
|
var prever string
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
UpgradeCmd.Flags().StringVarP(&prever, "prever", "p", "", "previous version of cronsun you are used")
|
|
|
|
}
|
|
|
|
|
|
|
|
var UpgradeCmd = &cobra.Command{
|
|
|
|
Use: "upgrade",
|
|
|
|
Short: "upgrade will upgrade data to the current version(" + cronsun.VersionNumber + ")",
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
var ea = NewExitAction()
|
|
|
|
|
|
|
|
prever = strings.TrimLeft(strings.TrimSpace(prever), "v")
|
|
|
|
if len(prever) < 5 {
|
|
|
|
ea.Exit("invalid version number")
|
|
|
|
}
|
|
|
|
|
2018-05-26 13:20:53 +00:00
|
|
|
nodesById := getIPMapper(ea, prever)
|
2018-03-05 03:41:08 +00:00
|
|
|
if prever < "0.3.0" {
|
|
|
|
fmt.Println("upgrading data to version 0.3.0")
|
2018-03-06 06:11:14 +00:00
|
|
|
if to_0_3_0(ea, nodesById) {
|
2018-03-05 03:41:08 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-03-19 07:36:10 +00:00
|
|
|
|
|
|
|
if prever < "0.3.1" {
|
|
|
|
fmt.Println("upgrading data to version 0.3.1")
|
|
|
|
if to_0_3_1(ea, nodesById) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-03-05 03:41:08 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-05-26 13:20:53 +00:00
|
|
|
func getIPMapper(ea *ExitAction, prever string) map[string]*cronsun.Node {
|
2018-03-05 03:41:08 +00:00
|
|
|
nodes, err := cronsun.GetNodes()
|
|
|
|
if err != nil {
|
|
|
|
ea.Exit("failed to fetch nodes from MongoDB: %s", err.Error())
|
|
|
|
}
|
|
|
|
|
2018-03-06 06:11:14 +00:00
|
|
|
var ipMapper = make(map[string]*cronsun.Node, len(nodes))
|
2018-03-05 03:41:08 +00:00
|
|
|
for _, n := range nodes {
|
|
|
|
n.IP = strings.TrimSpace(n.IP)
|
|
|
|
if n.IP == "" || n.ID == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-05-26 13:20:53 +00:00
|
|
|
if prever < "0.3.0" {
|
|
|
|
n.RmOldInfo()
|
|
|
|
}
|
2018-03-06 06:11:14 +00:00
|
|
|
ipMapper[n.IP] = n
|
2018-03-05 03:41:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ipMapper
|
|
|
|
}
|
|
|
|
|
2018-03-06 06:11:14 +00:00
|
|
|
// to_0_3_0 can be run many times
|
|
|
|
func to_0_3_0(ea *ExitAction, nodesById map[string]*cronsun.Node) (shouldStop bool) {
|
2018-03-05 03:41:08 +00:00
|
|
|
var replaceIDs = func(list []string) {
|
|
|
|
for i := range list {
|
2018-03-06 06:11:14 +00:00
|
|
|
if node, ok := nodesById[list[i]]; ok {
|
|
|
|
list[i] = node.ID
|
2018-03-05 03:41:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// update job data
|
|
|
|
gresp, err := cronsun.DefalutClient.Get(conf.Config.Cmd, clientv3.WithPrefix())
|
|
|
|
ea.ExitOnErr(err)
|
|
|
|
|
|
|
|
total := len(gresp.Kvs)
|
|
|
|
upgraded := 0
|
|
|
|
for i := range gresp.Kvs {
|
|
|
|
job := cronsun.Job{}
|
|
|
|
err = json.Unmarshal(gresp.Kvs[i].Value, &job)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("[Error] failed to decode job(%s) data: %s\n", string(gresp.Kvs[i].Key), err.Error())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, rule := range job.Rules {
|
|
|
|
replaceIDs(rule.ExcludeNodeIDs)
|
|
|
|
replaceIDs(rule.NodeIDs)
|
|
|
|
}
|
|
|
|
|
|
|
|
d, err := json.Marshal(&job)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("[Error] failed to encode job(%s) data: %s\n", string(gresp.Kvs[i].Key), err.Error())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = cronsun.DefalutClient.Put(job.Key(), string(d))
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("[Warn] failed to restore job(%s) data: %s\n", string(gresp.Kvs[i].Key), err.Error())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
upgraded++
|
|
|
|
}
|
|
|
|
if total != upgraded {
|
|
|
|
shouldStop = true
|
|
|
|
}
|
|
|
|
fmt.Printf("%d of %d jobs has been upgraded.\n", upgraded, total)
|
|
|
|
|
|
|
|
// migrate node group data
|
|
|
|
nodeGroups, err := cronsun.GetNodeGroups()
|
|
|
|
if err != nil {
|
|
|
|
ea.Exit("[Error] failed to get node group datas: ", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
total = len(nodeGroups)
|
|
|
|
upgraded = 0
|
|
|
|
for i := range nodeGroups {
|
|
|
|
replaceIDs(nodeGroups[i].NodeIDs)
|
|
|
|
if _, err = nodeGroups[i].Put(0); err != nil {
|
|
|
|
fmt.Printf("[Warn] failed to restore node group(id: %s, name: %s) data: %s\n", nodeGroups[i].ID, nodeGroups[i].Name, err.Error())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
upgraded++
|
|
|
|
}
|
|
|
|
if total != upgraded {
|
|
|
|
shouldStop = true
|
|
|
|
}
|
|
|
|
fmt.Printf("%d of %d node group has been upgraded.\n", upgraded, total)
|
|
|
|
|
|
|
|
// upgrade logs
|
|
|
|
cronsun.GetDb().WithC(cronsun.Coll_JobLog, func(c *mgo.Collection) error {
|
2018-03-06 06:11:14 +00:00
|
|
|
for ip, node := range nodesById {
|
|
|
|
_, err = c.UpdateAll(bson.M{"node": ip}, bson.M{"$set": bson.M{"node": node.ID, "hostname": node.Hostname}})
|
2018-03-05 03:41:08 +00:00
|
|
|
if err != nil {
|
2018-03-19 07:36:10 +00:00
|
|
|
fmt.Println("failed to upgrade job logs: ", err.Error())
|
2018-03-05 03:41:08 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shouldStop = true
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
|
2018-03-06 06:11:14 +00:00
|
|
|
// upgrade logs
|
|
|
|
cronsun.GetDb().WithC(cronsun.Coll_JobLatestLog, func(c *mgo.Collection) error {
|
|
|
|
for ip, node := range nodesById {
|
|
|
|
_, err = c.UpdateAll(bson.M{"node": ip}, bson.M{"$set": bson.M{"node": node.ID, "hostname": node.Hostname}})
|
|
|
|
if err != nil {
|
2018-03-19 07:36:10 +00:00
|
|
|
fmt.Println("failed to upgrade job latest logs: ", err.Error())
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shouldStop = true
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// to_0_3_0 can be run many times
|
|
|
|
func to_0_3_1(ea *ExitAction, nodesById map[string]*cronsun.Node) (shouldStop bool) {
|
|
|
|
// upgrade logs
|
|
|
|
var err error
|
|
|
|
cronsun.GetDb().WithC(cronsun.Coll_JobLog, func(c *mgo.Collection) error {
|
|
|
|
for _, node := range nodesById {
|
|
|
|
_, err = c.UpdateAll(bson.M{"node": node.ID}, bson.M{"$set": bson.M{"ip": node.IP}})
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to upgrade job logs: ", err.Error())
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shouldStop = true
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
|
|
|
|
cronsun.GetDb().WithC(cronsun.Coll_JobLatestLog, func(c *mgo.Collection) error {
|
|
|
|
for _, node := range nodesById {
|
|
|
|
_, err = c.UpdateAll(bson.M{"node": node.ID}, bson.M{"$set": bson.M{"ip": node.IP}})
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to upgrade job latest logs: ", err.Error())
|
2018-03-06 06:11:14 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shouldStop = true
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
|
2018-03-05 03:41:08 +00:00
|
|
|
return
|
|
|
|
}
|