func (d *NodeDescriber) Describe(namespace, name string) (string, error) { mc := d.Nodes() node, err := mc.Get(name) if err != nil { return "", err } var pods []*api.Pod allPods, err := d.Pods(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return "", err } for i := range allPods.Items { pod := &allPods.Items[i] if pod.Spec.NodeName != name { continue } pods = append(pods, pod) } var events *api.EventList if ref, err := api.GetReference(node); err != nil { glog.Errorf("Unable to construct reference to '%#v': %v", node, err) } else { // TODO: We haven't decided the namespace for Node object yet. ref.UID = types.UID(ref.Name) events, _ = d.Events("").Search(ref) } return describeNode(node, pods, events) }
func TestMakeBoundPodNoServices(t *testing.T) { registry := registrytest.ServiceRegistry{} factory := &BasicBoundPodFactory{ ServiceRegistry: ®istry, } pod, err := factory.MakeBoundPod("machine", &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foobar"}, Spec: api.PodSpec{ Containers: []api.Container{ { Name: "foo", }, }, }, }) if err != nil { t.Fatalf("unexpected error: %v", err) } container := pod.Spec.Containers[0] if len(container.Env) != 0 { t.Errorf("Expected zero env vars, got: %#v", pod) } if pod.Name != "foobar" { t.Errorf("Failed to assign ID to pod: %#v", pod.Name) } if _, err := api.GetReference(pod); err != nil { t.Errorf("Unable to get a reference to bound pod: %v", err) } }
func (d *PodDescriber) Describe(namespace, name string) (string, error) { rc := d.ReplicationControllers(namespace) pc := d.Pods(namespace) pod, err := pc.Get(name) if err != nil { eventsInterface := d.Events(namespace) events, err2 := eventsInterface.List( labels.Everything(), eventsInterface.GetFieldSelector(&name, &namespace, nil, nil)) if err2 == nil && len(events.Items) > 0 { return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err) DescribeEvents(events, out) return nil }) } return "", err } var events *api.EventList if ref, err := api.GetReference(pod); err != nil { glog.Errorf("Unable to construct reference to '%#v': %v", pod, err) } else { ref.Kind = "" events, _ = d.Events(namespace).Search(ref) } rcs, err := getReplicationControllersForLabels(rc, labels.Set(pod.Labels)) if err != nil { return "", err } return describePod(pod, rcs, events) }
func TestWatchHTTP(t *testing.T) { simpleStorage := &SimpleRESTStorage{} handler := handle(map[string]rest.Storage{"simples": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} dest, _ := url.Parse(server.URL) dest.Path = "/api/version/watch/simples" dest.RawQuery = "" request, err := http.NewRequest("GET", dest.String(), nil) if err != nil { t.Errorf("unexpected error: %v", err) } response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) } if response.StatusCode != http.StatusOK { t.Errorf("Unexpected response %#v", response) } decoder := json.NewDecoder(response.Body) for i, item := range watchTestTable { // Send simpleStorage.fakeWatch.Action(item.t, item.obj) // Test receive var got watchJSON err := decoder.Decode(&got) if err != nil { t.Fatalf("%d: Unexpected error: %v", i, err) } if got.Type != item.t { t.Errorf("%d: Unexpected type: %v", i, got.Type) } t.Logf("obj: %v", string(got.Object)) gotObj, err := codec.Decode(got.Object) if err != nil { t.Fatalf("Decode error: %v", err) } t.Logf("obj: %#v", gotObj) if _, err := api.GetReference(gotObj); err != nil { t.Errorf("Unable to construct reference: %v", err) } if e, a := item.obj, gotObj; !reflect.DeepEqual(e, a) { t.Errorf("Expected %#v, got %#v", e, a) } } simpleStorage.fakeWatch.Stop() var got watchJSON err = decoder.Decode(&got) if err == nil { t.Errorf("Unexpected non-error") } }
func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (volumeMap, error) { podVolumes := make(volumeMap) for i := range pod.Spec.Volumes { volSpec := &pod.Spec.Volumes[i] podRef, err := api.GetReference(pod) if err != nil { glog.Errorf("Error getting object reference for pod: %v", pod, err) return nil, err } // Try to use a plugin for this volume. builder, err := kl.newVolumeBuilderFromPlugins(volSpec, podRef) if err != nil { glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err) return nil, err } if builder == nil { return nil, errUnsupportedVolumeType } err = builder.SetUp() if err != nil { return nil, err } podVolumes[volSpec.Name] = builder } return podVolumes, nil }
func TestWatchWebsocket(t *testing.T) { simpleStorage := &SimpleRESTStorage{} _ = ResourceWatcher(simpleStorage) // Give compile error if this doesn't work. handler := Handle(map[string]RESTStorage{ "foo": simpleStorage, }, codec, "/api", "version", selfLinker) server := httptest.NewServer(handler) defer server.Close() dest, _ := url.Parse(server.URL) dest.Scheme = "ws" // Required by websocket, though the server never sees it. dest.Path = "/api/version/watch/foo" dest.RawQuery = "" ws, err := websocket.Dial(dest.String(), "", "http://localhost") if err != nil { t.Errorf("unexpected error: %v", err) } try := func(action watch.EventType, object runtime.Object) { // Send simpleStorage.fakeWatch.Action(action, object) // Test receive var got watchJSON err := websocket.JSON.Receive(ws, &got) if err != nil { t.Fatalf("Unexpected error: %v", err) } if got.Type != action { t.Errorf("Unexpected type: %v", got.Type) } gotObj, err := codec.Decode(got.Object) if err != nil { t.Fatalf("Decode error: %v", err) } if _, err := api.GetReference(gotObj); err != nil { t.Errorf("Unable to construct reference: %v", err) } if e, a := object, gotObj; !reflect.DeepEqual(e, a) { t.Errorf("Expected %#v, got %#v", e, a) } } for _, item := range watchTestTable { try(item.t, item.obj) } simpleStorage.fakeWatch.Stop() var got watchJSON err = websocket.JSON.Receive(ws, &got) if err == nil { t.Errorf("Unexpected non-error") } }
func (recorder *recorderImpl) Event(object runtime.Object, reason, message string) { ref, err := api.GetReference(object) if err != nil { glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v'", object, err, reason, message) return } event := makeEvent(ref, reason, message) event.Source = recorder.source recorder.Action(watch.Added, event) }
func (r RealPodControl) createReplica(namespace string, controller *api.ReplicationController) error { desiredLabels := make(labels.Set) for k, v := range controller.Spec.Template.Labels { desiredLabels[k] = v } desiredAnnotations := make(labels.Set) for k, v := range controller.Spec.Template.Annotations { desiredAnnotations[k] = v } createdByRef, err := api.GetReference(controller) if err != nil { return fmt.Errorf("unable to get controller reference: %v", err) } createdByRefJson, err := latest.Codec.Encode(&api.SerializedReference{ Reference: *createdByRef, }) if err != nil { return fmt.Errorf("unable to serialize controller reference: %v", err) } desiredAnnotations[CreatedByAnnotation] = string(createdByRefJson) // use the dash (if the name isn't too long) to make the pod name a bit prettier prefix := fmt.Sprintf("%s-", controller.Name) if ok, _ := validation.ValidatePodName(prefix, true); !ok { prefix = controller.Name } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Labels: desiredLabels, Annotations: desiredAnnotations, GenerateName: prefix, }, } if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.Spec); err != nil { return fmt.Errorf("unable to convert pod template: %v", err) } if labels.Set(pod.Labels).AsSelector().Empty() { return fmt.Errorf("unable to create pod replica, no labels") } if newPod, err := r.kubeClient.Pods(namespace).Create(pod); err != nil { r.recorder.Eventf(controller, "failedCreate", "Error creating: %v", err) return fmt.Errorf("unable to create pod replica: %v", err) } else { glog.V(4).Infof("Controller %v created pod %v", controller.Name, newPod.Name) r.recorder.Eventf(controller, "successfulCreate", "Created pod: %v", newPod.Name) } return nil }
func (r RealPodControl) createReplica(namespace string, controller api.ReplicationController) { desiredLabels := make(labels.Set) for k, v := range controller.Spec.Template.Labels { desiredLabels[k] = v } desiredAnnotations := make(labels.Set) for k, v := range controller.Spec.Template.Annotations { desiredAnnotations[k] = v } createdByRef, err := api.GetReference(&controller) if err != nil { util.HandleError(fmt.Errorf("unable to get controller reference: %v", err)) return } createdByRefJson, err := json.Marshal(createdByRef) if err != nil { util.HandleError(fmt.Errorf("unable to serialize controller reference: %v", err)) return } desiredAnnotations[CreatedByAnnotation] = string(createdByRefJson) // use the dash (if the name isn't too long) to make the pod name a bit prettier prefix := fmt.Sprintf("%s-", controller.Name) if ok, _ := validation.ValidatePodName(prefix, true); !ok { prefix = controller.Name } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Labels: desiredLabels, Annotations: desiredAnnotations, GenerateName: prefix, }, } if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.Spec); err != nil { util.HandleError(fmt.Errorf("unable to convert pod template: %v", err)) return } if labels.Set(pod.Labels).AsSelector().Empty() { util.HandleError(fmt.Errorf("unable to create pod replica, no labels")) return } if _, err := r.kubeClient.Pods(namespace).Create(pod); err != nil { r.recorder.Eventf(&controller, "failedCreate", "Error creating: %v", err) util.HandleError(fmt.Errorf("unable to create pod replica: %v", err)) } }
func (d *PodDescriber) Describe(namespace, name string) (string, error) { rc := d.ReplicationControllers(namespace) pc := d.Pods(namespace) pod, err := pc.Get(name) if err != nil { events, err2 := d.Events(namespace).List( labels.Everything(), labels.Set{ "involvedObject.name": name, "involvedObject.namespace": namespace, }.AsSelector(), ) if err2 == nil && len(events.Items) > 0 { return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err) describeEvents(events, out) return nil }) } return "", err } // TODO: remove me when pods are converted spec := &api.PodSpec{} if err := api.Scheme.Convert(&pod.Spec, spec); err != nil { glog.Errorf("Unable to convert pod manifest: %v", err) } var events *api.EventList if ref, err := api.GetReference(pod); err != nil { glog.Errorf("Unable to construct reference to '%#v': %v", pod, err) } else { ref.Kind = "" // Find BoundPod objects, too! events, _ = d.Events(namespace).Search(ref) } return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Name:\t%s\n", pod.Name) fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(spec)) fmt.Fprintf(out, "Host:\t%s\n", pod.Status.Host+"/"+pod.Status.HostIP) fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(pod.Labels)) fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Phase)) fmt.Fprintf(out, "Replication Controllers:\t%s\n", getReplicationControllersForLabels(rc, labels.Set(pod.Labels))) if events != nil { describeEvents(events, out) } return nil }) }
// Search finds events about the specified object. The namespace of the // object must match this event's client namespace unless the event client // was made with the "" namespace. func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { ref, err := api.GetReference(objOrRef) if err != nil { return nil, err } if e.namespace != "" && ref.Namespace != e.namespace { return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace) } stringRefUID := string(ref.UID) var refUID *string if stringRefUID != "" { refUID = &stringRefUID } fieldSelector := e.GetFieldSelector(&ref.Name, &ref.Namespace, &ref.Kind, refUID) return e.List(labels.Everything(), fieldSelector) }
// Search finds events about the specified object. The namespace of the // object must match this event's client namespace unless the event client // was made with the "" namespace. func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { ref, err := api.GetReference(objOrRef) if err != nil { return nil, err } // TODO: search by UID if it's set fields := labels.Set{ "involvedObject.kind": ref.Kind, "involvedObject.namespace": ref.Namespace, "involvedObject.name": ref.Name, }.AsSelector() if e.namespace != "" && ref.Namespace != e.namespace { return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace) } return e.List(labels.Everything(), fields) }
func getReplicaAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) { desiredAnnotations := make(labels.Set) for k, v := range template.Annotations { desiredAnnotations[k] = v } createdByRef, err := api.GetReference(object) if err != nil { return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err) } createdByRefJson, err := latest.Codec.Encode(&api.SerializedReference{ Reference: *createdByRef, }) if err != nil { return desiredAnnotations, fmt.Errorf("unable to serialize controller reference: %v", err) } desiredAnnotations[CreatedByAnnotation] = string(createdByRefJson) return desiredAnnotations, nil }
// Event constructs an event from the given information and puts it in the queue for sending. // 'object' is the object this event is about. Event will make a reference-- or you may also // pass a reference to the object directly. // 'reason' is the reason this event is generated. 'reason' should be short and unique; it will // be used to automate handling of events, so imagine people writing switch statements to // handle them. You want to make that easy. // 'message' is intended to be human readable. // // The resulting event will be created in the same namespace as the reference object. func Event(object runtime.Object, reason, message string) { ref, err := api.GetReference(object) if err != nil { glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v'", object, err, reason, message) return } t := util.Now() e := &api.Event{ ObjectMeta: api.ObjectMeta{ Name: fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()), Namespace: ref.Namespace, }, InvolvedObject: *ref, Reason: reason, Message: message, Timestamp: t, } events.Action(watch.Added, e) }
// Search finds events about the specified object. The namespace of the // object must match this event's client namespace unless the event client // was made with the "" namespace. func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { ref, err := api.GetReference(objOrRef) if err != nil { return nil, err } if e.namespace != "" && ref.Namespace != e.namespace { return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace) } fields := fields.Set{} if ref.Kind != "" { fields["involvedObject.kind"] = ref.Kind } if ref.Namespace != "" { fields["involvedObject.namespace"] = ref.Namespace } if ref.Name != "" { fields["involvedObject.name"] = ref.Name } if ref.UID != "" { fields["involvedObject.uid"] = string(ref.UID) } return e.List(labels.Everything(), fields.AsSelector()) }
func syncClaim(volumeIndex *persistentVolumeOrderedIndex, binderClient binderClient, claim *api.PersistentVolumeClaim) (err error) { glog.V(5).Infof("Synchronizing PersistentVolumeClaim[%s]\n", claim.Name) // claims can be in one of the following states: // // ClaimPending -- default value -- not bound to a claim. A volume that matches the claim may not exist. // ClaimBound -- bound to a volume. claim.Status.VolumeRef != nil currentPhase := claim.Status.Phase nextPhase := currentPhase switch currentPhase { // pending claims await a matching volume case api.ClaimPending: volume, err := volumeIndex.FindBestMatchForClaim(claim) if err != nil { return err } if volume == nil { return fmt.Errorf("A volume match does not exist for persistent claim: %s", claim.Name) } // make a binding reference to the claim. // triggers update of the claim in this controller, which builds claim status claim.Spec.VolumeName = volume.Name // TODO: make this similar to Pod's binding both with BindingREST subresource and GuaranteedUpdate helper in etcd.go claim, err = binderClient.UpdatePersistentVolumeClaim(claim) if err == nil { nextPhase = api.ClaimBound glog.V(5).Infof("PersistentVolumeClaim[%s] is bound\n", claim.Name) } else { // Rollback by unsetting the ClaimRef on the volume pointer. // the volume in the index will be unbound again and ready to be matched. claim.Spec.VolumeName = "" // Rollback by restoring original phase to claim pointer nextPhase = api.ClaimPending return fmt.Errorf("Error updating volume: %+v\n", err) } case api.ClaimBound: volume, err := binderClient.GetPersistentVolume(claim.Spec.VolumeName) if err != nil { return fmt.Errorf("Unexpected error getting persistent volume: %v\n", err) } if volume.Spec.ClaimRef == nil { glog.V(5).Infof("Rebuilding bind on pv.Spec.ClaimRef\n") claimRef, err := api.GetReference(claim) if err != nil { return fmt.Errorf("Unexpected error getting claim reference: %v\n", err) } volume.Spec.ClaimRef = claimRef _, err = binderClient.UpdatePersistentVolume(volume) if err != nil { return fmt.Errorf("Unexpected error saving PersistentVolume.Status: %+v", err) } } // all "actuals" are transferred from PV to PVC so the user knows what // type of volume they actually got for their claim. // Volumes cannot have zero AccessModes, so checking that a claim has access modes // is sufficient to tell us if these values have already been set. if len(claim.Status.AccessModes) == 0 { claim.Status.Phase = api.ClaimBound claim.Status.AccessModes = volume.Spec.AccessModes claim.Status.Capacity = volume.Spec.Capacity _, err := binderClient.UpdatePersistentVolumeClaimStatus(claim) if err != nil { return fmt.Errorf("Unexpected error saving claim status: %+v", err) } } } if currentPhase != nextPhase { claim.Status.Phase = nextPhase binderClient.UpdatePersistentVolumeClaimStatus(claim) } return nil }