renoki-co/php-k8s

Kubernetes Job not working as expected

makafanpeter opened this issue · 1 comments

I am working with the example given in the unit test here

         $pi = K8s::container()
            ->setName('pi')
            ->setImage('perl')
            ->setCommand(['perl',  '-Mbignum=bpi', '-wle', 'print bpi(2000)']);

        $pod = $this->cluster->pod()
            ->setName('perl')
            ->setContainers([$pi])
            ->restartOnFailure()
            ->neverRestart();

        $job = $this->cluster->job()
            ->setName('pi')
            ->setLabels(['tier' => 'backend'])
            ->setAnnotations(['perl/annotation' => 'yes'])
            ->setTTL(3600)
            ->setTemplate($pod);

Calling json_encode($job->toJsonPayload()) Outputs

{
    "apiVersion": "batch/v1",
    "kind": "Job",
    "metadata": {
        "name": "pi",
        "labels": {
            "tier": "backend"
        },
        "annotations": {
            "perl/annotation": "yes"
        },
        "namespace": "default"
    },
    "spec": {
        "ttlSecondsAfterFinished": 3600,
        "template": {
            "apiVersion": "v1",
            "kind": "Pod",
            "metadata": {
                "name": "perl",
                "namespace": "default"
            },
            "spec": {
                "containers": [
                    {
                        "name": "pi",
                        "image": "perl:latest",
                        "command": [
                            "perl",
                            "-Mbignum=bpi",
                            "-wle",
                            "print bpi(2000)"
                        ]
                    }
                ],
                "restartPolicy": "Never"
            }
        }
    }
}

Then finally calling $job = $job->createOrUpdate(); returns this error

