// Move is such an action that should be excuted in the following order: // 1. Delete the Pod to be moved. // 2. Replication controller will automatically create a new replica and post to api server. // 3. At the same time create a VMTEvent, containing move action info, and post it to etcd. // 4. Pod watcher in the vmturbo-service find the new Pod and the new VMTEvent. // 5. Schedule Pod according to move action. // This method delete the pod and create a VMTEvent. func (this *KubernetesActionExecutor) MovePod(podIdentifier, targetNodeIdentifier string, msgID int32) error { // Pod identifier in vmt server passed from VMTurbo server is in "namespace/podname" idArray := strings.Split(string(podIdentifier), "/") if len(idArray) < 2 { return fmt.Errorf("Invalid Pod identifier: %s", podIdentifier) } podNamespace := idArray[0] podName := idArray[1] if podName == "" { return fmt.Errorf("Pod name should not be empty.\n") } if podNamespace == "" { return fmt.Errorf("Pod namespace should not be empty.\n") } if targetNodeIdentifier == "" { return fmt.Errorf("Target node identifier should not be empty.\n") } glog.V(3).Infof("Now Moving Pod %s in namespace %s.", podName, podNamespace) var containers []api.Container params, containers, mustMakeCopy, err := this.rcTraversalPodExtraction(podName, podNamespace) if err != nil { glog.Errorf("Error creating Pod for move: %s\n", err) } // TODO make sure that Pod is moved to target VM if not, place it in source VM // placing Delete Pod here so there is no name conflict // Delete pod err = this.KubeClient.Pods(podNamespace).Delete(podName, nil) if err != nil { glog.Errorf("Error deleting pod %s: %s.\n", podName, err) return fmt.Errorf("Error deleting pod %s: %s.\n", podName, err) } else { glog.V(3).Infof("Successfully delete pod %s.\n", podName) } // complete Pod creation if mustMakeCopy { err = this.createPod(params, containers) if err != nil { glog.Errorf("Error creating Pod for move: %s\n", err) } } action := "move" // Create VMTEvent and post onto etcd. vmtEvents := registry.NewVMTEvents(this.KubeClient, "", this.EtcdStorage) event := registry.GenerateVMTEvent(action, podNamespace, podName, targetNodeIdentifier, int(msgID)) glog.V(3).Infof("vmt event is %++v, with msgId %d", event, msgID) _, errorPost := vmtEvents.Create(event) if errorPost != nil { glog.Errorf("Error posting vmtevent: %s\n", errorPost) fmt.Errorf("Error posting vmtevent: %s\n", errorPost) } return nil }
// Update replica of the target replication controller. func (this *KubernetesActionExecutor) ProvisionPods(targetReplicationController api.ReplicationController, newReplicas int, msgID int32) (err error) { targetReplicationController.Spec.Replicas = newReplicas namespace := targetReplicationController.Namespace KubeClient := this.KubeClient newRC, err := KubeClient.ReplicationControllers(namespace).Update(&targetReplicationController) if err != nil { return fmt.Errorf("Error updating replication controller %s: %s", targetReplicationController.Name, err) } glog.V(3).Infof("New replicas of %s is %d", newRC.Name, newRC.Spec.Replicas) action := "provision" vmtEvents := registry.NewVMTEvents(this.KubeClient, "", this.EtcdStorage) event := registry.GenerateVMTEvent(action, namespace, newRC.Name, "not specified", int(msgID)) glog.V(3).Infof("vmt event is %v, msgId is %d, %d", event, msgID, int(msgID)) _, errorPost := vmtEvents.Create(event) if errorPost != nil { glog.Errorf("Error posting vmtevent: %s\n", errorPost) } return }