[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/hyper-api/types/network"
|
||||||
"github.com/hyperhq/hypercli/cliconfig"
|
"github.com/hyperhq/hypercli/cliconfig"
|
||||||
"github.com/hyperhq/hypercli/opts"
|
"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/manager"
|
||||||
"github.com/virtual-kubelet/virtual-kubelet/providers"
|
"github.com/virtual-kubelet/virtual-kubelet/providers"
|
||||||
"k8s.io/api/core/v1"
|
"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
|
//one container in a Pod in hyper.sh currently
|
||||||
containerName := fmt.Sprintf("pod-%s-%s", pod.Name, pod.Spec.Containers[k].Name)
|
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.
|
// Add labels to the pod containers.
|
||||||
ctr.Labels = map[string]string{
|
ctr.Labels = map[string]string{
|
||||||
containerLabel: pod.Name,
|
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) {
|
func containerJSONToPod(container *types.ContainerJSON) (*v1.Pod, error) {
|
||||||
// TODO: convert containers into pods
|
|
||||||
podName, found := container.Config.Labels[containerLabel]
|
podName, found := container.Config.Labels[containerLabel]
|
||||||
if !found {
|
if !found {
|
||||||
return nil, fmt.Errorf("can not found podName: key %q not found in container label", containerLabel)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse Created time failed:%v", container.Created)
|
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{
|
p := v1.Pod{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
@@ -514,25 +581,24 @@ func containerJSONToPod(container *types.ContainerJSON) (*v1.Pod, error) {
|
|||||||
},
|
},
|
||||||
Status: v1.PodStatus{
|
Status: v1.PodStatus{
|
||||||
Phase: hyperStateToPodPhase(container.State.Status),
|
Phase: hyperStateToPodPhase(container.State.Status),
|
||||||
Conditions: []v1.PodCondition{},
|
Conditions: []v1.PodCondition{podCondition},
|
||||||
Message: "",
|
Message: "",
|
||||||
Reason: "",
|
Reason: "",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
PodIP: container.NetworkSettings.IPAddress,
|
PodIP: container.NetworkSettings.IPAddress,
|
||||||
ContainerStatuses: []v1.ContainerStatus{
|
ContainerStatuses: []v1.ContainerStatus{
|
||||||
{
|
{
|
||||||
Name: "",
|
Name: podName,
|
||||||
State: v1.ContainerState{},
|
|
||||||
Ready: container.State.Running,
|
|
||||||
RestartCount: int32(container.RestartCount),
|
RestartCount: int32(container.RestartCount),
|
||||||
Image: container.Config.Image,
|
Image: container.Config.Image,
|
||||||
ImageID: container.Image,
|
ImageID: container.Image,
|
||||||
ContainerID: container.ID,
|
ContainerID: container.ID,
|
||||||
|
Ready: container.State.Running,
|
||||||
|
State: containerState,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &p, nil
|
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)
|
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{
|
p := v1.Pod{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: "Pod",
|
Kind: "Pod",
|
||||||
@@ -574,7 +657,7 @@ func containerToPod(container *types.Container) (*v1.Pod, error) {
|
|||||||
},
|
},
|
||||||
Status: v1.PodStatus{
|
Status: v1.PodStatus{
|
||||||
//Phase: "",
|
//Phase: "",
|
||||||
Conditions: []v1.PodCondition{},
|
Conditions: []v1.PodCondition{podCondition},
|
||||||
Message: "",
|
Message: "",
|
||||||
Reason: "",
|
Reason: "",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
@@ -582,31 +665,31 @@ func containerToPod(container *types.Container) (*v1.Pod, error) {
|
|||||||
ContainerStatuses: []v1.ContainerStatus{
|
ContainerStatuses: []v1.ContainerStatus{
|
||||||
{
|
{
|
||||||
Name: container.Names[0],
|
Name: container.Names[0],
|
||||||
Ready: string(container.State) == string(v1.PodRunning),
|
|
||||||
Image: container.Image,
|
Image: container.Image,
|
||||||
ImageID: container.ImageID,
|
ImageID: container.ImageID,
|
||||||
ContainerID: container.ID,
|
ContainerID: container.ID,
|
||||||
|
Ready: isReady,
|
||||||
|
State: v1.ContainerState{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hyperStateToPodPhase(state string) v1.PodPhase {
|
func hyperStateToPodPhase(state string) v1.PodPhase {
|
||||||
switch strings.ToLower(state) {
|
switch strings.ToLower(state) {
|
||||||
case "running":
|
|
||||||
return v1.PodRunning
|
|
||||||
case "paused":
|
|
||||||
return v1.PodSucceeded
|
|
||||||
case "restarting":
|
|
||||||
return v1.PodPending
|
|
||||||
case "created":
|
case "created":
|
||||||
return v1.PodPending
|
return v1.PodPending
|
||||||
case "dead":
|
case "restarting":
|
||||||
return v1.PodFailed
|
return v1.PodPending
|
||||||
|
case "running":
|
||||||
|
return v1.PodRunning
|
||||||
case "exited":
|
case "exited":
|
||||||
|
return v1.PodSucceeded
|
||||||
|
case "paused":
|
||||||
|
return v1.PodSucceeded
|
||||||
|
case "dead":
|
||||||
return v1.PodFailed
|
return v1.PodFailed
|
||||||
}
|
}
|
||||||
return v1.PodUnknown
|
return v1.PodUnknown
|
||||||
@@ -634,3 +717,21 @@ func (p *HyperProvider) getDefaultRegion() string {
|
|||||||
}
|
}
|
||||||
return cliconfig.DefaultHyperRegion
|
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