[hyper-provider] 1. support pull image 2. improve containerJSONToPod()

This commit is contained in:
Jimmy Xu
2017-12-21 22:33:58 +08:00
parent fb34a8c990
commit 1b3d6eae82

View File

@@ -21,6 +21,8 @@ import (
"github.com/hyperhq/hyper-api/types/network"
"github.com/hyperhq/hypercli/cliconfig"
"github.com/hyperhq/hypercli/opts"
"github.com/hyperhq/hypercli/pkg/jsonmessage"
"github.com/hyperhq/hypercli/pkg/term"
"github.com/virtual-kubelet/virtual-kubelet/manager"
"github.com/virtual-kubelet/virtual-kubelet/providers"
"k8s.io/api/core/v1"
@@ -221,6 +223,10 @@ func (p *HyperProvider) CreatePod(pod *v1.Pod) error {
//one container in a Pod in hyper.sh currently
containerName := fmt.Sprintf("pod-%s-%s", pod.Name, pod.Spec.Containers[k].Name)
if err = p.ensureImage(ctr.Image); err != nil {
return err
}
// Add labels to the pod containers.
ctr.Labels = map[string]string{
containerLabel: pod.Name,
@@ -475,7 +481,6 @@ func getContainers(pod *v1.Pod) ([]container.Config, []container.HostConfig, err
}
func containerJSONToPod(container *types.ContainerJSON) (*v1.Pod, error) {
// TODO: convert containers into pods
podName, found := container.Config.Labels[containerLabel]
if !found {
return nil, fmt.Errorf("can not found podName: key %q not found in container label", containerLabel)
@@ -490,6 +495,68 @@ func containerJSONToPod(container *types.ContainerJSON) (*v1.Pod, error) {
if err != nil {
return nil, fmt.Errorf("parse Created time failed:%v", container.Created)
}
startedAt, err := time.Parse(time.RFC3339, container.State.StartedAt)
if err != nil {
return nil, fmt.Errorf("parse StartedAt time failed:%v", container.State.StartedAt)
}
finishedAt, err := time.Parse(time.RFC3339, container.State.FinishedAt)
if err != nil {
return nil, fmt.Errorf("parse FinishedAt time failed:%v", container.State.FinishedAt)
}
var (
podCondition v1.PodCondition
containerState v1.ContainerState
)
switch hyperStateToPodPhase(container.State.Status) {
case v1.PodPending:
podCondition = v1.PodCondition{
Type: v1.PodInitialized,
Status: v1.ConditionFalse,
}
containerState = v1.ContainerState{
Waiting: &v1.ContainerStateWaiting{},
}
case v1.PodRunning: // running
podCondition = v1.PodCondition{
Type: v1.PodReady,
Status: v1.ConditionTrue,
}
containerState = v1.ContainerState{
Running: &v1.ContainerStateRunning{
StartedAt: metav1.NewTime(startedAt),
},
}
case v1.PodSucceeded: // normal exit
podCondition = v1.PodCondition{
Type: v1.PodReasonUnschedulable,
Status: v1.ConditionFalse,
}
containerState = v1.ContainerState{
Terminated: &v1.ContainerStateTerminated{
ExitCode: int32(container.State.ExitCode),
FinishedAt: metav1.NewTime(finishedAt),
},
}
case v1.PodFailed: // exit with error
podCondition = v1.PodCondition{
Type: v1.PodReasonUnschedulable,
Status: v1.ConditionFalse,
}
containerState = v1.ContainerState{
Terminated: &v1.ContainerStateTerminated{
ExitCode: int32(container.State.ExitCode),
FinishedAt: metav1.NewTime(finishedAt),
Reason: container.State.Error,
},
}
default: //unkown
podCondition = v1.PodCondition{
Type: v1.PodReasonUnschedulable,
Status: v1.ConditionUnknown,
}
containerState = v1.ContainerState{}
}
p := v1.Pod{
TypeMeta: metav1.TypeMeta{
@@ -514,25 +581,24 @@ func containerJSONToPod(container *types.ContainerJSON) (*v1.Pod, error) {
},
Status: v1.PodStatus{
Phase: hyperStateToPodPhase(container.State.Status),
Conditions: []v1.PodCondition{},
Conditions: []v1.PodCondition{podCondition},
Message: "",
Reason: "",
HostIP: "",
PodIP: container.NetworkSettings.IPAddress,
ContainerStatuses: []v1.ContainerStatus{
{
Name: "",
State: v1.ContainerState{},
Ready: container.State.Running,
Name: podName,
RestartCount: int32(container.RestartCount),
Image: container.Config.Image,
ImageID: container.Image,
ContainerID: container.ID,
Ready: container.State.Running,
State: containerState,
},
},
},
}
return &p, nil
}
@@ -548,6 +614,23 @@ func containerToPod(container *types.Container) (*v1.Pod, error) {
return nil, fmt.Errorf("can not found nodeName: key %q not found in container label", containerLabel)
}
var (
podCondition v1.PodCondition
isReady bool = true
)
if strings.ToLower(string(container.State)) == strings.ToLower(string(v1.PodRunning)) {
podCondition = v1.PodCondition{
Type: v1.PodReady,
Status: v1.ConditionTrue,
}
} else {
podCondition = v1.PodCondition{
Type: v1.PodReasonUnschedulable,
Status: v1.ConditionFalse,
}
isReady = false
}
p := v1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
@@ -574,7 +657,7 @@ func containerToPod(container *types.Container) (*v1.Pod, error) {
},
Status: v1.PodStatus{
//Phase: "",
Conditions: []v1.PodCondition{},
Conditions: []v1.PodCondition{podCondition},
Message: "",
Reason: "",
HostIP: "",
@@ -582,31 +665,31 @@ func containerToPod(container *types.Container) (*v1.Pod, error) {
ContainerStatuses: []v1.ContainerStatus{
{
Name: container.Names[0],
Ready: string(container.State) == string(v1.PodRunning),
Image: container.Image,
ImageID: container.ImageID,
ContainerID: container.ID,
Ready: isReady,
State: v1.ContainerState{},
},
},
},
}
return &p, nil
}
func hyperStateToPodPhase(state string) v1.PodPhase {
switch strings.ToLower(state) {
case "running":
return v1.PodRunning
case "paused":
return v1.PodSucceeded
case "restarting":
return v1.PodPending
case "created":
return v1.PodPending
case "dead":
return v1.PodFailed
case "restarting":
return v1.PodPending
case "running":
return v1.PodRunning
case "exited":
return v1.PodSucceeded
case "paused":
return v1.PodSucceeded
case "dead":
return v1.PodFailed
}
return v1.PodUnknown
@@ -634,3 +717,21 @@ func (p *HyperProvider) getDefaultRegion() string {
}
return cliconfig.DefaultHyperRegion
}
func (p *HyperProvider) ensureImage(image string) error {
responseBody, err := p.hyperClient.ImagePull(context.Background(), image, types.ImagePullOptions{})
if err != nil {
return err
}
defer responseBody.Close()
var (
outFd uintptr
isTerminalOut bool
)
_, stdout, _ := term.StdStreams()
if stdout != nil {
outFd, isTerminalOut = term.GetFdInfo(stdout)
}
jsonmessage.DisplayJSONMessagesStream(responseBody, stdout, outFd, isTerminalOut, nil)
return nil
}