func syncJoinScore(left, right interface{}) int { dbc := left.(db.Container) dkc := right.(docker.Container) // Depending on the container, the command in the database could be // either The command plus it's arguments, or just it's arguments. To // handle that case, we check both. cmd1 := dkc.Args cmd2 := append([]string{dkc.Path}, dkc.Args...) dbcCmd := dbc.Command for key, value := range dbc.Env { if dkc.Env[key] != value { return -1 } } switch { case dbc.Image != dkc.Image: return -1 case len(dbcCmd) != 0 && !util.StrSliceEqual(dbcCmd, cmd1) && !util.StrSliceEqual(dbcCmd, cmd2): return -1 case dbc.DockerID == dkc.ID: return 0 default: return 1 } }
func containerJoinScore(left, right storeContainer) int { if left.Minion != right.Minion || left.Image != right.Image || !util.StrSliceEqual(left.Command, right.Command) || !util.StrStrMapEqual(left.Env, right.Env) { return -1 } score := util.EditDistance(left.Labels, right.Labels) if left.StitchID != right.StitchID { score++ } return score }
func updateContainers(view db.Database, spec stitch.Stitch) { score := func(l, r interface{}) int { left := l.(db.Container) right := r.(db.Container) if left.Image != right.Image || !util.StrSliceEqual(left.Command, right.Command) || !util.StrStrMapEqual(left.Env, right.Env) { return -1 } score := util.EditDistance(left.Labels, right.Labels) if left.StitchID != right.StitchID { score++ } return score } pairs, news, dbcs := join.Join(queryContainers(spec), view.SelectFromContainer(nil), score) for _, dbc := range dbcs { view.Remove(dbc.(db.Container)) } for _, new := range news { pairs = append(pairs, join.Pair{L: new, R: view.InsertContainer()}) } for _, pair := range pairs { newc := pair.L.(db.Container) dbc := pair.R.(db.Container) // By sorting the labels we prevent the database from getting confused // when their order is non deterministic. dbc.Labels = newc.Labels sort.Sort(sort.StringSlice(dbc.Labels)) dbc.Command = newc.Command dbc.Image = newc.Image dbc.Env = newc.Env dbc.StitchID = newc.StitchID view.Commit(dbc) } }