{
	"kind": "Status",
	"apiVersion": "v1",
	"metadata": [],
	"status": "Failure",
	"message": "Job.batch \"pi\" is invalid: [spec.selector: Required value, spec.template.metadata.labels: Invalid value: map[string]string(nil): `selector` does not match template `labels`, spec.selector: Invalid value: \"null\": field is immutable, spec.template: Invalid value: core.PodTemplateSpec{ObjectMeta:v1.ObjectMeta{Name:\"perl\", GenerateName:\"\", Namespace:\"default\", SelfLink:\"\", UID:\"\", ResourceVersion:\"\", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ClusterName:\"\", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, Spec:core.PodSpec{Volumes:[]core.Volume(nil), InitContainers:[]core.Container(nil), Containers:[]core.Container{core.Container{Name:\"pi\", Image:\"perl:latest\", Command:[]string{\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"}, Args:[]string(nil), WorkingDir:\"\", Ports:[]core.ContainerPort(nil), EnvFrom:[]core.EnvFromSource(nil), Env:[]core.EnvVar(nil), Resources:core.ResourceRequirements{Limits:core.ResourceList(nil), Requests:core.ResourceList(nil)}, VolumeMounts:[]core.VolumeMount(nil), VolumeDevices:[]core.VolumeDevice(nil), LivenessProbe:(*core.Probe)(nil), ReadinessProbe:(*core.Probe)(nil), StartupProbe:(*core.Probe)(nil), Lifecycle:(*core.Lifecycle)(nil), TerminationMessagePath:\"\/dev\/termination-log\", TerminationMessagePolicy:\"File\", ImagePullPolicy:\"Always\", SecurityContext:(*core.SecurityContext)(nil), Stdin:false, StdinOnce:false, TTY:false}}, EphemeralContainers:[]core.EphemeralContainer(nil), RestartPolicy:\"Never\", TerminationGracePeriodSeconds:(*int64)(0xc0076c8840), ActiveDeadlineSeconds:(*int64)(nil), DNSPolicy:\"ClusterFirst\", NodeSelector:map[string]string(nil), ServiceAccountName:\"\", AutomountServiceAccountToken:(*bool)(nil), NodeName:\"\", SecurityContext:(*core.PodSecurityContext)(0xc006528800), ImagePullSecrets:[]core.LocalObjectReference(nil), Hostname:\"\", Subdomain:\"\", SetHostnameAsFQDN:(*bool)(nil), Affinity:(*core.Affinity)(nil), SchedulerName:\"default-scheduler\", Tolerations:[]core.Toleration(nil), HostAliases:[]core.HostAlias(nil), PriorityClassName:\"\", Priority:(*int32)(nil), PreemptionPolicy:(*core.PreemptionPolicy)(nil), DNSConfig:(*core.PodDNSConfig)(nil), ReadinessGates:[]core.PodReadinessGate(nil), RuntimeClassName:(*string)(nil), Overhead:core.ResourceList(nil), EnableServiceLinks:(*bool)(nil), TopologySpreadConstraints:[]core.TopologySpreadConstraint(nil)}}: field is immutable]",
	"reason": "Invalid",
	"details": {
		"name": "pi",
		"group": "batch",
		"kind": "Job",
		"causes": [{
			"reason": "FieldValueRequired",
			"message": "Required value",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: map[string]string(nil): `selector` does not match template `labels`",
			"field": "spec.template.metadata.labels"
		}, {
			"reason": "FieldValueRequired",
			"message": "Required value",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: map[string]string(nil): `selector` does not match template `labels`",
			"field": "spec.template.metadata.labels"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: \"null\": field is immutable",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: core.PodTemplateSpec{ObjectMeta:v1.ObjectMeta{Name:\"perl\", GenerateName:\"\", Namespace:\"default\", SelfLink:\"\", UID:\"\", ResourceVersion:\"\", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ClusterName:\"\", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, Spec:core.PodSpec{Volumes:[]core.Volume(nil), InitContainers:[]core.Container(nil), Containers:[]core.Container{core.Container{Name:\"pi\", Image:\"perl:latest\", Command:[]string{\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"}, Args:[]string(nil), WorkingDir:\"\", Ports:[]core.ContainerPort(nil), EnvFrom:[]core.EnvFromSource(nil), Env:[]core.EnvVar(nil), Resources:core.ResourceRequirements{Limits:core.ResourceList(nil), Requests:core.ResourceList(nil)}, VolumeMounts:[]core.VolumeMount(nil), VolumeDevices:[]core.VolumeDevice(nil), LivenessProbe:(*core.Probe)(nil), ReadinessProbe:(*core.Probe)(nil), StartupProbe:(*core.Probe)(nil), Lifecycle:(*core.Lifecycle)(nil), TerminationMessagePath:\"\/dev\/termination-log\", TerminationMessagePolicy:\"File\", ImagePullPolicy:\"Always\", SecurityContext:(*core.SecurityContext)(nil), Stdin:false, StdinOnce:false, TTY:false}}, EphemeralContainers:[]core.EphemeralContainer(nil), RestartPolicy:\"Never\", TerminationGracePeriodSeconds:(*int64)(0xc0076c8840), ActiveDeadlineSeconds:(*int64)(nil), DNSPolicy:\"ClusterFirst\", NodeSelector:map[string]string(nil), ServiceAccountName:\"\", AutomountServiceAccountToken:(*bool)(nil), NodeName:\"\", SecurityContext:(*core.PodSecurityContext)(0xc006528800), ImagePullSecrets:[]core.LocalObjectReference(nil), Hostname:\"\", Subdomain:\"\", SetHostnameAsFQDN:(*bool)(nil), Affinity:(*core.Affinity)(nil), SchedulerName:\"default-scheduler\", Tolerations:[]core.Toleration(nil), HostAliases:[]core.HostAlias(nil), PriorityClassName:\"\", Priority:(*int32)(nil), PreemptionPolicy:(*core.PreemptionPolicy)(nil), DNSConfig:(*core.PodDNSConfig)(nil), ReadinessGates:[]core.PodReadinessGate(nil), RuntimeClassName:(*string)(nil), Overhead:core.ResourceList(nil), EnableServiceLinks:(*bool)(nil), TopologySpreadConstraints:[]core.TopologySpreadConstraint(nil)}}: field is immutable",
			"field": "spec.template"
		}]
	},
	"code": 422
}

What could I be doing wrong here?

I guess I was doing something wrong used $job = $job->create(); instead of $job = $job->createOrUpdate();