[hyper-provider] 1. support pull image 2. improve containerJSONToPod()
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user