func machineTxn(view db.Database, stitch stitch.Stitch) error { // XXX: How best to deal with machines that don't specify enough information? maxPrice, _ := stitch.QueryFloat("MaxPrice") stitchMachines := toDBMachine(stitch.QueryMachines(), maxPrice) dbMachines := view.SelectFromMachine(nil) scoreFun := func(left, right interface{}) int { stitchMachine := left.(db.Machine) dbMachine := right.(db.Machine) switch { case dbMachine.Provider != stitchMachine.Provider: return -1 case dbMachine.Region != stitchMachine.Region: return -1 case dbMachine.Size != "" && stitchMachine.Size != dbMachine.Size: return -1 case dbMachine.Role != db.None && dbMachine.Role != stitchMachine.Role: return -1 case dbMachine.DiskSize != stitchMachine.DiskSize: return -1 case dbMachine.PrivateIP == "": return 2 case dbMachine.PublicIP == "": return 1 default: return 0 } } pairs, bootList, terminateList := join.Join(stitchMachines, dbMachines, scoreFun) for _, toTerminate := range terminateList { toTerminate := toTerminate.(db.Machine) view.Remove(toTerminate) } for _, bootSet := range bootList { bootSet := bootSet.(db.Machine) pairs = append(pairs, join.Pair{L: bootSet, R: view.InsertMachine()}) } for _, pair := range pairs { stitchMachine := pair.L.(db.Machine) dbMachine := pair.R.(db.Machine) dbMachine.Role = stitchMachine.Role dbMachine.Size = stitchMachine.Size dbMachine.DiskSize = stitchMachine.DiskSize dbMachine.Provider = stitchMachine.Provider dbMachine.Region = stitchMachine.Region dbMachine.SSHKeys = stitchMachine.SSHKeys view.Commit(dbMachine) } return nil }