diff --git a/cmd/virtual-kubelet/commands/root/node.go b/cmd/virtual-kubelet/commands/root/node.go index 74227a63c..d1b6c08a1 100644 --- a/cmd/virtual-kubelet/commands/root/node.go +++ b/cmd/virtual-kubelet/commands/root/node.go @@ -25,6 +25,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const osLabel = "beta.kubernetes.io/os" + // NodeFromProvider builds a kubernetes node object from a provider // This is a temporary solution until node stuff actually split off from the provider interface itself. func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p providers.Provider, version string) *v1.Node { @@ -40,9 +42,7 @@ func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p provi Labels: map[string]string{ "type": "virtual-kubelet", "kubernetes.io/role": "agent", - "beta.kubernetes.io/os": strings.ToLower(p.OperatingSystem()), "kubernetes.io/hostname": name, - "alpha.service-controller.kubernetes.io/exclude-balancer": "true", }, }, Spec: v1.NodeSpec{ @@ -50,17 +50,16 @@ func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p provi }, Status: v1.NodeStatus{ NodeInfo: v1.NodeSystemInfo{ - OperatingSystem: p.OperatingSystem(), - Architecture: "amd64", - KubeletVersion: version, + Architecture: "amd64", + KubeletVersion: version, }, - Capacity: p.Capacity(ctx), - Allocatable: p.Capacity(ctx), - Conditions: p.NodeConditions(ctx), - Addresses: p.NodeAddresses(ctx), - DaemonEndpoints: *p.NodeDaemonEndpoints(ctx), }, } + + p.ConfigureNode(ctx, node) + if _, ok := node.ObjectMeta.Labels[osLabel]; !ok { + node.ObjectMeta.Labels[osLabel] = strings.ToLower(node.Status.NodeInfo.OperatingSystem) + } return node } diff --git a/providers/mock/mock.go b/providers/mock/mock.go index 0fbd82728..a1cbaf3cd 100644 --- a/providers/mock/mock.go +++ b/providers/mock/mock.go @@ -312,12 +312,6 @@ func (p *MockV0Provider) GetContainerLogs(ctx context.Context, namespace, podNam return ioutil.NopCloser(strings.NewReader("")), nil } -// Get full pod name as defined in the provider context -// TODO: Implementation -func (p *MockV0Provider) GetPodFullName(namespace string, pod string) string { - return "" -} - // RunInContainer executes a command in a container in the pod, copying data // between in/out/err and the container's stdin/stdout/stderr. func (p *MockV0Provider) RunInContainer(ctx context.Context, namespace, name, container string, cmd []string, attach api.AttachIO) error { @@ -360,11 +354,26 @@ func (p *MockV0Provider) GetPods(ctx context.Context) ([]*v1.Pod, error) { return pods, nil } -// Capacity returns a resource list containing the capacity limits. -func (p *MockV0Provider) Capacity(ctx context.Context) v1.ResourceList { - ctx, span := trace.StartSpan(ctx, "Capacity") +func (p *MockV0Provider) ConfigureNode(ctx context.Context, n *v1.Node) { + ctx, span := trace.StartSpan(ctx, "mock.ConfigureNode") defer span.End() + n.Status.Capacity = p.capacity() + n.Status.Allocatable = p.capacity() + n.Status.Conditions = p.nodeConditions() + n.Status.Addresses = p.nodeAddresses() + n.Status.DaemonEndpoints = p.nodeDaemonEndpoints() + os := p.operatingSystem + if os == "" { + os = "Linux" + } + n.Status.NodeInfo.OperatingSystem = os + n.Status.NodeInfo.Architecture = "amd64" + n.ObjectMeta.Labels["alpha.service-controller.kubernetes.io/exclude-balancer"] = "true" +} + +// Capacity returns a resource list containing the capacity limits. +func (p *MockV0Provider) capacity() v1.ResourceList { return v1.ResourceList{ "cpu": resource.MustParse(p.config.CPU), "memory": resource.MustParse(p.config.Memory), @@ -374,10 +383,7 @@ func (p *MockV0Provider) Capacity(ctx context.Context) v1.ResourceList { // NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), for updates to the node status // within Kubernetes. -func (p *MockV0Provider) NodeConditions(ctx context.Context) []v1.NodeCondition { - ctx, span := trace.StartSpan(ctx, "NodeConditions") - defer span.End() - +func (p *MockV0Provider) nodeConditions() []v1.NodeCondition { // TODO: Make this configurable return []v1.NodeCondition{ { @@ -426,10 +432,7 @@ func (p *MockV0Provider) NodeConditions(ctx context.Context) []v1.NodeCondition // NodeAddresses returns a list of addresses for the node status // within Kubernetes. -func (p *MockV0Provider) NodeAddresses(ctx context.Context) []v1.NodeAddress { - ctx, span := trace.StartSpan(ctx, "NodeAddresses") - defer span.End() - +func (p *MockV0Provider) nodeAddresses() []v1.NodeAddress { return []v1.NodeAddress{ { Type: "InternalIP", @@ -440,25 +443,14 @@ func (p *MockV0Provider) NodeAddresses(ctx context.Context) []v1.NodeAddress { // NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status // within Kubernetes. -func (p *MockV0Provider) NodeDaemonEndpoints(ctx context.Context) *v1.NodeDaemonEndpoints { - ctx, span := trace.StartSpan(ctx, "NodeDaemonEndpoints") - defer span.End() - - return &v1.NodeDaemonEndpoints{ +func (p *MockV0Provider) nodeDaemonEndpoints() v1.NodeDaemonEndpoints { + return v1.NodeDaemonEndpoints{ KubeletEndpoint: v1.DaemonEndpoint{ Port: p.daemonEndpointPort, }, } } -// OperatingSystem returns the operating system for this provider. -// This is a noop to default to Linux for now. - -func (p *MockV0Provider) OperatingSystem() string { - // This is harcoded due to: https://github.com/virtual-kubelet/virtual-kubelet/issues/632 - return "Linux" -} - // GetStatsSummary returns dummy stats for all pods known by this provider. func (p *MockV0Provider) GetStatsSummary(ctx context.Context) (*stats.Summary, error) { ctx, span := trace.StartSpan(ctx, "GetStatsSummary") diff --git a/providers/provider.go b/providers/provider.go index 4257b5769..81d53f820 100644 --- a/providers/provider.go +++ b/providers/provider.go @@ -25,23 +25,9 @@ type Provider interface { // between in/out/err and the container's stdin/stdout/stderr. RunInContainer(ctx context.Context, namespace, podName, containerName string, cmd []string, attach api.AttachIO) error - // Capacity returns a resource list with the capacity constraints of the provider. - Capacity(context.Context) v1.ResourceList - - // NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), which is - // polled periodically to update the node status within Kubernetes. - NodeConditions(context.Context) []v1.NodeCondition - - // NodeAddresses returns a list of addresses for the node status - // within Kubernetes. - NodeAddresses(context.Context) []v1.NodeAddress - - // NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status - // within Kubernetes. - NodeDaemonEndpoints(context.Context) *v1.NodeDaemonEndpoints - - // OperatingSystem returns the operating system the provider is for. - OperatingSystem() string + // ConfigureNode enables a provider to configure the node object that + // will be used for Kubernetes. + ConfigureNode(context.Context, *v1.Node) } // PodMetricsProvider is an optional interface that providers can implement to expose pod stats