From 64e7ac50ab3e29311f385357434eb7f5ad1ddb5b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:07:17 +0000 Subject: [PATCH 1/6] Initial plan From 5e0a8aa695bb5fa1a24da1b1a1b66146ba908cc1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:19:20 +0000 Subject: [PATCH 2/6] feat: dynamically update node resources from plugin ping response Agent-Logs-Url: https://github.com/interlink-hq/interLink/sessions/80d70d6e-9c74-48bb-aecf-d2a8e34692f5 Co-authored-by: dciangot <4144326+dciangot@users.noreply.github.com> --- pkg/interlink/types.go | 36 +++++++ pkg/interlink/types_test.go | 123 ++++++++++++++++++++++++ pkg/virtualkubelet/config_test.go | 138 +++++++++++++++++++++++++++ pkg/virtualkubelet/virtualkubelet.go | 73 +++++++++++++- 4 files changed, 369 insertions(+), 1 deletion(-) diff --git a/pkg/interlink/types.go b/pkg/interlink/types.go index 2fa9a810..4897ca4f 100644 --- a/pkg/interlink/types.go +++ b/pkg/interlink/types.go @@ -129,6 +129,42 @@ type LogStruct struct { Opts ContainerLogOpts `json:"Opts"` } +// PingResponse represents the optional structured response from the InterLink plugin ping endpoint. +// Plugins may return a JSON body with this structure to report their status and available resources. +// If the response body cannot be parsed as this structure, it is treated as a plain text response +// for backward compatibility. +type PingResponse struct { + // Status is the ping status string (e.g., "ok") + Status string `json:"status,omitempty"` + // Resources optionally contains resource capacity information reported by the plugin. + // When present, the Virtual Kubelet will update the node's Capacity and Allocatable fields. + Resources *ResourcesResponse `json:"resources,omitempty"` +} + +// ResourcesResponse represents the resource capacity information optionally returned by a plugin +// in a ping response. All fields are optional; omitted fields leave the current node capacity +// unchanged, preserving backward compatibility with plugins that do not report resources. +type ResourcesResponse struct { + // CPU specifies the total CPU capacity (e.g., "100", "2000m") + CPU string `json:"cpu,omitempty"` + // Memory specifies the total memory capacity (e.g., "128Gi", "64000Mi") + Memory string `json:"memory,omitempty"` + // Pods specifies the maximum number of pods this node can handle + Pods string `json:"pods,omitempty"` + // Accelerators lists hardware accelerators available on this node (GPUs, FPGAs, etc.) + Accelerators []AcceleratorResponse `json:"accelerators,omitempty"` +} + +// AcceleratorResponse represents a hardware accelerator (GPU, FPGA, etc.) reported by a plugin +// in a ping response. +type AcceleratorResponse struct { + // ResourceType specifies the Kubernetes extended-resource name (e.g., "nvidia.com/gpu", "xilinx.com/fpga") + ResourceType string `json:"resourceType"` + // Available indicates how many units of this accelerator are available, expressed as a + // Kubernetes quantity (e.g., "8", "16") + Available string `json:"available"` +} + // SpanConfig holds configuration for OpenTelemetry spans. // It's used to set additional attributes on tracing spans. type SpanConfig struct { diff --git a/pkg/interlink/types_test.go b/pkg/interlink/types_test.go index 1d6494a2..6c50ea6c 100644 --- a/pkg/interlink/types_test.go +++ b/pkg/interlink/types_test.go @@ -290,3 +290,126 @@ func TestPodStatus_MultipleContainers(t *testing.T) { assert.Equal(t, "container1", decoded.Containers[0].Name) assert.Equal(t, "init1", decoded.InitContainers[0].Name) } + +func TestPingResponse_JSONSerialization(t *testing.T) { + tests := []struct { + name string + input string + wantResp PingResponse + }{ + { + name: "status only", + input: `{"status":"ok"}`, + wantResp: PingResponse{ + Status: "ok", + Resources: nil, + }, + }, + { + name: "status with resources", + input: `{"status":"ok","resources":{"cpu":"100","memory":"256Gi","pods":"1000"}}`, + wantResp: PingResponse{ + Status: "ok", + Resources: &ResourcesResponse{ + CPU: "100", + Memory: "256Gi", + Pods: "1000", + }, + }, + }, + { + name: "status with resources and accelerators", + input: `{"status":"ok","resources":{"cpu":"50","memory":"128Gi","pods":"500","accelerators":[{"resourceType":"nvidia.com/gpu","available":"8"},{"resourceType":"xilinx.com/fpga","available":"2"}]}}`, + wantResp: PingResponse{ + Status: "ok", + Resources: &ResourcesResponse{ + CPU: "50", + Memory: "128Gi", + Pods: "500", + Accelerators: []AcceleratorResponse{ + {ResourceType: "nvidia.com/gpu", Available: "8"}, + {ResourceType: "xilinx.com/fpga", Available: "2"}, + }, + }, + }, + }, + { + name: "empty response (backward compat plain text)", + input: ``, + wantResp: PingResponse{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.input == "" { + // Plain-text ping responses should fail to unmarshal gracefully + var resp PingResponse + err := json.Unmarshal([]byte(tt.input), &resp) + assert.Error(t, err, "empty string should fail JSON unmarshal") + return + } + + var resp PingResponse + err := json.Unmarshal([]byte(tt.input), &resp) + require.NoError(t, err) + assert.Equal(t, tt.wantResp.Status, resp.Status) + if tt.wantResp.Resources == nil { + assert.Nil(t, resp.Resources) + } else { + require.NotNil(t, resp.Resources) + assert.Equal(t, tt.wantResp.Resources.CPU, resp.Resources.CPU) + assert.Equal(t, tt.wantResp.Resources.Memory, resp.Resources.Memory) + assert.Equal(t, tt.wantResp.Resources.Pods, resp.Resources.Pods) + assert.Equal(t, tt.wantResp.Resources.Accelerators, resp.Resources.Accelerators) + } + }) + } +} + +func TestPingResponse_RoundTrip(t *testing.T) { + original := PingResponse{ + Status: "ok", + Resources: &ResourcesResponse{ + CPU: "200", + Memory: "512Gi", + Pods: "2000", + Accelerators: []AcceleratorResponse{ + {ResourceType: "nvidia.com/gpu", Available: "16"}, + {ResourceType: "amd.com/gpu", Available: "4"}, + }, + }, + } + + data, err := json.Marshal(original) + require.NoError(t, err) + + var decoded PingResponse + err = json.Unmarshal(data, &decoded) + require.NoError(t, err) + + assert.Equal(t, original.Status, decoded.Status) + require.NotNil(t, decoded.Resources) + assert.Equal(t, original.Resources.CPU, decoded.Resources.CPU) + assert.Equal(t, original.Resources.Memory, decoded.Resources.Memory) + assert.Equal(t, original.Resources.Pods, decoded.Resources.Pods) + assert.Equal(t, original.Resources.Accelerators, decoded.Resources.Accelerators) +} + +func TestResourcesResponse_PartialFields(t *testing.T) { + // Only CPU is specified; other fields should be empty (omitted) + input := `{"cpu":"100"}` + var res ResourcesResponse + err := json.Unmarshal([]byte(input), &res) + require.NoError(t, err) + assert.Equal(t, "100", res.CPU) + assert.Empty(t, res.Memory) + assert.Empty(t, res.Pods) + assert.Empty(t, res.Accelerators) + + // Marshal back — memory/pods/accelerators should be omitted + data, err := json.Marshal(res) + require.NoError(t, err) + assert.NotContains(t, string(data), `"memory"`) + assert.NotContains(t, string(data), `"pods"`) +} diff --git a/pkg/virtualkubelet/config_test.go b/pkg/virtualkubelet/config_test.go index a800c6bf..d39e6ac4 100644 --- a/pkg/virtualkubelet/config_test.go +++ b/pkg/virtualkubelet/config_test.go @@ -1,9 +1,11 @@ package virtualkubelet import ( + "context" "testing" "github.com/stretchr/testify/assert" + types "github.com/interlink-hq/interlink/pkg/interlink" "k8s.io/apimachinery/pkg/api/resource" ) @@ -176,3 +178,139 @@ func TestGetResources_AcceleratorQuantities(t *testing.T) { fpgaQty := resourceList["xilinx.com/fpga"] assert.Equal(t, int64(1), fpgaQty.Value(), "xilinx.com/fpga should be 1") } + +func TestUpdateNodeResources_CPUMemoryPods(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + ctx := context.Background() + resources := &types.ResourcesResponse{ + CPU: "200", + Memory: "512Gi", + Pods: "2000", + } + provider.updateNodeResources(ctx, resources) + + cpuQty := provider.node.Status.Capacity["cpu"] + assert.Equal(t, int64(200), cpuQty.Value()) + memQty := provider.node.Status.Capacity["memory"] + assert.Equal(t, "512Gi", memQty.String()) + podsQty := provider.node.Status.Capacity["pods"] + assert.Equal(t, int64(2000), podsQty.Value()) + + // Allocatable should also be updated + allocCPU := provider.node.Status.Allocatable["cpu"] + assert.Equal(t, 0, cpuQty.Cmp(allocCPU), "allocatable CPU should match capacity CPU") + allocMem := provider.node.Status.Allocatable["memory"] + assert.Equal(t, 0, memQty.Cmp(allocMem), "allocatable memory should match capacity memory") + allocPods := provider.node.Status.Allocatable["pods"] + assert.Equal(t, 0, podsQty.Cmp(allocPods), "allocatable pods should match capacity pods") +} + +func TestUpdateNodeResources_Accelerators(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + ctx := context.Background() + resources := &types.ResourcesResponse{ + Accelerators: []types.AcceleratorResponse{ + {ResourceType: "nvidia.com/gpu", Available: "8"}, + {ResourceType: "xilinx.com/fpga", Available: "2"}, + }, + } + provider.updateNodeResources(ctx, resources) + + gpuQty := provider.node.Status.Capacity["nvidia.com/gpu"] + assert.Equal(t, int64(8), gpuQty.Value()) + fpgaQty := provider.node.Status.Capacity["xilinx.com/fpga"] + assert.Equal(t, int64(2), fpgaQty.Value()) +} + +func TestUpdateNodeResources_InvalidValues(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + originalCPU := provider.node.Status.Capacity["cpu"].DeepCopy() + + ctx := context.Background() + resources := &types.ResourcesResponse{ + CPU: "not-a-valid-quantity", + } + provider.updateNodeResources(ctx, resources) + + // CPU should remain unchanged when invalid value is provided + currentCPU := provider.node.Status.Capacity["cpu"] + assert.Equal(t, originalCPU.Value(), currentCPU.Value()) +} + +func TestUpdateNodeResources_Nil(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + originalCPU := provider.node.Status.Capacity["cpu"].DeepCopy() + + ctx := context.Background() + // Passing nil should be a no-op + provider.updateNodeResources(ctx, nil) + + currentCPU := provider.node.Status.Capacity["cpu"] + assert.Equal(t, originalCPU.Value(), currentCPU.Value()) +} + +func TestUpdateNodeResources_PartialUpdate(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + originalMemory := provider.node.Status.Capacity["memory"].DeepCopy() + originalPods := provider.node.Status.Capacity["pods"].DeepCopy() + + ctx := context.Background() + // Only update CPU, leave memory and pods unchanged + resources := &types.ResourcesResponse{ + CPU: "500", + } + provider.updateNodeResources(ctx, resources) + + cpuQty := provider.node.Status.Capacity["cpu"] + assert.Equal(t, int64(500), cpuQty.Value()) + // Memory and pods should be unchanged + currentMemory := provider.node.Status.Capacity["memory"] + assert.Equal(t, originalMemory.Value(), currentMemory.Value()) + currentPods := provider.node.Status.Capacity["pods"] + assert.Equal(t, originalPods.Value(), currentPods.Value()) +} diff --git a/pkg/virtualkubelet/virtualkubelet.go b/pkg/virtualkubelet/virtualkubelet.go index da2a2b61..b6e86488 100644 --- a/pkg/virtualkubelet/virtualkubelet.go +++ b/pkg/virtualkubelet/virtualkubelet.go @@ -7,6 +7,7 @@ import ( "embed" "encoding/base64" "encoding/hex" + "encoding/json" "fmt" "io" mathrand "math/rand" @@ -652,7 +653,16 @@ func (p *Provider) nodeUpdate(ctx context.Context) { p.node.Annotations = make(map[string]string) } p.node.Annotations["interlink.virtual-kubelet.io/ping-response"] = respBody - log.G(ctx).Info("Ping succeded with exit code: ", code) + + // Try to parse the response body for optional resource update information + if respBody != "" { + var pingResp types.PingResponse + if err := json.Unmarshal([]byte(respBody), &pingResp); err == nil && pingResp.Resources != nil { + p.updateNodeResources(ctx, pingResp.Resources) + } + } + + log.G(ctx).Info("Ping succeeded with exit code: ", code) p.onNodeChangeCallback(p.node) } log.G(ctx).Info("endNodeLoop") @@ -664,6 +674,67 @@ func (p *Provider) Ping(_ context.Context) error { return nil } +// updateNodeResources updates the node's Capacity and Allocatable based on the resource +// information reported by the plugin in a ping response. Only fields explicitly set in +// the response are updated; omitted fields retain their current values. +func (p *Provider) updateNodeResources(ctx context.Context, resources *types.ResourcesResponse) { + if resources == nil { + return + } + + capacity := p.node.Status.Capacity + allocatable := p.node.Status.Allocatable + + if resources.CPU != "" { + q, err := resource.ParseQuantity(resources.CPU) + if err != nil { + log.G(ctx).Warnf("Invalid CPU value %q in ping response: %v", resources.CPU, err) + } else { + capacity[v1.ResourceCPU] = q + allocatable[v1.ResourceCPU] = q + log.G(ctx).Infof("Updated node CPU capacity to %s", resources.CPU) + } + } + + if resources.Memory != "" { + q, err := resource.ParseQuantity(resources.Memory) + if err != nil { + log.G(ctx).Warnf("Invalid memory value %q in ping response: %v", resources.Memory, err) + } else { + capacity[v1.ResourceMemory] = q + allocatable[v1.ResourceMemory] = q + log.G(ctx).Infof("Updated node memory capacity to %s", resources.Memory) + } + } + + if resources.Pods != "" { + q, err := resource.ParseQuantity(resources.Pods) + if err != nil { + log.G(ctx).Warnf("Invalid pods value %q in ping response: %v", resources.Pods, err) + } else { + capacity[v1.ResourcePods] = q + allocatable[v1.ResourcePods] = q + log.G(ctx).Infof("Updated node pods capacity to %s", resources.Pods) + } + } + + for _, acc := range resources.Accelerators { + if acc.ResourceType == "" { + log.G(ctx).Warn("Skipping accelerator with empty resourceType in ping response") + continue + } + q, err := resource.ParseQuantity(acc.Available) + if err != nil { + log.G(ctx).Warnf("Invalid quantity %q for accelerator %q in ping response: %v", acc.Available, acc.ResourceType, err) + continue + } + rName := v1.ResourceName(acc.ResourceType) + capacity[rName] = q + allocatable[rName] = q + log.G(ctx).Infof("Updated node accelerator %s capacity to %s", acc.ResourceType, acc.Available) + } +} + // hasExposedPorts checks if any container in the pod has exposed ports func hasExposedPorts(pod *v1.Pod) bool { for _, container := range pod.Spec.Containers { From c714361aaac91ec9539d37293ee47803d2190373 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Apr 2026 06:51:32 +0000 Subject: [PATCH 3/6] feat: support taints in plugin ping response Agent-Logs-Url: https://github.com/interlink-hq/interLink/sessions/ab8b0dc8-951f-4aaa-85b8-26f7028530f4 Co-authored-by: dciangot <4144326+dciangot@users.noreply.github.com> --- pkg/interlink/types.go | 15 ++++++++ pkg/virtualkubelet/virtualkubelet.go | 57 +++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/pkg/interlink/types.go b/pkg/interlink/types.go index 4897ca4f..5356d7cf 100644 --- a/pkg/interlink/types.go +++ b/pkg/interlink/types.go @@ -139,6 +139,21 @@ type PingResponse struct { // Resources optionally contains resource capacity information reported by the plugin. // When present, the Virtual Kubelet will update the node's Capacity and Allocatable fields. Resources *ResourcesResponse `json:"resources,omitempty"` + // Taints optionally contains a list of taints to apply to the node. + // When present (even as an empty list), the node's non-system taints are replaced with + // this list. When absent, existing taints are left unchanged. + Taints *[]TaintResponse `json:"taints,omitempty"` +} + +// TaintResponse represents a Kubernetes taint to be applied to the virtual node, +// as reported by a plugin in a ping response. +type TaintResponse struct { + // Key is the taint key (e.g., "virtual-node.interlink/no-schedule") + Key string `json:"key"` + // Value is the taint value (optional) + Value string `json:"value,omitempty"` + // Effect specifies the taint effect: "NoSchedule", "PreferNoSchedule", or "NoExecute" + Effect string `json:"effect"` } // ResourcesResponse represents the resource capacity information optionally returned by a plugin diff --git a/pkg/virtualkubelet/virtualkubelet.go b/pkg/virtualkubelet/virtualkubelet.go index b6e86488..0f495e9e 100644 --- a/pkg/virtualkubelet/virtualkubelet.go +++ b/pkg/virtualkubelet/virtualkubelet.go @@ -657,8 +657,13 @@ func (p *Provider) nodeUpdate(ctx context.Context) { // Try to parse the response body for optional resource update information if respBody != "" { var pingResp types.PingResponse - if err := json.Unmarshal([]byte(respBody), &pingResp); err == nil && pingResp.Resources != nil { - p.updateNodeResources(ctx, pingResp.Resources) + if err := json.Unmarshal([]byte(respBody), &pingResp); err == nil { + if pingResp.Resources != nil { + p.updateNodeResources(ctx, pingResp.Resources) + } + if pingResp.Taints != nil { + p.updateNodeTaints(ctx, pingResp.Taints) + } } } @@ -735,6 +740,54 @@ func (p *Provider) updateNodeResources(ctx context.Context, resources *types.Res } } +// updateNodeTaints replaces the node's non-system taints with the taints reported by the +// plugin in a ping response. The system taint "virtual-node.interlink/no-schedule" is always +// preserved regardless of the plugin-provided list. An empty slice clears all plugin-managed taints. +// Unknown taint effects default to NoSchedule (same behaviour as config-based taints) with a warning. +func (p *Provider) updateNodeTaints(ctx context.Context, taints *[]types.TaintResponse) { + if taints == nil { + return + } + + // Collect system taints that must always be present. + systemTaints := []v1.Taint{} + for _, t := range p.node.Spec.Taints { + if t.Key == "virtual-node.interlink/no-schedule" { + systemTaints = append(systemTaints, t) + } + } + + newTaints := systemTaints + for _, t := range *taints { + if t.Key == "" { + log.G(ctx).Warn("Skipping taint with empty key in ping response") + continue + } + + var effect v1.TaintEffect + switch t.Effect { + case "NoSchedule": + effect = v1.TaintEffectNoSchedule + case "PreferNoSchedule": + effect = v1.TaintEffectPreferNoSchedule + case "NoExecute": + effect = v1.TaintEffectNoExecute + default: + effect = v1.TaintEffectNoSchedule + log.G(ctx).Warnf("Unknown taint effect %q for key %q in ping response, defaulting to NoSchedule", t.Effect, t.Key) + } + + newTaints = append(newTaints, v1.Taint{ + Key: t.Key, + Value: t.Value, + Effect: effect, + }) + log.G(ctx).Infof("Adding taint key=%q value=%q effect=%q from ping response", t.Key, t.Value, t.Effect) + } + + p.node.Spec.Taints = newTaints +} + // hasExposedPorts checks if any container in the pod has exposed ports func hasExposedPorts(pod *v1.Pod) bool { for _, container := range pod.Spec.Containers { From 70c546be797b65017b68c220d4853c5e10b0d8f9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:01:43 +0000 Subject: [PATCH 4/6] fix: validate dynamic node resource and taint updates --- cmd/openapi-gen/main.go | 2 +- docs/openapi/interlink-openapi.json | 2 +- pkg/virtualkubelet/config_test.go | 135 ++++++++++++++++++++++++++- pkg/virtualkubelet/virtualkubelet.go | 19 ++++ 4 files changed, 155 insertions(+), 3 deletions(-) diff --git a/cmd/openapi-gen/main.go b/cmd/openapi-gen/main.go index 44958ad0..a5c593cf 100644 --- a/cmd/openapi-gen/main.go +++ b/cmd/openapi-gen/main.go @@ -59,7 +59,7 @@ func main() { } pingOp.AddReqStructure(nil) - pingOp.AddRespStructure(nil, func(cu *openapi.ContentUnit) { cu.HTTPStatus = http.StatusOK }) + pingOp.AddRespStructure(new(interlink.PingResponse), func(cu *openapi.ContentUnit) { cu.HTTPStatus = http.StatusOK }) err = reflector.AddOperation(pingOp) if err != nil { diff --git a/docs/openapi/interlink-openapi.json b/docs/openapi/interlink-openapi.json index c599b01f..2eaf8feb 100644 --- a/docs/openapi/interlink-openapi.json +++ b/docs/openapi/interlink-openapi.json @@ -1 +1 @@ -{"openapi":"3.0.3","info":{"title":"interLink server API","description":"This is the API spec for the Virtual Kubelet to interLink API server communication","version":"0.4.0"},"paths":{"/create":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkPodCreateRequests"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkRetrievedPodData"}}}}}}},"/delete":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Pod"}}}},"responses":{"200":{"description":"OK"}}}},"/getLogs":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkLogStruct"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/pinglink":{"post":{"responses":{"200":{"description":"OK"}}}},"/status":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1Pod"},"nullable":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkPodStatus"}}}}}}}}},"components":{"schemas":{"InterlinkApptainerOptions":{"type":"object","properties":{"cleanenv":{"type":"boolean"},"containall":{"type":"boolean"},"executable":{"type":"string"},"fakeroot":{"type":"boolean"},"fuseMode":{"type":"string"},"noHome":{"type":"boolean"},"noInit":{"type":"boolean"},"noPrivs":{"type":"boolean"},"nvidiaSupport":{"type":"boolean"},"unsquash":{"type":"boolean"}}},"InterlinkContainerLogOpts":{"type":"object","properties":{"Bytes":{"type":"integer"},"Follow":{"type":"boolean"},"Previous":{"type":"boolean"},"SinceSeconds":{"type":"integer"},"SinceTime":{"type":"string","format":"date-time"},"Tail":{"type":"integer"},"Timestamps":{"type":"boolean"}}},"InterlinkLogStruct":{"type":"object","properties":{"ContainerName":{"type":"string"},"Namespace":{"type":"string"},"Opts":{"$ref":"#/components/schemas/InterlinkContainerLogOpts"},"PodName":{"type":"string"},"PodUID":{"type":"string"}}},"InterlinkPodCreateRequests":{"type":"object","properties":{"configmaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"jobscriptURL":{"type":"string"},"pod":{"$ref":"#/components/schemas/V1Pod"},"projectedvolumesmaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"secrets":{"type":"array","items":{"$ref":"#/components/schemas/V1Secret"},"nullable":true}}},"InterlinkPodStatus":{"type":"object","properties":{"JID":{"type":"string"},"UID":{"type":"string"},"containers":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"},"nullable":true},"initContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"},"nullable":true},"name":{"type":"string"},"namespace":{"type":"string"}}},"InterlinkRetrievedContainer":{"type":"object","properties":{"configMaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"emptyDirs":{"type":"array","items":{"type":"string"},"nullable":true},"name":{"type":"string"},"projectedvolumemaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"secrets":{"type":"array","items":{"$ref":"#/components/schemas/V1Secret"},"nullable":true}}},"InterlinkRetrievedPodData":{"type":"object","properties":{"container":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkRetrievedContainer"},"nullable":true},"jobConfig":{"$ref":"#/components/schemas/InterlinkScriptBuildConfig"},"jobScript":{"type":"string"},"pod":{"$ref":"#/components/schemas/V1Pod"}}},"InterlinkScriptBuildConfig":{"type":"object","properties":{"ApptainerOptions":{"$ref":"#/components/schemas/InterlinkApptainerOptions"},"SingularityHubProxy":{"$ref":"#/components/schemas/InterlinkSingularityHubConfig"},"Volumes":{"$ref":"#/components/schemas/InterlinkVolumesOptions"}}},"InterlinkSingularityHubConfig":{"type":"object","properties":{"cache_validity_seconds":{"type":"integer"},"master_token":{"type":"string"},"server":{"type":"string"}}},"InterlinkVolumesOptions":{"type":"object","properties":{"additional_directories_in_path":{"type":"array","items":{"type":"string"},"nullable":true},"apptainer_cachedir":{"type":"string"},"fuse_sleep_seconds":{"type":"integer"},"image_dir":{"type":"string"},"scratch_area":{"type":"string"}}},"IntstrIntOrString":{"type":"object"},"ResourceQuantity":{"type":"object"},"V1AWSElasticBlockStoreVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"partition":{"type":"integer"},"readOnly":{"type":"boolean"},"volumeID":{"type":"string"}}},"V1Affinity":{"type":"object","properties":{"nodeAffinity":{"$ref":"#/components/schemas/V1NodeAffinity"},"podAffinity":{"$ref":"#/components/schemas/V1PodAffinity"},"podAntiAffinity":{"$ref":"#/components/schemas/V1PodAntiAffinity"}}},"V1AppArmorProfile":{"type":"object","properties":{"localhostProfile":{"type":"string","nullable":true},"type":{"type":"string"}}},"V1AzureDiskVolumeSource":{"type":"object","properties":{"cachingMode":{"type":"string","nullable":true},"diskName":{"type":"string"},"diskURI":{"type":"string"},"fsType":{"type":"string","nullable":true},"kind":{"type":"string","nullable":true},"readOnly":{"type":"boolean","nullable":true}}},"V1AzureFileVolumeSource":{"type":"object","properties":{"readOnly":{"type":"boolean"},"secretName":{"type":"string"},"shareName":{"type":"string"}}},"V1CSIVolumeSource":{"type":"object","properties":{"driver":{"type":"string"},"fsType":{"type":"string","nullable":true},"nodePublishSecretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"readOnly":{"type":"boolean","nullable":true},"volumeAttributes":{"type":"object","additionalProperties":{"type":"string"}}}},"V1Capabilities":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string"}},"drop":{"type":"array","items":{"type":"string"}}}},"V1CephFSVolumeSource":{"type":"object","properties":{"monitors":{"type":"array","items":{"type":"string"},"nullable":true},"path":{"type":"string"},"readOnly":{"type":"boolean"},"secretFile":{"type":"string"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"user":{"type":"string"}}},"V1CinderVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"volumeID":{"type":"string"}}},"V1ClusterTrustBundleProjection":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"name":{"type":"string","nullable":true},"optional":{"type":"boolean","nullable":true},"path":{"type":"string"},"signerName":{"type":"string","nullable":true}}},"V1ConfigMap":{"type":"object","properties":{"apiVersion":{"type":"string"},"binaryData":{"type":"object","additionalProperties":{"type":"string","format":"base64"}},"data":{"type":"object","additionalProperties":{"type":"string"}},"immutable":{"type":"boolean","nullable":true},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"}}},"V1ConfigMapEnvSource":{"type":"object","properties":{"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapKeySelector":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1Container":{"type":"object","properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":"array","items":{"type":"string"}},"env":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvVar"}},"envFrom":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvFromSource"}},"image":{"type":"string"},"imagePullPolicy":{"type":"string"},"lifecycle":{"$ref":"#/components/schemas/V1Lifecycle"},"livenessProbe":{"$ref":"#/components/schemas/V1Probe"},"name":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerPort"}},"readinessProbe":{"$ref":"#/components/schemas/V1Probe"},"resizePolicy":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerResizePolicy"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string","nullable":true},"securityContext":{"$ref":"#/components/schemas/V1SecurityContext"},"startupProbe":{"$ref":"#/components/schemas/V1Probe"},"stdin":{"type":"boolean"},"stdinOnce":{"type":"boolean"},"terminationMessagePath":{"type":"string"},"terminationMessagePolicy":{"type":"string"},"tty":{"type":"boolean"},"volumeDevices":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeDevice"}},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMount"}},"workingDir":{"type":"string"}}},"V1ContainerPort":{"type":"object","properties":{"containerPort":{"type":"integer"},"hostIP":{"type":"string"},"hostPort":{"type":"integer"},"name":{"type":"string"},"protocol":{"type":"string"}}},"V1ContainerResizePolicy":{"type":"object","properties":{"resourceName":{"type":"string"},"restartPolicy":{"type":"string"}}},"V1ContainerState":{"type":"object","properties":{"running":{"$ref":"#/components/schemas/V1ContainerStateRunning"},"terminated":{"$ref":"#/components/schemas/V1ContainerStateTerminated"},"waiting":{"$ref":"#/components/schemas/V1ContainerStateWaiting"}}},"V1ContainerStateRunning":{"type":"object","properties":{"startedAt":{"type":"string"}}},"V1ContainerStateTerminated":{"type":"object","properties":{"containerID":{"type":"string"},"exitCode":{"type":"integer"},"finishedAt":{"type":"string"},"message":{"type":"string"},"reason":{"type":"string"},"signal":{"type":"integer"},"startedAt":{"type":"string"}}},"V1ContainerStateWaiting":{"type":"object","properties":{"message":{"type":"string"},"reason":{"type":"string"}}},"V1ContainerStatus":{"type":"object","properties":{"allocatedResources":{"$ref":"#/components/schemas/V1ResourceList"},"allocatedResourcesStatus":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceStatus"}},"containerID":{"type":"string"},"image":{"type":"string"},"imageID":{"type":"string"},"lastState":{"$ref":"#/components/schemas/V1ContainerState"},"name":{"type":"string"},"ready":{"type":"boolean"},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartCount":{"type":"integer"},"started":{"type":"boolean","nullable":true},"state":{"$ref":"#/components/schemas/V1ContainerState"},"stopSignal":{"type":"string","nullable":true},"user":{"$ref":"#/components/schemas/V1ContainerUser"},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMountStatus"}}}},"V1ContainerUser":{"type":"object","properties":{"linux":{"$ref":"#/components/schemas/V1LinuxContainerUser"}}},"V1DownwardAPIProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1DownwardAPIVolumeFile"}}}},"V1DownwardAPIVolumeFile":{"type":"object","properties":{"fieldRef":{"$ref":"#/components/schemas/V1ObjectFieldSelector"},"mode":{"type":"integer","nullable":true},"path":{"type":"string"},"resourceFieldRef":{"$ref":"#/components/schemas/V1ResourceFieldSelector"}}},"V1DownwardAPIVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1DownwardAPIVolumeFile"}}}},"V1EmptyDirVolumeSource":{"type":"object","properties":{"medium":{"type":"string"},"sizeLimit":{"$ref":"#/components/schemas/ResourceQuantity"}}},"V1EnvFromSource":{"type":"object","properties":{"configMapRef":{"$ref":"#/components/schemas/V1ConfigMapEnvSource"},"prefix":{"type":"string"},"secretRef":{"$ref":"#/components/schemas/V1SecretEnvSource"}}},"V1EnvVar":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"},"valueFrom":{"$ref":"#/components/schemas/V1EnvVarSource"}}},"V1EnvVarSource":{"type":"object","properties":{"configMapKeyRef":{"$ref":"#/components/schemas/V1ConfigMapKeySelector"},"fieldRef":{"$ref":"#/components/schemas/V1ObjectFieldSelector"},"resourceFieldRef":{"$ref":"#/components/schemas/V1ResourceFieldSelector"},"secretKeyRef":{"$ref":"#/components/schemas/V1SecretKeySelector"}}},"V1EphemeralContainer":{"type":"object","properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":"array","items":{"type":"string"}},"env":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvVar"}},"envFrom":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvFromSource"}},"image":{"type":"string"},"imagePullPolicy":{"type":"string"},"lifecycle":{"$ref":"#/components/schemas/V1Lifecycle"},"livenessProbe":{"$ref":"#/components/schemas/V1Probe"},"name":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerPort"}},"readinessProbe":{"$ref":"#/components/schemas/V1Probe"},"resizePolicy":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerResizePolicy"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string","nullable":true},"securityContext":{"$ref":"#/components/schemas/V1SecurityContext"},"startupProbe":{"$ref":"#/components/schemas/V1Probe"},"stdin":{"type":"boolean"},"stdinOnce":{"type":"boolean"},"targetContainerName":{"type":"string"},"terminationMessagePath":{"type":"string"},"terminationMessagePolicy":{"type":"string"},"tty":{"type":"boolean"},"volumeDevices":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeDevice"}},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMount"}},"workingDir":{"type":"string"}}},"V1EphemeralVolumeSource":{"type":"object","properties":{"volumeClaimTemplate":{"$ref":"#/components/schemas/V1PersistentVolumeClaimTemplate"}}},"V1ExecAction":{"type":"object","properties":{"command":{"type":"array","items":{"type":"string"}}}},"V1FCVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"lun":{"type":"integer","nullable":true},"readOnly":{"type":"boolean"},"targetWWNs":{"type":"array","items":{"type":"string"}},"wwids":{"type":"array","items":{"type":"string"}}}},"V1FieldsV1":{"type":"object"},"V1FlexVolumeSource":{"type":"object","properties":{"driver":{"type":"string"},"fsType":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"}}},"V1FlockerVolumeSource":{"type":"object","properties":{"datasetName":{"type":"string"},"datasetUUID":{"type":"string"}}},"V1GCEPersistentDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"partition":{"type":"integer"},"pdName":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1GRPCAction":{"type":"object","properties":{"port":{"type":"integer"},"service":{"type":"string","nullable":true}}},"V1GitRepoVolumeSource":{"type":"object","properties":{"directory":{"type":"string"},"repository":{"type":"string"},"revision":{"type":"string"}}},"V1GlusterfsVolumeSource":{"type":"object","properties":{"endpoints":{"type":"string"},"path":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1HTTPGetAction":{"type":"object","properties":{"host":{"type":"string"},"httpHeaders":{"type":"array","items":{"$ref":"#/components/schemas/V1HTTPHeader"}},"path":{"type":"string"},"port":{"$ref":"#/components/schemas/IntstrIntOrString"},"scheme":{"type":"string"}}},"V1HTTPHeader":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}},"V1HostAlias":{"type":"object","properties":{"hostnames":{"type":"array","items":{"type":"string"}},"ip":{"type":"string"}}},"V1HostIP":{"type":"object","properties":{"ip":{"type":"string"}}},"V1HostPathVolumeSource":{"type":"object","properties":{"path":{"type":"string"},"type":{"type":"string","nullable":true}}},"V1ISCSIVolumeSource":{"type":"object","properties":{"chapAuthDiscovery":{"type":"boolean"},"chapAuthSession":{"type":"boolean"},"fsType":{"type":"string"},"initiatorName":{"type":"string","nullable":true},"iqn":{"type":"string"},"iscsiInterface":{"type":"string"},"lun":{"type":"integer"},"portals":{"type":"array","items":{"type":"string"}},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"targetPortal":{"type":"string"}}},"V1ImageVolumeSource":{"type":"object","properties":{"pullPolicy":{"type":"string"},"reference":{"type":"string"}}},"V1KeyToPath":{"type":"object","properties":{"key":{"type":"string"},"mode":{"type":"integer","nullable":true},"path":{"type":"string"}}},"V1LabelSelector":{"type":"object","properties":{"matchExpressions":{"type":"array","items":{"$ref":"#/components/schemas/V1LabelSelectorRequirement"}},"matchLabels":{"type":"object","additionalProperties":{"type":"string"}}}},"V1LabelSelectorRequirement":{"type":"object","properties":{"key":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}}},"V1Lifecycle":{"type":"object","properties":{"postStart":{"$ref":"#/components/schemas/V1LifecycleHandler"},"preStop":{"$ref":"#/components/schemas/V1LifecycleHandler"},"stopSignal":{"type":"string","nullable":true}}},"V1LifecycleHandler":{"type":"object","properties":{"exec":{"$ref":"#/components/schemas/V1ExecAction"},"httpGet":{"$ref":"#/components/schemas/V1HTTPGetAction"},"sleep":{"$ref":"#/components/schemas/V1SleepAction"},"tcpSocket":{"$ref":"#/components/schemas/V1TCPSocketAction"}}},"V1LinuxContainerUser":{"type":"object","properties":{"gid":{"type":"integer"},"supplementalGroups":{"type":"array","items":{"type":"integer"}},"uid":{"type":"integer"}}},"V1LocalObjectReference":{"type":"object","properties":{"name":{"type":"string"}}},"V1ManagedFieldsEntry":{"type":"object","properties":{"apiVersion":{"type":"string"},"fieldsType":{"type":"string"},"fieldsV1":{"$ref":"#/components/schemas/V1FieldsV1"},"manager":{"type":"string"},"operation":{"type":"string"},"subresource":{"type":"string"},"time":{"type":"string"}}},"V1NFSVolumeSource":{"type":"object","properties":{"path":{"type":"string"},"readOnly":{"type":"boolean"},"server":{"type":"string"}}},"V1NodeAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PreferredSchedulingTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"$ref":"#/components/schemas/V1NodeSelector"}}},"V1NodeSelector":{"type":"object","properties":{"nodeSelectorTerms":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorTerm"},"nullable":true}}},"V1NodeSelectorRequirement":{"type":"object","properties":{"key":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}}},"V1NodeSelectorTerm":{"type":"object","properties":{"matchExpressions":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorRequirement"}},"matchFields":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorRequirement"}}}},"V1ObjectFieldSelector":{"type":"object","properties":{"apiVersion":{"type":"string"},"fieldPath":{"type":"string"}}},"V1ObjectMeta":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"}},"creationTimestamp":{"type":"string"},"deletionGracePeriodSeconds":{"type":"integer","nullable":true},"deletionTimestamp":{"type":"string"},"finalizers":{"type":"array","items":{"type":"string"}},"generateName":{"type":"string"},"generation":{"type":"integer"},"labels":{"type":"object","additionalProperties":{"type":"string"}},"managedFields":{"type":"array","items":{"$ref":"#/components/schemas/V1ManagedFieldsEntry"}},"name":{"type":"string"},"namespace":{"type":"string"},"ownerReferences":{"type":"array","items":{"$ref":"#/components/schemas/V1OwnerReference"}},"resourceVersion":{"type":"string"},"selfLink":{"type":"string"},"uid":{"type":"string"}}},"V1OwnerReference":{"type":"object","properties":{"apiVersion":{"type":"string"},"blockOwnerDeletion":{"type":"boolean","nullable":true},"controller":{"type":"boolean","nullable":true},"kind":{"type":"string"},"name":{"type":"string"},"uid":{"type":"string"}}},"V1PersistentVolumeClaimSpec":{"type":"object","properties":{"accessModes":{"type":"array","items":{"type":"string"}},"dataSource":{"$ref":"#/components/schemas/V1TypedLocalObjectReference"},"dataSourceRef":{"$ref":"#/components/schemas/V1TypedObjectReference"},"resources":{"$ref":"#/components/schemas/V1VolumeResourceRequirements"},"selector":{"$ref":"#/components/schemas/V1LabelSelector"},"storageClassName":{"type":"string","nullable":true},"volumeAttributesClassName":{"type":"string","nullable":true},"volumeMode":{"type":"string","nullable":true},"volumeName":{"type":"string"}}},"V1PersistentVolumeClaimTemplate":{"type":"object","properties":{"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"spec":{"$ref":"#/components/schemas/V1PersistentVolumeClaimSpec"}}},"V1PersistentVolumeClaimVolumeSource":{"type":"object","properties":{"claimName":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1PhotonPersistentDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"pdID":{"type":"string"}}},"V1Pod":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"spec":{"$ref":"#/components/schemas/V1PodSpec"},"status":{"$ref":"#/components/schemas/V1PodStatus"}}},"V1PodAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1WeightedPodAffinityTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PodAffinityTerm"}}}},"V1PodAffinityTerm":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"matchLabelKeys":{"type":"array","items":{"type":"string"}},"mismatchLabelKeys":{"type":"array","items":{"type":"string"}},"namespaceSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"namespaces":{"type":"array","items":{"type":"string"}},"topologyKey":{"type":"string"}}},"V1PodAntiAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1WeightedPodAffinityTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PodAffinityTerm"}}}},"V1PodCondition":{"type":"object","properties":{"lastProbeTime":{"type":"string"},"lastTransitionTime":{"type":"string"},"message":{"type":"string"},"observedGeneration":{"type":"integer"},"reason":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"}}},"V1PodDNSConfig":{"type":"object","properties":{"nameservers":{"type":"array","items":{"type":"string"}},"options":{"type":"array","items":{"$ref":"#/components/schemas/V1PodDNSConfigOption"}},"searches":{"type":"array","items":{"type":"string"}}}},"V1PodDNSConfigOption":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string","nullable":true}}},"V1PodIP":{"type":"object","properties":{"ip":{"type":"string"}}},"V1PodOS":{"type":"object","properties":{"name":{"type":"string"}}},"V1PodReadinessGate":{"type":"object","properties":{"conditionType":{"type":"string"}}},"V1PodResourceClaim":{"type":"object","properties":{"name":{"type":"string"},"resourceClaimName":{"type":"string","nullable":true},"resourceClaimTemplateName":{"type":"string","nullable":true}}},"V1PodResourceClaimStatus":{"type":"object","properties":{"name":{"type":"string"},"resourceClaimName":{"type":"string","nullable":true}}},"V1PodSchedulingGate":{"type":"object","properties":{"name":{"type":"string"}}},"V1PodSecurityContext":{"type":"object","properties":{"appArmorProfile":{"$ref":"#/components/schemas/V1AppArmorProfile"},"fsGroup":{"type":"integer","nullable":true},"fsGroupChangePolicy":{"type":"string","nullable":true},"runAsGroup":{"type":"integer","nullable":true},"runAsNonRoot":{"type":"boolean","nullable":true},"runAsUser":{"type":"integer","nullable":true},"seLinuxChangePolicy":{"type":"string","nullable":true},"seLinuxOptions":{"$ref":"#/components/schemas/V1SELinuxOptions"},"seccompProfile":{"$ref":"#/components/schemas/V1SeccompProfile"},"supplementalGroups":{"type":"array","items":{"type":"integer"}},"supplementalGroupsPolicy":{"type":"string","nullable":true},"sysctls":{"type":"array","items":{"$ref":"#/components/schemas/V1Sysctl"}},"windowsOptions":{"$ref":"#/components/schemas/V1WindowsSecurityContextOptions"}}},"V1PodSpec":{"type":"object","properties":{"activeDeadlineSeconds":{"type":"integer","nullable":true},"affinity":{"$ref":"#/components/schemas/V1Affinity"},"automountServiceAccountToken":{"type":"boolean","nullable":true},"containers":{"type":"array","items":{"$ref":"#/components/schemas/V1Container"},"nullable":true},"dnsConfig":{"$ref":"#/components/schemas/V1PodDNSConfig"},"dnsPolicy":{"type":"string"},"enableServiceLinks":{"type":"boolean","nullable":true},"ephemeralContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1EphemeralContainer"}},"hostAliases":{"type":"array","items":{"$ref":"#/components/schemas/V1HostAlias"}},"hostIPC":{"type":"boolean"},"hostNetwork":{"type":"boolean"},"hostPID":{"type":"boolean"},"hostUsers":{"type":"boolean","nullable":true},"hostname":{"type":"string"},"imagePullSecrets":{"type":"array","items":{"$ref":"#/components/schemas/V1LocalObjectReference"}},"initContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1Container"}},"nodeName":{"type":"string"},"nodeSelector":{"type":"object","additionalProperties":{"type":"string"}},"os":{"$ref":"#/components/schemas/V1PodOS"},"overhead":{"$ref":"#/components/schemas/V1ResourceList"},"preemptionPolicy":{"type":"string","nullable":true},"priority":{"type":"integer","nullable":true},"priorityClassName":{"type":"string"},"readinessGates":{"type":"array","items":{"$ref":"#/components/schemas/V1PodReadinessGate"}},"resourceClaims":{"type":"array","items":{"$ref":"#/components/schemas/V1PodResourceClaim"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string"},"runtimeClassName":{"type":"string","nullable":true},"schedulerName":{"type":"string"},"schedulingGates":{"type":"array","items":{"$ref":"#/components/schemas/V1PodSchedulingGate"}},"securityContext":{"$ref":"#/components/schemas/V1PodSecurityContext"},"serviceAccount":{"type":"string"},"serviceAccountName":{"type":"string"},"setHostnameAsFQDN":{"type":"boolean","nullable":true},"shareProcessNamespace":{"type":"boolean","nullable":true},"subdomain":{"type":"string"},"terminationGracePeriodSeconds":{"type":"integer","nullable":true},"tolerations":{"type":"array","items":{"$ref":"#/components/schemas/V1Toleration"}},"topologySpreadConstraints":{"type":"array","items":{"$ref":"#/components/schemas/V1TopologySpreadConstraint"}},"volumes":{"type":"array","items":{"$ref":"#/components/schemas/V1Volume"}}}},"V1PodStatus":{"type":"object","properties":{"conditions":{"type":"array","items":{"$ref":"#/components/schemas/V1PodCondition"}},"containerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"ephemeralContainerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"hostIP":{"type":"string"},"hostIPs":{"type":"array","items":{"$ref":"#/components/schemas/V1HostIP"}},"initContainerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"message":{"type":"string"},"nominatedNodeName":{"type":"string"},"observedGeneration":{"type":"integer"},"phase":{"type":"string"},"podIP":{"type":"string"},"podIPs":{"type":"array","items":{"$ref":"#/components/schemas/V1PodIP"}},"qosClass":{"type":"string"},"reason":{"type":"string"},"resize":{"type":"string"},"resourceClaimStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1PodResourceClaimStatus"}},"startTime":{"type":"string"}}},"V1PortworxVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"volumeID":{"type":"string"}}},"V1PreferredSchedulingTerm":{"type":"object","properties":{"preference":{"$ref":"#/components/schemas/V1NodeSelectorTerm"},"weight":{"type":"integer"}}},"V1Probe":{"type":"object","properties":{"exec":{"$ref":"#/components/schemas/V1ExecAction"},"failureThreshold":{"type":"integer"},"grpc":{"$ref":"#/components/schemas/V1GRPCAction"},"httpGet":{"$ref":"#/components/schemas/V1HTTPGetAction"},"initialDelaySeconds":{"type":"integer"},"periodSeconds":{"type":"integer"},"successThreshold":{"type":"integer"},"tcpSocket":{"$ref":"#/components/schemas/V1TCPSocketAction"},"terminationGracePeriodSeconds":{"type":"integer","nullable":true},"timeoutSeconds":{"type":"integer"}}},"V1ProjectedVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"sources":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeProjection"},"nullable":true}}},"V1QuobyteVolumeSource":{"type":"object","properties":{"group":{"type":"string"},"readOnly":{"type":"boolean"},"registry":{"type":"string"},"tenant":{"type":"string"},"user":{"type":"string"},"volume":{"type":"string"}}},"V1RBDVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"image":{"type":"string"},"keyring":{"type":"string"},"monitors":{"type":"array","items":{"type":"string"},"nullable":true},"pool":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"user":{"type":"string"}}},"V1ResourceClaim":{"type":"object","properties":{"name":{"type":"string"},"request":{"type":"string"}}},"V1ResourceFieldSelector":{"type":"object","properties":{"containerName":{"type":"string"},"divisor":{"$ref":"#/components/schemas/ResourceQuantity"},"resource":{"type":"string"}}},"V1ResourceHealth":{"type":"object","properties":{"health":{"type":"string"},"resourceID":{"type":"string"}}},"V1ResourceList":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ResourceQuantity"}},"V1ResourceRequirements":{"type":"object","properties":{"claims":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceClaim"}},"limits":{"$ref":"#/components/schemas/V1ResourceList"},"requests":{"$ref":"#/components/schemas/V1ResourceList"}}},"V1ResourceStatus":{"type":"object","properties":{"name":{"type":"string"},"resources":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceHealth"}}}},"V1SELinuxOptions":{"type":"object","properties":{"level":{"type":"string"},"role":{"type":"string"},"type":{"type":"string"},"user":{"type":"string"}}},"V1ScaleIOVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"gateway":{"type":"string"},"protectionDomain":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"sslEnabled":{"type":"boolean"},"storageMode":{"type":"string"},"storagePool":{"type":"string"},"system":{"type":"string"},"volumeName":{"type":"string"}}},"V1SeccompProfile":{"type":"object","properties":{"localhostProfile":{"type":"string","nullable":true},"type":{"type":"string"}}},"V1Secret":{"type":"object","properties":{"apiVersion":{"type":"string"},"data":{"type":"object","additionalProperties":{"type":"string","format":"base64"}},"immutable":{"type":"boolean","nullable":true},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"stringData":{"type":"object","additionalProperties":{"type":"string"}},"type":{"type":"string"}}},"V1SecretEnvSource":{"type":"object","properties":{"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretKeySelector":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"optional":{"type":"boolean","nullable":true},"secretName":{"type":"string"}}},"V1SecurityContext":{"type":"object","properties":{"allowPrivilegeEscalation":{"type":"boolean","nullable":true},"appArmorProfile":{"$ref":"#/components/schemas/V1AppArmorProfile"},"capabilities":{"$ref":"#/components/schemas/V1Capabilities"},"privileged":{"type":"boolean","nullable":true},"procMount":{"type":"string","nullable":true},"readOnlyRootFilesystem":{"type":"boolean","nullable":true},"runAsGroup":{"type":"integer","nullable":true},"runAsNonRoot":{"type":"boolean","nullable":true},"runAsUser":{"type":"integer","nullable":true},"seLinuxOptions":{"$ref":"#/components/schemas/V1SELinuxOptions"},"seccompProfile":{"$ref":"#/components/schemas/V1SeccompProfile"},"windowsOptions":{"$ref":"#/components/schemas/V1WindowsSecurityContextOptions"}}},"V1ServiceAccountTokenProjection":{"type":"object","properties":{"audience":{"type":"string"},"expirationSeconds":{"type":"integer","nullable":true},"path":{"type":"string"}}},"V1SleepAction":{"type":"object","properties":{"seconds":{"type":"integer"}}},"V1StorageOSVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"volumeName":{"type":"string"},"volumeNamespace":{"type":"string"}}},"V1Sysctl":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}},"V1TCPSocketAction":{"type":"object","properties":{"host":{"type":"string"},"port":{"$ref":"#/components/schemas/IntstrIntOrString"}}},"V1Toleration":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"operator":{"type":"string"},"tolerationSeconds":{"type":"integer","nullable":true},"value":{"type":"string"}}},"V1TopologySpreadConstraint":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"matchLabelKeys":{"type":"array","items":{"type":"string"}},"maxSkew":{"type":"integer"},"minDomains":{"type":"integer","nullable":true},"nodeAffinityPolicy":{"type":"string","nullable":true},"nodeTaintsPolicy":{"type":"string","nullable":true},"topologyKey":{"type":"string"},"whenUnsatisfiable":{"type":"string"}}},"V1TypedLocalObjectReference":{"type":"object","properties":{"apiGroup":{"type":"string","nullable":true},"kind":{"type":"string"},"name":{"type":"string"}}},"V1TypedObjectReference":{"type":"object","properties":{"apiGroup":{"type":"string","nullable":true},"kind":{"type":"string"},"name":{"type":"string"},"namespace":{"type":"string","nullable":true}}},"V1Volume":{"type":"object","properties":{"awsElasticBlockStore":{"$ref":"#/components/schemas/V1AWSElasticBlockStoreVolumeSource"},"azureDisk":{"$ref":"#/components/schemas/V1AzureDiskVolumeSource"},"azureFile":{"$ref":"#/components/schemas/V1AzureFileVolumeSource"},"cephfs":{"$ref":"#/components/schemas/V1CephFSVolumeSource"},"cinder":{"$ref":"#/components/schemas/V1CinderVolumeSource"},"configMap":{"$ref":"#/components/schemas/V1ConfigMapVolumeSource"},"csi":{"$ref":"#/components/schemas/V1CSIVolumeSource"},"downwardAPI":{"$ref":"#/components/schemas/V1DownwardAPIVolumeSource"},"emptyDir":{"$ref":"#/components/schemas/V1EmptyDirVolumeSource"},"ephemeral":{"$ref":"#/components/schemas/V1EphemeralVolumeSource"},"fc":{"$ref":"#/components/schemas/V1FCVolumeSource"},"flexVolume":{"$ref":"#/components/schemas/V1FlexVolumeSource"},"flocker":{"$ref":"#/components/schemas/V1FlockerVolumeSource"},"gcePersistentDisk":{"$ref":"#/components/schemas/V1GCEPersistentDiskVolumeSource"},"gitRepo":{"$ref":"#/components/schemas/V1GitRepoVolumeSource"},"glusterfs":{"$ref":"#/components/schemas/V1GlusterfsVolumeSource"},"hostPath":{"$ref":"#/components/schemas/V1HostPathVolumeSource"},"image":{"$ref":"#/components/schemas/V1ImageVolumeSource"},"iscsi":{"$ref":"#/components/schemas/V1ISCSIVolumeSource"},"name":{"type":"string"},"nfs":{"$ref":"#/components/schemas/V1NFSVolumeSource"},"persistentVolumeClaim":{"$ref":"#/components/schemas/V1PersistentVolumeClaimVolumeSource"},"photonPersistentDisk":{"$ref":"#/components/schemas/V1PhotonPersistentDiskVolumeSource"},"portworxVolume":{"$ref":"#/components/schemas/V1PortworxVolumeSource"},"projected":{"$ref":"#/components/schemas/V1ProjectedVolumeSource"},"quobyte":{"$ref":"#/components/schemas/V1QuobyteVolumeSource"},"rbd":{"$ref":"#/components/schemas/V1RBDVolumeSource"},"scaleIO":{"$ref":"#/components/schemas/V1ScaleIOVolumeSource"},"secret":{"$ref":"#/components/schemas/V1SecretVolumeSource"},"storageos":{"$ref":"#/components/schemas/V1StorageOSVolumeSource"},"vsphereVolume":{"$ref":"#/components/schemas/V1VsphereVirtualDiskVolumeSource"}}},"V1VolumeDevice":{"type":"object","properties":{"devicePath":{"type":"string"},"name":{"type":"string"}}},"V1VolumeMount":{"type":"object","properties":{"mountPath":{"type":"string"},"mountPropagation":{"type":"string","nullable":true},"name":{"type":"string"},"readOnly":{"type":"boolean"},"recursiveReadOnly":{"type":"string","nullable":true},"subPath":{"type":"string"},"subPathExpr":{"type":"string"}}},"V1VolumeMountStatus":{"type":"object","properties":{"mountPath":{"type":"string"},"name":{"type":"string"},"readOnly":{"type":"boolean"},"recursiveReadOnly":{"type":"string","nullable":true}}},"V1VolumeProjection":{"type":"object","properties":{"clusterTrustBundle":{"$ref":"#/components/schemas/V1ClusterTrustBundleProjection"},"configMap":{"$ref":"#/components/schemas/V1ConfigMapProjection"},"downwardAPI":{"$ref":"#/components/schemas/V1DownwardAPIProjection"},"secret":{"$ref":"#/components/schemas/V1SecretProjection"},"serviceAccountToken":{"$ref":"#/components/schemas/V1ServiceAccountTokenProjection"}}},"V1VolumeResourceRequirements":{"type":"object","properties":{"limits":{"$ref":"#/components/schemas/V1ResourceList"},"requests":{"$ref":"#/components/schemas/V1ResourceList"}}},"V1VsphereVirtualDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"storagePolicyID":{"type":"string"},"storagePolicyName":{"type":"string"},"volumePath":{"type":"string"}}},"V1WeightedPodAffinityTerm":{"type":"object","properties":{"podAffinityTerm":{"$ref":"#/components/schemas/V1PodAffinityTerm"},"weight":{"type":"integer"}}},"V1WindowsSecurityContextOptions":{"type":"object","properties":{"gmsaCredentialSpec":{"type":"string","nullable":true},"gmsaCredentialSpecName":{"type":"string","nullable":true},"hostProcess":{"type":"boolean","nullable":true},"runAsUserName":{"type":"string","nullable":true}}}}}} \ No newline at end of file +{"openapi":"3.0.3","info":{"title":"interLink server API","description":"This is the API spec for the Virtual Kubelet to interLink API server communication","version":"0.4.0"},"paths":{"/create":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkPodCreateRequests"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkRetrievedPodData"}}}}}}},"/delete":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Pod"}}}},"responses":{"200":{"description":"OK"}}}},"/getLogs":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkLogStruct"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/pinglink":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterlinkPingResponse"}}}}}}},"/status":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1Pod"},"nullable":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkPodStatus"}}}}}}}}},"components":{"schemas":{"InterlinkAcceleratorResponse":{"type":"object","properties":{"available":{"type":"string"},"resourceType":{"type":"string"}}},"InterlinkApptainerOptions":{"type":"object","properties":{"cleanenv":{"type":"boolean"},"containall":{"type":"boolean"},"executable":{"type":"string"},"fakeroot":{"type":"boolean"},"fuseMode":{"type":"string"},"noHome":{"type":"boolean"},"noInit":{"type":"boolean"},"noPrivs":{"type":"boolean"},"nvidiaSupport":{"type":"boolean"},"unsquash":{"type":"boolean"}}},"InterlinkContainerLogOpts":{"type":"object","properties":{"Bytes":{"type":"integer"},"Follow":{"type":"boolean"},"Previous":{"type":"boolean"},"SinceSeconds":{"type":"integer"},"SinceTime":{"type":"string","format":"date-time"},"Tail":{"type":"integer"},"Timestamps":{"type":"boolean"}}},"InterlinkLogStruct":{"type":"object","properties":{"ContainerName":{"type":"string"},"Namespace":{"type":"string"},"Opts":{"$ref":"#/components/schemas/InterlinkContainerLogOpts"},"PodName":{"type":"string"},"PodUID":{"type":"string"}}},"InterlinkPingResponse":{"type":"object","properties":{"resources":{"$ref":"#/components/schemas/InterlinkResourcesResponse"},"status":{"type":"string"},"taints":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkTaintResponse"},"nullable":true}}},"InterlinkPodCreateRequests":{"type":"object","properties":{"configmaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"jobscriptURL":{"type":"string"},"pod":{"$ref":"#/components/schemas/V1Pod"},"projectedvolumesmaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"secrets":{"type":"array","items":{"$ref":"#/components/schemas/V1Secret"},"nullable":true}}},"InterlinkPodStatus":{"type":"object","properties":{"JID":{"type":"string"},"UID":{"type":"string"},"containers":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"},"nullable":true},"initContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"},"nullable":true},"name":{"type":"string"},"namespace":{"type":"string"}}},"InterlinkResourcesResponse":{"type":"object","properties":{"accelerators":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkAcceleratorResponse"}},"cpu":{"type":"string"},"memory":{"type":"string"},"pods":{"type":"string"}}},"InterlinkRetrievedContainer":{"type":"object","properties":{"configMaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"emptyDirs":{"type":"array","items":{"type":"string"},"nullable":true},"name":{"type":"string"},"projectedvolumemaps":{"type":"array","items":{"$ref":"#/components/schemas/V1ConfigMap"},"nullable":true},"secrets":{"type":"array","items":{"$ref":"#/components/schemas/V1Secret"},"nullable":true}}},"InterlinkRetrievedPodData":{"type":"object","properties":{"container":{"type":"array","items":{"$ref":"#/components/schemas/InterlinkRetrievedContainer"},"nullable":true},"jobConfig":{"$ref":"#/components/schemas/InterlinkScriptBuildConfig"},"jobScript":{"type":"string"},"pod":{"$ref":"#/components/schemas/V1Pod"}}},"InterlinkScriptBuildConfig":{"type":"object","properties":{"ApptainerOptions":{"$ref":"#/components/schemas/InterlinkApptainerOptions"},"SingularityHubProxy":{"$ref":"#/components/schemas/InterlinkSingularityHubConfig"},"Volumes":{"$ref":"#/components/schemas/InterlinkVolumesOptions"}}},"InterlinkSingularityHubConfig":{"type":"object","properties":{"cache_validity_seconds":{"type":"integer"},"master_token":{"type":"string"},"server":{"type":"string"}}},"InterlinkTaintResponse":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"InterlinkVolumesOptions":{"type":"object","properties":{"additional_directories_in_path":{"type":"array","items":{"type":"string"},"nullable":true},"apptainer_cachedir":{"type":"string"},"fuse_sleep_seconds":{"type":"integer"},"image_dir":{"type":"string"},"scratch_area":{"type":"string"}}},"IntstrIntOrString":{"type":"object"},"ResourceQuantity":{"type":"object"},"V1AWSElasticBlockStoreVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"partition":{"type":"integer"},"readOnly":{"type":"boolean"},"volumeID":{"type":"string"}}},"V1Affinity":{"type":"object","properties":{"nodeAffinity":{"$ref":"#/components/schemas/V1NodeAffinity"},"podAffinity":{"$ref":"#/components/schemas/V1PodAffinity"},"podAntiAffinity":{"$ref":"#/components/schemas/V1PodAntiAffinity"}}},"V1AppArmorProfile":{"type":"object","properties":{"localhostProfile":{"type":"string","nullable":true},"type":{"type":"string"}}},"V1AzureDiskVolumeSource":{"type":"object","properties":{"cachingMode":{"type":"string","nullable":true},"diskName":{"type":"string"},"diskURI":{"type":"string"},"fsType":{"type":"string","nullable":true},"kind":{"type":"string","nullable":true},"readOnly":{"type":"boolean","nullable":true}}},"V1AzureFileVolumeSource":{"type":"object","properties":{"readOnly":{"type":"boolean"},"secretName":{"type":"string"},"shareName":{"type":"string"}}},"V1CSIVolumeSource":{"type":"object","properties":{"driver":{"type":"string"},"fsType":{"type":"string","nullable":true},"nodePublishSecretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"readOnly":{"type":"boolean","nullable":true},"volumeAttributes":{"type":"object","additionalProperties":{"type":"string"}}}},"V1Capabilities":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string"}},"drop":{"type":"array","items":{"type":"string"}}}},"V1CephFSVolumeSource":{"type":"object","properties":{"monitors":{"type":"array","items":{"type":"string"},"nullable":true},"path":{"type":"string"},"readOnly":{"type":"boolean"},"secretFile":{"type":"string"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"user":{"type":"string"}}},"V1CinderVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"volumeID":{"type":"string"}}},"V1ClusterTrustBundleProjection":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"name":{"type":"string","nullable":true},"optional":{"type":"boolean","nullable":true},"path":{"type":"string"},"signerName":{"type":"string","nullable":true}}},"V1ConfigMap":{"type":"object","properties":{"apiVersion":{"type":"string"},"binaryData":{"type":"object","additionalProperties":{"type":"string","format":"base64"}},"data":{"type":"object","additionalProperties":{"type":"string"}},"immutable":{"type":"boolean","nullable":true},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"}}},"V1ConfigMapEnvSource":{"type":"object","properties":{"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapKeySelector":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1ConfigMapVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1Container":{"type":"object","properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":"array","items":{"type":"string"}},"env":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvVar"}},"envFrom":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvFromSource"}},"image":{"type":"string"},"imagePullPolicy":{"type":"string"},"lifecycle":{"$ref":"#/components/schemas/V1Lifecycle"},"livenessProbe":{"$ref":"#/components/schemas/V1Probe"},"name":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerPort"}},"readinessProbe":{"$ref":"#/components/schemas/V1Probe"},"resizePolicy":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerResizePolicy"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string","nullable":true},"securityContext":{"$ref":"#/components/schemas/V1SecurityContext"},"startupProbe":{"$ref":"#/components/schemas/V1Probe"},"stdin":{"type":"boolean"},"stdinOnce":{"type":"boolean"},"terminationMessagePath":{"type":"string"},"terminationMessagePolicy":{"type":"string"},"tty":{"type":"boolean"},"volumeDevices":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeDevice"}},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMount"}},"workingDir":{"type":"string"}}},"V1ContainerPort":{"type":"object","properties":{"containerPort":{"type":"integer"},"hostIP":{"type":"string"},"hostPort":{"type":"integer"},"name":{"type":"string"},"protocol":{"type":"string"}}},"V1ContainerResizePolicy":{"type":"object","properties":{"resourceName":{"type":"string"},"restartPolicy":{"type":"string"}}},"V1ContainerState":{"type":"object","properties":{"running":{"$ref":"#/components/schemas/V1ContainerStateRunning"},"terminated":{"$ref":"#/components/schemas/V1ContainerStateTerminated"},"waiting":{"$ref":"#/components/schemas/V1ContainerStateWaiting"}}},"V1ContainerStateRunning":{"type":"object","properties":{"startedAt":{"type":"string"}}},"V1ContainerStateTerminated":{"type":"object","properties":{"containerID":{"type":"string"},"exitCode":{"type":"integer"},"finishedAt":{"type":"string"},"message":{"type":"string"},"reason":{"type":"string"},"signal":{"type":"integer"},"startedAt":{"type":"string"}}},"V1ContainerStateWaiting":{"type":"object","properties":{"message":{"type":"string"},"reason":{"type":"string"}}},"V1ContainerStatus":{"type":"object","properties":{"allocatedResources":{"$ref":"#/components/schemas/V1ResourceList"},"allocatedResourcesStatus":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceStatus"}},"containerID":{"type":"string"},"image":{"type":"string"},"imageID":{"type":"string"},"lastState":{"$ref":"#/components/schemas/V1ContainerState"},"name":{"type":"string"},"ready":{"type":"boolean"},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartCount":{"type":"integer"},"started":{"type":"boolean","nullable":true},"state":{"$ref":"#/components/schemas/V1ContainerState"},"stopSignal":{"type":"string","nullable":true},"user":{"$ref":"#/components/schemas/V1ContainerUser"},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMountStatus"}}}},"V1ContainerUser":{"type":"object","properties":{"linux":{"$ref":"#/components/schemas/V1LinuxContainerUser"}}},"V1DownwardAPIProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1DownwardAPIVolumeFile"}}}},"V1DownwardAPIVolumeFile":{"type":"object","properties":{"fieldRef":{"$ref":"#/components/schemas/V1ObjectFieldSelector"},"mode":{"type":"integer","nullable":true},"path":{"type":"string"},"resourceFieldRef":{"$ref":"#/components/schemas/V1ResourceFieldSelector"}}},"V1DownwardAPIVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1DownwardAPIVolumeFile"}}}},"V1EmptyDirVolumeSource":{"type":"object","properties":{"medium":{"type":"string"},"sizeLimit":{"$ref":"#/components/schemas/ResourceQuantity"}}},"V1EnvFromSource":{"type":"object","properties":{"configMapRef":{"$ref":"#/components/schemas/V1ConfigMapEnvSource"},"prefix":{"type":"string"},"secretRef":{"$ref":"#/components/schemas/V1SecretEnvSource"}}},"V1EnvVar":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"},"valueFrom":{"$ref":"#/components/schemas/V1EnvVarSource"}}},"V1EnvVarSource":{"type":"object","properties":{"configMapKeyRef":{"$ref":"#/components/schemas/V1ConfigMapKeySelector"},"fieldRef":{"$ref":"#/components/schemas/V1ObjectFieldSelector"},"resourceFieldRef":{"$ref":"#/components/schemas/V1ResourceFieldSelector"},"secretKeyRef":{"$ref":"#/components/schemas/V1SecretKeySelector"}}},"V1EphemeralContainer":{"type":"object","properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":"array","items":{"type":"string"}},"env":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvVar"}},"envFrom":{"type":"array","items":{"$ref":"#/components/schemas/V1EnvFromSource"}},"image":{"type":"string"},"imagePullPolicy":{"type":"string"},"lifecycle":{"$ref":"#/components/schemas/V1Lifecycle"},"livenessProbe":{"$ref":"#/components/schemas/V1Probe"},"name":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerPort"}},"readinessProbe":{"$ref":"#/components/schemas/V1Probe"},"resizePolicy":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerResizePolicy"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string","nullable":true},"securityContext":{"$ref":"#/components/schemas/V1SecurityContext"},"startupProbe":{"$ref":"#/components/schemas/V1Probe"},"stdin":{"type":"boolean"},"stdinOnce":{"type":"boolean"},"targetContainerName":{"type":"string"},"terminationMessagePath":{"type":"string"},"terminationMessagePolicy":{"type":"string"},"tty":{"type":"boolean"},"volumeDevices":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeDevice"}},"volumeMounts":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeMount"}},"workingDir":{"type":"string"}}},"V1EphemeralVolumeSource":{"type":"object","properties":{"volumeClaimTemplate":{"$ref":"#/components/schemas/V1PersistentVolumeClaimTemplate"}}},"V1ExecAction":{"type":"object","properties":{"command":{"type":"array","items":{"type":"string"}}}},"V1FCVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"lun":{"type":"integer","nullable":true},"readOnly":{"type":"boolean"},"targetWWNs":{"type":"array","items":{"type":"string"}},"wwids":{"type":"array","items":{"type":"string"}}}},"V1FieldsV1":{"type":"object"},"V1FlexVolumeSource":{"type":"object","properties":{"driver":{"type":"string"},"fsType":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"}}},"V1FlockerVolumeSource":{"type":"object","properties":{"datasetName":{"type":"string"},"datasetUUID":{"type":"string"}}},"V1GCEPersistentDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"partition":{"type":"integer"},"pdName":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1GRPCAction":{"type":"object","properties":{"port":{"type":"integer"},"service":{"type":"string","nullable":true}}},"V1GitRepoVolumeSource":{"type":"object","properties":{"directory":{"type":"string"},"repository":{"type":"string"},"revision":{"type":"string"}}},"V1GlusterfsVolumeSource":{"type":"object","properties":{"endpoints":{"type":"string"},"path":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1HTTPGetAction":{"type":"object","properties":{"host":{"type":"string"},"httpHeaders":{"type":"array","items":{"$ref":"#/components/schemas/V1HTTPHeader"}},"path":{"type":"string"},"port":{"$ref":"#/components/schemas/IntstrIntOrString"},"scheme":{"type":"string"}}},"V1HTTPHeader":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}},"V1HostAlias":{"type":"object","properties":{"hostnames":{"type":"array","items":{"type":"string"}},"ip":{"type":"string"}}},"V1HostIP":{"type":"object","properties":{"ip":{"type":"string"}}},"V1HostPathVolumeSource":{"type":"object","properties":{"path":{"type":"string"},"type":{"type":"string","nullable":true}}},"V1ISCSIVolumeSource":{"type":"object","properties":{"chapAuthDiscovery":{"type":"boolean"},"chapAuthSession":{"type":"boolean"},"fsType":{"type":"string"},"initiatorName":{"type":"string","nullable":true},"iqn":{"type":"string"},"iscsiInterface":{"type":"string"},"lun":{"type":"integer"},"portals":{"type":"array","items":{"type":"string"}},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"targetPortal":{"type":"string"}}},"V1ImageVolumeSource":{"type":"object","properties":{"pullPolicy":{"type":"string"},"reference":{"type":"string"}}},"V1KeyToPath":{"type":"object","properties":{"key":{"type":"string"},"mode":{"type":"integer","nullable":true},"path":{"type":"string"}}},"V1LabelSelector":{"type":"object","properties":{"matchExpressions":{"type":"array","items":{"$ref":"#/components/schemas/V1LabelSelectorRequirement"}},"matchLabels":{"type":"object","additionalProperties":{"type":"string"}}}},"V1LabelSelectorRequirement":{"type":"object","properties":{"key":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}}},"V1Lifecycle":{"type":"object","properties":{"postStart":{"$ref":"#/components/schemas/V1LifecycleHandler"},"preStop":{"$ref":"#/components/schemas/V1LifecycleHandler"},"stopSignal":{"type":"string","nullable":true}}},"V1LifecycleHandler":{"type":"object","properties":{"exec":{"$ref":"#/components/schemas/V1ExecAction"},"httpGet":{"$ref":"#/components/schemas/V1HTTPGetAction"},"sleep":{"$ref":"#/components/schemas/V1SleepAction"},"tcpSocket":{"$ref":"#/components/schemas/V1TCPSocketAction"}}},"V1LinuxContainerUser":{"type":"object","properties":{"gid":{"type":"integer"},"supplementalGroups":{"type":"array","items":{"type":"integer"}},"uid":{"type":"integer"}}},"V1LocalObjectReference":{"type":"object","properties":{"name":{"type":"string"}}},"V1ManagedFieldsEntry":{"type":"object","properties":{"apiVersion":{"type":"string"},"fieldsType":{"type":"string"},"fieldsV1":{"$ref":"#/components/schemas/V1FieldsV1"},"manager":{"type":"string"},"operation":{"type":"string"},"subresource":{"type":"string"},"time":{"type":"string"}}},"V1NFSVolumeSource":{"type":"object","properties":{"path":{"type":"string"},"readOnly":{"type":"boolean"},"server":{"type":"string"}}},"V1NodeAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PreferredSchedulingTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"$ref":"#/components/schemas/V1NodeSelector"}}},"V1NodeSelector":{"type":"object","properties":{"nodeSelectorTerms":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorTerm"},"nullable":true}}},"V1NodeSelectorRequirement":{"type":"object","properties":{"key":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}}},"V1NodeSelectorTerm":{"type":"object","properties":{"matchExpressions":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorRequirement"}},"matchFields":{"type":"array","items":{"$ref":"#/components/schemas/V1NodeSelectorRequirement"}}}},"V1ObjectFieldSelector":{"type":"object","properties":{"apiVersion":{"type":"string"},"fieldPath":{"type":"string"}}},"V1ObjectMeta":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"}},"creationTimestamp":{"type":"string"},"deletionGracePeriodSeconds":{"type":"integer","nullable":true},"deletionTimestamp":{"type":"string"},"finalizers":{"type":"array","items":{"type":"string"}},"generateName":{"type":"string"},"generation":{"type":"integer"},"labels":{"type":"object","additionalProperties":{"type":"string"}},"managedFields":{"type":"array","items":{"$ref":"#/components/schemas/V1ManagedFieldsEntry"}},"name":{"type":"string"},"namespace":{"type":"string"},"ownerReferences":{"type":"array","items":{"$ref":"#/components/schemas/V1OwnerReference"}},"resourceVersion":{"type":"string"},"selfLink":{"type":"string"},"uid":{"type":"string"}}},"V1OwnerReference":{"type":"object","properties":{"apiVersion":{"type":"string"},"blockOwnerDeletion":{"type":"boolean","nullable":true},"controller":{"type":"boolean","nullable":true},"kind":{"type":"string"},"name":{"type":"string"},"uid":{"type":"string"}}},"V1PersistentVolumeClaimSpec":{"type":"object","properties":{"accessModes":{"type":"array","items":{"type":"string"}},"dataSource":{"$ref":"#/components/schemas/V1TypedLocalObjectReference"},"dataSourceRef":{"$ref":"#/components/schemas/V1TypedObjectReference"},"resources":{"$ref":"#/components/schemas/V1VolumeResourceRequirements"},"selector":{"$ref":"#/components/schemas/V1LabelSelector"},"storageClassName":{"type":"string","nullable":true},"volumeAttributesClassName":{"type":"string","nullable":true},"volumeMode":{"type":"string","nullable":true},"volumeName":{"type":"string"}}},"V1PersistentVolumeClaimTemplate":{"type":"object","properties":{"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"spec":{"$ref":"#/components/schemas/V1PersistentVolumeClaimSpec"}}},"V1PersistentVolumeClaimVolumeSource":{"type":"object","properties":{"claimName":{"type":"string"},"readOnly":{"type":"boolean"}}},"V1PhotonPersistentDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"pdID":{"type":"string"}}},"V1Pod":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"spec":{"$ref":"#/components/schemas/V1PodSpec"},"status":{"$ref":"#/components/schemas/V1PodStatus"}}},"V1PodAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1WeightedPodAffinityTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PodAffinityTerm"}}}},"V1PodAffinityTerm":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"matchLabelKeys":{"type":"array","items":{"type":"string"}},"mismatchLabelKeys":{"type":"array","items":{"type":"string"}},"namespaceSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"namespaces":{"type":"array","items":{"type":"string"}},"topologyKey":{"type":"string"}}},"V1PodAntiAffinity":{"type":"object","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1WeightedPodAffinityTerm"}},"requiredDuringSchedulingIgnoredDuringExecution":{"type":"array","items":{"$ref":"#/components/schemas/V1PodAffinityTerm"}}}},"V1PodCondition":{"type":"object","properties":{"lastProbeTime":{"type":"string"},"lastTransitionTime":{"type":"string"},"message":{"type":"string"},"observedGeneration":{"type":"integer"},"reason":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"}}},"V1PodDNSConfig":{"type":"object","properties":{"nameservers":{"type":"array","items":{"type":"string"}},"options":{"type":"array","items":{"$ref":"#/components/schemas/V1PodDNSConfigOption"}},"searches":{"type":"array","items":{"type":"string"}}}},"V1PodDNSConfigOption":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string","nullable":true}}},"V1PodIP":{"type":"object","properties":{"ip":{"type":"string"}}},"V1PodOS":{"type":"object","properties":{"name":{"type":"string"}}},"V1PodReadinessGate":{"type":"object","properties":{"conditionType":{"type":"string"}}},"V1PodResourceClaim":{"type":"object","properties":{"name":{"type":"string"},"resourceClaimName":{"type":"string","nullable":true},"resourceClaimTemplateName":{"type":"string","nullable":true}}},"V1PodResourceClaimStatus":{"type":"object","properties":{"name":{"type":"string"},"resourceClaimName":{"type":"string","nullable":true}}},"V1PodSchedulingGate":{"type":"object","properties":{"name":{"type":"string"}}},"V1PodSecurityContext":{"type":"object","properties":{"appArmorProfile":{"$ref":"#/components/schemas/V1AppArmorProfile"},"fsGroup":{"type":"integer","nullable":true},"fsGroupChangePolicy":{"type":"string","nullable":true},"runAsGroup":{"type":"integer","nullable":true},"runAsNonRoot":{"type":"boolean","nullable":true},"runAsUser":{"type":"integer","nullable":true},"seLinuxChangePolicy":{"type":"string","nullable":true},"seLinuxOptions":{"$ref":"#/components/schemas/V1SELinuxOptions"},"seccompProfile":{"$ref":"#/components/schemas/V1SeccompProfile"},"supplementalGroups":{"type":"array","items":{"type":"integer"}},"supplementalGroupsPolicy":{"type":"string","nullable":true},"sysctls":{"type":"array","items":{"$ref":"#/components/schemas/V1Sysctl"}},"windowsOptions":{"$ref":"#/components/schemas/V1WindowsSecurityContextOptions"}}},"V1PodSpec":{"type":"object","properties":{"activeDeadlineSeconds":{"type":"integer","nullable":true},"affinity":{"$ref":"#/components/schemas/V1Affinity"},"automountServiceAccountToken":{"type":"boolean","nullable":true},"containers":{"type":"array","items":{"$ref":"#/components/schemas/V1Container"},"nullable":true},"dnsConfig":{"$ref":"#/components/schemas/V1PodDNSConfig"},"dnsPolicy":{"type":"string"},"enableServiceLinks":{"type":"boolean","nullable":true},"ephemeralContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1EphemeralContainer"}},"hostAliases":{"type":"array","items":{"$ref":"#/components/schemas/V1HostAlias"}},"hostIPC":{"type":"boolean"},"hostNetwork":{"type":"boolean"},"hostPID":{"type":"boolean"},"hostUsers":{"type":"boolean","nullable":true},"hostname":{"type":"string"},"imagePullSecrets":{"type":"array","items":{"$ref":"#/components/schemas/V1LocalObjectReference"}},"initContainers":{"type":"array","items":{"$ref":"#/components/schemas/V1Container"}},"nodeName":{"type":"string"},"nodeSelector":{"type":"object","additionalProperties":{"type":"string"}},"os":{"$ref":"#/components/schemas/V1PodOS"},"overhead":{"$ref":"#/components/schemas/V1ResourceList"},"preemptionPolicy":{"type":"string","nullable":true},"priority":{"type":"integer","nullable":true},"priorityClassName":{"type":"string"},"readinessGates":{"type":"array","items":{"$ref":"#/components/schemas/V1PodReadinessGate"}},"resourceClaims":{"type":"array","items":{"$ref":"#/components/schemas/V1PodResourceClaim"}},"resources":{"$ref":"#/components/schemas/V1ResourceRequirements"},"restartPolicy":{"type":"string"},"runtimeClassName":{"type":"string","nullable":true},"schedulerName":{"type":"string"},"schedulingGates":{"type":"array","items":{"$ref":"#/components/schemas/V1PodSchedulingGate"}},"securityContext":{"$ref":"#/components/schemas/V1PodSecurityContext"},"serviceAccount":{"type":"string"},"serviceAccountName":{"type":"string"},"setHostnameAsFQDN":{"type":"boolean","nullable":true},"shareProcessNamespace":{"type":"boolean","nullable":true},"subdomain":{"type":"string"},"terminationGracePeriodSeconds":{"type":"integer","nullable":true},"tolerations":{"type":"array","items":{"$ref":"#/components/schemas/V1Toleration"}},"topologySpreadConstraints":{"type":"array","items":{"$ref":"#/components/schemas/V1TopologySpreadConstraint"}},"volumes":{"type":"array","items":{"$ref":"#/components/schemas/V1Volume"}}}},"V1PodStatus":{"type":"object","properties":{"conditions":{"type":"array","items":{"$ref":"#/components/schemas/V1PodCondition"}},"containerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"ephemeralContainerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"hostIP":{"type":"string"},"hostIPs":{"type":"array","items":{"$ref":"#/components/schemas/V1HostIP"}},"initContainerStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1ContainerStatus"}},"message":{"type":"string"},"nominatedNodeName":{"type":"string"},"observedGeneration":{"type":"integer"},"phase":{"type":"string"},"podIP":{"type":"string"},"podIPs":{"type":"array","items":{"$ref":"#/components/schemas/V1PodIP"}},"qosClass":{"type":"string"},"reason":{"type":"string"},"resize":{"type":"string"},"resourceClaimStatuses":{"type":"array","items":{"$ref":"#/components/schemas/V1PodResourceClaimStatus"}},"startTime":{"type":"string"}}},"V1PortworxVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"volumeID":{"type":"string"}}},"V1PreferredSchedulingTerm":{"type":"object","properties":{"preference":{"$ref":"#/components/schemas/V1NodeSelectorTerm"},"weight":{"type":"integer"}}},"V1Probe":{"type":"object","properties":{"exec":{"$ref":"#/components/schemas/V1ExecAction"},"failureThreshold":{"type":"integer"},"grpc":{"$ref":"#/components/schemas/V1GRPCAction"},"httpGet":{"$ref":"#/components/schemas/V1HTTPGetAction"},"initialDelaySeconds":{"type":"integer"},"periodSeconds":{"type":"integer"},"successThreshold":{"type":"integer"},"tcpSocket":{"$ref":"#/components/schemas/V1TCPSocketAction"},"terminationGracePeriodSeconds":{"type":"integer","nullable":true},"timeoutSeconds":{"type":"integer"}}},"V1ProjectedVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"sources":{"type":"array","items":{"$ref":"#/components/schemas/V1VolumeProjection"},"nullable":true}}},"V1QuobyteVolumeSource":{"type":"object","properties":{"group":{"type":"string"},"readOnly":{"type":"boolean"},"registry":{"type":"string"},"tenant":{"type":"string"},"user":{"type":"string"},"volume":{"type":"string"}}},"V1RBDVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"image":{"type":"string"},"keyring":{"type":"string"},"monitors":{"type":"array","items":{"type":"string"},"nullable":true},"pool":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"user":{"type":"string"}}},"V1ResourceClaim":{"type":"object","properties":{"name":{"type":"string"},"request":{"type":"string"}}},"V1ResourceFieldSelector":{"type":"object","properties":{"containerName":{"type":"string"},"divisor":{"$ref":"#/components/schemas/ResourceQuantity"},"resource":{"type":"string"}}},"V1ResourceHealth":{"type":"object","properties":{"health":{"type":"string"},"resourceID":{"type":"string"}}},"V1ResourceList":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ResourceQuantity"}},"V1ResourceRequirements":{"type":"object","properties":{"claims":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceClaim"}},"limits":{"$ref":"#/components/schemas/V1ResourceList"},"requests":{"$ref":"#/components/schemas/V1ResourceList"}}},"V1ResourceStatus":{"type":"object","properties":{"name":{"type":"string"},"resources":{"type":"array","items":{"$ref":"#/components/schemas/V1ResourceHealth"}}}},"V1SELinuxOptions":{"type":"object","properties":{"level":{"type":"string"},"role":{"type":"string"},"type":{"type":"string"},"user":{"type":"string"}}},"V1ScaleIOVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"gateway":{"type":"string"},"protectionDomain":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"sslEnabled":{"type":"boolean"},"storageMode":{"type":"string"},"storagePool":{"type":"string"},"system":{"type":"string"},"volumeName":{"type":"string"}}},"V1SeccompProfile":{"type":"object","properties":{"localhostProfile":{"type":"string","nullable":true},"type":{"type":"string"}}},"V1Secret":{"type":"object","properties":{"apiVersion":{"type":"string"},"data":{"type":"object","additionalProperties":{"type":"string","format":"base64"}},"immutable":{"type":"boolean","nullable":true},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/V1ObjectMeta"},"stringData":{"type":"object","additionalProperties":{"type":"string"}},"type":{"type":"string"}}},"V1SecretEnvSource":{"type":"object","properties":{"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretKeySelector":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretProjection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"name":{"type":"string"},"optional":{"type":"boolean","nullable":true}}},"V1SecretVolumeSource":{"type":"object","properties":{"defaultMode":{"type":"integer","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/V1KeyToPath"}},"optional":{"type":"boolean","nullable":true},"secretName":{"type":"string"}}},"V1SecurityContext":{"type":"object","properties":{"allowPrivilegeEscalation":{"type":"boolean","nullable":true},"appArmorProfile":{"$ref":"#/components/schemas/V1AppArmorProfile"},"capabilities":{"$ref":"#/components/schemas/V1Capabilities"},"privileged":{"type":"boolean","nullable":true},"procMount":{"type":"string","nullable":true},"readOnlyRootFilesystem":{"type":"boolean","nullable":true},"runAsGroup":{"type":"integer","nullable":true},"runAsNonRoot":{"type":"boolean","nullable":true},"runAsUser":{"type":"integer","nullable":true},"seLinuxOptions":{"$ref":"#/components/schemas/V1SELinuxOptions"},"seccompProfile":{"$ref":"#/components/schemas/V1SeccompProfile"},"windowsOptions":{"$ref":"#/components/schemas/V1WindowsSecurityContextOptions"}}},"V1ServiceAccountTokenProjection":{"type":"object","properties":{"audience":{"type":"string"},"expirationSeconds":{"type":"integer","nullable":true},"path":{"type":"string"}}},"V1SleepAction":{"type":"object","properties":{"seconds":{"type":"integer"}}},"V1StorageOSVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"readOnly":{"type":"boolean"},"secretRef":{"$ref":"#/components/schemas/V1LocalObjectReference"},"volumeName":{"type":"string"},"volumeNamespace":{"type":"string"}}},"V1Sysctl":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}},"V1TCPSocketAction":{"type":"object","properties":{"host":{"type":"string"},"port":{"$ref":"#/components/schemas/IntstrIntOrString"}}},"V1Toleration":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"operator":{"type":"string"},"tolerationSeconds":{"type":"integer","nullable":true},"value":{"type":"string"}}},"V1TopologySpreadConstraint":{"type":"object","properties":{"labelSelector":{"$ref":"#/components/schemas/V1LabelSelector"},"matchLabelKeys":{"type":"array","items":{"type":"string"}},"maxSkew":{"type":"integer"},"minDomains":{"type":"integer","nullable":true},"nodeAffinityPolicy":{"type":"string","nullable":true},"nodeTaintsPolicy":{"type":"string","nullable":true},"topologyKey":{"type":"string"},"whenUnsatisfiable":{"type":"string"}}},"V1TypedLocalObjectReference":{"type":"object","properties":{"apiGroup":{"type":"string","nullable":true},"kind":{"type":"string"},"name":{"type":"string"}}},"V1TypedObjectReference":{"type":"object","properties":{"apiGroup":{"type":"string","nullable":true},"kind":{"type":"string"},"name":{"type":"string"},"namespace":{"type":"string","nullable":true}}},"V1Volume":{"type":"object","properties":{"awsElasticBlockStore":{"$ref":"#/components/schemas/V1AWSElasticBlockStoreVolumeSource"},"azureDisk":{"$ref":"#/components/schemas/V1AzureDiskVolumeSource"},"azureFile":{"$ref":"#/components/schemas/V1AzureFileVolumeSource"},"cephfs":{"$ref":"#/components/schemas/V1CephFSVolumeSource"},"cinder":{"$ref":"#/components/schemas/V1CinderVolumeSource"},"configMap":{"$ref":"#/components/schemas/V1ConfigMapVolumeSource"},"csi":{"$ref":"#/components/schemas/V1CSIVolumeSource"},"downwardAPI":{"$ref":"#/components/schemas/V1DownwardAPIVolumeSource"},"emptyDir":{"$ref":"#/components/schemas/V1EmptyDirVolumeSource"},"ephemeral":{"$ref":"#/components/schemas/V1EphemeralVolumeSource"},"fc":{"$ref":"#/components/schemas/V1FCVolumeSource"},"flexVolume":{"$ref":"#/components/schemas/V1FlexVolumeSource"},"flocker":{"$ref":"#/components/schemas/V1FlockerVolumeSource"},"gcePersistentDisk":{"$ref":"#/components/schemas/V1GCEPersistentDiskVolumeSource"},"gitRepo":{"$ref":"#/components/schemas/V1GitRepoVolumeSource"},"glusterfs":{"$ref":"#/components/schemas/V1GlusterfsVolumeSource"},"hostPath":{"$ref":"#/components/schemas/V1HostPathVolumeSource"},"image":{"$ref":"#/components/schemas/V1ImageVolumeSource"},"iscsi":{"$ref":"#/components/schemas/V1ISCSIVolumeSource"},"name":{"type":"string"},"nfs":{"$ref":"#/components/schemas/V1NFSVolumeSource"},"persistentVolumeClaim":{"$ref":"#/components/schemas/V1PersistentVolumeClaimVolumeSource"},"photonPersistentDisk":{"$ref":"#/components/schemas/V1PhotonPersistentDiskVolumeSource"},"portworxVolume":{"$ref":"#/components/schemas/V1PortworxVolumeSource"},"projected":{"$ref":"#/components/schemas/V1ProjectedVolumeSource"},"quobyte":{"$ref":"#/components/schemas/V1QuobyteVolumeSource"},"rbd":{"$ref":"#/components/schemas/V1RBDVolumeSource"},"scaleIO":{"$ref":"#/components/schemas/V1ScaleIOVolumeSource"},"secret":{"$ref":"#/components/schemas/V1SecretVolumeSource"},"storageos":{"$ref":"#/components/schemas/V1StorageOSVolumeSource"},"vsphereVolume":{"$ref":"#/components/schemas/V1VsphereVirtualDiskVolumeSource"}}},"V1VolumeDevice":{"type":"object","properties":{"devicePath":{"type":"string"},"name":{"type":"string"}}},"V1VolumeMount":{"type":"object","properties":{"mountPath":{"type":"string"},"mountPropagation":{"type":"string","nullable":true},"name":{"type":"string"},"readOnly":{"type":"boolean"},"recursiveReadOnly":{"type":"string","nullable":true},"subPath":{"type":"string"},"subPathExpr":{"type":"string"}}},"V1VolumeMountStatus":{"type":"object","properties":{"mountPath":{"type":"string"},"name":{"type":"string"},"readOnly":{"type":"boolean"},"recursiveReadOnly":{"type":"string","nullable":true}}},"V1VolumeProjection":{"type":"object","properties":{"clusterTrustBundle":{"$ref":"#/components/schemas/V1ClusterTrustBundleProjection"},"configMap":{"$ref":"#/components/schemas/V1ConfigMapProjection"},"downwardAPI":{"$ref":"#/components/schemas/V1DownwardAPIProjection"},"secret":{"$ref":"#/components/schemas/V1SecretProjection"},"serviceAccountToken":{"$ref":"#/components/schemas/V1ServiceAccountTokenProjection"}}},"V1VolumeResourceRequirements":{"type":"object","properties":{"limits":{"$ref":"#/components/schemas/V1ResourceList"},"requests":{"$ref":"#/components/schemas/V1ResourceList"}}},"V1VsphereVirtualDiskVolumeSource":{"type":"object","properties":{"fsType":{"type":"string"},"storagePolicyID":{"type":"string"},"storagePolicyName":{"type":"string"},"volumePath":{"type":"string"}}},"V1WeightedPodAffinityTerm":{"type":"object","properties":{"podAffinityTerm":{"$ref":"#/components/schemas/V1PodAffinityTerm"},"weight":{"type":"integer"}}},"V1WindowsSecurityContextOptions":{"type":"object","properties":{"gmsaCredentialSpec":{"type":"string","nullable":true},"gmsaCredentialSpecName":{"type":"string","nullable":true},"hostProcess":{"type":"boolean","nullable":true},"runAsUserName":{"type":"string","nullable":true}}}}}} \ No newline at end of file diff --git a/pkg/virtualkubelet/config_test.go b/pkg/virtualkubelet/config_test.go index d39e6ac4..419dcd7d 100644 --- a/pkg/virtualkubelet/config_test.go +++ b/pkg/virtualkubelet/config_test.go @@ -4,8 +4,9 @@ import ( "context" "testing" - "github.com/stretchr/testify/assert" types "github.com/interlink-hq/interlink/pkg/interlink" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) @@ -264,6 +265,56 @@ func TestUpdateNodeResources_InvalidValues(t *testing.T) { assert.Equal(t, originalCPU.Value(), currentCPU.Value()) } +func TestUpdateNodeResources_InvalidPodsQuantity(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + originalPods := provider.node.Status.Capacity["pods"].DeepCopy() + + for _, pods := range []string{"500m", "-1"} { + t.Run(pods, func(t *testing.T) { + ctx := context.Background() + provider.updateNodeResources(ctx, &types.ResourcesResponse{Pods: pods}) + + currentPods := provider.node.Status.Capacity["pods"] + assert.Equal(t, originalPods.Value(), currentPods.Value()) + }) + } +} + +func TestUpdateNodeResources_InvalidAcceleratorQuantity(t *testing.T) { + config := Config{ + Resources: Resources{ + CPU: "10", + Memory: "32Gi", + Pods: "100", + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + for _, available := range []string{"500m", "-1"} { + t.Run(available, func(t *testing.T) { + ctx := context.Background() + provider.updateNodeResources(ctx, &types.ResourcesResponse{ + Accelerators: []types.AcceleratorResponse{ + {ResourceType: "nvidia.com/gpu", Available: available}, + }, + }) + + _, exists := provider.node.Status.Capacity[v1.ResourceName("nvidia.com/gpu")] + assert.False(t, exists) + }) + } +} + func TestUpdateNodeResources_Nil(t *testing.T) { config := Config{ Resources: Resources{ @@ -314,3 +365,85 @@ func TestUpdateNodeResources_PartialUpdate(t *testing.T) { currentPods := provider.node.Status.Capacity["pods"] assert.Equal(t, originalPods.Value(), currentPods.Value()) } + +func TestUpdateNodeTaints_ReplacesPluginManagedTaintsAndPreservesSystemTaint(t *testing.T) { + config := Config{ + NodeTaints: []TaintSpec{ + {Key: "existing", Value: "old", Effect: "NoExecute"}, + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + taints := []types.TaintResponse{ + {Key: "virtual-node.interlink/no-schedule", Value: "false", Effect: "NoSchedule"}, + {Key: "plugin", Value: "new", Effect: "PreferNoSchedule"}, + } + provider.updateNodeTaints(context.Background(), &taints) + + assert.Equal(t, []v1.Taint{ + { + Key: "virtual-node.interlink/no-schedule", + Value: "true", + Effect: v1.TaintEffectNoSchedule, + }, + { + Key: "plugin", + Value: "new", + Effect: v1.TaintEffectPreferNoSchedule, + }, + }, provider.node.Spec.Taints) +} + +func TestUpdateNodeTaints_EmptySliceClearsPluginManagedTaints(t *testing.T) { + config := Config{ + NodeTaints: []TaintSpec{ + {Key: "existing", Value: "old", Effect: "NoExecute"}, + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + taints := []types.TaintResponse{} + provider.updateNodeTaints(context.Background(), &taints) + + assert.Equal(t, []v1.Taint{ + { + Key: "virtual-node.interlink/no-schedule", + Value: "true", + Effect: v1.TaintEffectNoSchedule, + }, + }, provider.node.Spec.Taints) +} + +func TestUpdateNodeTaints_NilLeavesExistingTaintsUnchangedAndUnknownEffectDefaults(t *testing.T) { + config := Config{ + NodeTaints: []TaintSpec{ + {Key: "existing", Value: "old", Effect: "NoExecute"}, + }, + } + provider, err := NewProviderConfig(config, "test-node", "v1.0", "linux", "10.0.0.1", 10250, nil) + assert.NoError(t, err) + + originalTaints := append([]v1.Taint(nil), provider.node.Spec.Taints...) + provider.updateNodeTaints(context.Background(), nil) + assert.Equal(t, originalTaints, provider.node.Spec.Taints) + + taints := []types.TaintResponse{ + {Key: "plugin", Value: "new", Effect: "UnexpectedEffect"}, + } + provider.updateNodeTaints(context.Background(), &taints) + + assert.Equal(t, []v1.Taint{ + { + Key: "virtual-node.interlink/no-schedule", + Value: "true", + Effect: v1.TaintEffectNoSchedule, + }, + { + Key: "plugin", + Value: "new", + Effect: v1.TaintEffectNoSchedule, + }, + }, provider.node.Spec.Taints) +} diff --git a/pkg/virtualkubelet/virtualkubelet.go b/pkg/virtualkubelet/virtualkubelet.go index 0f495e9e..638705a3 100644 --- a/pkg/virtualkubelet/virtualkubelet.go +++ b/pkg/virtualkubelet/virtualkubelet.go @@ -716,6 +716,8 @@ func (p *Provider) updateNodeResources(ctx context.Context, resources *types.Res q, err := resource.ParseQuantity(resources.Pods) if err != nil { log.G(ctx).Warnf("Invalid pods value %q in ping response: %v", resources.Pods, err) + } else if !isNonNegativeIntegerQuantity(q) { + log.G(ctx).Warnf("Invalid pods value %q in ping response: must be a non-negative integer quantity", resources.Pods) } else { capacity[v1.ResourcePods] = q allocatable[v1.ResourcePods] = q @@ -733,6 +735,10 @@ func (p *Provider) updateNodeResources(ctx context.Context, resources *types.Res log.G(ctx).Warnf("Invalid quantity %q for accelerator %q in ping response: %v", acc.Available, acc.ResourceType, err) continue } + if !isNonNegativeIntegerQuantity(q) { + log.G(ctx).Warnf("Invalid quantity %q for accelerator %q in ping response: must be a non-negative integer quantity", acc.Available, acc.ResourceType) + continue + } rName := v1.ResourceName(acc.ResourceType) capacity[rName] = q allocatable[rName] = q @@ -740,6 +746,15 @@ func (p *Provider) updateNodeResources(ctx context.Context, resources *types.Res } } +func isNonNegativeIntegerQuantity(q resource.Quantity) bool { + if q.Sign() < 0 { + return false + } + + _, ok := q.AsInt64() + return ok +} + // updateNodeTaints replaces the node's non-system taints with the taints reported by the // plugin in a ping response. The system taint "virtual-node.interlink/no-schedule" is always // preserved regardless of the plugin-provided list. An empty slice clears all plugin-managed taints. @@ -763,6 +778,10 @@ func (p *Provider) updateNodeTaints(ctx context.Context, taints *[]types.TaintRe log.G(ctx).Warn("Skipping taint with empty key in ping response") continue } + if t.Key == "virtual-node.interlink/no-schedule" { + log.G(ctx).Warn("Skipping system taint key \"virtual-node.interlink/no-schedule\" in ping response") + continue + } var effect v1.TaintEffect switch t.Effect { From 23954fb7ef5bc81634f8844b7995c6724f8c0240 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:05:26 +0000 Subject: [PATCH 5/6] refactor: reuse system taint key constant --- pkg/virtualkubelet/virtualkubelet.go | 43 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/pkg/virtualkubelet/virtualkubelet.go b/pkg/virtualkubelet/virtualkubelet.go index 638705a3..7ef6d868 100644 --- a/pkg/virtualkubelet/virtualkubelet.go +++ b/pkg/virtualkubelet/virtualkubelet.go @@ -50,23 +50,24 @@ var defaultWstunnelTemplate embed.FS var meshScriptTemplate embed.FS const ( - DefaultCPUCapacity = "100" - DefaultMemoryCapacity = "3000G" - DefaultPodCapacity = "10000" - DefaultGPUCapacity = "0" - DefaultFPGACapacity = "0" - DefaultListenPort = 10250 - NamespaceKey = "namespace" - NameKey = "name" - CREATE = 0 - DELETE = 1 - nvidiaGPU = "nvidia.com/gpu" - amdGPU = "amd.com/gpu" - intelGPU = "intel.com/gpu" - xilinxFPGA = "xilinx.com/fpga" - intelFPGA = "intel.com/fpga" - DefaultProtocol = "TCP" - DefaultWstunnelCommand = "curl -L -f -k https://github.com/erebe/wstunnel/releases/download/v10.4.4/wstunnel_10.4.4_linux_amd64.tar.gz -o wstunnel.tar.gz && tar -xzvf wstunnel.tar.gz && chmod +x wstunnel && ./wstunnel client --http-upgrade-path-prefix %s %s ws://%s:80 &" + DefaultCPUCapacity = "100" + DefaultMemoryCapacity = "3000G" + DefaultPodCapacity = "10000" + DefaultGPUCapacity = "0" + DefaultFPGACapacity = "0" + DefaultListenPort = 10250 + NamespaceKey = "namespace" + NameKey = "name" + CREATE = 0 + DELETE = 1 + nvidiaGPU = "nvidia.com/gpu" + amdGPU = "amd.com/gpu" + intelGPU = "intel.com/gpu" + xilinxFPGA = "xilinx.com/fpga" + intelFPGA = "intel.com/fpga" + virtualNodeNoScheduleTaint = "virtual-node.interlink/no-schedule" + DefaultProtocol = "TCP" + DefaultWstunnelCommand = "curl -L -f -k https://github.com/erebe/wstunnel/releases/download/v10.4.4/wstunnel_10.4.4_linux_amd64.tar.gz -o wstunnel.tar.gz && tar -xzvf wstunnel.tar.gz && chmod +x wstunnel && ./wstunnel client --http-upgrade-path-prefix %s %s ws://%s:80 &" ) // Annotations for WireGuard and WStunnel configuration @@ -420,7 +421,7 @@ func NewProviderConfig( taints := []v1.Taint{ { - Key: "virtual-node.interlink/no-schedule", + Key: virtualNodeNoScheduleTaint, Value: strconv.FormatBool(true), Effect: v1.TaintEffectNoSchedule, }, @@ -767,7 +768,7 @@ func (p *Provider) updateNodeTaints(ctx context.Context, taints *[]types.TaintRe // Collect system taints that must always be present. systemTaints := []v1.Taint{} for _, t := range p.node.Spec.Taints { - if t.Key == "virtual-node.interlink/no-schedule" { + if t.Key == virtualNodeNoScheduleTaint { systemTaints = append(systemTaints, t) } } @@ -778,8 +779,8 @@ func (p *Provider) updateNodeTaints(ctx context.Context, taints *[]types.TaintRe log.G(ctx).Warn("Skipping taint with empty key in ping response") continue } - if t.Key == "virtual-node.interlink/no-schedule" { - log.G(ctx).Warn("Skipping system taint key \"virtual-node.interlink/no-schedule\" in ping response") + if t.Key == virtualNodeNoScheduleTaint { + log.G(ctx).Warnf("Skipping system taint key %q in ping response", virtualNodeNoScheduleTaint) continue } From b21e9cf8019d4cd2e9b89c4212ac1d635154763e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:24:50 +0000 Subject: [PATCH 6/6] fix: satisfy golint ifelse switch rule --- pkg/virtualkubelet/virtualkubelet.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/virtualkubelet/virtualkubelet.go b/pkg/virtualkubelet/virtualkubelet.go index 7ef6d868..55eb33a9 100644 --- a/pkg/virtualkubelet/virtualkubelet.go +++ b/pkg/virtualkubelet/virtualkubelet.go @@ -715,11 +715,12 @@ func (p *Provider) updateNodeResources(ctx context.Context, resources *types.Res if resources.Pods != "" { q, err := resource.ParseQuantity(resources.Pods) - if err != nil { + switch { + case err != nil: log.G(ctx).Warnf("Invalid pods value %q in ping response: %v", resources.Pods, err) - } else if !isNonNegativeIntegerQuantity(q) { + case !isNonNegativeIntegerQuantity(q): log.G(ctx).Warnf("Invalid pods value %q in ping response: must be a non-negative integer quantity", resources.Pods) - } else { + default: capacity[v1.ResourcePods] = q allocatable[v1.ResourcePods] = q log.G(ctx).Infof("Updated node pods capacity to %s", resources.Pods)