diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index e5ff81b3502f..b2c5796b3814 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -3085,6 +3085,162 @@ }, "type": "object" }, + "io.argoproj.workflow.v1alpha1.ContainerNode": { + "properties": { + "args": { + "description": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "items": { + "type": "string" + }, + "type": "array" + }, + "command": { + "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "items": { + "type": "string" + }, + "type": "array" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + }, + "env": { + "description": "List of environment variables to set in the container. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVar" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "envFrom": { + "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvFromSource" + }, + "type": "array" + }, + "image": { + "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + "type": "string" + }, + "imagePullPolicy": { + "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + "type": "string" + }, + "lifecycle": { + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated." + }, + "livenessProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "name": { + "description": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + "type": "string" + }, + "ports": { + "description": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "containerPort", + "protocol" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge" + }, + "readinessProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "resources": { + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "description": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/" + }, + "securityContext": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "description": "Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" + }, + "startupProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "stdin": { + "description": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + "type": "boolean" + }, + "stdinOnce": { + "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + "type": "boolean" + }, + "terminationMessagePath": { + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + "type": "string" + }, + "tty": { + "description": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + "type": "boolean" + }, + "volumeDevices": { + "description": "volumeDevices is the list of block devices to be used by the container.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeDevice" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge" + }, + "volumeMounts": { + "description": "Pod volumes to mount into the container's filesystem. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge" + }, + "workingDir": { + "description": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.argoproj.workflow.v1alpha1.ContainerSetTemplate": { + "properties": { + "containers": { + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ContainerNode" + }, + "type": "array" + }, + "volumeMounts": { + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + }, + "type": "array" + } + }, + "required": [ + "containers" + ], + "type": "object" + }, "io.argoproj.workflow.v1alpha1.ContinueOn": { "description": "ContinueOn defines if a workflow should continue even if a task or step fails/errors. It can be specified if the workflow should continue when the pod errors, fails or both.", "properties": { @@ -4682,6 +4838,10 @@ "$ref": "#/definitions/io.k8s.api.core.v1.Container", "description": "Container is the main container image to run in the pod" }, + "containerSet": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ContainerSetTemplate", + "description": "ContainerSet groups multiple containers within a single pod." + }, "daemon": { "description": "Deamon will allow a workflow to proceed to the next step so long as the container reaches readiness", "type": "boolean" diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index faddc4e21b74..b7c43eb6f3c2 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -6501,6 +6501,162 @@ } } }, + "io.argoproj.workflow.v1alpha1.ContainerNode": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "args": { + "description": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string" + } + }, + "command": { + "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string" + } + }, + "dependencies": { + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "description": "List of environment variables to set in the container. Cannot be updated.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVar" + }, + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "envFrom": { + "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvFromSource" + } + }, + "image": { + "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + "type": "string" + }, + "imagePullPolicy": { + "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + "type": "string" + }, + "lifecycle": { + "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle" + }, + "livenessProbe": { + "description": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/io.k8s.api.core.v1.Probe" + }, + "name": { + "description": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + "type": "string" + }, + "ports": { + "description": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort" + }, + "x-kubernetes-list-map-keys": [ + "containerPort", + "protocol" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge" + }, + "readinessProbe": { + "description": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/io.k8s.api.core.v1.Probe" + }, + "resources": { + "description": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/", + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "securityContext": { + "description": "Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext" + }, + "startupProbe": { + "description": "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/io.k8s.api.core.v1.Probe" + }, + "stdin": { + "description": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + "type": "boolean" + }, + "stdinOnce": { + "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + "type": "boolean" + }, + "terminationMessagePath": { + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + "type": "string" + }, + "tty": { + "description": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + "type": "boolean" + }, + "volumeDevices": { + "description": "volumeDevices is the list of block devices to be used by the container.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeDevice" + }, + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge" + }, + "volumeMounts": { + "description": "Pod volumes to mount into the container's filesystem. Cannot be updated.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + }, + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge" + }, + "workingDir": { + "description": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "type": "string" + } + } + }, + "io.argoproj.workflow.v1alpha1.ContainerSetTemplate": { + "type": "object", + "required": [ + "containers" + ], + "properties": { + "containers": { + "type": "array", + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ContainerNode" + } + }, + "volumeMounts": { + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + } + } + }, "io.argoproj.workflow.v1alpha1.ContinueOn": { "description": "ContinueOn defines if a workflow should continue even if a task or step fails/errors. It can be specified if the workflow should continue when the pod errors, fails or both.", "type": "object", @@ -8100,6 +8256,10 @@ "description": "Container is the main container image to run in the pod", "$ref": "#/definitions/io.k8s.api.core.v1.Container" }, + "containerSet": { + "description": "ContainerSet groups multiple containers within a single pod.", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ContainerSetTemplate" + }, "daemon": { "description": "Deamon will allow a workflow to proceed to the next step so long as the container reaches readiness", "type": "boolean" diff --git a/cmd/argoexec/commands/emissary.go b/cmd/argoexec/commands/emissary.go index 291350cba339..33edf7ff894a 100644 --- a/cmd/argoexec/commands/emissary.go +++ b/cmd/argoexec/commands/emissary.go @@ -73,6 +73,29 @@ func NewEmissaryCommand() *cobra.Command { return fmt.Errorf("failed to unmarshal template: %w", err) } + for _, x := range template.ContainerSet.GetGraph() { + if x.Name == containerName { + for _, y := range x.Dependencies { + logger.Infof("waiting for dependency %q", y) + for { + data, err := ioutil.ReadFile(varRunArgo + "/ctr/" + y + "/exitcode") + if os.IsNotExist(err) { + time.Sleep(3 * time.Second) + continue + } + exitCode, err := strconv.Atoi(string(data)) + if err != nil { + return fmt.Errorf("failed to read exit-code of dependency %q: %w", y, err) + } + if exitCode != 0 { + return fmt.Errorf("dependency %q exited with non-zero code: %d", y, exitCode) + } + break + } + } + } + } + name, err = exec.LookPath(name) if err != nil { return fmt.Errorf("failed to find name in PATH: %w", err) diff --git a/docs/container-set-template.md b/docs/container-set-template.md new file mode 100644 index 000000000000..eff5a73bb317 --- /dev/null +++ b/docs/container-set-template.md @@ -0,0 +1,65 @@ +# Container Set Template + +![alpha](assets/alpha.svg) + +> v3.1 and after + +A container set templates is similar to a normal container or script template, but allows you to specify multiple +containers to run within a single pod. + +Because you have multiple containers within a pod, they will be scheduled on the same host. You can use cheap and fast +empty-dir volumes instead of persistent volume claims to share data between steps. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: container-set-template- +spec: + entrypoint: main + templates: + - name: main + volumes: + - name: workpsace + emptyDir: { } + containerSet: + volumeMounts: + - mountPath: /workspace + name: workspace + containers: + - name: a + image: argoproj/argosay:v2 + - name: b + image: argoproj/argosay:v2 + - name: main + image: argoproj/argosay:v2 + dependencies: + - a + - b + outputs: + parameters: + - name: message + valueFrom: + path: /workpsace/message +``` + +There are a couple of caveats: + +1. You must use the [Emissary Executor](workflow-executors.md#emissary-emissary). +2. Or all containers must run in parallel - i.e. it is a graph with no dependencies. + +The containers can be arranged as a graph by specifying dependencies. This is suitable for running 10s rather than 100s +of containers. + +## Inputs and Outputs + +As with the container and script templates, inputs and outputs can only be loaded and saved from a container +named `main`. + +All container set templates that have artifacts must/should have a container named `main`. + +If you want to use base-layer artifacts, `main` must be last to finish, so it must be the root node in the graph. + +That is may not be practical. + +Instead, have a workspace volume and make sure all artifacts paths are on that volume. diff --git a/docs/fields.md b/docs/fields.md index 4ff24f8c8b62..27bf53a5d52c 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -46,6 +46,16 @@ Workflow is the definition of a workflow resource - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -397,6 +407,16 @@ WorkflowSpec is the specification of a Workflow. - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -768,6 +788,16 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -1097,6 +1127,16 @@ WorkflowTemplateSpec is a spec of WorkflowTemplate. - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -1432,6 +1472,8 @@ Arguments to a template - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) - [`daemon-nginx.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/daemon-nginx.yaml) @@ -1594,6 +1636,14 @@ ExecutorConfig holds configurations of an executor container. Examples with this field (click to open)
+- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`selected-executor-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/selected-executor-workflow.yaml) @@ -1758,6 +1808,16 @@ Template is a reusable and composable unit of execution in a workflow - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -2013,6 +2073,7 @@ Template is a reusable and composable unit of execution in a workflow |`archiveLocation`|[`ArtifactLocation`](#artifactlocation)|Location in which all files related to the step will be stored (logs, artifacts, etc...). Can be overridden by individual items in Outputs. If omitted, will use the default artifact repository location configured in the controller, appended with the / in the key.| |`automountServiceAccountToken`|`boolean`|AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in pods. ServiceAccountName of ExecutorConfig must be specified if this value is false.| |`container`|[`Container`](#container)|Container is the main container image to run in the pod| +|`containerSet`|[`ContainerSetTemplate`](#containersettemplate)|ContainerSet groups multiple containers within a single pod.| |`daemon`|`boolean`|Deamon will allow a workflow to proceed to the next step so long as the container reaches readiness| |`dag`|[`DAGTemplate`](#dagtemplate)|DAG template subtype which runs a DAG| |`data`|[`Data`](#data)|Data is a data template| @@ -2184,6 +2245,8 @@ Outputs hold parameters, artifacts, and results from a step - [`ci-output-artifact.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci-output-artifact.yaml) +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) - [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) @@ -2290,6 +2353,8 @@ Artifact indicates an artifact to place at a specified path - [`ci.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci.yaml) +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) - [`fun-with-gifs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/fun-with-gifs.yaml) @@ -2377,6 +2442,10 @@ Parameter indicate a passed string parameter to a service template with an optio - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) @@ -2631,6 +2700,31 @@ ArtifactLocation describes a location for a single or multiple artifacts. It is |`raw`|[`RawArtifact`](#rawartifact)|Raw contains raw artifact location details| |`s3`|[`S3Artifact`](#s3artifact)|S3 contains S3 artifact location details| +## ContainerSetTemplate + +_No description available_ + +
+Examples with this field (click to open) +
+ +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`containers`|`Array<`[`ContainerNode`](#containernode)`>`|_No description available_| +|`volumeMounts`|`Array<`[`VolumeMount`](#volumemount)`>`|_No description available_| + ## DAGTemplate DAGTemplate is a template subtype for directed acyclic graph templates @@ -2645,6 +2739,8 @@ DAGTemplate is a template subtype for directed acyclic graph templates - [`clustertemplates.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cluster-workflow-template/clustertemplates.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`dag-coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-coinflip.yaml) - [`dag-continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-continue-on-fail.yaml) @@ -2800,6 +2896,8 @@ Inputs are the mechanism for passing parameters, artifacts, volumes from one tem - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) - [`daemon-nginx.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/daemon-nginx.yaml) @@ -3003,6 +3101,8 @@ ScriptTemplate is a template subtype to enable scripting through code steps - [`colored-logs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/colored-logs.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) - [`dag-coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-coinflip.yaml) @@ -3560,6 +3660,8 @@ ValueFrom describes a location in which to obtain the value to a parameter - [`artifact-path-placeholders.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/artifact-path-placeholders.yaml) +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) - [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) @@ -3666,6 +3768,16 @@ MetricLabel is a single label for a prometheus metric Examples with this field (click to open)
+- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) - [`daemoned-stateful-set-with-service.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/daemoned-stateful-set-with-service.yaml) @@ -3701,6 +3813,62 @@ MetricLabel is a single label for a prometheus metric RetryNodeAntiAffinity is a placeholder for future expansion, only empty nodeAntiAffinity is allowed. In order to prevent running steps on the same host, it uses "kubernetes.io/hostname". +## ContainerNode + +_No description available_ + +
+Examples with this field (click to open) +
+ +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + +- [`daemoned-stateful-set-with-service.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/daemoned-stateful-set-with-service.yaml) + +- [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) + +- [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) + +- [`pod-spec-patch-wf-tmpl.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/pod-spec-patch-wf-tmpl.yaml) + +- [`pod-spec-yaml-patch.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/pod-spec-yaml-patch.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`args`|`Array< string >`|Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell| +|`command`|`Array< string >`|Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell| +|`dependencies`|`Array< string >`|_No description available_| +|`env`|`Array<`[`EnvVar`](#envvar)`>`|List of environment variables to set in the container. Cannot be updated.| +|`envFrom`|`Array<`[`EnvFromSource`](#envfromsource)`>`|List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.| +|`image`|`string`|Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.| +|`imagePullPolicy`|`string`|Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images| +|`lifecycle`|[`Lifecycle`](#lifecycle)|Actions that the management system should take in response to container lifecycle events. Cannot be updated.| +|`livenessProbe`|[`Probe`](#probe)|Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes| +|`name`|`string`|Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.| +|`ports`|`Array<`[`ContainerPort`](#containerport)`>`|List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated.| +|`readinessProbe`|[`Probe`](#probe)|Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes| +|`resources`|[`ResourceRequirements`](#resourcerequirements)|Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/| +|`securityContext`|[`SecurityContext`](#securitycontext)|Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/| +|`startupProbe`|[`Probe`](#probe)|StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes| +|`stdin`|`boolean`|Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.| +|`stdinOnce`|`boolean`|Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false| +|`terminationMessagePath`|`string`|Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.| +|`terminationMessagePolicy`|`string`|Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.| +|`tty`|`boolean`|Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.| +|`volumeDevices`|`Array<`[`VolumeDevice`](#volumedevice)`>`|volumeDevices is the list of block devices to be used by the container.| +|`volumeMounts`|`Array<`[`VolumeMount`](#volumemount)`>`|Pod volumes to mount into the container's filesystem. Cannot be updated.| +|`workingDir`|`string`|Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.| + ## DAGTask DAGTask represents a node in the graph during DAG execution @@ -3715,6 +3883,8 @@ DAGTask represents a node in the graph during DAG execution - [`clustertemplates.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cluster-workflow-template/clustertemplates.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`dag-coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-coinflip.yaml) - [`dag-continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-continue-on-fail.yaml) @@ -3792,6 +3962,8 @@ DataSource sources external data into a data template - [`colored-logs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/colored-logs.yaml) +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) - [`dag-coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-coinflip.yaml) @@ -4127,6 +4299,16 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -4558,6 +4740,8 @@ Volume represents a named volume in a pod that may be accessed by any container - [`buildkit-template.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/buildkit-template.yaml) +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`init-container.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/init-container.yaml) - [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/secrets.yaml) @@ -4962,6 +5146,47 @@ Selects a key from a ConfigMap. |`name`|`string`|Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names| |`optional`|`boolean`|Specify whether the ConfigMap or its key must be defined| +## VolumeMount + +VolumeMount describes a mounting of a Volume within a container. + +
+Examples with this field (click to open) +
+ +- [`buildkit-template.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/buildkit-template.yaml) + +- [`ci-output-artifact.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci-output-artifact.yaml) + +- [`ci.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + +- [`fun-with-gifs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/fun-with-gifs.yaml) + +- [`init-container.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/init-container.yaml) + +- [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/secrets.yaml) + +- [`volumes-emptydir.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-emptydir.yaml) + +- [`volumes-existing.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-existing.yaml) + +- [`volumes-pvc.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-pvc.yaml) + +- [`work-avoidance.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/work-avoidance.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`mountPath`|`string`|Path within the container at which the volume should be mounted. Must not contain ':'.| +|`mountPropagation`|`string`|mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.| +|`name`|`string`|This must match the Name of a Volume.| +|`readOnly`|`boolean`|Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.| +|`subPath`|`string`|Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root).| +|`subPathExpr`|`string`|Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive.| + ## EnvVar EnvVar represents an environment variable present in a Container. @@ -5115,45 +5340,6 @@ volumeDevice describes a mapping of a raw block device within a container. |`devicePath`|`string`|devicePath is the path inside of the container that the device will be mapped to.| |`name`|`string`|name must match the name of a persistentVolumeClaim in the pod| -## VolumeMount - -VolumeMount describes a mounting of a Volume within a container. - -
-Examples with this field (click to open) -
- -- [`buildkit-template.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/buildkit-template.yaml) - -- [`ci-output-artifact.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci-output-artifact.yaml) - -- [`ci.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci.yaml) - -- [`fun-with-gifs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/fun-with-gifs.yaml) - -- [`init-container.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/init-container.yaml) - -- [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/secrets.yaml) - -- [`volumes-emptydir.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-emptydir.yaml) - -- [`volumes-existing.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-existing.yaml) - -- [`volumes-pvc.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-pvc.yaml) - -- [`work-avoidance.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/work-avoidance.yaml) -
- -### Fields -| Field Name | Field Type | Description | -|:----------:|:----------:|---------------| -|`mountPath`|`string`|Path within the container at which the volume should be mounted. Must not contain ':'.| -|`mountPropagation`|`string`|mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.| -|`name`|`string`|This must match the Name of a Volume.| -|`readOnly`|`boolean`|Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.| -|`subPath`|`string`|Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root).| -|`subPathExpr`|`string`|Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive.| - ## SecretKeySelector SecretKeySelector selects a key of a Secret. @@ -5332,6 +5518,16 @@ PersistentVolumeClaimSpec describes the common attributes of storage devices and - [`conditionals.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/conditionals.yaml) +- [`graph-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/graph-workflow.yaml) + +- [`outputs-result-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/outputs-result-workflow.yaml) + +- [`parallel-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/parallel-workflow.yaml) + +- [`sequence-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/sequence-workflow.yaml) + +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`continue-on-fail.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/continue-on-fail.yaml) - [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) @@ -5723,6 +5919,8 @@ Represents an empty directory for a pod. Empty directory volumes support ownersh Examples with this field (click to open)
+- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`init-container.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/init-container.yaml) - [`volumes-emptydir.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/volumes-emptydir.yaml) @@ -6007,6 +6205,8 @@ EnvVarSource represents a source for the value of an EnvVar. - [`artifact-path-placeholders.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/artifact-path-placeholders.yaml) +- [`workspace-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/container-set-template/workspace-workflow.yaml) + - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) - [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) diff --git a/examples/container-set-template/graph-workflow.yaml b/examples/container-set-template/graph-workflow.yaml new file mode 100644 index 000000000000..06eb7617e881 --- /dev/null +++ b/examples/container-set-template/graph-workflow.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: graph- + labels: + workflows.argoproj.io/test: "true" + workflows.argoproj.io/container-runtime-executor: emissary + annotations: + workflows.argoproj.io/description: | + This workflow demonstrates running a graph of tasks within containers in a single pod. + workflows.argoproj.io/version: ">= 3.1.0" + workflows.argoproj.io/verify.py: | + assert status["phase"] == "Succeeded" +spec: + entrypoint: main + templates: + - name: main + containerSet: + containers: + - name: a + image: argoproj/argosay:v2 + - name: b + image: argoproj/argosay:v2 + dependencies: + - a + - name: c + image: argoproj/argosay:v2 + dependencies: + - a + - name: d + image: argoproj/argosay:v2 + dependencies: + - b + - c \ No newline at end of file diff --git a/examples/container-set-template/outputs-result-workflow.yaml b/examples/container-set-template/outputs-result-workflow.yaml new file mode 100644 index 000000000000..42e745215b3e --- /dev/null +++ b/examples/container-set-template/outputs-result-workflow.yaml @@ -0,0 +1,51 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: outputs-result- + labels: + workflows.argoproj.io/test: "true" + workflows.argoproj.io/container-runtime-executor: emissary + annotations: + workflows.argoproj.io/description: | + This workflow demonstrates collecting outputs (specifically the stdout result) from a pod. + + Specifially, you must have a container named "main". + workflows.argoproj.io/version: ">= 3.1.0" + workflows.argoproj.io/verify.py: | + assert status["phase"] == "Succeeded" +spec: + entrypoint: main + templates: + - name: main + dag: + tasks: + - name: a + template: group + - name: b + template: verify + arguments: + parameters: + - name: x + value: "{{tasks.a.outputs.result}}" + dependencies: + - a + + - name: group + containerSet: + containers: + - name: main + image: python:alpine3.6 + args: + - -c + - | + print("hi") + + - name: verify + inputs: + parameters: + - name: x + script: + image: python:alpine3.6 + source: | + assert "{{inputs.parameters.x}}" == "hi" + diff --git a/examples/container-set-template/parallel-workflow.yaml b/examples/container-set-template/parallel-workflow.yaml new file mode 100644 index 000000000000..da4109a1c07f --- /dev/null +++ b/examples/container-set-template/parallel-workflow.yaml @@ -0,0 +1,22 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: parallel- + labels: + workflows.argoproj.io/test: "true" + annotations: + workflows.argoproj.io/description: | + This workflow demonstrates running a parallel containers within a single pod. + workflows.argoproj.io/version: ">= 3.1.0" + workflows.argoproj.io/verify.py: | + assert status["phase"] == "Succeeded" +spec: + entrypoint: main + templates: + - name: main + containerSet: + containers: + - name: a + image: argoproj/argosay:v2 + - name: b + image: argoproj/argosay:v2 \ No newline at end of file diff --git a/examples/container-set-template/sequence-workflow.yaml b/examples/container-set-template/sequence-workflow.yaml new file mode 100644 index 000000000000..c315bea217bc --- /dev/null +++ b/examples/container-set-template/sequence-workflow.yaml @@ -0,0 +1,29 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: sequence- + labels: + workflows.argoproj.io/test: "true" + workflows.argoproj.io/container-runtime-executor: emissary + annotations: + workflows.argoproj.io/description: | + This workflow demonstrates running a sequence of containers within a single pod. + workflows.argoproj.io/version: ">= 3.1.0" + workflows.argoproj.io/verify.py: | + assert status["phase"] == "Succeeded" +spec: + entrypoint: main + templates: + - name: main + containerSet: + containers: + - name: a + image: argoproj/argosay:v2 + - name: b + image: argoproj/argosay:v2 + dependencies: + - a + - name: c + image: argoproj/argosay:v2 + dependencies: + - b \ No newline at end of file diff --git a/examples/container-set-template/workspace-workflow.yaml b/examples/container-set-template/workspace-workflow.yaml new file mode 100644 index 000000000000..0066c6e4e68b --- /dev/null +++ b/examples/container-set-template/workspace-workflow.yaml @@ -0,0 +1,39 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: workspace- + labels: + workflows.argoproj.io/test: "true" + workflows.argoproj.io/container-runtime-executor: emissary + annotations: + workflows.argoproj.io/description: | + This workflow demonstrates using a workspace to share files between containers. This also allows containers not + called "main" to create output artifacts. + workflows.argoproj.io/version: ">= 3.1.0" + workflows.argoproj.io/verify.py: | + assert status["phase"] == "Succeeded" +spec: + entrypoint: main + templates: + - name: main + volumes: + - name: workspace + emptyDir: { } + containerSet: + volumeMounts: + - mountPath: /workspace + name: workspace + containers: + - name: a + image: argoproj/argosay:v2 + args: [ echo, hi, /workspace/out ] + - name: main + image: argoproj/argosay:v2 + outputs: + parameters: + - name: out + valueFrom: + path: /workspace/out + artifacts: + - name: out + path: /workspace/out \ No newline at end of file diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml index ac6555406386..f7cf0a5d5dd6 100644 --- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml @@ -2040,6 +2040,581 @@ spec: required: - image type: object + containerSet: + properties: + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + required: + - containers + type: object daemon: type: boolean dag: diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index cfd1c762b83f..4888d77d08e7 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -2061,6 +2061,581 @@ spec: required: - image type: object + containerSet: + properties: + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + required: + - containers + type: object daemon: type: boolean dag: diff --git a/manifests/base/crds/full/argoproj.io_workflows.yaml b/manifests/base/crds/full/argoproj.io_workflows.yaml index c52202c97f44..3700f005af61 100644 --- a/manifests/base/crds/full/argoproj.io_workflows.yaml +++ b/manifests/base/crds/full/argoproj.io_workflows.yaml @@ -2049,277 +2049,852 @@ spec: required: - image type: object - daemon: - type: boolean - dag: + containerSet: properties: - failFast: - type: boolean - target: - type: string - tasks: + containers: items: properties: - arguments: - properties: - artifacts: - items: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: properties: - archive: + configMapKeyRef: properties: - none: - type: object - tar: - properties: - compressionLevel: - format: int32 - type: integer - type: object - zip: - type: object + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key type: object - archiveLogs: - type: boolean - artifactory: + fieldRef: properties: - passwordSecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - url: + apiVersion: + type: string + fieldPath: type: string - usernameSecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object required: - - url + - fieldPath type: object - from: - type: string - gcs: + resourceFieldRef: properties: - bucket: + containerName: type: string - key: + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: type: string - serviceAccountKeySecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object required: - - key + - resource type: object - git: + secretKeyRef: properties: - depth: - format: int64 - type: integer - fetch: - items: - type: string - type: array - insecureIgnoreHostKey: + key: + type: string + name: + type: string + optional: type: boolean - passwordSecret: + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: properties: - key: - type: string name: type: string - optional: - type: boolean + value: + type: string required: - - key + - name + - value type: object - repo: - type: string - revision: + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: type: string - sshPrivateKeySecret: + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: properties: - key: - type: string name: type: string - optional: - type: boolean - required: - - key - type: object - usernameSecret: - properties: - key: - type: string - name: + value: type: string - optional: - type: boolean required: - - key + - name + - value type: object - required: - - repo - type: object - globalName: - type: string - hdfs: - properties: - addresses: - items: - type: string - type: array - force: - type: boolean - hdfsUser: - type: string - krbCCacheSecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - krbConfigConfigMap: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - krbKeytabSecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - krbRealm: - type: string - krbServicePrincipalName: - type: string - krbUsername: - type: string - path: - type: string - required: - - path - type: object - http: - properties: - headers: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - url: - type: string - required: - - url - type: object - mode: - format: int32 - type: integer - name: + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: type: string - optional: - type: boolean - oss: + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: properties: - accessKeySecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - bucket: - type: string - createBucketIfNotPresent: - type: boolean - endpoint: + name: type: string - key: + value: type: string - secretKeySecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object required: - - key + - name + - value type: object - path: + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: type: string - raw: + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: properties: - data: + name: + type: string + value: type: string required: - - data + - name + - value type: object - recurseMode: - type: boolean - s3: - properties: - accessKeySecret: - properties: - key: - type: string - name: - type: string - optional: - type: boolean + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + required: + - containers + type: object + daemon: + type: boolean + dag: + properties: + failFast: + type: boolean + target: + type: string + tasks: + items: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean required: - key type: object @@ -8739,44 +9314,218 @@ spec: type: string operator: type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object + type: string type: array + topologyKey: + type: string + required: + - topologyKey type: object weight: format: int32 type: integer required: - - preference + - podAffinityTerm - weight type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: + items: + properties: + labelSelector: properties: matchExpressions: items: @@ -8794,979 +9543,1382 @@ spec: - operator type: object type: array - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array + matchLabels: + additionalProperties: + type: string + type: object type: object - type: array + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean required: - - nodeSelectorTerms + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key type: object + required: + - key type: object - podAffinity: + raw: properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + type: object + automountServiceAccountToken: + type: boolean + container: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: properties: - podAffinityTerm: + configMapKeyRef: properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: + key: + type: string + name: type: string + optional: + type: boolean required: - - topologyKey + - key type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: + fieldRef: properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath type: object - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: + resourceFieldRef: properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: type: string required: - - topologyKey + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: + name: type: string - required: - - topologyKey + optional: + type: boolean type: object - type: array - type: object - type: object - archiveLocation: - properties: - archiveLogs: - type: boolean - artifactory: + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: properties: - passwordSecret: + postStart: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - url: - type: string - usernameSecret: + preStop: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - required: - - url type: object - gcs: + livenessProbe: properties: - bucket: - type: string - key: - type: string - serviceAccountKeySecret: + exec: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + command: + items: + type: string + type: array type: object - required: - - key - type: object - git: - properties: - depth: - format: int64 + failureThreshold: + format: int32 type: integer - fetch: - items: - type: string - type: array - insecureIgnoreHostKey: - type: boolean - passwordSecret: + httpGet: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean - required: - - key - type: object - repo: - type: string - revision: - type: string - sshPrivateKeySecret: - properties: - key: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: type: string - name: + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key + - port type: object - usernameSecret: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object - required: - - repo + timeoutSeconds: + format: int32 + type: integer type: object - hdfs: - properties: - addresses: - items: + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: type: string - type: array - force: - type: boolean - hdfsUser: - type: string - krbCCacheSecret: + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + command: + items: + type: string + type: array type: object - krbConfigConfigMap: + failureThreshold: + format: int32 + type: integer + httpGet: properties: - key: + host: type: string - name: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key + - port type: object - krbKeytabSecret: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object - krbRealm: - type: string - krbServicePrincipalName: - type: string - krbUsername: - type: string - path: - type: string - required: - - path + timeoutSeconds: + format: int32 + type: integer type: object - http: + resources: properties: - headers: - items: - properties: - name: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: type: string - value: + type: array + drop: + items: type: string - required: - - name - - value - type: object - type: array - url: + type: array + type: object + privileged: + type: boolean + procMount: type: string - required: - - url - type: object - oss: - properties: - accessKeySecret: + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: properties: - key: + level: type: string - name: + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: type: string - optional: - type: boolean required: - - key + - type type: object - bucket: - type: string - createBucketIfNotPresent: - type: boolean - endpoint: - type: string - key: - type: string - secretKeySecret: + windowsOptions: properties: - key: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: type: string - name: + runAsUserName: type: string - optional: - type: boolean - required: - - key type: object - required: - - key - type: object - raw: - properties: - data: - type: string - required: - - data type: object - s3: + startupProbe: properties: - accessKeySecret: + exec: properties: - key: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: type: string - name: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key - type: object - bucket: - type: string - createBucketIfNotPresent: - properties: - objectLocking: - type: boolean + - port type: object - endpoint: - type: string - insecure: - type: boolean - key: - type: string - region: - type: string - roleARN: - type: string - secretKeySecret: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object - useSDKCreds: - type: boolean + timeoutSeconds: + format: int32 + type: integer type: object - type: object - automountServiceAccountToken: - type: boolean - container: - properties: - args: + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: items: - type: string + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object type: array - command: + volumeMounts: items: - type: string + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object type: array - env: + workingDir: + type: string + required: + - name + type: object + containerSet: + properties: + containers: items: properties: - name: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: type: string - value: + imagePullPolicy: type: string - valueFrom: + lifecycle: properties: - configMapKeyRef: + postStart: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - fieldRef: + preStop: properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - resourceFieldRef: + type: object + livenessProbe: + properties: + exec: properties: - containerName: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: type: string - divisor: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - resource: + scheme: type: string required: - - resource + - port type: object - secretKeyRef: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object + timeoutSeconds: + format: int32 + type: integer type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - prefix: + name: type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: + ports: + items: properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: + containerPort: + format: int32 + type: integer + hostIP: type: string - required: - - port - type: object - tcpSocket: - properties: - host: + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true required: - - port + - containerPort type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: anyOf: - type: integer - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: + type: object + requests: + additionalProperties: anyOf: - type: integer - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: properties: - name: - type: string - value: - type: string - required: - - name - - value + add: + items: + type: string + type: array + drop: + items: + type: string + type: array type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: properties: - name: + level: type: string - value: + role: + type: string + type: + type: string + user: type: string - required: - - name - - value type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + seccompProfile: properties: - name: + localhostProfile: type: string - value: + type: type: string required: - - name - - value + - type type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: type: string - name: + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: type: string required: - - devicePath - name type: object type: array @@ -9790,10 +10942,8 @@ spec: - name type: object type: array - workingDir: - type: string required: - - name + - containers type: object daemon: type: boolean @@ -15021,7 +16171,180 @@ spec: type: boolean artifactory: properties: - passwordSecret: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: properties: key: type: string @@ -15032,9 +16355,15 @@ spec: required: - key type: object - url: + bucket: type: string - usernameSecret: + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: properties: key: type: string @@ -15046,15 +16375,46 @@ spec: - key type: object required: - - url + - key type: object - gcs: + raw: properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object bucket: type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean key: type: string - serviceAccountKeySecret: + region: + type: string + roleARN: + type: string + secretKeySecret: properties: key: type: string @@ -15065,738 +16425,1105 @@ spec: required: - key type: object - required: - - key + useSDKCreds: + type: boolean type: object - git: + type: object + automountServiceAccountToken: + type: boolean + container: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: properties: - depth: - format: int64 - type: integer - fetch: - items: - type: string - type: array - insecureIgnoreHostKey: - type: boolean - passwordSecret: + exec: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + command: + items: + type: string + type: array type: object - repo: - type: string - revision: - type: string - sshPrivateKeySecret: + failureThreshold: + format: int32 + type: integer + httpGet: properties: - key: + host: type: string - name: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key + - port type: object - usernameSecret: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object - required: - - repo + timeoutSeconds: + format: int32 + type: integer type: object - hdfs: - properties: - addresses: - items: + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: type: string - type: array - force: - type: boolean - hdfsUser: - type: string - krbCCacheSecret: + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + command: + items: + type: string + type: array type: object - krbConfigConfigMap: + failureThreshold: + format: int32 + type: integer + httpGet: properties: - key: + host: type: string - name: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key + - port type: object - krbKeytabSecret: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object - krbRealm: - type: string - krbServicePrincipalName: - type: string - krbUsername: - type: string - path: - type: string - required: - - path + timeoutSeconds: + format: int32 + type: integer type: object - http: + resources: properties: - headers: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - url: - type: string - required: - - url + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object type: object - oss: + securityContext: properties: - accessKeySecret: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: properties: - key: + level: type: string - name: + role: + type: string + type: + type: string + user: type: string - optional: - type: boolean - required: - - key type: object - bucket: - type: string - createBucketIfNotPresent: - type: boolean - endpoint: - type: string - key: - type: string - secretKeySecret: + seccompProfile: properties: - key: + localhostProfile: type: string - name: + type: type: string - optional: - type: boolean required: - - key + - type type: object - required: - - key - type: object - raw: - properties: - data: - type: string - required: - - data - type: object - s3: - properties: - accessKeySecret: + windowsOptions: properties: - key: + gmsaCredentialSpec: type: string - name: + gmsaCredentialSpecName: + type: string + runAsUserName: type: string - optional: - type: boolean - required: - - key type: object - bucket: - type: string - createBucketIfNotPresent: + type: object + startupProbe: + properties: + exec: properties: - objectLocking: - type: boolean + command: + items: + type: string + type: array type: object - endpoint: - type: string - insecure: - type: boolean - key: - type: string - region: - type: string - roleARN: - type: string - secretKeySecret: + failureThreshold: + format: int32 + type: integer + httpGet: properties: - key: + host: type: string - name: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - optional: - type: boolean required: - - key + - port type: object - useSDKCreds: - type: boolean + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer type: object - type: object - automountServiceAccountToken: - type: boolean - container: - properties: - args: + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: items: - type: string + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object type: array - command: + volumeMounts: items: - type: string + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object type: array - env: + workingDir: + type: string + required: + - name + type: object + containerSet: + properties: + containers: items: properties: - name: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: type: string - value: + imagePullPolicy: type: string - valueFrom: + lifecycle: properties: - configMapKeyRef: + postStart: properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - fieldRef: + preStop: properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object type: object - resourceFieldRef: + type: object + livenessProbe: + properties: + exec: properties: - containerName: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: type: string - divisor: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - resource: + scheme: type: string required: - - resource + - port type: object - secretKeyRef: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - key: - type: string - name: + host: type: string - optional: - type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - key + - port type: object + timeoutSeconds: + format: int32 + type: integer type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - prefix: + name: type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: + ports: + items: properties: - host: + containerPort: + format: int32 + type: integer + hostIP: type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: + hostPort: + format: int32 + type: integer + name: type: string - port: + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: anyOf: - type: integer - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: + type: object + requests: + additionalProperties: anyOf: - type: integer - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: properties: - name: + level: type: string - value: + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: type: string required: - - name - - value + - type type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + windowsOptions: properties: - name: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: type: string - value: + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string required: - - name - - value + - port type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - httpGet: - properties: - host: - type: string - httpHeaders: - items: + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: properties: - name: - type: string - value: + host: type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true required: - - name - - value + - port type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: type: string - name: + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: type: string required: - - devicePath - name type: object type: array @@ -15820,10 +17547,8 @@ spec: - name type: object type: array - workingDir: - type: string required: - - name + - containers type: object daemon: type: boolean diff --git a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml index 6d4d0d585de1..468a3d5caa11 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml @@ -2039,6 +2039,581 @@ spec: required: - image type: object + containerSet: + properties: + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + dependencies: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + required: + - containers + type: object daemon: type: boolean dag: diff --git a/manifests/quick-start-minimal.yaml b/manifests/quick-start-minimal.yaml index 401b22528c37..0d517d227e32 100644 --- a/manifests/quick-start-minimal.yaml +++ b/manifests/quick-start-minimal.yaml @@ -616,6 +616,10 @@ data: selector: matchLabels: workflows.argoproj.io/container-runtime-executor: k8sapi + - name: emissary + selector: + matchLabels: + workflows.argoproj.io/container-runtime-executor: emissary executor: | resources: requests: diff --git a/manifests/quick-start-mysql.yaml b/manifests/quick-start-mysql.yaml index 086233b2dc72..4ab349b34152 100644 --- a/manifests/quick-start-mysql.yaml +++ b/manifests/quick-start-mysql.yaml @@ -616,6 +616,10 @@ data: selector: matchLabels: workflows.argoproj.io/container-runtime-executor: k8sapi + - name: emissary + selector: + matchLabels: + workflows.argoproj.io/container-runtime-executor: emissary executor: | resources: requests: diff --git a/manifests/quick-start-postgres.yaml b/manifests/quick-start-postgres.yaml index a43ff1b0fdd7..24f04f73bacf 100644 --- a/manifests/quick-start-postgres.yaml +++ b/manifests/quick-start-postgres.yaml @@ -616,6 +616,10 @@ data: selector: matchLabels: workflows.argoproj.io/container-runtime-executor: k8sapi + - name: emissary + selector: + matchLabels: + workflows.argoproj.io/container-runtime-executor: emissary executor: | resources: requests: diff --git a/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml b/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml index 49c85ea6b0b1..15e57eed5b3d 100644 --- a/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml +++ b/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml @@ -11,6 +11,10 @@ data: selector: matchLabels: workflows.argoproj.io/container-runtime-executor: k8sapi + - name: emissary + selector: + matchLabels: + workflows.argoproj.io/container-runtime-executor: emissary images: | argoproj/argosay:v1: command: [cowsay] diff --git a/mkdocs.yml b/mkdocs.yml index 0299a47c2da5..5e5356e72ae3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,7 @@ nav: - cluster-workflow-templates.md - cron-workflows.md - cron-backfill.md + - container-set-template.md - work-avoidance.md - enhanced-depends-logic.md - artifact-repository-ref.md diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list index 84efe31f430c..68367f09ae94 100644 --- a/pkg/apis/api-rules/violation_exceptions.list +++ b/pkg/apis/api-rules/violation_exceptions.list @@ -1,4 +1,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Arguments,Parameters +API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,ContainerNode,Dependencies +API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,ContainerSetTemplate,Containers +API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,ContainerSetTemplate,VolumeMounts API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,CronWorkflowStatus,Active API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,DAGTask,Dependencies API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,DAGTask,WithItems diff --git a/pkg/apis/workflow/v1alpha1/container_set_template_types.go b/pkg/apis/workflow/v1alpha1/container_set_template_types.go new file mode 100644 index 000000000000..86fac908bf31 --- /dev/null +++ b/pkg/apis/workflow/v1alpha1/container_set_template_types.go @@ -0,0 +1,48 @@ +package v1alpha1 + +import corev1 "k8s.io/api/core/v1" + +type ContainerSetTemplate struct { + Containers []ContainerNode `json:"containers" protobuf:"bytes,4,rep,name=containers"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" protobuf:"bytes,3,rep,name=volumeMounts"` +} + +func (in *ContainerSetTemplate) GetContainers() []corev1.Container { + var ctrs []corev1.Container + for _, t := range in.GetGraph() { + c := t.Container + c.VolumeMounts = append(c.VolumeMounts, in.VolumeMounts...) + ctrs = append(ctrs, c) + } + return ctrs +} + +func (in *ContainerSetTemplate) HasContainerNamed(n string) bool { + for _, c := range in.GetContainers() { + if n == c.Name { + return true + } + } + return false +} + +func (in *ContainerSetTemplate) GetGraph() []ContainerNode { + if in == nil { + return nil + } + return in.Containers +} + +func (in *ContainerSetTemplate) HasSequencedContainers() bool { + for _, n := range in.GetGraph() { + if len(n.Dependencies) > 0 { + return true + } + } + return false +} + +type ContainerNode struct { + corev1.Container `json:",inline" protobuf:"bytes,1,opt,name=container"` + Dependencies []string `json:"dependencies,omitempty" protobuf:"bytes,2,rep,name=dependencies"` +} diff --git a/pkg/apis/workflow/v1alpha1/container_set_template_types_test.go b/pkg/apis/workflow/v1alpha1/container_set_template_types_test.go new file mode 100644 index 000000000000..ea27f3f212f8 --- /dev/null +++ b/pkg/apis/workflow/v1alpha1/container_set_template_types_test.go @@ -0,0 +1,36 @@ +package v1alpha1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +func TestContainerSetTemplate(t *testing.T) { + t.Run("Empty", func(t *testing.T) { + x := &ContainerSetTemplate{} + assert.Empty(t, x.GetGraph()) + assert.Empty(t, x.GetContainers()) + assert.False(t, x.HasSequencedContainers()) + }) + t.Run("Single", func(t *testing.T) { + x := &ContainerSetTemplate{Containers: []ContainerNode{{}}} + assert.Len(t, x.GetGraph(), 1) + assert.Len(t, x.GetContainers(), 1) + assert.False(t, x.HasSequencedContainers()) + }) + t.Run("Parallel", func(t *testing.T) { + x := &ContainerSetTemplate{Containers: []ContainerNode{{}, {}}} + assert.Len(t, x.GetGraph(), 2) + assert.Len(t, x.GetContainers(), 2) + assert.False(t, x.HasSequencedContainers()) + }) + t.Run("Graph", func(t *testing.T) { + x := &ContainerSetTemplate{Containers: []ContainerNode{{Container: corev1.Container{Name: "a"}}, {Dependencies: []string{"a"}}}} + assert.Len(t, x.GetGraph(), 2) + assert.Len(t, x.GetContainers(), 2) + assert.True(t, x.HasSequencedContainers()) + assert.True(t, x.HasContainerNamed("a")) + }) +} diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index 8eaaa5222aa2..1c427d908b30 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -456,10 +456,66 @@ func (m *Condition) XXX_DiscardUnknown() { var xxx_messageInfo_Condition proto.InternalMessageInfo +func (m *ContainerNode) Reset() { *m = ContainerNode{} } +func (*ContainerNode) ProtoMessage() {} +func (*ContainerNode) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{15} +} +func (m *ContainerNode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContainerNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ContainerNode) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContainerNode.Merge(m, src) +} +func (m *ContainerNode) XXX_Size() int { + return m.Size() +} +func (m *ContainerNode) XXX_DiscardUnknown() { + xxx_messageInfo_ContainerNode.DiscardUnknown(m) +} + +var xxx_messageInfo_ContainerNode proto.InternalMessageInfo + +func (m *ContainerSetTemplate) Reset() { *m = ContainerSetTemplate{} } +func (*ContainerSetTemplate) ProtoMessage() {} +func (*ContainerSetTemplate) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{16} +} +func (m *ContainerSetTemplate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContainerSetTemplate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ContainerSetTemplate) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContainerSetTemplate.Merge(m, src) +} +func (m *ContainerSetTemplate) XXX_Size() int { + return m.Size() +} +func (m *ContainerSetTemplate) XXX_DiscardUnknown() { + xxx_messageInfo_ContainerSetTemplate.DiscardUnknown(m) +} + +var xxx_messageInfo_ContainerSetTemplate proto.InternalMessageInfo + func (m *ContinueOn) Reset() { *m = ContinueOn{} } func (*ContinueOn) ProtoMessage() {} func (*ContinueOn) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{15} + return fileDescriptor_724696e352c3df5f, []int{17} } func (m *ContinueOn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -487,7 +543,7 @@ var xxx_messageInfo_ContinueOn proto.InternalMessageInfo func (m *Counter) Reset() { *m = Counter{} } func (*Counter) ProtoMessage() {} func (*Counter) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{16} + return fileDescriptor_724696e352c3df5f, []int{18} } func (m *Counter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -515,7 +571,7 @@ var xxx_messageInfo_Counter proto.InternalMessageInfo func (m *CreateS3BucketOptions) Reset() { *m = CreateS3BucketOptions{} } func (*CreateS3BucketOptions) ProtoMessage() {} func (*CreateS3BucketOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{17} + return fileDescriptor_724696e352c3df5f, []int{19} } func (m *CreateS3BucketOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -543,7 +599,7 @@ var xxx_messageInfo_CreateS3BucketOptions proto.InternalMessageInfo func (m *CronWorkflow) Reset() { *m = CronWorkflow{} } func (*CronWorkflow) ProtoMessage() {} func (*CronWorkflow) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{18} + return fileDescriptor_724696e352c3df5f, []int{20} } func (m *CronWorkflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -571,7 +627,7 @@ var xxx_messageInfo_CronWorkflow proto.InternalMessageInfo func (m *CronWorkflowList) Reset() { *m = CronWorkflowList{} } func (*CronWorkflowList) ProtoMessage() {} func (*CronWorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{19} + return fileDescriptor_724696e352c3df5f, []int{21} } func (m *CronWorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -599,7 +655,7 @@ var xxx_messageInfo_CronWorkflowList proto.InternalMessageInfo func (m *CronWorkflowSpec) Reset() { *m = CronWorkflowSpec{} } func (*CronWorkflowSpec) ProtoMessage() {} func (*CronWorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{20} + return fileDescriptor_724696e352c3df5f, []int{22} } func (m *CronWorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -627,7 +683,7 @@ var xxx_messageInfo_CronWorkflowSpec proto.InternalMessageInfo func (m *CronWorkflowStatus) Reset() { *m = CronWorkflowStatus{} } func (*CronWorkflowStatus) ProtoMessage() {} func (*CronWorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{21} + return fileDescriptor_724696e352c3df5f, []int{23} } func (m *CronWorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -655,7 +711,7 @@ var xxx_messageInfo_CronWorkflowStatus proto.InternalMessageInfo func (m *DAGTask) Reset() { *m = DAGTask{} } func (*DAGTask) ProtoMessage() {} func (*DAGTask) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{22} + return fileDescriptor_724696e352c3df5f, []int{24} } func (m *DAGTask) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -683,7 +739,7 @@ var xxx_messageInfo_DAGTask proto.InternalMessageInfo func (m *DAGTemplate) Reset() { *m = DAGTemplate{} } func (*DAGTemplate) ProtoMessage() {} func (*DAGTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{23} + return fileDescriptor_724696e352c3df5f, []int{25} } func (m *DAGTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -711,7 +767,7 @@ var xxx_messageInfo_DAGTemplate proto.InternalMessageInfo func (m *Data) Reset() { *m = Data{} } func (*Data) ProtoMessage() {} func (*Data) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{24} + return fileDescriptor_724696e352c3df5f, []int{26} } func (m *Data) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -739,7 +795,7 @@ var xxx_messageInfo_Data proto.InternalMessageInfo func (m *DataSource) Reset() { *m = DataSource{} } func (*DataSource) ProtoMessage() {} func (*DataSource) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{25} + return fileDescriptor_724696e352c3df5f, []int{27} } func (m *DataSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -767,7 +823,7 @@ var xxx_messageInfo_DataSource proto.InternalMessageInfo func (m *Event) Reset() { *m = Event{} } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{26} + return fileDescriptor_724696e352c3df5f, []int{28} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -795,7 +851,7 @@ var xxx_messageInfo_Event proto.InternalMessageInfo func (m *ExecutorConfig) Reset() { *m = ExecutorConfig{} } func (*ExecutorConfig) ProtoMessage() {} func (*ExecutorConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{27} + return fileDescriptor_724696e352c3df5f, []int{29} } func (m *ExecutorConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -823,7 +879,7 @@ var xxx_messageInfo_ExecutorConfig proto.InternalMessageInfo func (m *GCSArtifact) Reset() { *m = GCSArtifact{} } func (*GCSArtifact) ProtoMessage() {} func (*GCSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{28} + return fileDescriptor_724696e352c3df5f, []int{30} } func (m *GCSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -851,7 +907,7 @@ var xxx_messageInfo_GCSArtifact proto.InternalMessageInfo func (m *GCSBucket) Reset() { *m = GCSBucket{} } func (*GCSBucket) ProtoMessage() {} func (*GCSBucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{29} + return fileDescriptor_724696e352c3df5f, []int{31} } func (m *GCSBucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -879,7 +935,7 @@ var xxx_messageInfo_GCSBucket proto.InternalMessageInfo func (m *Gauge) Reset() { *m = Gauge{} } func (*Gauge) ProtoMessage() {} func (*Gauge) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{30} + return fileDescriptor_724696e352c3df5f, []int{32} } func (m *Gauge) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -907,7 +963,7 @@ var xxx_messageInfo_Gauge proto.InternalMessageInfo func (m *GitArtifact) Reset() { *m = GitArtifact{} } func (*GitArtifact) ProtoMessage() {} func (*GitArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{31} + return fileDescriptor_724696e352c3df5f, []int{33} } func (m *GitArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -935,7 +991,7 @@ var xxx_messageInfo_GitArtifact proto.InternalMessageInfo func (m *HDFSArtifact) Reset() { *m = HDFSArtifact{} } func (*HDFSArtifact) ProtoMessage() {} func (*HDFSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{32} + return fileDescriptor_724696e352c3df5f, []int{34} } func (m *HDFSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -963,7 +1019,7 @@ var xxx_messageInfo_HDFSArtifact proto.InternalMessageInfo func (m *HDFSConfig) Reset() { *m = HDFSConfig{} } func (*HDFSConfig) ProtoMessage() {} func (*HDFSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{33} + return fileDescriptor_724696e352c3df5f, []int{35} } func (m *HDFSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -991,7 +1047,7 @@ var xxx_messageInfo_HDFSConfig proto.InternalMessageInfo func (m *HDFSKrbConfig) Reset() { *m = HDFSKrbConfig{} } func (*HDFSKrbConfig) ProtoMessage() {} func (*HDFSKrbConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{34} + return fileDescriptor_724696e352c3df5f, []int{36} } func (m *HDFSKrbConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1019,7 +1075,7 @@ var xxx_messageInfo_HDFSKrbConfig proto.InternalMessageInfo func (m *HTTPArtifact) Reset() { *m = HTTPArtifact{} } func (*HTTPArtifact) ProtoMessage() {} func (*HTTPArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{35} + return fileDescriptor_724696e352c3df5f, []int{37} } func (m *HTTPArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1047,7 +1103,7 @@ var xxx_messageInfo_HTTPArtifact proto.InternalMessageInfo func (m *Header) Reset() { *m = Header{} } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{36} + return fileDescriptor_724696e352c3df5f, []int{38} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1075,7 +1131,7 @@ var xxx_messageInfo_Header proto.InternalMessageInfo func (m *Histogram) Reset() { *m = Histogram{} } func (*Histogram) ProtoMessage() {} func (*Histogram) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{37} + return fileDescriptor_724696e352c3df5f, []int{39} } func (m *Histogram) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1103,7 +1159,7 @@ var xxx_messageInfo_Histogram proto.InternalMessageInfo func (m *Inputs) Reset() { *m = Inputs{} } func (*Inputs) ProtoMessage() {} func (*Inputs) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{38} + return fileDescriptor_724696e352c3df5f, []int{40} } func (m *Inputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1131,7 +1187,7 @@ var xxx_messageInfo_Inputs proto.InternalMessageInfo func (m *Item) Reset() { *m = Item{} } func (*Item) ProtoMessage() {} func (*Item) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{39} + return fileDescriptor_724696e352c3df5f, []int{41} } func (m *Item) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1159,7 +1215,7 @@ var xxx_messageInfo_Item proto.InternalMessageInfo func (m *Link) Reset() { *m = Link{} } func (*Link) ProtoMessage() {} func (*Link) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{40} + return fileDescriptor_724696e352c3df5f, []int{42} } func (m *Link) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1187,7 +1243,7 @@ var xxx_messageInfo_Link proto.InternalMessageInfo func (m *MemoizationStatus) Reset() { *m = MemoizationStatus{} } func (*MemoizationStatus) ProtoMessage() {} func (*MemoizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{41} + return fileDescriptor_724696e352c3df5f, []int{43} } func (m *MemoizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1215,7 +1271,7 @@ var xxx_messageInfo_MemoizationStatus proto.InternalMessageInfo func (m *Memoize) Reset() { *m = Memoize{} } func (*Memoize) ProtoMessage() {} func (*Memoize) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{42} + return fileDescriptor_724696e352c3df5f, []int{44} } func (m *Memoize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1243,7 +1299,7 @@ var xxx_messageInfo_Memoize proto.InternalMessageInfo func (m *Metadata) Reset() { *m = Metadata{} } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{43} + return fileDescriptor_724696e352c3df5f, []int{45} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1271,7 +1327,7 @@ var xxx_messageInfo_Metadata proto.InternalMessageInfo func (m *MetricLabel) Reset() { *m = MetricLabel{} } func (*MetricLabel) ProtoMessage() {} func (*MetricLabel) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{44} + return fileDescriptor_724696e352c3df5f, []int{46} } func (m *MetricLabel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1299,7 +1355,7 @@ var xxx_messageInfo_MetricLabel proto.InternalMessageInfo func (m *Metrics) Reset() { *m = Metrics{} } func (*Metrics) ProtoMessage() {} func (*Metrics) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{45} + return fileDescriptor_724696e352c3df5f, []int{47} } func (m *Metrics) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1327,7 +1383,7 @@ var xxx_messageInfo_Metrics proto.InternalMessageInfo func (m *Mutex) Reset() { *m = Mutex{} } func (*Mutex) ProtoMessage() {} func (*Mutex) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{46} + return fileDescriptor_724696e352c3df5f, []int{48} } func (m *Mutex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1355,7 +1411,7 @@ var xxx_messageInfo_Mutex proto.InternalMessageInfo func (m *MutexHolding) Reset() { *m = MutexHolding{} } func (*MutexHolding) ProtoMessage() {} func (*MutexHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{47} + return fileDescriptor_724696e352c3df5f, []int{49} } func (m *MutexHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1383,7 +1439,7 @@ var xxx_messageInfo_MutexHolding proto.InternalMessageInfo func (m *MutexStatus) Reset() { *m = MutexStatus{} } func (*MutexStatus) ProtoMessage() {} func (*MutexStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{48} + return fileDescriptor_724696e352c3df5f, []int{50} } func (m *MutexStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1411,7 +1467,7 @@ var xxx_messageInfo_MutexStatus proto.InternalMessageInfo func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{49} + return fileDescriptor_724696e352c3df5f, []int{51} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1439,7 +1495,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *NodeSynchronizationStatus) Reset() { *m = NodeSynchronizationStatus{} } func (*NodeSynchronizationStatus) ProtoMessage() {} func (*NodeSynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{50} + return fileDescriptor_724696e352c3df5f, []int{52} } func (m *NodeSynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1467,7 +1523,7 @@ var xxx_messageInfo_NodeSynchronizationStatus proto.InternalMessageInfo func (m *NoneStrategy) Reset() { *m = NoneStrategy{} } func (*NoneStrategy) ProtoMessage() {} func (*NoneStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{51} + return fileDescriptor_724696e352c3df5f, []int{53} } func (m *NoneStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1495,7 +1551,7 @@ var xxx_messageInfo_NoneStrategy proto.InternalMessageInfo func (m *OSSArtifact) Reset() { *m = OSSArtifact{} } func (*OSSArtifact) ProtoMessage() {} func (*OSSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{52} + return fileDescriptor_724696e352c3df5f, []int{54} } func (m *OSSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1523,7 +1579,7 @@ var xxx_messageInfo_OSSArtifact proto.InternalMessageInfo func (m *OSSBucket) Reset() { *m = OSSBucket{} } func (*OSSBucket) ProtoMessage() {} func (*OSSBucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{53} + return fileDescriptor_724696e352c3df5f, []int{55} } func (m *OSSBucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1551,7 +1607,7 @@ var xxx_messageInfo_OSSBucket proto.InternalMessageInfo func (m *Outputs) Reset() { *m = Outputs{} } func (*Outputs) ProtoMessage() {} func (*Outputs) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{54} + return fileDescriptor_724696e352c3df5f, []int{56} } func (m *Outputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1579,7 +1635,7 @@ var xxx_messageInfo_Outputs proto.InternalMessageInfo func (m *ParallelSteps) Reset() { *m = ParallelSteps{} } func (*ParallelSteps) ProtoMessage() {} func (*ParallelSteps) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{55} + return fileDescriptor_724696e352c3df5f, []int{57} } func (m *ParallelSteps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1607,7 +1663,7 @@ var xxx_messageInfo_ParallelSteps proto.InternalMessageInfo func (m *Parameter) Reset() { *m = Parameter{} } func (*Parameter) ProtoMessage() {} func (*Parameter) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{56} + return fileDescriptor_724696e352c3df5f, []int{58} } func (m *Parameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1635,7 +1691,7 @@ var xxx_messageInfo_Parameter proto.InternalMessageInfo func (m *PodGC) Reset() { *m = PodGC{} } func (*PodGC) ProtoMessage() {} func (*PodGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{57} + return fileDescriptor_724696e352c3df5f, []int{59} } func (m *PodGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1663,7 +1719,7 @@ var xxx_messageInfo_PodGC proto.InternalMessageInfo func (m *Prometheus) Reset() { *m = Prometheus{} } func (*Prometheus) ProtoMessage() {} func (*Prometheus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{58} + return fileDescriptor_724696e352c3df5f, []int{60} } func (m *Prometheus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1691,7 +1747,7 @@ var xxx_messageInfo_Prometheus proto.InternalMessageInfo func (m *RawArtifact) Reset() { *m = RawArtifact{} } func (*RawArtifact) ProtoMessage() {} func (*RawArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{59} + return fileDescriptor_724696e352c3df5f, []int{61} } func (m *RawArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1719,7 +1775,7 @@ var xxx_messageInfo_RawArtifact proto.InternalMessageInfo func (m *ResourceTemplate) Reset() { *m = ResourceTemplate{} } func (*ResourceTemplate) ProtoMessage() {} func (*ResourceTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{60} + return fileDescriptor_724696e352c3df5f, []int{62} } func (m *ResourceTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1747,7 +1803,7 @@ var xxx_messageInfo_ResourceTemplate proto.InternalMessageInfo func (m *RetryAffinity) Reset() { *m = RetryAffinity{} } func (*RetryAffinity) ProtoMessage() {} func (*RetryAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{61} + return fileDescriptor_724696e352c3df5f, []int{63} } func (m *RetryAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1775,7 +1831,7 @@ var xxx_messageInfo_RetryAffinity proto.InternalMessageInfo func (m *RetryNodeAntiAffinity) Reset() { *m = RetryNodeAntiAffinity{} } func (*RetryNodeAntiAffinity) ProtoMessage() {} func (*RetryNodeAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{62} + return fileDescriptor_724696e352c3df5f, []int{64} } func (m *RetryNodeAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1803,7 +1859,7 @@ var xxx_messageInfo_RetryNodeAntiAffinity proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{63} + return fileDescriptor_724696e352c3df5f, []int{65} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1831,7 +1887,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *S3Artifact) Reset() { *m = S3Artifact{} } func (*S3Artifact) ProtoMessage() {} func (*S3Artifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{64} + return fileDescriptor_724696e352c3df5f, []int{66} } func (m *S3Artifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1859,7 +1915,7 @@ var xxx_messageInfo_S3Artifact proto.InternalMessageInfo func (m *S3Bucket) Reset() { *m = S3Bucket{} } func (*S3Bucket) ProtoMessage() {} func (*S3Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{65} + return fileDescriptor_724696e352c3df5f, []int{67} } func (m *S3Bucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1887,7 +1943,7 @@ var xxx_messageInfo_S3Bucket proto.InternalMessageInfo func (m *ScriptTemplate) Reset() { *m = ScriptTemplate{} } func (*ScriptTemplate) ProtoMessage() {} func (*ScriptTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{66} + return fileDescriptor_724696e352c3df5f, []int{68} } func (m *ScriptTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1915,7 +1971,7 @@ var xxx_messageInfo_ScriptTemplate proto.InternalMessageInfo func (m *SemaphoreHolding) Reset() { *m = SemaphoreHolding{} } func (*SemaphoreHolding) ProtoMessage() {} func (*SemaphoreHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{67} + return fileDescriptor_724696e352c3df5f, []int{69} } func (m *SemaphoreHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1943,7 +1999,7 @@ var xxx_messageInfo_SemaphoreHolding proto.InternalMessageInfo func (m *SemaphoreRef) Reset() { *m = SemaphoreRef{} } func (*SemaphoreRef) ProtoMessage() {} func (*SemaphoreRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{68} + return fileDescriptor_724696e352c3df5f, []int{70} } func (m *SemaphoreRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1971,7 +2027,7 @@ var xxx_messageInfo_SemaphoreRef proto.InternalMessageInfo func (m *SemaphoreStatus) Reset() { *m = SemaphoreStatus{} } func (*SemaphoreStatus) ProtoMessage() {} func (*SemaphoreStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{69} + return fileDescriptor_724696e352c3df5f, []int{71} } func (m *SemaphoreStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1999,7 +2055,7 @@ var xxx_messageInfo_SemaphoreStatus proto.InternalMessageInfo func (m *Sequence) Reset() { *m = Sequence{} } func (*Sequence) ProtoMessage() {} func (*Sequence) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{70} + return fileDescriptor_724696e352c3df5f, []int{72} } func (m *Sequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2027,7 +2083,7 @@ var xxx_messageInfo_Sequence proto.InternalMessageInfo func (m *Submit) Reset() { *m = Submit{} } func (*Submit) ProtoMessage() {} func (*Submit) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{71} + return fileDescriptor_724696e352c3df5f, []int{73} } func (m *Submit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2055,7 +2111,7 @@ var xxx_messageInfo_Submit proto.InternalMessageInfo func (m *SubmitOpts) Reset() { *m = SubmitOpts{} } func (*SubmitOpts) ProtoMessage() {} func (*SubmitOpts) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{72} + return fileDescriptor_724696e352c3df5f, []int{74} } func (m *SubmitOpts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2083,7 +2139,7 @@ var xxx_messageInfo_SubmitOpts proto.InternalMessageInfo func (m *SuppliedValueFrom) Reset() { *m = SuppliedValueFrom{} } func (*SuppliedValueFrom) ProtoMessage() {} func (*SuppliedValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{73} + return fileDescriptor_724696e352c3df5f, []int{75} } func (m *SuppliedValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2111,7 +2167,7 @@ var xxx_messageInfo_SuppliedValueFrom proto.InternalMessageInfo func (m *SuspendTemplate) Reset() { *m = SuspendTemplate{} } func (*SuspendTemplate) ProtoMessage() {} func (*SuspendTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{74} + return fileDescriptor_724696e352c3df5f, []int{76} } func (m *SuspendTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2139,7 +2195,7 @@ var xxx_messageInfo_SuspendTemplate proto.InternalMessageInfo func (m *Synchronization) Reset() { *m = Synchronization{} } func (*Synchronization) ProtoMessage() {} func (*Synchronization) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{75} + return fileDescriptor_724696e352c3df5f, []int{77} } func (m *Synchronization) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2167,7 +2223,7 @@ var xxx_messageInfo_Synchronization proto.InternalMessageInfo func (m *SynchronizationStatus) Reset() { *m = SynchronizationStatus{} } func (*SynchronizationStatus) ProtoMessage() {} func (*SynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{76} + return fileDescriptor_724696e352c3df5f, []int{78} } func (m *SynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2195,7 +2251,7 @@ var xxx_messageInfo_SynchronizationStatus proto.InternalMessageInfo func (m *TTLStrategy) Reset() { *m = TTLStrategy{} } func (*TTLStrategy) ProtoMessage() {} func (*TTLStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{77} + return fileDescriptor_724696e352c3df5f, []int{79} } func (m *TTLStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2223,7 +2279,7 @@ var xxx_messageInfo_TTLStrategy proto.InternalMessageInfo func (m *TarStrategy) Reset() { *m = TarStrategy{} } func (*TarStrategy) ProtoMessage() {} func (*TarStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{78} + return fileDescriptor_724696e352c3df5f, []int{80} } func (m *TarStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2251,7 +2307,7 @@ var xxx_messageInfo_TarStrategy proto.InternalMessageInfo func (m *Template) Reset() { *m = Template{} } func (*Template) ProtoMessage() {} func (*Template) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{79} + return fileDescriptor_724696e352c3df5f, []int{81} } func (m *Template) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2279,7 +2335,7 @@ var xxx_messageInfo_Template proto.InternalMessageInfo func (m *TemplateRef) Reset() { *m = TemplateRef{} } func (*TemplateRef) ProtoMessage() {} func (*TemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{80} + return fileDescriptor_724696e352c3df5f, []int{82} } func (m *TemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2307,7 +2363,7 @@ var xxx_messageInfo_TemplateRef proto.InternalMessageInfo func (m *TransformationStep) Reset() { *m = TransformationStep{} } func (*TransformationStep) ProtoMessage() {} func (*TransformationStep) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{81} + return fileDescriptor_724696e352c3df5f, []int{83} } func (m *TransformationStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2335,7 +2391,7 @@ var xxx_messageInfo_TransformationStep proto.InternalMessageInfo func (m *UserContainer) Reset() { *m = UserContainer{} } func (*UserContainer) ProtoMessage() {} func (*UserContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{82} + return fileDescriptor_724696e352c3df5f, []int{84} } func (m *UserContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2363,7 +2419,7 @@ var xxx_messageInfo_UserContainer proto.InternalMessageInfo func (m *ValueFrom) Reset() { *m = ValueFrom{} } func (*ValueFrom) ProtoMessage() {} func (*ValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{83} + return fileDescriptor_724696e352c3df5f, []int{85} } func (m *ValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2391,7 +2447,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo func (m *Version) Reset() { *m = Version{} } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{84} + return fileDescriptor_724696e352c3df5f, []int{86} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2419,7 +2475,7 @@ var xxx_messageInfo_Version proto.InternalMessageInfo func (m *VolumeClaimGC) Reset() { *m = VolumeClaimGC{} } func (*VolumeClaimGC) ProtoMessage() {} func (*VolumeClaimGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{85} + return fileDescriptor_724696e352c3df5f, []int{87} } func (m *VolumeClaimGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2447,7 +2503,7 @@ var xxx_messageInfo_VolumeClaimGC proto.InternalMessageInfo func (m *Workflow) Reset() { *m = Workflow{} } func (*Workflow) ProtoMessage() {} func (*Workflow) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{86} + return fileDescriptor_724696e352c3df5f, []int{88} } func (m *Workflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2475,7 +2531,7 @@ var xxx_messageInfo_Workflow proto.InternalMessageInfo func (m *WorkflowEventBinding) Reset() { *m = WorkflowEventBinding{} } func (*WorkflowEventBinding) ProtoMessage() {} func (*WorkflowEventBinding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{87} + return fileDescriptor_724696e352c3df5f, []int{89} } func (m *WorkflowEventBinding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2503,7 +2559,7 @@ var xxx_messageInfo_WorkflowEventBinding proto.InternalMessageInfo func (m *WorkflowEventBindingList) Reset() { *m = WorkflowEventBindingList{} } func (*WorkflowEventBindingList) ProtoMessage() {} func (*WorkflowEventBindingList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{88} + return fileDescriptor_724696e352c3df5f, []int{90} } func (m *WorkflowEventBindingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2531,7 +2587,7 @@ var xxx_messageInfo_WorkflowEventBindingList proto.InternalMessageInfo func (m *WorkflowEventBindingSpec) Reset() { *m = WorkflowEventBindingSpec{} } func (*WorkflowEventBindingSpec) ProtoMessage() {} func (*WorkflowEventBindingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{89} + return fileDescriptor_724696e352c3df5f, []int{91} } func (m *WorkflowEventBindingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2559,7 +2615,7 @@ var xxx_messageInfo_WorkflowEventBindingSpec proto.InternalMessageInfo func (m *WorkflowList) Reset() { *m = WorkflowList{} } func (*WorkflowList) ProtoMessage() {} func (*WorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{90} + return fileDescriptor_724696e352c3df5f, []int{92} } func (m *WorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2587,7 +2643,7 @@ var xxx_messageInfo_WorkflowList proto.InternalMessageInfo func (m *WorkflowSpec) Reset() { *m = WorkflowSpec{} } func (*WorkflowSpec) ProtoMessage() {} func (*WorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{91} + return fileDescriptor_724696e352c3df5f, []int{93} } func (m *WorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2615,7 +2671,7 @@ var xxx_messageInfo_WorkflowSpec proto.InternalMessageInfo func (m *WorkflowStatus) Reset() { *m = WorkflowStatus{} } func (*WorkflowStatus) ProtoMessage() {} func (*WorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{92} + return fileDescriptor_724696e352c3df5f, []int{94} } func (m *WorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2643,7 +2699,7 @@ var xxx_messageInfo_WorkflowStatus proto.InternalMessageInfo func (m *WorkflowStep) Reset() { *m = WorkflowStep{} } func (*WorkflowStep) ProtoMessage() {} func (*WorkflowStep) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{93} + return fileDescriptor_724696e352c3df5f, []int{95} } func (m *WorkflowStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2671,7 +2727,7 @@ var xxx_messageInfo_WorkflowStep proto.InternalMessageInfo func (m *WorkflowTemplate) Reset() { *m = WorkflowTemplate{} } func (*WorkflowTemplate) ProtoMessage() {} func (*WorkflowTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{94} + return fileDescriptor_724696e352c3df5f, []int{96} } func (m *WorkflowTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2699,7 +2755,7 @@ var xxx_messageInfo_WorkflowTemplate proto.InternalMessageInfo func (m *WorkflowTemplateList) Reset() { *m = WorkflowTemplateList{} } func (*WorkflowTemplateList) ProtoMessage() {} func (*WorkflowTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{95} + return fileDescriptor_724696e352c3df5f, []int{97} } func (m *WorkflowTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2727,7 +2783,7 @@ var xxx_messageInfo_WorkflowTemplateList proto.InternalMessageInfo func (m *WorkflowTemplateRef) Reset() { *m = WorkflowTemplateRef{} } func (*WorkflowTemplateRef) ProtoMessage() {} func (*WorkflowTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{96} + return fileDescriptor_724696e352c3df5f, []int{98} } func (m *WorkflowTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2755,7 +2811,7 @@ var xxx_messageInfo_WorkflowTemplateRef proto.InternalMessageInfo func (m *WorkflowTemplateSpec) Reset() { *m = WorkflowTemplateSpec{} } func (*WorkflowTemplateSpec) ProtoMessage() {} func (*WorkflowTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{97} + return fileDescriptor_724696e352c3df5f, []int{99} } func (m *WorkflowTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2783,7 +2839,7 @@ var xxx_messageInfo_WorkflowTemplateSpec proto.InternalMessageInfo func (m *ZipStrategy) Reset() { *m = ZipStrategy{} } func (*ZipStrategy) ProtoMessage() {} func (*ZipStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{98} + return fileDescriptor_724696e352c3df5f, []int{100} } func (m *ZipStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2824,6 +2880,8 @@ func init() { proto.RegisterType((*ClusterWorkflowTemplate)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ClusterWorkflowTemplate") proto.RegisterType((*ClusterWorkflowTemplateList)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ClusterWorkflowTemplateList") proto.RegisterType((*Condition)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Condition") + proto.RegisterType((*ContainerNode)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ContainerNode") + proto.RegisterType((*ContainerSetTemplate)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ContainerSetTemplate") proto.RegisterType((*ContinueOn)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ContinueOn") proto.RegisterType((*Counter)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Counter") proto.RegisterType((*CreateS3BucketOptions)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.CreateS3BucketOptions") @@ -2923,491 +2981,497 @@ func init() { } var fileDescriptor_724696e352c3df5f = []byte{ - // 7740 bytes of a gzipped FileDescriptorProto + // 7838 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5b, 0x70, 0x24, 0x59, - 0x76, 0xd0, 0x64, 0x49, 0x25, 0x55, 0x9d, 0x92, 0x5a, 0xea, 0xdb, 0xaf, 0x1a, 0x4d, 0x4f, 0x6b, - 0x9c, 0xe3, 0x19, 0xa6, 0x61, 0x56, 0xf2, 0x74, 0xef, 0xc0, 0xc0, 0x06, 0xf6, 0xaa, 0xa4, 0x96, - 0xba, 0xa7, 0x5b, 0x8f, 0x39, 0xa5, 0xee, 0x89, 0x9d, 0x1d, 0x96, 0x4d, 0x55, 0x5d, 0x55, 0xe5, - 0xa8, 0x2a, 0x33, 0x27, 0x33, 0x4b, 0x6a, 0xed, 0xcc, 0xac, 0x17, 0x03, 0xf6, 0x2e, 0xc6, 0x18, - 0xcc, 0x86, 0xbd, 0x36, 0x3f, 0x1b, 0xc0, 0x02, 0x01, 0x0e, 0x02, 0x13, 0x7c, 0x99, 0x5f, 0x3e, - 0x96, 0xe0, 0x03, 0x47, 0x18, 0xc2, 0x1b, 0x01, 0xc8, 0xac, 0xcc, 0xeb, 0x07, 0xfe, 0xbc, 0x38, - 0x1a, 0x7f, 0x10, 0xf7, 0x99, 0x37, 0xb3, 0xb2, 0xba, 0xa5, 0xe9, 0x54, 0xef, 0x46, 0xac, 0xff, - 0xaa, 0xce, 0x39, 0xf7, 0x9c, 0xfb, 0xbe, 0xe7, 0x75, 0x6f, 0xc2, 0x56, 0xc7, 0x8d, 0xbb, 0x83, - 0x9d, 0x85, 0x96, 0xdf, 0x5f, 0x74, 0xc2, 0x8e, 0x1f, 0x84, 0xfe, 0x07, 0xfc, 0xc7, 0x67, 0x0e, - 0xfc, 0x70, 0x6f, 0xb7, 0xe7, 0x1f, 0x44, 0x8b, 0xfb, 0x37, 0x17, 0x83, 0xbd, 0xce, 0xa2, 0x13, - 0xb8, 0xd1, 0xa2, 0x82, 0x2e, 0xee, 0xbf, 0xe1, 0xf4, 0x82, 0xae, 0xf3, 0xc6, 0x62, 0x87, 0x7a, - 0x34, 0x74, 0x62, 0xda, 0x5e, 0x08, 0x42, 0x3f, 0xf6, 0xc9, 0xe7, 0x13, 0x8e, 0x0b, 0x8a, 0x23, - 0xff, 0xf1, 0x97, 0x35, 0xc7, 0x85, 0xfd, 0x9b, 0x0b, 0xc1, 0x5e, 0x67, 0x81, 0x71, 0x5c, 0x50, - 0xd0, 0x05, 0xc5, 0x71, 0xee, 0x33, 0x46, 0x9d, 0x3a, 0x7e, 0xc7, 0x5f, 0xe4, 0x8c, 0x77, 0x06, - 0xbb, 0xfc, 0x1f, 0xff, 0xc3, 0x7f, 0x09, 0x81, 0x73, 0xf6, 0xde, 0x5b, 0xd1, 0x82, 0xeb, 0xb3, - 0xfa, 0x2d, 0xb6, 0xfc, 0x90, 0x2e, 0xee, 0x0f, 0x55, 0x6a, 0xee, 0xba, 0x41, 0x13, 0xf8, 0x3d, - 0xb7, 0x75, 0xb8, 0xb8, 0xff, 0xc6, 0x0e, 0x8d, 0x87, 0xeb, 0x3f, 0xf7, 0xd9, 0x84, 0xb4, 0xef, - 0xb4, 0xba, 0xae, 0x47, 0xc3, 0xc3, 0xa4, 0xfd, 0x7d, 0x1a, 0x3b, 0x79, 0x02, 0x16, 0x47, 0x95, - 0x0a, 0x07, 0x5e, 0xec, 0xf6, 0xe9, 0x50, 0x81, 0x3f, 0xfb, 0xa4, 0x02, 0x51, 0xab, 0x4b, 0xfb, - 0xce, 0x50, 0xb9, 0x9b, 0xa3, 0xca, 0x0d, 0x62, 0xb7, 0xb7, 0xe8, 0x7a, 0x71, 0x14, 0x87, 0xd9, - 0x42, 0xf6, 0x2d, 0x98, 0x58, 0xea, 0xfb, 0x03, 0x2f, 0x26, 0x9f, 0x83, 0xf2, 0xbe, 0xd3, 0x1b, - 0xd0, 0xba, 0xf5, 0x92, 0xf5, 0x5a, 0xb5, 0xf1, 0xca, 0x77, 0x8f, 0xe6, 0x9f, 0x3b, 0x3e, 0x9a, - 0x2f, 0x3f, 0x60, 0xc0, 0x47, 0x47, 0xf3, 0x17, 0xa9, 0xd7, 0xf2, 0xdb, 0xae, 0xd7, 0x59, 0xfc, - 0x20, 0xf2, 0xbd, 0x85, 0x8d, 0x41, 0x7f, 0x87, 0x86, 0x28, 0xca, 0xd8, 0xbf, 0x5b, 0x82, 0x99, - 0xa5, 0xb0, 0xd5, 0x75, 0xf7, 0x69, 0x33, 0x66, 0xfc, 0x3b, 0x87, 0xa4, 0x0b, 0x63, 0xb1, 0x13, - 0x72, 0x76, 0xb5, 0x1b, 0xeb, 0x0b, 0x4f, 0x3b, 0xf8, 0x0b, 0xdb, 0x4e, 0xa8, 0x78, 0x37, 0x26, - 0x8f, 0x8f, 0xe6, 0xc7, 0xb6, 0x9d, 0x10, 0x99, 0x08, 0xd2, 0x83, 0x71, 0xcf, 0xf7, 0x68, 0xbd, - 0xc4, 0x45, 0x6d, 0x3c, 0xbd, 0xa8, 0x0d, 0xdf, 0xd3, 0xed, 0x68, 0x54, 0x8e, 0x8f, 0xe6, 0xc7, - 0x19, 0x04, 0xb9, 0x14, 0xd6, 0xae, 0xaf, 0xb8, 0x41, 0x7d, 0xac, 0xa8, 0x76, 0xbd, 0xe7, 0x06, - 0xe9, 0x76, 0xbd, 0xe7, 0x06, 0xc8, 0x44, 0xd8, 0xdf, 0x28, 0x41, 0x75, 0x29, 0xec, 0x0c, 0xfa, - 0xd4, 0x8b, 0x23, 0xf2, 0xb3, 0x00, 0x81, 0x13, 0x3a, 0x7d, 0x1a, 0xd3, 0x30, 0xaa, 0x5b, 0x2f, - 0x8d, 0xbd, 0x56, 0xbb, 0x71, 0xf7, 0xe9, 0xc5, 0x6f, 0x29, 0x9e, 0x0d, 0x22, 0x87, 0x1c, 0x34, - 0x28, 0x42, 0x43, 0x24, 0xf9, 0x08, 0xaa, 0x4e, 0x18, 0xbb, 0xbb, 0x4e, 0x2b, 0x8e, 0xea, 0x25, - 0x2e, 0xff, 0xed, 0xa7, 0x97, 0xbf, 0x24, 0x59, 0x36, 0xce, 0x4b, 0xf1, 0x55, 0x05, 0x89, 0x30, - 0x91, 0x67, 0xff, 0xcf, 0x71, 0xa8, 0x28, 0x04, 0x79, 0x09, 0xc6, 0x3d, 0xa7, 0xaf, 0xa6, 0xea, - 0x94, 0x2c, 0x38, 0xbe, 0xe1, 0xf4, 0xd9, 0x20, 0x39, 0x7d, 0xca, 0x28, 0x02, 0x27, 0xee, 0xf2, - 0x29, 0x61, 0x50, 0x6c, 0x39, 0x71, 0x17, 0x39, 0x86, 0x5c, 0x85, 0xf1, 0xbe, 0xdf, 0xa6, 0x7c, - 0x1c, 0xcb, 0x62, 0x90, 0xd7, 0xfd, 0x36, 0x45, 0x0e, 0x65, 0xe5, 0x77, 0x43, 0xbf, 0x5f, 0x1f, - 0x4f, 0x97, 0x5f, 0x0d, 0xfd, 0x3e, 0x72, 0x0c, 0xf9, 0x96, 0x05, 0xb3, 0xaa, 0x7a, 0xf7, 0xfc, - 0x96, 0x13, 0xbb, 0xbe, 0x57, 0x2f, 0xf3, 0x49, 0x81, 0xc5, 0xf5, 0x8a, 0xe2, 0xdc, 0xa8, 0xcb, - 0x2a, 0xcc, 0x66, 0x31, 0x38, 0x54, 0x0b, 0x72, 0x03, 0xa0, 0xd3, 0xf3, 0x77, 0x9c, 0x1e, 0xeb, - 0x90, 0xfa, 0x04, 0x6f, 0x82, 0x1e, 0xdc, 0x35, 0x8d, 0x41, 0x83, 0x8a, 0x3c, 0x84, 0x49, 0x47, - 0x2c, 0xe0, 0xfa, 0x24, 0x6f, 0xc4, 0x3b, 0x45, 0x34, 0x22, 0xb5, 0x23, 0x34, 0x6a, 0xc7, 0x47, - 0xf3, 0x93, 0x12, 0x88, 0x4a, 0x1c, 0x79, 0x1d, 0x2a, 0x7e, 0xc0, 0xea, 0xed, 0xf4, 0xea, 0x95, - 0x97, 0xac, 0xd7, 0x2a, 0x8d, 0x59, 0x59, 0xd7, 0xca, 0xa6, 0x84, 0xa3, 0xa6, 0x20, 0xd7, 0x61, - 0x32, 0x1a, 0xec, 0xb0, 0x71, 0xac, 0x57, 0x79, 0xc3, 0x66, 0x24, 0xf1, 0x64, 0x53, 0x80, 0x51, - 0xe1, 0xc9, 0x9b, 0x50, 0x0b, 0x69, 0x6b, 0x10, 0x46, 0x94, 0x0d, 0x6c, 0x1d, 0x38, 0xef, 0x0b, - 0x92, 0xbc, 0x86, 0x09, 0x0a, 0x4d, 0x3a, 0xfb, 0xb7, 0x27, 0x61, 0xa8, 0x93, 0xc9, 0x1b, 0x50, - 0x93, 0xf5, 0xbd, 0xe7, 0x77, 0x22, 0x3e, 0xf1, 0x2a, 0x8d, 0x19, 0xc6, 0x67, 0x29, 0x01, 0xa3, - 0x49, 0x43, 0xda, 0x50, 0x8a, 0x6e, 0xca, 0x3d, 0xe9, 0xde, 0xd3, 0x77, 0x66, 0xf3, 0xa6, 0x5e, - 0x29, 0x13, 0xc7, 0x47, 0xf3, 0xa5, 0xe6, 0x4d, 0x2c, 0x45, 0x37, 0xd9, 0x6e, 0xd4, 0x71, 0xe3, - 0xe2, 0x76, 0xa3, 0x35, 0x37, 0xd6, 0x72, 0xf8, 0x6e, 0xb4, 0xe6, 0xc6, 0xc8, 0x44, 0xb0, 0x5d, - 0xb6, 0x1b, 0xc7, 0x01, 0x5f, 0x12, 0x85, 0xec, 0xb2, 0xb7, 0xb7, 0xb7, 0xb7, 0xb4, 0x2c, 0xbe, - 0x00, 0x19, 0x04, 0xb9, 0x14, 0xf2, 0x75, 0x8b, 0xf5, 0xb8, 0x40, 0xfa, 0xe1, 0xa1, 0x5c, 0x59, - 0xf7, 0x8b, 0x5b, 0x59, 0x7e, 0x78, 0xa8, 0x85, 0xcb, 0x81, 0xd4, 0x08, 0x34, 0x45, 0xf3, 0x86, - 0xb7, 0x77, 0x23, 0xbe, 0x90, 0x8a, 0x69, 0xf8, 0xca, 0x6a, 0x33, 0xd3, 0xf0, 0x95, 0xd5, 0x26, - 0x72, 0x29, 0x6c, 0x40, 0x43, 0xe7, 0x40, 0x2e, 0xc2, 0x02, 0x06, 0x14, 0x9d, 0x83, 0xf4, 0x80, - 0xa2, 0x73, 0x80, 0x4c, 0x04, 0x93, 0xe4, 0x47, 0x11, 0x5f, 0x73, 0x85, 0x48, 0xda, 0x6c, 0x36, - 0xd3, 0x92, 0x36, 0x9b, 0x4d, 0x64, 0x22, 0xf8, 0x24, 0x6d, 0x45, 0x7c, 0xc1, 0x16, 0x33, 0x49, - 0x97, 0x33, 0x92, 0xd6, 0x96, 0x9b, 0xc8, 0x44, 0xd8, 0xdf, 0xb0, 0x60, 0x5a, 0xa1, 0xd8, 0x26, - 0x10, 0x91, 0x87, 0x50, 0x51, 0x83, 0x29, 0x75, 0x91, 0x22, 0x0f, 0x2d, 0xbd, 0x55, 0x29, 0x08, - 0x6a, 0x69, 0xf6, 0x87, 0x70, 0x49, 0x43, 0x69, 0xe0, 0x47, 0x2e, 0x9f, 0x5a, 0x74, 0x97, 0x2c, - 0x42, 0xb5, 0xe5, 0x7b, 0xbb, 0x6e, 0x67, 0xdd, 0x09, 0xe4, 0x19, 0xa6, 0x0f, 0xbf, 0x65, 0x85, - 0xc0, 0x84, 0x86, 0xbc, 0x08, 0x63, 0x7b, 0xf4, 0x50, 0x1e, 0x66, 0x35, 0x49, 0x3a, 0x76, 0x97, - 0x1e, 0x22, 0x83, 0xff, 0x85, 0xca, 0xb7, 0xbe, 0x3d, 0xff, 0xdc, 0xd7, 0xfe, 0xf3, 0x4b, 0xcf, - 0xd9, 0xff, 0xb2, 0x04, 0x2f, 0xe4, 0xca, 0x6c, 0xc6, 0x4e, 0x3c, 0x88, 0xc8, 0x6f, 0x5a, 0x70, - 0xc9, 0xc9, 0xc3, 0xcb, 0xae, 0x79, 0xb7, 0xb8, 0xae, 0x49, 0xb1, 0x6f, 0xbc, 0x28, 0x2b, 0x9d, - 0xdf, 0x23, 0x98, 0x5f, 0x29, 0xd6, 0x51, 0xec, 0x34, 0x8f, 0x02, 0xa7, 0x45, 0x65, 0xeb, 0x75, - 0x47, 0x6d, 0x28, 0x04, 0x26, 0x34, 0xec, 0x74, 0x68, 0xd3, 0x5d, 0x67, 0xd0, 0x13, 0x3b, 0x62, - 0x25, 0x39, 0x1d, 0x56, 0x04, 0x18, 0x15, 0xde, 0xe8, 0xb4, 0x7f, 0x67, 0xc1, 0x85, 0x9c, 0x5d, - 0x81, 0xf5, 0xfa, 0x20, 0xec, 0xc9, 0x01, 0xd2, 0xbd, 0x7e, 0x1f, 0xef, 0x21, 0x83, 0x93, 0x6f, - 0x5a, 0x30, 0x63, 0x6c, 0x13, 0x4b, 0x03, 0xa9, 0x6e, 0x14, 0x74, 0x74, 0xa6, 0x18, 0x37, 0xae, - 0x48, 0xf1, 0x33, 0x19, 0x04, 0x66, 0xab, 0x60, 0xff, 0x9e, 0x05, 0x59, 0x22, 0xe2, 0xc0, 0xb9, - 0x41, 0x44, 0x43, 0xd6, 0x4f, 0x4d, 0xda, 0x0a, 0xa9, 0x5a, 0x09, 0xaf, 0x2c, 0x08, 0x9b, 0x81, - 0xd5, 0x62, 0x81, 0x59, 0x48, 0x0b, 0xfb, 0x6f, 0x2c, 0x08, 0x8a, 0xbb, 0xf4, 0xb0, 0x49, 0x7b, - 0x94, 0xf1, 0x68, 0x90, 0xe3, 0xa3, 0xf9, 0x73, 0xf7, 0x53, 0x0c, 0x30, 0xc3, 0x90, 0x89, 0x08, - 0x9c, 0x28, 0x3a, 0xf0, 0xc3, 0xb6, 0x14, 0x51, 0x3a, 0xb5, 0x88, 0xad, 0x14, 0x03, 0xcc, 0x30, - 0xb4, 0xff, 0x8d, 0x05, 0x93, 0x0d, 0xa7, 0xb5, 0xe7, 0xef, 0xee, 0x32, 0xa5, 0xa1, 0x3d, 0x08, - 0x85, 0xd2, 0x25, 0x06, 0x48, 0xaf, 0xc4, 0x15, 0x09, 0x47, 0x4d, 0x41, 0xb6, 0x61, 0x42, 0x74, - 0x87, 0xac, 0xd4, 0x4f, 0x19, 0x95, 0xd2, 0xb6, 0x12, 0x1f, 0x0e, 0x66, 0x2b, 0x2d, 0x08, 0x5b, - 0x69, 0xe1, 0x8e, 0x17, 0x6f, 0x32, 0x93, 0xc3, 0xf5, 0x3a, 0x0d, 0x38, 0x3e, 0x9a, 0x9f, 0x58, - 0xe5, 0x3c, 0x50, 0xf2, 0x62, 0xfa, 0x45, 0xdf, 0x79, 0xa8, 0xc4, 0xf1, 0x09, 0x57, 0x4d, 0xf4, - 0x8b, 0xf5, 0x04, 0x85, 0x26, 0x9d, 0xfd, 0x25, 0x28, 0x2f, 0x3b, 0xad, 0x2e, 0x25, 0xf7, 0xb3, - 0xdb, 0x40, 0xed, 0xc6, 0x6b, 0x79, 0xbd, 0xa5, 0xb7, 0x04, 0xb3, 0xc3, 0xa6, 0x47, 0x6d, 0x16, - 0xf6, 0x1f, 0x5a, 0x70, 0x65, 0xb9, 0x37, 0x88, 0x62, 0x1a, 0xbe, 0x2b, 0xe7, 0xd5, 0x36, 0xed, - 0x07, 0x3d, 0x27, 0xa6, 0xe4, 0xcb, 0x50, 0x61, 0x76, 0x6a, 0xdb, 0x89, 0x1d, 0x29, 0x71, 0x74, - 0x57, 0xf0, 0x99, 0xc9, 0xa8, 0x59, 0x1d, 0x36, 0x77, 0x3e, 0xa0, 0xad, 0x78, 0x9d, 0xc6, 0x4e, - 0xa2, 0x49, 0x26, 0x30, 0xd4, 0x5c, 0xc9, 0x43, 0x18, 0x8f, 0x02, 0xda, 0x92, 0x1d, 0xfd, 0xe0, - 0xe9, 0x57, 0x42, 0xb6, 0x0d, 0xcd, 0x80, 0xb6, 0x12, 0x85, 0x9c, 0xfd, 0x43, 0x2e, 0xd1, 0xfe, - 0x7f, 0x16, 0xbc, 0x30, 0xa2, 0xdd, 0xf7, 0xdc, 0x28, 0x26, 0xef, 0x0f, 0xb5, 0x7d, 0xe1, 0x64, - 0x6d, 0x67, 0xa5, 0x79, 0xcb, 0xf5, 0x14, 0x53, 0x10, 0xa3, 0xdd, 0x5f, 0x85, 0xb2, 0x1b, 0xd3, - 0xbe, 0x32, 0x8c, 0xbe, 0xf0, 0xf4, 0x0d, 0x1f, 0xd1, 0x96, 0xc6, 0xb4, 0xb2, 0xcc, 0xef, 0x30, - 0x79, 0x28, 0xc4, 0xda, 0xff, 0xd6, 0x02, 0x36, 0x1d, 0xda, 0xae, 0x54, 0x57, 0xc7, 0xe3, 0xc3, - 0x40, 0x19, 0x48, 0x6a, 0xf3, 0x1d, 0xdf, 0x3e, 0x0c, 0x98, 0x29, 0x3f, 0xad, 0x09, 0x19, 0x00, - 0x39, 0x29, 0xf9, 0x12, 0x4c, 0x44, 0xfc, 0x90, 0x90, 0x1b, 0xed, 0xaa, 0x2c, 0x34, 0x21, 0x8e, - 0x8e, 0x47, 0x47, 0xf3, 0x27, 0xf2, 0x7f, 0x2c, 0x68, 0xde, 0xa2, 0x1c, 0x4a, 0xae, 0x6c, 0x6b, - 0xee, 0xd3, 0x28, 0x72, 0x3a, 0x54, 0xae, 0x14, 0xbd, 0x35, 0xaf, 0x0b, 0x30, 0x2a, 0xbc, 0xfd, - 0x05, 0x80, 0x65, 0xdf, 0x8b, 0x5d, 0x6f, 0x40, 0x37, 0x3d, 0xf2, 0x32, 0x94, 0x69, 0x18, 0xfa, - 0xa1, 0x54, 0xba, 0x75, 0xf3, 0x6f, 0x31, 0x20, 0x0a, 0x1c, 0x79, 0x95, 0xad, 0x70, 0xb7, 0x47, - 0xdb, 0xbc, 0xf6, 0x95, 0xc6, 0x39, 0x55, 0xfb, 0x55, 0x0e, 0x45, 0x89, 0xb5, 0x17, 0x60, 0x72, - 0xd9, 0x1f, 0x78, 0x31, 0x0d, 0x19, 0x5f, 0xd3, 0xe1, 0x31, 0x9d, 0x72, 0x78, 0x28, 0xc7, 0xc6, - 0x36, 0x5c, 0x5a, 0x0e, 0x29, 0x9b, 0x76, 0x37, 0x1b, 0x83, 0xd6, 0x1e, 0x8d, 0x85, 0x49, 0x12, - 0x91, 0xcf, 0xc1, 0xb4, 0xcf, 0xe7, 0xff, 0x3d, 0xbf, 0xb5, 0xe7, 0x7a, 0x1d, 0x79, 0xde, 0x5c, - 0x92, 0x5c, 0xa6, 0x37, 0x4d, 0x24, 0xa6, 0x69, 0xed, 0xff, 0x56, 0x82, 0xa9, 0xe5, 0xd0, 0xf7, - 0xd4, 0xd8, 0x3e, 0x83, 0x75, 0x19, 0xa7, 0xd6, 0x65, 0x01, 0x16, 0xaa, 0x59, 0xff, 0x51, 0x6b, - 0x92, 0x7c, 0xac, 0x27, 0x95, 0x30, 0x50, 0xb6, 0x0b, 0x96, 0xcb, 0x79, 0x27, 0x83, 0x9d, 0x9e, - 0x72, 0xf6, 0x7f, 0xb7, 0x60, 0xd6, 0x24, 0x7f, 0x06, 0xdb, 0x40, 0x94, 0xde, 0x06, 0x36, 0x8a, - 0x6d, 0xef, 0x88, 0xb5, 0xff, 0x8d, 0x89, 0x74, 0x3b, 0xd9, 0x00, 0x90, 0x6f, 0x59, 0x30, 0x75, - 0x60, 0x00, 0x64, 0x63, 0x37, 0x8a, 0xdb, 0x91, 0xf9, 0xa8, 0xff, 0xa4, 0xac, 0xd1, 0x94, 0x09, - 0x7d, 0x94, 0xf9, 0x8f, 0xa9, 0x9a, 0xb0, 0xc3, 0x3b, 0x6a, 0x75, 0x69, 0x7b, 0xd0, 0x53, 0x5a, - 0x9d, 0xee, 0xd2, 0xa6, 0x84, 0xa3, 0xa6, 0x20, 0xef, 0xc3, 0xf9, 0x96, 0xef, 0xb5, 0x06, 0x61, - 0x48, 0xbd, 0xd6, 0xe1, 0x16, 0xf7, 0xd1, 0xca, 0x2d, 0x64, 0x41, 0x16, 0x3b, 0xbf, 0x9c, 0x25, - 0x78, 0x94, 0x07, 0xc4, 0x61, 0x46, 0xc2, 0x9f, 0x10, 0x05, 0xd4, 0x6b, 0x73, 0xc3, 0xb6, 0x62, - 0xfa, 0x13, 0x38, 0x18, 0x15, 0x9e, 0xdc, 0x87, 0x2b, 0x51, 0xcc, 0xd4, 0x2d, 0xaf, 0xb3, 0x42, - 0x9d, 0x76, 0xcf, 0xf5, 0x98, 0xf2, 0xe3, 0x7b, 0xed, 0x88, 0x5b, 0xa7, 0x63, 0x8d, 0x17, 0x8e, - 0x8f, 0xe6, 0xaf, 0x34, 0xf3, 0x49, 0x70, 0x54, 0x59, 0xf2, 0x25, 0x98, 0x8b, 0x06, 0xad, 0x16, - 0x8d, 0xa2, 0xdd, 0x41, 0xef, 0x6d, 0x7f, 0x27, 0xba, 0xed, 0x46, 0x4c, 0x73, 0xbb, 0xe7, 0xf6, - 0xdd, 0x98, 0x1b, 0x9d, 0xe5, 0xc6, 0xb5, 0xe3, 0xa3, 0xf9, 0xb9, 0xe6, 0x48, 0x2a, 0x7c, 0x0c, - 0x07, 0x82, 0x70, 0x59, 0x6c, 0x7e, 0x43, 0xbc, 0x27, 0x39, 0xef, 0xb9, 0xe3, 0xa3, 0xf9, 0xcb, - 0xab, 0xb9, 0x14, 0x38, 0xa2, 0x24, 0x1b, 0xc1, 0xd8, 0xed, 0xd3, 0xaf, 0xf8, 0x1e, 0xe5, 0xf6, - 0xa3, 0x31, 0x82, 0xdb, 0x12, 0x8e, 0x9a, 0x82, 0x7c, 0x90, 0xcc, 0x44, 0xb6, 0x5c, 0xa4, 0x1d, - 0x78, 0xfa, 0x1d, 0xee, 0xe2, 0xf1, 0xd1, 0xfc, 0xec, 0xbb, 0x06, 0x27, 0xb6, 0xe4, 0x30, 0xc5, - 0xdb, 0xfe, 0xdd, 0x12, 0x90, 0xe1, 0x2d, 0x82, 0xdc, 0x85, 0x09, 0xa7, 0x15, 0xbb, 0xfb, 0x54, - 0x3a, 0x4e, 0x5f, 0xce, 0x53, 0xb4, 0x84, 0x28, 0xa4, 0xbb, 0x94, 0xcd, 0x10, 0x9a, 0xec, 0x2b, - 0x4b, 0xbc, 0x28, 0x4a, 0x16, 0xc4, 0x87, 0xf3, 0x3d, 0x27, 0x8a, 0xd5, 0x5c, 0x6d, 0xb3, 0x26, - 0xcb, 0x8d, 0xf5, 0x4f, 0x9f, 0xac, 0x51, 0xac, 0x44, 0xe3, 0x12, 0x9b, 0xb9, 0xf7, 0xb2, 0x8c, - 0x70, 0x98, 0x37, 0xf9, 0x59, 0x80, 0x96, 0x3a, 0x56, 0xd9, 0x56, 0x5a, 0x90, 0xeb, 0x57, 0x1f, - 0xd5, 0xc9, 0xd9, 0xa1, 0x41, 0x11, 0x1a, 0x22, 0xed, 0x7f, 0x31, 0x09, 0x93, 0x2b, 0x4b, 0x6b, - 0xdb, 0x4e, 0xb4, 0x77, 0x02, 0xe7, 0x2b, 0x9b, 0x1d, 0x52, 0x5b, 0xc9, 0xae, 0x6f, 0xa5, 0xc5, - 0xa0, 0xa6, 0x20, 0x1f, 0x43, 0xd5, 0x51, 0x4e, 0x6e, 0x79, 0x4c, 0xdc, 0x2d, 0xc2, 0x80, 0x92, - 0x2c, 0x4d, 0xbf, 0xb2, 0x04, 0x61, 0x22, 0x90, 0x7c, 0xcd, 0x82, 0x9a, 0xaa, 0x0a, 0xb3, 0x83, - 0xc7, 0x0b, 0x0b, 0x57, 0x24, 0x4c, 0x85, 0x7f, 0xc9, 0x00, 0xa0, 0x29, 0x92, 0x7c, 0x16, 0xa6, - 0xda, 0x94, 0xed, 0x30, 0xd4, 0x6b, 0xb9, 0x94, 0x6d, 0x26, 0x63, 0xac, 0xcb, 0xd8, 0xa6, 0xba, - 0x62, 0xc0, 0x31, 0x45, 0x45, 0x0e, 0xa0, 0x7a, 0xe0, 0xc6, 0x5d, 0x7e, 0x10, 0xd4, 0x27, 0xf8, - 0x94, 0x58, 0x7d, 0xfa, 0x5a, 0x33, 0x76, 0x49, 0x8f, 0xbd, 0xab, 0x04, 0x60, 0x22, 0x8b, 0x19, - 0xe5, 0xec, 0x0f, 0x0f, 0x12, 0xf0, 0x2d, 0xa4, 0x9a, 0x2e, 0xc0, 0x11, 0x98, 0xd0, 0xb0, 0x2e, - 0x9e, 0x62, 0xff, 0x9a, 0xf4, 0xc3, 0x01, 0x5b, 0x57, 0xd2, 0xe3, 0x54, 0x80, 0x1b, 0x46, 0x71, - 0x14, 0x9d, 0xf5, 0xae, 0x21, 0x03, 0x53, 0x12, 0xd9, 0x9c, 0x3d, 0xe8, 0x52, 0x4f, 0xba, 0x8c, - 0xf5, 0x9c, 0x7d, 0xb7, 0x4b, 0x3d, 0xe4, 0x18, 0xf2, 0x31, 0x5f, 0x62, 0x52, 0xe7, 0xe4, 0xbe, - 0xe2, 0x42, 0xbc, 0xb6, 0x89, 0x1e, 0xdb, 0x38, 0x27, 0xd7, 0x97, 0xfc, 0x8f, 0x86, 0x3c, 0xa6, - 0xbe, 0xfa, 0xde, 0xad, 0x87, 0x6e, 0x5c, 0xaf, 0xf1, 0x1a, 0xea, 0x9d, 0x67, 0x93, 0x43, 0x51, - 0x62, 0x85, 0x7f, 0x83, 0x4d, 0x82, 0xa8, 0x3e, 0x95, 0x56, 0xa2, 0xc5, 0x4c, 0x89, 0x50, 0xe1, - 0xed, 0x7f, 0x6f, 0x41, 0x8d, 0x2d, 0x59, 0xb5, 0xcc, 0x5e, 0x85, 0x89, 0xd8, 0x09, 0x3b, 0xd2, - 0xf6, 0x37, 0x44, 0x6c, 0x73, 0x28, 0x4a, 0x2c, 0xf1, 0xa0, 0x1c, 0x3b, 0xd1, 0x9e, 0xd2, 0x60, - 0xee, 0x3c, 0x7d, 0x1f, 0xc8, 0x8d, 0x23, 0x51, 0x5e, 0xd8, 0xbf, 0x08, 0x85, 0x18, 0xf2, 0x1a, - 0x54, 0xd8, 0x21, 0xb3, 0xea, 0x44, 0xca, 0x67, 0x33, 0xc5, 0x36, 0x8a, 0x55, 0x09, 0x43, 0x8d, - 0xb5, 0xff, 0x6e, 0x09, 0xc6, 0x57, 0x84, 0x2e, 0x3b, 0x11, 0xf9, 0x83, 0xb0, 0x45, 0xa5, 0x4e, - 0x53, 0xc0, 0x38, 0x31, 0xbe, 0x4d, 0xce, 0xd3, 0xd0, 0x26, 0xf9, 0x7f, 0x94, 0xb2, 0xc8, 0x37, - 0x2d, 0x38, 0x17, 0x87, 0x8e, 0x17, 0xed, 0xfa, 0x61, 0x5f, 0x98, 0xfc, 0xa2, 0x8b, 0x0a, 0x50, - 0x6a, 0xb7, 0x53, 0x7c, 0x9b, 0x31, 0x0d, 0x1a, 0x97, 0x65, 0x35, 0xce, 0xa5, 0x71, 0x98, 0xa9, - 0x83, 0xfd, 0x6b, 0x16, 0x40, 0x52, 0x7b, 0xf2, 0x75, 0x0b, 0xa6, 0x1d, 0xd3, 0x01, 0x2a, 0xfb, - 0x68, 0xb3, 0x38, 0x9f, 0x14, 0x67, 0xdb, 0x38, 0xcf, 0xac, 0x9c, 0x14, 0x08, 0xd3, 0x82, 0xed, - 0x37, 0xa1, 0x7c, 0x6b, 0x9f, 0x7a, 0x5c, 0x5b, 0x88, 0xa4, 0xdf, 0x22, 0xeb, 0xac, 0x51, 0xfe, - 0x0c, 0xd4, 0x14, 0xf6, 0xfb, 0x70, 0xee, 0xd6, 0x43, 0xda, 0x1a, 0xc4, 0x7e, 0x28, 0xfc, 0x1b, - 0xe4, 0x6d, 0x20, 0x11, 0x0d, 0xf7, 0xdd, 0x16, 0x5d, 0x6a, 0xb5, 0x98, 0xf5, 0xb6, 0x91, 0x9c, - 0x3f, 0x73, 0x92, 0x13, 0x69, 0x0e, 0x51, 0x60, 0x4e, 0x29, 0xfb, 0x9f, 0x5a, 0x50, 0x33, 0xdc, - 0xc7, 0xec, 0xf4, 0xe9, 0x2c, 0x37, 0x85, 0x6d, 0x27, 0xbb, 0xea, 0x6e, 0x21, 0x0e, 0x6a, 0xc1, - 0x32, 0xd9, 0x1a, 0x35, 0x08, 0x13, 0x81, 0x4f, 0x70, 0xec, 0xda, 0xbf, 0x65, 0x41, 0x52, 0x8e, - 0xad, 0xe0, 0x9d, 0xa4, 0x9e, 0xc6, 0x0a, 0x96, 0x7c, 0x25, 0x96, 0x7c, 0x0c, 0x57, 0xd2, 0x0d, - 0xe7, 0x7e, 0xa3, 0xd3, 0xfb, 0xe4, 0x84, 0x3a, 0x9b, 0xcf, 0x09, 0x47, 0x89, 0xb0, 0x1f, 0x40, - 0x79, 0xcd, 0x19, 0x74, 0xe8, 0x89, 0xec, 0x6b, 0xb6, 0xfa, 0x43, 0xea, 0xf4, 0x62, 0xa5, 0x41, - 0xc9, 0xd5, 0x8f, 0x12, 0x86, 0x1a, 0x6b, 0xff, 0xe6, 0x38, 0xd4, 0x8c, 0xe0, 0x14, 0xdb, 0xd2, - 0x43, 0x1a, 0xf8, 0x59, 0x35, 0x04, 0x69, 0xe0, 0x23, 0xc7, 0xb0, 0x69, 0x17, 0xd2, 0x7d, 0x37, - 0x12, 0x2b, 0x35, 0x35, 0xed, 0x50, 0xc2, 0x51, 0x53, 0x90, 0x79, 0x28, 0xb7, 0x69, 0x10, 0x77, - 0xf9, 0x26, 0x34, 0xde, 0xa8, 0xb2, 0xaa, 0xae, 0x30, 0x00, 0x0a, 0x38, 0x23, 0xd8, 0xa5, 0x71, - 0xab, 0x5b, 0x1f, 0xe7, 0xe7, 0x33, 0x27, 0x58, 0x65, 0x00, 0x14, 0xf0, 0x1c, 0x2f, 0x6b, 0xf9, - 0xec, 0xbd, 0xac, 0x13, 0x05, 0x7b, 0x59, 0x49, 0x00, 0x17, 0xa2, 0xa8, 0xbb, 0x15, 0xba, 0xfb, - 0x4e, 0x4c, 0x93, 0x99, 0x33, 0x79, 0x1a, 0x39, 0x57, 0x8e, 0x8f, 0xe6, 0x2f, 0x34, 0x9b, 0xb7, - 0xb3, 0x5c, 0x30, 0x8f, 0x35, 0x69, 0xc2, 0x25, 0xd7, 0x8b, 0x68, 0x6b, 0x10, 0xd2, 0x3b, 0x1d, - 0xcf, 0x0f, 0xe9, 0x6d, 0x3f, 0x62, 0xec, 0x64, 0x34, 0x58, 0x87, 0x0e, 0xee, 0xe4, 0x11, 0x61, - 0x7e, 0x59, 0xfb, 0x7b, 0x16, 0x4c, 0x99, 0x71, 0x36, 0xa6, 0x85, 0x40, 0x77, 0x65, 0xb5, 0x29, - 0xf6, 0x94, 0xe2, 0x4e, 0x8e, 0xdb, 0x9a, 0x67, 0xa2, 0x45, 0x27, 0x30, 0x34, 0x64, 0x9e, 0x20, - 0x29, 0xe1, 0x65, 0x28, 0xef, 0xfa, 0xec, 0x60, 0x1b, 0x4b, 0xfb, 0xba, 0x56, 0x19, 0x10, 0x05, - 0xce, 0xfe, 0x81, 0x05, 0x86, 0x04, 0xf2, 0x37, 0x2d, 0x98, 0x66, 0x42, 0xee, 0x86, 0x3b, 0xa9, - 0xb6, 0x6d, 0x16, 0xd3, 0x36, 0xcd, 0x36, 0xf1, 0x6d, 0xa5, 0xc0, 0x98, 0x16, 0x4e, 0xfe, 0x0c, - 0x54, 0x9d, 0x76, 0x3b, 0xa4, 0x51, 0x44, 0x85, 0x0e, 0x51, 0x15, 0xbe, 0xea, 0x25, 0x05, 0xc4, - 0x04, 0xcf, 0x96, 0x68, 0xb7, 0xbd, 0x1b, 0xb1, 0x59, 0x2f, 0x4d, 0x7a, 0xbd, 0x44, 0x99, 0x10, - 0x06, 0x47, 0x4d, 0x61, 0xff, 0xd2, 0x38, 0xa4, 0x65, 0x93, 0x36, 0xcc, 0xec, 0x85, 0x3b, 0xcb, - 0xdc, 0x9f, 0xfe, 0x69, 0x22, 0x1b, 0x17, 0x8e, 0x8f, 0xe6, 0x67, 0xee, 0xa6, 0x39, 0x60, 0x96, - 0xa5, 0x94, 0x72, 0x97, 0x1e, 0xc6, 0xce, 0xce, 0xa7, 0xd9, 0x48, 0x95, 0x14, 0x93, 0x03, 0x66, - 0x59, 0x92, 0x37, 0xa1, 0xb6, 0x17, 0xee, 0xa8, 0x0d, 0x20, 0x1b, 0x4e, 0xb8, 0x9b, 0xa0, 0xd0, - 0xa4, 0x63, 0x5d, 0xb8, 0x17, 0xee, 0xb0, 0x0d, 0x53, 0x65, 0xab, 0xe8, 0x2e, 0xbc, 0x2b, 0xe1, - 0xa8, 0x29, 0x48, 0x00, 0x64, 0x4f, 0xf5, 0x9e, 0x8e, 0x1e, 0xc8, 0x7d, 0xea, 0xe4, 0xc1, 0x87, - 0xcb, 0xec, 0xc0, 0xbd, 0x3b, 0xc4, 0x07, 0x73, 0x78, 0x93, 0x2f, 0xc0, 0x95, 0xbd, 0x70, 0x47, - 0x1e, 0x23, 0x5b, 0xa1, 0xeb, 0xb5, 0xdc, 0x20, 0x95, 0x99, 0x32, 0x2f, 0xab, 0x7b, 0xe5, 0x6e, - 0x3e, 0x19, 0x8e, 0x2a, 0x6f, 0xff, 0x7d, 0xb6, 0xc6, 0x8d, 0x24, 0x82, 0x27, 0x45, 0xec, 0x22, - 0x98, 0xec, 0x52, 0xa7, 0x4d, 0x43, 0xa5, 0xdc, 0xde, 0x2e, 0x60, 0x89, 0x70, 0x86, 0x89, 0x1e, - 0x2e, 0xfe, 0x47, 0xa8, 0x24, 0xd9, 0x9b, 0x30, 0x21, 0x60, 0x27, 0x30, 0x9c, 0xf5, 0x91, 0x59, - 0x7a, 0x8c, 0x4b, 0xfa, 0x3b, 0x16, 0x54, 0xb9, 0x33, 0xa6, 0xc3, 0x8c, 0x2b, 0x5d, 0x64, 0xec, - 0x31, 0xa7, 0x6c, 0x04, 0x93, 0x42, 0x37, 0x88, 0xf8, 0xe1, 0x55, 0x48, 0xc3, 0x45, 0xda, 0x60, - 0xd2, 0x70, 0xa1, 0x84, 0x44, 0xa8, 0x24, 0xd9, 0x3f, 0x5f, 0x82, 0x89, 0x3b, 0x5e, 0x30, 0xf8, - 0xb1, 0x4f, 0x5d, 0x5b, 0x87, 0x71, 0x66, 0x39, 0xa7, 0x33, 0x2c, 0xa7, 0x1a, 0xaf, 0x98, 0xd9, - 0x95, 0xf5, 0x74, 0x76, 0x25, 0x3a, 0x07, 0x2a, 0x2a, 0x22, 0xca, 0x18, 0xe1, 0xea, 0x1e, 0x8c, - 0xdf, 0x73, 0xbd, 0xbd, 0x93, 0x4d, 0xa7, 0xa8, 0xe5, 0x07, 0x43, 0xd3, 0xa9, 0xc9, 0x80, 0x28, - 0x70, 0x6a, 0xcd, 0x8c, 0xe5, 0xaf, 0x19, 0xfb, 0xe7, 0x2c, 0x38, 0xbf, 0x4e, 0xfb, 0xbe, 0xfb, - 0x15, 0x27, 0x09, 0xea, 0xb0, 0x42, 0x5d, 0x37, 0x96, 0x11, 0x19, 0x5d, 0xe8, 0xb6, 0x1b, 0x23, - 0x83, 0x3f, 0x41, 0xad, 0xe5, 0xf9, 0x0f, 0x6c, 0x7b, 0xdd, 0x48, 0xf6, 0xb9, 0x24, 0xff, 0x41, - 0x21, 0x30, 0xa1, 0xb1, 0x7f, 0xdb, 0x82, 0x49, 0x51, 0x09, 0xaa, 0x78, 0x5b, 0x23, 0x78, 0x77, - 0xa1, 0xcc, 0xcb, 0xc9, 0x1d, 0x7a, 0xad, 0x00, 0x13, 0x9e, 0xb1, 0x13, 0xea, 0x1e, 0xff, 0x89, - 0x42, 0x00, 0x53, 0xc7, 0xfb, 0xce, 0xc3, 0x25, 0x1d, 0xcf, 0xd2, 0xea, 0xf8, 0x3a, 0x87, 0xa2, - 0xc4, 0xda, 0xbf, 0x31, 0x06, 0x15, 0xe5, 0xac, 0x24, 0xbf, 0x62, 0x41, 0xcd, 0xf1, 0x3c, 0x3f, - 0x76, 0x84, 0x2f, 0x4f, 0xac, 0x85, 0x2f, 0x3e, 0x7d, 0x2d, 0x95, 0x84, 0x85, 0xa5, 0x84, 0xfb, - 0x2d, 0x2f, 0x0e, 0x0f, 0x93, 0x23, 0xc4, 0xc0, 0xa0, 0x59, 0x09, 0xf2, 0x55, 0x98, 0xe8, 0x39, - 0x3b, 0xb4, 0xa7, 0x96, 0xc6, 0x83, 0x02, 0xab, 0x73, 0x8f, 0x33, 0x16, 0x35, 0xd1, 0x3d, 0x24, - 0x80, 0x28, 0xa5, 0xce, 0xfd, 0x34, 0xcc, 0x66, 0x6b, 0x4d, 0x66, 0x8d, 0x61, 0x16, 0x23, 0x7b, - 0x31, 0xb5, 0x39, 0xaa, 0x75, 0x51, 0x7a, 0xcb, 0x9a, 0xfb, 0xf3, 0x50, 0x33, 0xc4, 0x9c, 0xa6, - 0xa8, 0xfd, 0x0e, 0xd4, 0xd6, 0x69, 0x1c, 0xba, 0x2d, 0xce, 0xe0, 0x49, 0x93, 0xeb, 0x44, 0xfb, - 0xf3, 0x2f, 0xf0, 0xc9, 0xca, 0x78, 0x46, 0xe4, 0x63, 0x80, 0x20, 0xf4, 0xfb, 0x34, 0xee, 0xd2, - 0x81, 0x1a, 0xec, 0x02, 0x74, 0xce, 0x2d, 0xcd, 0x53, 0x78, 0x95, 0x92, 0xff, 0x68, 0xc8, 0xb3, - 0xaf, 0x43, 0x79, 0x7d, 0x10, 0xd3, 0x87, 0x4f, 0xde, 0x2a, 0xec, 0x2f, 0xc2, 0x14, 0x27, 0xbd, - 0xed, 0xf7, 0xd8, 0x2e, 0xc4, 0x5a, 0xda, 0x67, 0xff, 0xb3, 0xc6, 0x1b, 0x27, 0x42, 0x81, 0x63, - 0x2b, 0xa0, 0xeb, 0xf7, 0xda, 0x34, 0x94, 0xfd, 0xa1, 0xc7, 0xf7, 0x36, 0x87, 0xa2, 0xc4, 0xda, - 0x7f, 0xb5, 0x04, 0x35, 0x5e, 0x50, 0xee, 0x1e, 0x87, 0x30, 0xd9, 0x15, 0x72, 0x64, 0x97, 0x14, - 0x10, 0x94, 0x32, 0x6b, 0x6f, 0x9c, 0xc6, 0x02, 0x80, 0x4a, 0x1e, 0x13, 0x7d, 0xe0, 0xb8, 0x31, - 0x13, 0x5d, 0x3a, 0x5b, 0xd1, 0xef, 0x0a, 0x31, 0xa8, 0xe4, 0xd9, 0xff, 0x63, 0x06, 0x60, 0xc3, - 0x6f, 0x53, 0xd9, 0x09, 0x73, 0x50, 0x72, 0xdb, 0xb2, 0x7b, 0x41, 0x16, 0x2a, 0xdd, 0x59, 0xc1, - 0x92, 0xdb, 0xd6, 0xe3, 0x55, 0x1a, 0xb9, 0xb5, 0xbf, 0x09, 0xb5, 0xb6, 0x1b, 0x05, 0x3d, 0xe7, - 0x70, 0x23, 0x47, 0x59, 0x5c, 0x49, 0x50, 0x68, 0xd2, 0x91, 0xd7, 0x65, 0x5e, 0x80, 0x50, 0x14, - 0xeb, 0x99, 0xbc, 0x80, 0x0a, 0xab, 0x9e, 0x91, 0x12, 0xf0, 0x16, 0x4c, 0x29, 0x3f, 0x35, 0x97, - 0x52, 0xe6, 0xa5, 0x2e, 0xaa, 0x88, 0xdf, 0xb6, 0x81, 0xc3, 0x14, 0xe5, 0x90, 0x57, 0x7d, 0xe2, - 0xd9, 0x7b, 0xd5, 0x3f, 0x07, 0xd3, 0xea, 0x2f, 0x3f, 0xef, 0xea, 0x17, 0x79, 0xed, 0xb5, 0x11, - 0xb3, 0x6d, 0x22, 0x31, 0x4d, 0x4b, 0x7e, 0x0a, 0xca, 0x41, 0xd7, 0x89, 0xa8, 0xf4, 0x6f, 0x2b, - 0x27, 0x53, 0x79, 0x8b, 0x01, 0x1f, 0x1d, 0xcd, 0x57, 0x59, 0x4f, 0xf1, 0x3f, 0x28, 0x08, 0xc9, - 0x0d, 0x80, 0x1d, 0x7f, 0xe0, 0xb5, 0x9d, 0xf0, 0xf0, 0xce, 0x8a, 0x8c, 0x89, 0x69, 0xad, 0xa4, - 0xa1, 0x31, 0x68, 0x50, 0x99, 0x29, 0x11, 0xd5, 0xc7, 0xa7, 0x44, 0x90, 0x2f, 0x42, 0x95, 0xc7, - 0x0f, 0x69, 0x7b, 0x29, 0x96, 0xde, 0xe9, 0xd3, 0x84, 0x9a, 0xf4, 0xf1, 0xda, 0x54, 0x4c, 0x30, - 0xe1, 0x47, 0xbe, 0x04, 0xb0, 0xeb, 0x7a, 0x6e, 0xd4, 0xe5, 0xdc, 0x6b, 0xa7, 0xe6, 0xae, 0xdb, - 0xb9, 0xaa, 0xb9, 0xa0, 0xc1, 0x91, 0xbc, 0x0f, 0xe7, 0x69, 0x14, 0xbb, 0x7d, 0x27, 0xa6, 0x6d, - 0x9d, 0x2e, 0x55, 0xe7, 0x21, 0x53, 0x1d, 0xc1, 0xbd, 0x95, 0x25, 0x78, 0x94, 0x07, 0xc4, 0x61, - 0x46, 0xe4, 0x2d, 0xa8, 0x04, 0xa1, 0xdf, 0x61, 0x16, 0x65, 0x7d, 0x8e, 0x77, 0xe3, 0x55, 0x65, - 0x00, 0x6d, 0x49, 0xf8, 0x23, 0xe3, 0x37, 0x6a, 0x6a, 0xf2, 0x47, 0x16, 0x9c, 0x0f, 0xa9, 0x70, - 0xef, 0x46, 0xba, 0x62, 0x97, 0xf8, 0xbe, 0xd0, 0x2a, 0xe2, 0x16, 0x89, 0x5a, 0xec, 0x0b, 0x98, - 0x95, 0x22, 0x0e, 0x44, 0xaa, 0x5a, 0x3f, 0x84, 0x7f, 0x94, 0x07, 0xfc, 0xb9, 0xdf, 0x9f, 0x9f, - 0x1f, 0xbe, 0xd2, 0xa4, 0x99, 0xb3, 0x95, 0xf7, 0x37, 0x7e, 0x7f, 0x7e, 0x56, 0xfd, 0x4f, 0x3a, - 0x6d, 0xa8, 0x91, 0x6c, 0x7f, 0x0f, 0xfc, 0xf6, 0x9d, 0x2d, 0x19, 0x46, 0xd0, 0xfb, 0xfb, 0x16, - 0x03, 0xa2, 0xc0, 0x91, 0xd7, 0xa0, 0xd2, 0x76, 0x68, 0xdf, 0xf7, 0x68, 0xbb, 0x3e, 0x9d, 0x38, - 0xe7, 0x56, 0x24, 0x0c, 0x35, 0x96, 0xf4, 0x60, 0xc2, 0xe5, 0xaa, 0x7e, 0xfd, 0x1c, 0x9f, 0x3d, - 0x05, 0xd8, 0x17, 0xc2, 0x74, 0x10, 0x89, 0x77, 0xe2, 0x37, 0x4a, 0x19, 0x24, 0x80, 0x49, 0x7f, - 0x10, 0x73, 0x71, 0x33, 0x5c, 0x5c, 0x01, 0x41, 0x8a, 0x4d, 0xc1, 0x50, 0xdc, 0x51, 0x90, 0x7f, - 0x50, 0x89, 0x61, 0x3d, 0xd1, 0xea, 0xba, 0xbd, 0x76, 0x48, 0xbd, 0xfa, 0x2c, 0xf7, 0x69, 0xf0, - 0x9e, 0x58, 0x96, 0x30, 0xd4, 0x58, 0xf2, 0xe7, 0x60, 0xda, 0x1f, 0xc4, 0x7c, 0x91, 0xb3, 0xf1, - 0x8f, 0xea, 0xe7, 0x39, 0x39, 0xf7, 0x96, 0x6f, 0x9a, 0x08, 0x4c, 0xd3, 0xb1, 0xcd, 0xb6, 0xeb, - 0x47, 0x31, 0xfb, 0xc3, 0x37, 0xdb, 0xcb, 0xe9, 0xcd, 0xf6, 0xb6, 0x81, 0xc3, 0x14, 0x25, 0xf9, - 0x96, 0x05, 0xe7, 0xfb, 0x59, 0x15, 0xbd, 0x7e, 0x85, 0xf7, 0x4c, 0xb3, 0x08, 0x55, 0x2e, 0xc3, - 0x5a, 0x04, 0xae, 0x87, 0xc0, 0x38, 0x5c, 0x09, 0x9e, 0x6f, 0x1c, 0x1d, 0x7a, 0xad, 0x6e, 0xe8, - 0x7b, 0xe9, 0xea, 0x3d, 0xcf, 0xab, 0xf7, 0xc5, 0x82, 0x56, 0x59, 0x9e, 0x88, 0xc6, 0xf3, 0xc7, - 0x47, 0xf3, 0x97, 0x72, 0x51, 0x98, 0x5f, 0xa9, 0xb9, 0x15, 0xb8, 0x9c, 0xbf, 0x52, 0x9f, 0xa4, - 0x53, 0x8e, 0x99, 0x3a, 0xe5, 0x2a, 0x3c, 0x3f, 0xb2, 0x52, 0x6c, 0xcf, 0x57, 0x0a, 0x88, 0x95, - 0xde, 0xf3, 0x87, 0x14, 0x86, 0x73, 0x30, 0x65, 0x5e, 0x44, 0xe3, 0xa1, 0x0b, 0x23, 0xc7, 0x9e, - 0x7c, 0x0c, 0x55, 0xbf, 0x59, 0x78, 0xe8, 0x62, 0xb3, 0x39, 0x14, 0xba, 0xd0, 0x20, 0x4c, 0x04, - 0x3e, 0x29, 0x74, 0xf1, 0x8b, 0x63, 0x90, 0x94, 0x23, 0xaf, 0x43, 0x85, 0x7a, 0xed, 0xc0, 0x77, - 0xbd, 0x38, 0x1b, 0x01, 0xba, 0x25, 0xe1, 0xa8, 0x29, 0x8c, 0x40, 0x47, 0xe9, 0xb1, 0x81, 0x8e, - 0x36, 0xcc, 0x38, 0x3c, 0xed, 0x25, 0x71, 0x53, 0x8f, 0x9d, 0xda, 0x2f, 0xb7, 0x94, 0xe6, 0x80, - 0x59, 0x96, 0x4c, 0x4a, 0x94, 0x14, 0xe5, 0x52, 0xc6, 0x4f, 0x2d, 0xa5, 0x99, 0xe6, 0x80, 0x59, - 0x96, 0xe4, 0x7d, 0xa8, 0xb7, 0x78, 0xa2, 0xa1, 0x68, 0xe3, 0x9d, 0xdd, 0x0d, 0x3f, 0xde, 0x0a, - 0x69, 0x44, 0x3d, 0x11, 0x46, 0xa8, 0x34, 0x5e, 0x92, 0xbd, 0x50, 0x5f, 0x1e, 0x41, 0x87, 0x23, - 0x39, 0xd8, 0xff, 0xb1, 0x04, 0x6a, 0x53, 0xfb, 0xf1, 0x76, 0xc6, 0x10, 0x1b, 0x26, 0x42, 0x1a, - 0xa9, 0x0b, 0x02, 0x55, 0x71, 0xbe, 0x20, 0x87, 0xa0, 0xc4, 0xb0, 0xdd, 0x9e, 0x3e, 0x74, 0xe3, - 0x65, 0xbf, 0xad, 0x34, 0x65, 0xbe, 0xdb, 0xdf, 0x92, 0x30, 0xd4, 0x58, 0xfb, 0xaf, 0x59, 0x30, - 0xcd, 0x5a, 0xd9, 0xeb, 0xd1, 0x5e, 0x33, 0xa6, 0x41, 0x44, 0x22, 0x28, 0x47, 0xec, 0x47, 0x71, - 0x96, 0x4d, 0x92, 0xc9, 0x44, 0x03, 0xc3, 0x87, 0xc3, 0x84, 0xa0, 0x90, 0x65, 0xff, 0xaf, 0x12, - 0x54, 0x75, 0x67, 0x9f, 0xc0, 0x31, 0x74, 0x23, 0xb9, 0x26, 0x21, 0x56, 0x58, 0xdd, 0xb8, 0x22, - 0xc1, 0xd4, 0xdb, 0x25, 0xef, 0x50, 0x24, 0xbe, 0xeb, 0xfb, 0x12, 0xe4, 0xf5, 0xb4, 0xa3, 0xf1, - 0xb2, 0xe9, 0xbd, 0x32, 0xe8, 0xa5, 0xc7, 0xf1, 0x21, 0x54, 0xf9, 0x8f, 0x55, 0x75, 0x89, 0xb2, - 0x90, 0x39, 0xf6, 0x40, 0xb1, 0x14, 0x21, 0x05, 0xfd, 0x17, 0x13, 0x61, 0x99, 0xcb, 0x8f, 0xe5, - 0x13, 0x5d, 0x7e, 0xbc, 0x0e, 0xe3, 0xd4, 0x1b, 0xf4, 0x79, 0x1a, 0x4d, 0x95, 0x1f, 0x6f, 0xe3, - 0xb7, 0xbc, 0x41, 0x3f, 0xdd, 0x32, 0x4e, 0x62, 0xff, 0x2b, 0x0b, 0x98, 0x92, 0xb4, 0xb6, 0x4c, - 0xfe, 0x22, 0x54, 0x22, 0xb9, 0x35, 0xcb, 0xae, 0xfe, 0x09, 0x1d, 0xd5, 0x96, 0xf0, 0x47, 0x47, - 0xf3, 0xd3, 0x9c, 0x58, 0x01, 0x50, 0x17, 0x21, 0x3d, 0x98, 0xe6, 0xee, 0x0f, 0xb5, 0x4f, 0x48, - 0x87, 0xd5, 0xcd, 0x13, 0x26, 0xa3, 0x9a, 0x45, 0x85, 0x76, 0x91, 0x02, 0x61, 0x9a, 0xb9, 0xfd, - 0xaf, 0xc7, 0xc1, 0xf0, 0x12, 0x9c, 0x60, 0x8a, 0x7c, 0x98, 0xf1, 0x09, 0xad, 0x17, 0xe2, 0x13, - 0x52, 0x8e, 0x16, 0xb1, 0xec, 0xd2, 0x6e, 0x20, 0x56, 0xa9, 0x2e, 0xed, 0x05, 0x72, 0x82, 0xe9, - 0x4a, 0xdd, 0xa6, 0xbd, 0x00, 0x39, 0x46, 0xa7, 0xf1, 0x8c, 0x8f, 0x4c, 0xe3, 0xe9, 0x42, 0xb9, - 0xe3, 0x0c, 0x3a, 0x54, 0x86, 0x34, 0x0a, 0x70, 0xff, 0xf1, 0x60, 0xb6, 0x70, 0xff, 0xf1, 0x9f, - 0x28, 0x04, 0xb0, 0x19, 0xde, 0x55, 0x5e, 0x78, 0x69, 0xdf, 0x16, 0x30, 0xc3, 0xb5, 0x63, 0x5f, - 0xcc, 0x70, 0xfd, 0x17, 0x13, 0x61, 0x4c, 0xfd, 0x6d, 0x89, 0x1c, 0x76, 0x19, 0x95, 0xbd, 0x53, - 0x44, 0x9e, 0x12, 0x67, 0x28, 0xd4, 0x5f, 0xf9, 0x07, 0x95, 0x18, 0x7b, 0x11, 0x6a, 0xc6, 0x35, - 0x42, 0x36, 0x0c, 0x3a, 0x7d, 0xda, 0x18, 0x86, 0x15, 0x27, 0x76, 0x90, 0x63, 0xec, 0xbf, 0x37, - 0x06, 0xda, 0x0c, 0x31, 0x33, 0x90, 0x9c, 0x96, 0x71, 0x63, 0x27, 0x95, 0x5e, 0xe9, 0x7b, 0x28, - 0xb1, 0xcc, 0x72, 0xef, 0xd3, 0xb0, 0xa3, 0x15, 0x1f, 0xb9, 0x47, 0x69, 0xcb, 0x7d, 0xdd, 0x44, - 0x62, 0x9a, 0x96, 0x69, 0x1a, 0x7d, 0xc7, 0x73, 0x77, 0x69, 0x14, 0x67, 0x23, 0x8a, 0xeb, 0x12, - 0x8e, 0x9a, 0x82, 0xac, 0xc1, 0xf9, 0x88, 0xc6, 0x9b, 0x07, 0x1e, 0x0d, 0x75, 0xda, 0xa7, 0xcc, - 0x03, 0x7e, 0x5e, 0xd9, 0x66, 0xcd, 0x2c, 0x01, 0x0e, 0x97, 0x21, 0x2b, 0x30, 0x2b, 0x53, 0x70, - 0x75, 0x06, 0xa5, 0xdc, 0x7b, 0xf4, 0xc5, 0xed, 0x66, 0x06, 0x8f, 0x43, 0x25, 0x18, 0x97, 0x5d, - 0xc7, 0xed, 0x0d, 0x42, 0x9a, 0x70, 0x99, 0x48, 0x73, 0x59, 0xcd, 0xe0, 0x71, 0xa8, 0x04, 0x4f, - 0x54, 0xe8, 0x39, 0x9d, 0xa8, 0x3e, 0x69, 0x24, 0x2a, 0x30, 0x00, 0x0a, 0xb8, 0xfd, 0xcf, 0x2c, - 0x98, 0x46, 0x1a, 0x87, 0x87, 0x4b, 0xbb, 0xcc, 0x4a, 0x8f, 0x0f, 0xc9, 0xaf, 0x5b, 0x30, 0xeb, - 0xf9, 0x6d, 0xba, 0xe4, 0xc5, 0xae, 0x02, 0x16, 0x77, 0x25, 0x90, 0xcb, 0xda, 0xc8, 0xb0, 0x17, - 0xd9, 0xbc, 0x59, 0x28, 0x0e, 0x55, 0xc3, 0xbe, 0x02, 0x97, 0x72, 0x19, 0xd8, 0xdf, 0x1e, 0x93, - 0xcd, 0xd0, 0x83, 0xff, 0x0e, 0x94, 0x7b, 0x3c, 0xb3, 0xd9, 0xfa, 0x94, 0xd7, 0xbc, 0x78, 0x5f, - 0x89, 0xd4, 0x67, 0xc1, 0x89, 0xac, 0x40, 0x2d, 0x64, 0x32, 0x64, 0xde, 0xb9, 0x98, 0x8a, 0x76, - 0x72, 0x89, 0x5c, 0xa3, 0x1e, 0xa5, 0xff, 0xa2, 0x59, 0x8c, 0x7c, 0x04, 0x93, 0x3b, 0xe2, 0xe6, - 0x9a, 0xd4, 0x50, 0x0b, 0x58, 0xb2, 0xf2, 0x2a, 0x1c, 0x3f, 0x89, 0xd5, 0xbd, 0xb8, 0x47, 0xc9, - 0x4f, 0x54, 0x12, 0xc9, 0x21, 0x54, 0x1c, 0x35, 0xa6, 0xe3, 0x45, 0xa5, 0x06, 0xa4, 0xe6, 0x8f, - 0xd0, 0x8f, 0xf4, 0x18, 0x6a, 0x71, 0xf6, 0x77, 0x2c, 0x80, 0xe4, 0xe2, 0x3a, 0x79, 0x08, 0x95, - 0xe8, 0x66, 0xca, 0x60, 0x29, 0x22, 0x09, 0x54, 0x72, 0x34, 0x92, 0xca, 0x24, 0x04, 0xb5, 0xb4, - 0x27, 0x59, 0x2b, 0xdf, 0x2c, 0x83, 0x2e, 0x75, 0x46, 0xc6, 0xca, 0xab, 0x4c, 0xf1, 0xec, 0x24, - 0x17, 0x05, 0x35, 0x1d, 0x72, 0x28, 0x4a, 0x2c, 0x53, 0x3e, 0x55, 0x46, 0x8b, 0xdc, 0x89, 0x78, - 0xe7, 0xaa, 0xe4, 0x17, 0xd4, 0xd8, 0x3c, 0xf3, 0xa7, 0xfc, 0x4c, 0xcc, 0x9f, 0x89, 0xe2, 0xcd, - 0x9f, 0xeb, 0x30, 0x19, 0xfa, 0x3d, 0xba, 0x84, 0x1b, 0xd2, 0xe5, 0xaa, 0xcd, 0x62, 0x14, 0x60, - 0x54, 0x78, 0xf2, 0x26, 0xd4, 0x06, 0x11, 0x6d, 0xae, 0xdc, 0x5d, 0x0e, 0x69, 0x3b, 0x92, 0x49, - 0x42, 0xda, 0xf5, 0x7d, 0x3f, 0x41, 0xa1, 0x49, 0x47, 0x7e, 0xcb, 0x7a, 0x8c, 0x85, 0x55, 0x2d, - 0x6a, 0xab, 0xcb, 0xbd, 0x2c, 0xd6, 0xb8, 0xfa, 0x29, 0xcd, 0xb6, 0xaf, 0x5b, 0x70, 0xae, 0xd9, - 0x0a, 0xdd, 0x20, 0xd6, 0x87, 0xe8, 0x06, 0xbf, 0x34, 0x1a, 0x3b, 0x6c, 0x2f, 0x93, 0x6b, 0xe8, - 0xc5, 0x11, 0x79, 0x1b, 0x82, 0x28, 0x75, 0xb5, 0x5c, 0x80, 0x30, 0x61, 0xc1, 0xa6, 0xa5, 0xcc, - 0xa5, 0xcd, 0x4c, 0xdf, 0x74, 0xf6, 0xab, 0xfd, 0x01, 0xcc, 0x36, 0x69, 0xdf, 0x09, 0xba, 0x3c, - 0xc7, 0x4a, 0x04, 0x53, 0x16, 0xa1, 0x1a, 0x29, 0x58, 0xf6, 0x1e, 0xbb, 0x26, 0xc6, 0x84, 0x86, - 0xbc, 0x22, 0x02, 0x3f, 0x2a, 0x01, 0xa3, 0x2a, 0xd4, 0x0d, 0x11, 0x2d, 0x8a, 0x50, 0xe1, 0xec, - 0x03, 0x98, 0x4a, 0x8a, 0xd3, 0x5d, 0xd2, 0x81, 0x99, 0x96, 0x91, 0x86, 0x92, 0x5c, 0x57, 0x3f, - 0x79, 0xc6, 0x0a, 0x9f, 0x85, 0xcb, 0x69, 0x26, 0x98, 0xe5, 0x6a, 0xff, 0x72, 0x09, 0x66, 0xb4, - 0x64, 0xe9, 0xb0, 0xf9, 0x24, 0x1b, 0xac, 0xc2, 0x22, 0xf2, 0xd6, 0xd3, 0x3d, 0xf9, 0x98, 0x80, - 0xd5, 0x27, 0xd9, 0x80, 0xd5, 0x99, 0x8a, 0x1f, 0xf2, 0x41, 0x7d, 0xa7, 0x04, 0x15, 0x9d, 0x45, - 0xff, 0x0e, 0x94, 0xb9, 0x46, 0xf8, 0x74, 0xc7, 0x2b, 0xd7, 0x2e, 0x51, 0x70, 0x62, 0x2c, 0x79, - 0x1c, 0xe2, 0x53, 0x5f, 0xcc, 0xae, 0x0a, 0x63, 0xd8, 0x09, 0x63, 0x14, 0x9c, 0xc8, 0x5d, 0x18, - 0xa3, 0x5e, 0x5b, 0x9e, 0xb3, 0xa7, 0x67, 0xc8, 0xdf, 0x93, 0xb8, 0xe5, 0xb5, 0x91, 0x71, 0xe1, - 0xf7, 0x4a, 0x79, 0xaa, 0xb5, 0xb4, 0x39, 0x92, 0x7b, 0xa5, 0x1c, 0x8a, 0x12, 0x6b, 0xff, 0xe2, - 0x18, 0x4c, 0x34, 0x07, 0x3b, 0x4c, 0x63, 0xf8, 0x87, 0x16, 0x5c, 0x38, 0xc8, 0x5c, 0xda, 0x4d, - 0xa6, 0xec, 0xfd, 0xe2, 0x6f, 0x44, 0x23, 0xdd, 0x6d, 0xbc, 0x20, 0xeb, 0x75, 0x21, 0x07, 0x89, - 0x79, 0xd5, 0x49, 0x5d, 0x39, 0x1d, 0x3b, 0xa3, 0xab, 0xe0, 0xc6, 0xc5, 0x9e, 0x52, 0xf1, 0x17, - 0x7b, 0xa6, 0x47, 0x5d, 0xea, 0xb1, 0xff, 0x78, 0x1c, 0x40, 0x8c, 0xc6, 0x66, 0x10, 0x9f, 0xc4, - 0xda, 0x7d, 0x0b, 0xa6, 0xd4, 0xcb, 0x68, 0x1b, 0x49, 0xe0, 0x55, 0x3b, 0xdf, 0xd7, 0x0c, 0x1c, - 0xa6, 0x28, 0xc9, 0x0d, 0x00, 0xea, 0xc5, 0xe1, 0xa1, 0x50, 0x17, 0xc6, 0xd3, 0xee, 0x86, 0x5b, - 0x1a, 0x83, 0x06, 0x15, 0x59, 0x48, 0x79, 0xe0, 0xc4, 0x75, 0x9f, 0x73, 0x8f, 0x71, 0x98, 0x7d, - 0x0e, 0xa6, 0xf5, 0xbf, 0x55, 0xb7, 0xa7, 0x12, 0xe7, 0xb4, 0x41, 0xb4, 0x65, 0x22, 0x31, 0x4d, - 0x4b, 0x7e, 0x1a, 0xce, 0xa5, 0x53, 0xb5, 0xe5, 0x01, 0xab, 0xef, 0x17, 0xa4, 0x33, 0xbc, 0x31, - 0x43, 0xcd, 0x56, 0x40, 0x3b, 0x3c, 0xc4, 0x81, 0x27, 0x4f, 0x5a, 0xbd, 0x02, 0x56, 0x38, 0x14, - 0x25, 0x96, 0x75, 0x21, 0x2b, 0x49, 0x43, 0x01, 0xe7, 0x47, 0x6a, 0x25, 0xe9, 0xc2, 0xa6, 0x81, - 0xc3, 0x14, 0x25, 0x93, 0x20, 0x5d, 0x0d, 0x90, 0x5e, 0x63, 0x19, 0xff, 0x40, 0x00, 0xe7, 0xfc, - 0xb4, 0xa5, 0x26, 0x42, 0x95, 0x9f, 0x3d, 0xe1, 0xbc, 0x4d, 0x95, 0x15, 0xb9, 0xd0, 0x19, 0xc3, - 0x2e, 0xc3, 0x9f, 0xa9, 0x1a, 0x66, 0xb2, 0xce, 0x54, 0x3a, 0xca, 0x3e, 0x2a, 0x9f, 0xc6, 0xbe, - 0x00, 0xe7, 0x9b, 0x83, 0x20, 0xe8, 0xb9, 0xb4, 0xad, 0x5d, 0x54, 0xf6, 0xcf, 0xc0, 0x8c, 0xbc, - 0x51, 0xaa, 0xcf, 0xf2, 0x53, 0x3d, 0x62, 0x61, 0xff, 0x91, 0x05, 0x33, 0x99, 0x98, 0x02, 0xf9, - 0x28, 0x7b, 0x02, 0x17, 0xe2, 0x71, 0x34, 0x0f, 0x5f, 0xb1, 0xca, 0x72, 0x4f, 0xf3, 0xae, 0xca, - 0x11, 0x29, 0x2c, 0xd5, 0x8a, 0x67, 0x52, 0x88, 0x2d, 0xdd, 0x4c, 0x34, 0xb1, 0x7f, 0xa1, 0x04, - 0xf9, 0x81, 0x1c, 0xf2, 0xd5, 0xe1, 0x0e, 0x78, 0xa7, 0xc0, 0x0e, 0x90, 0x91, 0xa4, 0xd1, 0x7d, - 0xe0, 0xa5, 0xfb, 0x60, 0xbd, 0xa0, 0x3e, 0x90, 0x72, 0x87, 0x7b, 0xe2, 0xff, 0x5a, 0x50, 0xdb, - 0xde, 0xbe, 0xa7, 0x2d, 0x5e, 0x84, 0xcb, 0x91, 0xb8, 0x47, 0xbc, 0xb4, 0x1b, 0xd3, 0x70, 0xd9, - 0xef, 0x07, 0x3d, 0xaa, 0x27, 0x94, 0xbc, 0xdc, 0xdb, 0xcc, 0xa5, 0xc0, 0x11, 0x25, 0xc9, 0x1d, - 0xb8, 0x60, 0x62, 0xa4, 0xdf, 0x82, 0xb7, 0xb0, 0x2c, 0x53, 0xfb, 0x87, 0xd1, 0x98, 0x57, 0x26, - 0xcb, 0x4a, 0x3a, 0x2f, 0xe4, 0x9b, 0x7b, 0x43, 0xac, 0x24, 0x1a, 0xf3, 0xca, 0xd8, 0x9b, 0x50, - 0x33, 0x5e, 0x80, 0x24, 0x9f, 0x87, 0xd9, 0x96, 0xdf, 0x0f, 0x42, 0x1a, 0x45, 0xae, 0xef, 0xdd, - 0xa3, 0xfb, 0xb4, 0x27, 0x9b, 0xcc, 0xfd, 0x0a, 0xcb, 0x19, 0x1c, 0x0e, 0x51, 0xdb, 0x7f, 0xf0, - 0x02, 0xe8, 0xeb, 0xa8, 0x27, 0x38, 0x22, 0x02, 0x1d, 0xe2, 0x2e, 0x17, 0x1c, 0xe2, 0xd6, 0xfb, - 0x5d, 0x26, 0xcc, 0x1d, 0x27, 0x61, 0xee, 0x89, 0xa2, 0xc3, 0xdc, 0x5a, 0xe3, 0x1b, 0x0a, 0x75, - 0xff, 0xaa, 0x05, 0x53, 0x9e, 0xdf, 0xa6, 0xda, 0x2f, 0x3d, 0xc9, 0xd5, 0xce, 0xf7, 0x8b, 0xcb, - 0xdd, 0x11, 0x21, 0x5b, 0xc9, 0x5e, 0x24, 0x42, 0xe8, 0x63, 0xc2, 0x44, 0x61, 0xaa, 0x1e, 0x64, - 0xd5, 0x70, 0x63, 0x88, 0x1b, 0xa4, 0x57, 0xf3, 0xd4, 0xff, 0x27, 0xf9, 0x24, 0xc8, 0x43, 0x43, - 0xf1, 0xa9, 0x16, 0xe5, 0x84, 0x50, 0xf9, 0x8e, 0x86, 0xb7, 0x51, 0xdd, 0x4f, 0x4f, 0x14, 0x22, - 0x1b, 0x26, 0x44, 0xc6, 0x84, 0x7c, 0x8b, 0x90, 0x3b, 0xc1, 0x45, 0x36, 0x05, 0x4a, 0x0c, 0x89, - 0x55, 0xfc, 0xa8, 0xc6, 0xbb, 0x7d, 0xb3, 0x98, 0xc0, 0x9c, 0x8e, 0x4f, 0xe5, 0x07, 0x90, 0xc8, - 0xdb, 0xa6, 0x55, 0x39, 0x75, 0x12, 0xab, 0x72, 0x7a, 0xa4, 0x45, 0x19, 0xc3, 0x44, 0xc4, 0x6d, - 0x56, 0x9e, 0x33, 0x52, 0xbb, 0xb1, 0x55, 0xc0, 0x7e, 0x9c, 0xb2, 0x81, 0x45, 0xbf, 0x09, 0x18, - 0x4a, 0x59, 0xe4, 0x63, 0xa8, 0xa8, 0x2c, 0x17, 0x99, 0x83, 0x82, 0x45, 0x38, 0xb9, 0xd2, 0x2e, - 0x6c, 0x75, 0x39, 0x4d, 0x40, 0x51, 0x4b, 0x24, 0x5d, 0x18, 0x6b, 0x3b, 0x1d, 0x99, 0x8d, 0xb2, - 0x5e, 0xcc, 0x95, 0x59, 0x25, 0x93, 0x1b, 0x24, 0x2b, 0x4b, 0x6b, 0xc8, 0x44, 0x90, 0x87, 0xc9, - 0x7b, 0x15, 0xb3, 0x85, 0x1d, 0x77, 0x69, 0xbd, 0x44, 0x58, 0xe5, 0x43, 0xcf, 0x5f, 0xb4, 0xa5, - 0xd7, 0xff, 0x4f, 0x71, 0xb1, 0xab, 0xc5, 0xdc, 0xb9, 0x15, 0xcf, 0x1f, 0x26, 0x91, 0x03, 0x72, - 0x0b, 0x26, 0xf7, 0xfd, 0xde, 0xa0, 0x2f, 0x33, 0x67, 0x6a, 0x37, 0xe6, 0xf2, 0xe6, 0xe1, 0x03, - 0x4e, 0x92, 0xec, 0x62, 0xe2, 0x7f, 0x84, 0xaa, 0x2c, 0xf9, 0x65, 0x0b, 0xce, 0xb1, 0xe5, 0xae, - 0x67, 0x68, 0x54, 0x27, 0x45, 0x2d, 0xa8, 0xfb, 0x11, 0x3b, 0x2e, 0xd5, 0x42, 0xd0, 0x7a, 0xf4, - 0x9d, 0x94, 0x38, 0xcc, 0x88, 0x27, 0x9f, 0x40, 0x25, 0x72, 0xdb, 0xb4, 0xe5, 0x84, 0x51, 0xfd, - 0xc2, 0xd9, 0x54, 0x25, 0x71, 0x80, 0x4a, 0x41, 0xa8, 0x45, 0x92, 0xbf, 0xc3, 0x5f, 0xab, 0x93, - 0xaf, 0x93, 0xca, 0xd7, 0x6a, 0x2f, 0x9e, 0xd9, 0x6b, 0xb5, 0xc2, 0xb5, 0x98, 0x16, 0x87, 0x59, - 0xf9, 0xe4, 0xaf, 0x58, 0x70, 0x49, 0x3c, 0xa9, 0x91, 0x7d, 0x4f, 0xe5, 0xd2, 0xa7, 0x34, 0xde, - 0x79, 0xca, 0xcf, 0x52, 0x1e, 0x4b, 0xcc, 0x97, 0xc4, 0xef, 0x4b, 0x87, 0x66, 0x10, 0x81, 0x27, - 0x5e, 0x15, 0xe7, 0x22, 0xd7, 0x8f, 0xdf, 0xf2, 0x18, 0x6d, 0x0a, 0x84, 0x69, 0xc1, 0xe4, 0x0d, - 0xa8, 0x05, 0x72, 0xaf, 0x76, 0xa3, 0x3e, 0x4f, 0xe0, 0x1a, 0x13, 0x49, 0xae, 0x5b, 0x09, 0x18, - 0x4d, 0x1a, 0x72, 0x1f, 0x6a, 0xb1, 0xdf, 0xa3, 0xa1, 0x34, 0x50, 0xea, 0x7c, 0x5e, 0x5d, 0xcb, - 0x5b, 0x31, 0xdb, 0x9a, 0x2c, 0x31, 0x60, 0x12, 0x58, 0x84, 0x26, 0x1f, 0x66, 0x70, 0xaa, 0xe7, - 0x77, 0x42, 0x6e, 0x0f, 0x3f, 0x9f, 0x36, 0x38, 0x9b, 0x26, 0x12, 0xd3, 0xb4, 0x64, 0x0d, 0xce, - 0x07, 0xa1, 0xeb, 0x87, 0x6e, 0x7c, 0xb8, 0xdc, 0x73, 0xa2, 0x88, 0x33, 0x10, 0x89, 0x99, 0x3a, - 0xa6, 0xb6, 0x95, 0x25, 0xc0, 0xe1, 0x32, 0xe4, 0x35, 0xa8, 0x28, 0x60, 0xfd, 0x05, 0xae, 0xda, - 0x4d, 0x89, 0xa4, 0x4e, 0x01, 0x43, 0x8d, 0x1d, 0x71, 0x41, 0xfc, 0xea, 0xa7, 0xb9, 0x20, 0x4e, - 0xda, 0x70, 0xd5, 0x19, 0xc4, 0x3e, 0xbf, 0xdd, 0x94, 0x2e, 0xb2, 0xed, 0xef, 0x51, 0xaf, 0xfe, - 0x92, 0x48, 0xc6, 0x39, 0x3e, 0x9a, 0xbf, 0xba, 0xf4, 0x18, 0x3a, 0x7c, 0x2c, 0x17, 0xf2, 0x15, - 0xa8, 0x50, 0x79, 0xc9, 0xbd, 0xfe, 0x13, 0x45, 0x1d, 0x93, 0xe9, 0x6b, 0xf3, 0x2a, 0x69, 0x45, - 0xc0, 0x50, 0xcb, 0x23, 0xdb, 0x50, 0xeb, 0xfa, 0x51, 0xbc, 0xd4, 0x73, 0x9d, 0x88, 0x46, 0xf5, - 0x17, 0xf9, 0xa4, 0xc9, 0x3d, 0xee, 0x6f, 0x2b, 0xb2, 0x64, 0xce, 0xdc, 0x4e, 0x4a, 0xa2, 0xc9, - 0x86, 0x50, 0x1e, 0x27, 0x18, 0xf0, 0x21, 0xf4, 0xbd, 0x98, 0x3e, 0x8c, 0xeb, 0xd7, 0x78, 0xc3, - 0x5e, 0xcd, 0xe3, 0xbc, 0xe5, 0xb7, 0x9b, 0x69, 0x6a, 0x1d, 0x28, 0x30, 0x81, 0x98, 0xe5, 0x49, - 0xde, 0x82, 0xa9, 0xc0, 0x6f, 0x37, 0x03, 0xda, 0xda, 0x72, 0xe2, 0x56, 0xb7, 0x3e, 0x9f, 0xf6, - 0xd4, 0x6c, 0x19, 0x38, 0x4c, 0x51, 0x92, 0x00, 0x26, 0xfb, 0xe2, 0x5a, 0x46, 0xfd, 0xe5, 0xa2, - 0xd4, 0x69, 0x79, 0xcf, 0x43, 0x9c, 0x98, 0xf2, 0x0f, 0x2a, 0x31, 0xe4, 0x1f, 0x58, 0x30, 0x93, - 0x49, 0x34, 0xac, 0xff, 0x64, 0x61, 0x87, 0x76, 0x9a, 0x71, 0xe3, 0x55, 0xde, 0x7d, 0x69, 0xe0, - 0xa3, 0x61, 0x10, 0x66, 0x6b, 0x24, 0xfa, 0x85, 0xdf, 0xad, 0xaa, 0xbf, 0x52, 0x5c, 0xbf, 0x70, - 0x86, 0xaa, 0x5f, 0xf8, 0x1f, 0x54, 0x62, 0xc8, 0x75, 0x98, 0x8c, 0xdd, 0x3e, 0xf5, 0x07, 0x71, - 0xfd, 0xd5, 0x74, 0xb0, 0x67, 0x5b, 0x80, 0x51, 0xe1, 0xe7, 0x7e, 0x06, 0xce, 0x0f, 0x59, 0x0b, - 0xa7, 0xba, 0xe0, 0xf3, 0x6b, 0xcc, 0x60, 0x36, 0xdc, 0x9e, 0x45, 0xbf, 0x5e, 0xf4, 0x16, 0x4c, - 0xb5, 0xc4, 0x43, 0x8d, 0xe2, 0x96, 0xc1, 0x78, 0xda, 0xed, 0xb5, 0x6c, 0xe0, 0x30, 0x45, 0x69, - 0xdf, 0x06, 0x32, 0xfc, 0xec, 0x07, 0xf7, 0x27, 0x3e, 0x54, 0x86, 0xaa, 0xac, 0x65, 0xe2, 0x4f, - 0xd4, 0x18, 0x34, 0xa8, 0xec, 0x7f, 0x6c, 0xc1, 0x74, 0x4a, 0x13, 0x28, 0x3c, 0x4a, 0xb4, 0x0a, - 0xa4, 0xef, 0x86, 0xa1, 0x1f, 0x0a, 0x45, 0x6b, 0x9d, 0x6d, 0x64, 0x91, 0x7c, 0xb0, 0x81, 0x5f, - 0x06, 0x5e, 0x1f, 0xc2, 0x62, 0x4e, 0x09, 0xfb, 0x57, 0xc6, 0x20, 0xc9, 0xda, 0xd2, 0xf7, 0xe1, - 0xad, 0x91, 0xf7, 0xe1, 0x5f, 0x87, 0xca, 0x07, 0x91, 0xef, 0x6d, 0x25, 0xb7, 0xe6, 0xf5, 0x58, - 0xbc, 0xdd, 0xdc, 0xdc, 0xe0, 0x94, 0x9a, 0x82, 0x53, 0x7f, 0xb8, 0xea, 0xf6, 0xe2, 0xe1, 0xdb, - 0xe4, 0x6f, 0xbf, 0x23, 0xe0, 0xa8, 0x29, 0xf8, 0xbb, 0x92, 0xfb, 0x54, 0xfb, 0x43, 0x93, 0x77, - 0x25, 0x19, 0x10, 0x05, 0x8e, 0x2c, 0x42, 0x55, 0xbb, 0x53, 0xa5, 0x77, 0x57, 0xf7, 0x94, 0x76, - 0xbb, 0x62, 0x42, 0xc3, 0xd5, 0x3c, 0xe9, 0xfb, 0x93, 0x56, 0x7b, 0xb3, 0x08, 0x05, 0x3d, 0xe3, - 0x4d, 0x14, 0x7b, 0xbb, 0x02, 0xa3, 0x16, 0x69, 0x66, 0xf6, 0x95, 0x4f, 0x98, 0xd9, 0x67, 0xff, - 0xf5, 0x31, 0x98, 0x7c, 0x40, 0x43, 0xfe, 0x0a, 0xc6, 0x75, 0x98, 0xdc, 0x17, 0x3f, 0xb3, 0xe9, - 0xc9, 0x92, 0x02, 0x15, 0x9e, 0x75, 0xcd, 0xce, 0xc0, 0xed, 0xb5, 0x57, 0x92, 0x85, 0xa2, 0xbb, - 0xa6, 0xa1, 0x10, 0x98, 0xd0, 0xb0, 0x02, 0x1d, 0xa6, 0x12, 0xf7, 0xfb, 0x6e, 0x9c, 0xbd, 0xf6, - 0xb9, 0xa6, 0x10, 0x98, 0xd0, 0x90, 0x57, 0x61, 0xa2, 0xe3, 0xc6, 0xdb, 0x4e, 0x27, 0x1b, 0x7c, - 0x59, 0xe3, 0x50, 0x94, 0x58, 0xee, 0xbd, 0x77, 0xe3, 0xed, 0x90, 0x72, 0x7f, 0xdd, 0xd0, 0x3d, - 0xa5, 0x35, 0x03, 0x87, 0x29, 0x4a, 0x5e, 0x25, 0x5f, 0xb6, 0x4c, 0x7a, 0xd5, 0x93, 0x2a, 0x29, - 0x04, 0x26, 0x34, 0x6c, 0x8a, 0xb5, 0xfc, 0x7e, 0xe0, 0xf6, 0x64, 0xf2, 0x95, 0x31, 0xc5, 0x96, - 0x25, 0x1c, 0x35, 0x05, 0xa3, 0x66, 0xbb, 0x04, 0x5b, 0xe1, 0xd9, 0x67, 0xf2, 0xb6, 0x24, 0x1c, - 0x35, 0x85, 0xfd, 0x00, 0xa6, 0xc5, 0x62, 0x59, 0xee, 0x39, 0x6e, 0x7f, 0x6d, 0x99, 0xdc, 0x1a, - 0xca, 0x30, 0xbc, 0x9e, 0x93, 0x61, 0x78, 0x29, 0x55, 0x68, 0x38, 0xd3, 0xd0, 0xfe, 0x5e, 0x09, - 0x2a, 0xcf, 0xf0, 0xa5, 0xd1, 0x20, 0xf5, 0xd2, 0x68, 0xd1, 0xef, 0x4d, 0xe6, 0xbd, 0x32, 0xfa, - 0x30, 0xf3, 0xca, 0xe8, 0x56, 0x91, 0x49, 0xb7, 0x8f, 0x7d, 0x61, 0xf4, 0x07, 0x16, 0x5c, 0x54, - 0xa4, 0x7c, 0xdf, 0x68, 0xb8, 0x1e, 0x0f, 0xdb, 0x9e, 0x7d, 0x37, 0x7f, 0x9c, 0xea, 0xe6, 0xf7, - 0x8a, 0x6b, 0xb2, 0xd9, 0x8e, 0x91, 0x8f, 0x2d, 0xff, 0xa1, 0x05, 0xf5, 0xbc, 0x02, 0xcf, 0xe0, - 0x89, 0xd5, 0x8f, 0xd2, 0x4f, 0xac, 0x3e, 0x38, 0x9b, 0x96, 0x8f, 0x78, 0x6a, 0xf5, 0x07, 0x23, - 0xda, 0xcd, 0xdf, 0x35, 0xed, 0xa9, 0x13, 0xc5, 0x2a, 0x2a, 0x20, 0x22, 0x44, 0xe4, 0x1f, 0x4d, - 0x3d, 0x98, 0x88, 0x78, 0x8c, 0x53, 0x4e, 0x81, 0xdb, 0x45, 0x9c, 0x33, 0x8c, 0x9f, 0xf4, 0xaf, - 0xf1, 0xdf, 0x28, 0x65, 0xd8, 0xff, 0xc5, 0x82, 0xa9, 0x67, 0xf8, 0x8e, 0xae, 0x9f, 0x1e, 0xe4, - 0xb7, 0x8b, 0x1b, 0xe4, 0x11, 0x03, 0xfb, 0x9f, 0xae, 0x42, 0xea, 0xc9, 0x5a, 0xf2, 0x11, 0x54, - 0x95, 0x92, 0xa7, 0x92, 0xf9, 0xdf, 0x2e, 0xce, 0x07, 0x9e, 0x1c, 0x33, 0x0a, 0x12, 0x61, 0x22, - 0x2f, 0x13, 0x55, 0x2e, 0x9d, 0x28, 0xaa, 0xfc, 0xc3, 0x7d, 0x47, 0x33, 0xdf, 0x04, 0x1f, 0x3f, - 0x13, 0x13, 0xfc, 0x6a, 0xe1, 0x26, 0xf8, 0x8b, 0xcf, 0xd8, 0x04, 0x37, 0xbc, 0x9c, 0xe5, 0xa7, - 0xf0, 0x72, 0x7e, 0x04, 0x17, 0xf7, 0x93, 0xc3, 0x5f, 0xcf, 0x24, 0xf9, 0x1c, 0xe8, 0xf5, 0x5c, - 0xc3, 0x9b, 0x29, 0x32, 0x51, 0x4c, 0xbd, 0xd8, 0x50, 0x1b, 0xf4, 0x8d, 0xd9, 0x8b, 0x0f, 0x72, - 0xd8, 0x61, 0xae, 0x90, 0xac, 0xbb, 0x6a, 0xf2, 0x04, 0xee, 0xaa, 0x7f, 0x32, 0xf2, 0xf3, 0x23, - 0x95, 0xb3, 0xfd, 0xfc, 0xc8, 0xf3, 0xa7, 0xfe, 0xf4, 0xc8, 0x2b, 0x89, 0x9f, 0x5d, 0x64, 0x32, - 0xe4, 0x3b, 0xc5, 0x7f, 0x23, 0x1b, 0x2d, 0x03, 0xde, 0xf5, 0x5f, 0x2e, 0x56, 0xeb, 0x29, 0x20, - 0x62, 0x56, 0x7b, 0x8a, 0x88, 0x59, 0xc6, 0xcb, 0x38, 0x55, 0x90, 0x97, 0xd1, 0x83, 0x59, 0xb7, - 0xef, 0x74, 0xe8, 0xd6, 0xa0, 0xd7, 0x13, 0x69, 0xa0, 0x51, 0x7d, 0x9a, 0xf3, 0xce, 0xcd, 0xeb, - 0xbb, 0xe7, 0xb7, 0x9c, 0x5e, 0xf6, 0x89, 0x66, 0x9d, 0x17, 0x7f, 0x27, 0xc3, 0x09, 0x87, 0x78, - 0xb3, 0x09, 0xcb, 0xef, 0xcd, 0xd2, 0x98, 0xf5, 0x36, 0x8f, 0x12, 0xc9, 0x6f, 0x78, 0xdd, 0x4e, - 0xc0, 0x68, 0xd2, 0x90, 0xbb, 0x50, 0x6d, 0x7b, 0x91, 0xcc, 0xfd, 0x9e, 0xe1, 0x9b, 0xd9, 0x67, - 0xd8, 0x16, 0xb8, 0xb2, 0xd1, 0xd4, 0x59, 0xdf, 0x57, 0x73, 0xae, 0x64, 0x6b, 0x3c, 0x26, 0xe5, - 0xc9, 0x3a, 0x67, 0x26, 0xdf, 0x68, 0x13, 0xc1, 0x9b, 0x97, 0x46, 0xf8, 0xc6, 0x56, 0x36, 0xd4, - 0x9b, 0x72, 0xd3, 0x52, 0x9c, 0x7c, 0x6c, 0x2d, 0xe1, 0x60, 0xbc, 0x19, 0x7b, 0xfe, 0xb1, 0x6f, - 0xc6, 0xf2, 0xb7, 0x18, 0xe2, 0x9e, 0xf6, 0x6f, 0x5f, 0x2b, 0xec, 0x2d, 0x86, 0x24, 0x0f, 0x41, - 0xbe, 0xc5, 0x90, 0x00, 0xd0, 0x14, 0x49, 0x36, 0x47, 0xf9, 0xf9, 0x2f, 0xf0, 0x4d, 0xe3, 0xf4, - 0x5e, 0x7b, 0xd3, 0x35, 0x7c, 0xf1, 0xb1, 0xae, 0xe1, 0x21, 0x57, 0xf6, 0xa5, 0x53, 0xb8, 0xb2, - 0xbb, 0xfc, 0x96, 0xfc, 0xda, 0xb2, 0x8c, 0x09, 0x14, 0xa0, 0xd0, 0xf1, 0xdb, 0x60, 0x22, 0xaf, - 0x83, 0xff, 0x44, 0x21, 0x80, 0x6c, 0xc1, 0xc5, 0xc0, 0x6f, 0x0f, 0xb9, 0xc5, 0x79, 0x10, 0x20, - 0x79, 0xd0, 0xe0, 0xe2, 0x56, 0x0e, 0x0d, 0xe6, 0x96, 0xe4, 0xdb, 0x73, 0x02, 0xe7, 0xcf, 0x2d, - 0x94, 0xe5, 0xf6, 0x9c, 0x80, 0xd1, 0xa4, 0xc9, 0x3a, 0x86, 0x9f, 0x3f, 0x33, 0xc7, 0xf0, 0xdc, - 0x33, 0x70, 0x0c, 0xbf, 0x70, 0x62, 0xc7, 0xf0, 0x27, 0x70, 0x21, 0xf0, 0xdb, 0x2b, 0x6e, 0x14, - 0x0e, 0x78, 0xbe, 0x76, 0x63, 0xd0, 0xee, 0xd0, 0x98, 0x7b, 0x96, 0x6b, 0x37, 0x6e, 0x98, 0x95, - 0x14, 0x1f, 0x88, 0x5d, 0x90, 0x1f, 0x88, 0xe5, 0x0b, 0x35, 0x53, 0x8a, 0x1b, 0x4c, 0x3c, 0xb1, - 0x25, 0x07, 0x89, 0x79, 0x72, 0x4c, 0xbf, 0xf4, 0x4b, 0xcf, 0xc6, 0x2f, 0xfd, 0x79, 0xa8, 0x44, - 0xdd, 0x41, 0xdc, 0xf6, 0x0f, 0x3c, 0x1e, 0x7c, 0xa8, 0xea, 0xaf, 0x38, 0x54, 0x9a, 0x12, 0xfe, - 0xe8, 0x68, 0x7e, 0x56, 0xfd, 0x36, 0x5c, 0x0a, 0x12, 0x42, 0xbe, 0x3d, 0x22, 0xc7, 0xd5, 0x3e, - 0xcb, 0x1c, 0xd7, 0x2b, 0xa7, 0xca, 0x6f, 0xcd, 0x73, 0xbe, 0xbf, 0xfc, 0x23, 0xe7, 0x7c, 0xff, - 0x75, 0x0b, 0xa6, 0xf7, 0x4d, 0xff, 0x8d, 0x0c, 0x10, 0x14, 0x10, 0x7e, 0x4c, 0xb9, 0x85, 0x1a, - 0x36, 0xdb, 0xec, 0x52, 0xa0, 0x47, 0x59, 0x00, 0xa6, 0x6b, 0x92, 0x13, 0x1a, 0x7d, 0xe5, 0x87, - 0x15, 0x1a, 0xfd, 0x84, 0x6f, 0x66, 0x2a, 0xa5, 0x86, 0x47, 0x0d, 0x8a, 0x4d, 0xdb, 0x51, 0x1b, - 0xa3, 0xce, 0xda, 0x31, 0xe5, 0x3d, 0x7d, 0x14, 0xe2, 0xf7, 0x08, 0x9c, 0xcb, 0x7c, 0x91, 0xe2, - 0xb3, 0xea, 0x89, 0x21, 0xe1, 0xd9, 0xbb, 0x96, 0x7d, 0x62, 0x68, 0x5a, 0xd1, 0xa7, 0x9e, 0x19, - 0x4a, 0xbd, 0x03, 0x54, 0x3a, 0xd3, 0x77, 0x80, 0xc6, 0x9e, 0xcd, 0x3b, 0x40, 0xb3, 0x67, 0xf1, - 0x0e, 0xd0, 0xf9, 0x53, 0xbd, 0x03, 0x64, 0xbc, 0xc3, 0x34, 0xfe, 0x84, 0x77, 0x98, 0x96, 0x60, - 0x46, 0x25, 0x12, 0x52, 0xf9, 0xc0, 0x8b, 0xf0, 0x36, 0xeb, 0x0f, 0xf4, 0x2d, 0xa7, 0xd1, 0x98, - 0xa5, 0x27, 0xdf, 0xb0, 0xa0, 0xec, 0xf1, 0x92, 0x13, 0x45, 0x3d, 0xfe, 0x97, 0x9e, 0x5a, 0xdc, - 0x5a, 0x90, 0x4f, 0xee, 0xa9, 0xec, 0x94, 0x32, 0x87, 0x3d, 0x52, 0x3f, 0x50, 0xd4, 0x80, 0xbc, - 0x0f, 0x75, 0x7f, 0x77, 0xb7, 0xe7, 0x3b, 0xed, 0xe4, 0xb1, 0x22, 0xe5, 0x0e, 0x17, 0xc9, 0xd8, - 0xfa, 0xd5, 0x89, 0xcd, 0x11, 0x74, 0x38, 0x92, 0x03, 0x33, 0xf7, 0x66, 0xa2, 0xd8, 0x0f, 0x69, - 0x3b, 0x31, 0x4d, 0xab, 0xbc, 0xcd, 0xb4, 0xf0, 0x36, 0x37, 0xd3, 0x72, 0x44, 0xeb, 0xf5, 0xa0, - 0x64, 0xb0, 0x98, 0xad, 0x16, 0x09, 0xe1, 0x72, 0x90, 0x67, 0x19, 0x47, 0x32, 0xfd, 0xf1, 0x71, - 0xf6, 0xb9, 0x5a, 0xba, 0x97, 0x73, 0x6d, 0xeb, 0x08, 0x47, 0x70, 0x36, 0x9f, 0x31, 0xaa, 0x3c, - 0x9b, 0x67, 0x8c, 0xd2, 0xdf, 0x91, 0x99, 0x7e, 0xe6, 0xdf, 0x91, 0x21, 0x7f, 0x9c, 0xfb, 0xe2, - 0x96, 0x30, 0x28, 0x3b, 0x85, 0xcf, 0x89, 0x1f, 0xb9, 0x57, 0xb7, 0xfe, 0x91, 0x05, 0x73, 0x62, - 0xe6, 0xe5, 0x7d, 0xd5, 0x50, 0xe6, 0x2d, 0x16, 0x1d, 0x31, 0xe1, 0xf1, 0xd9, 0x66, 0x4a, 0x2a, - 0x77, 0xe4, 0x3f, 0xa6, 0x26, 0xe4, 0x57, 0x73, 0x94, 0xa7, 0x99, 0xa2, 0x5c, 0x34, 0xf9, 0xaf, - 0x35, 0x5d, 0x38, 0x3e, 0x89, 0xbe, 0xf4, 0xcf, 0x47, 0x7a, 0x90, 0x08, 0xaf, 0xde, 0x5f, 0x3a, - 0x23, 0x0f, 0x92, 0xf9, 0xa4, 0xd4, 0x69, 0xfc, 0x48, 0x73, 0x3f, 0x6f, 0x89, 0x57, 0x1f, 0x47, - 0xbe, 0x4d, 0xba, 0x63, 0x2a, 0x0d, 0x85, 0xbc, 0x0e, 0x9a, 0x6c, 0xc4, 0xe6, 0x23, 0xa9, 0x7f, - 0xcb, 0x82, 0x8b, 0x79, 0x9b, 0x64, 0x4e, 0x95, 0xbe, 0x9c, 0xae, 0x52, 0x81, 0x6e, 0x6f, 0xb3, - 0x42, 0xc5, 0x3c, 0xb6, 0xf5, 0x1f, 0x26, 0x0c, 0xbf, 0x7d, 0x4c, 0x83, 0x3f, 0xf9, 0x3c, 0x55, - 0xd1, 0x0f, 0x69, 0xa6, 0x3e, 0x34, 0x55, 0xfe, 0x61, 0x7d, 0x68, 0x6a, 0xe2, 0xd3, 0x7c, 0x68, - 0x6a, 0xf2, 0x87, 0xf6, 0xa1, 0xa9, 0xca, 0x09, 0x3f, 0x34, 0x55, 0xfd, 0xd1, 0xfc, 0xd0, 0x94, - 0xfd, 0x7f, 0x2c, 0x98, 0xfd, 0xb1, 0xfa, 0x7a, 0xf0, 0xff, 0x36, 0x22, 0xf9, 0xcf, 0xf0, 0xb3, - 0xc1, 0x07, 0xe9, 0x38, 0x27, 0x16, 0xdf, 0xe2, 0x11, 0xf1, 0xce, 0x0f, 0x21, 0xcf, 0x95, 0x72, - 0xb2, 0xab, 0xb2, 0xa9, 0x84, 0xb7, 0xd2, 0x89, 0x13, 0xde, 0x7e, 0xa9, 0x34, 0xdc, 0xc5, 0x5c, - 0xdb, 0xf8, 0xfa, 0xb3, 0xf9, 0x54, 0xe9, 0xc5, 0xbc, 0x4f, 0x95, 0x66, 0x3e, 0x4d, 0x9a, 0xfd, - 0x54, 0x65, 0xe9, 0x0c, 0x3f, 0x55, 0x39, 0x0d, 0xb5, 0xf7, 0xdc, 0x40, 0x7b, 0x41, 0x16, 0xbe, - 0xfb, 0xfd, 0x6b, 0xcf, 0xfd, 0xce, 0xf7, 0xaf, 0x3d, 0xf7, 0xbd, 0xef, 0x5f, 0x7b, 0xee, 0x6b, - 0xc7, 0xd7, 0xac, 0xef, 0x1e, 0x5f, 0xb3, 0x7e, 0xe7, 0xf8, 0x9a, 0xf5, 0xbd, 0xe3, 0x6b, 0xd6, - 0x7f, 0x3d, 0xbe, 0x66, 0xfd, 0xed, 0x3f, 0xb8, 0xf6, 0xdc, 0x7b, 0x15, 0xd5, 0xb6, 0xff, 0x1f, - 0x00, 0x00, 0xff, 0xff, 0x83, 0x81, 0x8e, 0x7e, 0xa1, 0x8b, 0x00, 0x00, + 0x76, 0xd0, 0x64, 0x49, 0x25, 0x55, 0x9d, 0x92, 0x5a, 0xea, 0xdb, 0xaf, 0x1a, 0x4d, 0x4f, 0xab, + 0x9d, 0xe3, 0x19, 0xa6, 0x61, 0x56, 0xf2, 0x74, 0xef, 0xc0, 0xc0, 0x06, 0xf6, 0xaa, 0xa4, 0x96, + 0xd4, 0xa3, 0xd6, 0x63, 0x4e, 0xa9, 0x7b, 0x62, 0x67, 0x87, 0x65, 0x53, 0x55, 0x57, 0x55, 0x39, + 0xaa, 0xca, 0xac, 0xc9, 0xcc, 0xd2, 0x63, 0x67, 0x66, 0xbd, 0xd8, 0x60, 0xef, 0x62, 0x1b, 0x83, + 0x59, 0xec, 0xb5, 0xf9, 0xd9, 0x00, 0x16, 0x08, 0x70, 0x10, 0x98, 0xe0, 0xcb, 0xfc, 0xf2, 0xb1, + 0x04, 0x1f, 0x38, 0xc2, 0x10, 0xde, 0x08, 0x40, 0x66, 0xc5, 0xf3, 0x07, 0x3e, 0x88, 0xf0, 0xda, + 0xd1, 0xf8, 0x83, 0xb8, 0xcf, 0xbc, 0x99, 0x95, 0xd5, 0x2d, 0x4d, 0xa7, 0x7a, 0x36, 0x62, 0xfd, + 0x57, 0x75, 0xce, 0xb9, 0xe7, 0xdc, 0xe7, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x4d, 0xd8, 0x6a, 0xb9, + 0x51, 0xbb, 0xbf, 0x33, 0xd7, 0xf0, 0xbb, 0xf3, 0x4e, 0xd0, 0xf2, 0x7b, 0x81, 0xff, 0x3e, 0xff, + 0xf1, 0x99, 0x03, 0x3f, 0xd8, 0xdb, 0xed, 0xf8, 0x07, 0xe1, 0xfc, 0xfe, 0x9d, 0xf9, 0xde, 0x5e, + 0x6b, 0xde, 0xe9, 0xb9, 0xe1, 0xbc, 0x82, 0xce, 0xef, 0xbf, 0xee, 0x74, 0x7a, 0x6d, 0xe7, 0xf5, + 0xf9, 0x16, 0xf5, 0x68, 0xe0, 0x44, 0xb4, 0x39, 0xd7, 0x0b, 0xfc, 0xc8, 0x27, 0x9f, 0x8f, 0x39, + 0xce, 0x29, 0x8e, 0xfc, 0xc7, 0x5f, 0xd6, 0x1c, 0xe7, 0xf6, 0xef, 0xcc, 0xf5, 0xf6, 0x5a, 0x73, + 0x8c, 0xe3, 0x9c, 0x82, 0xce, 0x29, 0x8e, 0x33, 0x9f, 0x31, 0xea, 0xd4, 0xf2, 0x5b, 0xfe, 0x3c, + 0x67, 0xbc, 0xd3, 0xdf, 0xe5, 0xff, 0xf8, 0x1f, 0xfe, 0x4b, 0x08, 0x9c, 0xb1, 0xf7, 0xde, 0x0c, + 0xe7, 0x5c, 0x9f, 0xd5, 0x6f, 0xbe, 0xe1, 0x07, 0x74, 0x7e, 0x7f, 0xa0, 0x52, 0x33, 0xb7, 0x0c, + 0x9a, 0x9e, 0xdf, 0x71, 0x1b, 0x47, 0xf3, 0xfb, 0xaf, 0xef, 0xd0, 0x68, 0xb0, 0xfe, 0x33, 0x9f, + 0x8d, 0x49, 0xbb, 0x4e, 0xa3, 0xed, 0x7a, 0x34, 0x38, 0x8a, 0xdb, 0xdf, 0xa5, 0x91, 0x93, 0x25, + 0x60, 0x7e, 0x58, 0xa9, 0xa0, 0xef, 0x45, 0x6e, 0x97, 0x0e, 0x14, 0xf8, 0xb3, 0x4f, 0x2a, 0x10, + 0x36, 0xda, 0xb4, 0xeb, 0x0c, 0x94, 0xbb, 0x33, 0xac, 0x5c, 0x3f, 0x72, 0x3b, 0xf3, 0xae, 0x17, + 0x85, 0x51, 0x90, 0x2e, 0x64, 0xdf, 0x85, 0xb1, 0x85, 0xae, 0xdf, 0xf7, 0x22, 0xf2, 0x39, 0x28, + 0xee, 0x3b, 0x9d, 0x3e, 0xad, 0x5a, 0x37, 0xad, 0x57, 0xcb, 0xb5, 0x97, 0xbf, 0x7b, 0x3c, 0xfb, + 0xdc, 0xc9, 0xf1, 0x6c, 0xf1, 0x21, 0x03, 0x3e, 0x3a, 0x9e, 0xbd, 0x4c, 0xbd, 0x86, 0xdf, 0x74, + 0xbd, 0xd6, 0xfc, 0xfb, 0xa1, 0xef, 0xcd, 0x6d, 0xf4, 0xbb, 0x3b, 0x34, 0x40, 0x51, 0xc6, 0xfe, + 0xdd, 0x02, 0x4c, 0x2d, 0x04, 0x8d, 0xb6, 0xbb, 0x4f, 0xeb, 0x11, 0xe3, 0xdf, 0x3a, 0x22, 0x6d, + 0x18, 0x89, 0x9c, 0x80, 0xb3, 0xab, 0xdc, 0x5e, 0x9f, 0x7b, 0xda, 0xc1, 0x9f, 0xdb, 0x76, 0x02, + 0xc5, 0xbb, 0x36, 0x7e, 0x72, 0x3c, 0x3b, 0xb2, 0xed, 0x04, 0xc8, 0x44, 0x90, 0x0e, 0x8c, 0x7a, + 0xbe, 0x47, 0xab, 0x05, 0x2e, 0x6a, 0xe3, 0xe9, 0x45, 0x6d, 0xf8, 0x9e, 0x6e, 0x47, 0xad, 0x74, + 0x72, 0x3c, 0x3b, 0xca, 0x20, 0xc8, 0xa5, 0xb0, 0x76, 0x7d, 0xc5, 0xed, 0x55, 0x47, 0xf2, 0x6a, + 0xd7, 0xbb, 0x6e, 0x2f, 0xd9, 0xae, 0x77, 0xdd, 0x1e, 0x32, 0x11, 0xf6, 0x37, 0x0a, 0x50, 0x5e, + 0x08, 0x5a, 0xfd, 0x2e, 0xf5, 0xa2, 0x90, 0xfc, 0x34, 0x40, 0xcf, 0x09, 0x9c, 0x2e, 0x8d, 0x68, + 0x10, 0x56, 0xad, 0x9b, 0x23, 0xaf, 0x56, 0x6e, 0xaf, 0x3d, 0xbd, 0xf8, 0x2d, 0xc5, 0xb3, 0x46, + 0xe4, 0x90, 0x83, 0x06, 0x85, 0x68, 0x88, 0x24, 0x1f, 0x42, 0xd9, 0x09, 0x22, 0x77, 0xd7, 0x69, + 0x44, 0x61, 0xb5, 0xc0, 0xe5, 0xbf, 0xf5, 0xf4, 0xf2, 0x17, 0x24, 0xcb, 0xda, 0x45, 0x29, 0xbe, + 0xac, 0x20, 0x21, 0xc6, 0xf2, 0xec, 0xff, 0x39, 0x0a, 0x25, 0x85, 0x20, 0x37, 0x61, 0xd4, 0x73, + 0xba, 0x6a, 0xaa, 0x4e, 0xc8, 0x82, 0xa3, 0x1b, 0x4e, 0x97, 0x0d, 0x92, 0xd3, 0xa5, 0x8c, 0xa2, + 0xe7, 0x44, 0x6d, 0x3e, 0x25, 0x0c, 0x8a, 0x2d, 0x27, 0x6a, 0x23, 0xc7, 0x90, 0xeb, 0x30, 0xda, + 0xf5, 0x9b, 0x94, 0x8f, 0x63, 0x51, 0x0c, 0xf2, 0xba, 0xdf, 0xa4, 0xc8, 0xa1, 0xac, 0xfc, 0x6e, + 0xe0, 0x77, 0xab, 0xa3, 0xc9, 0xf2, 0xcb, 0x81, 0xdf, 0x45, 0x8e, 0x21, 0xdf, 0xb2, 0x60, 0x5a, + 0x55, 0xef, 0xbe, 0xdf, 0x70, 0x22, 0xd7, 0xf7, 0xaa, 0x45, 0x3e, 0x29, 0x30, 0xbf, 0x5e, 0x51, + 0x9c, 0x6b, 0x55, 0x59, 0x85, 0xe9, 0x34, 0x06, 0x07, 0x6a, 0x41, 0x6e, 0x03, 0xb4, 0x3a, 0xfe, + 0x8e, 0xd3, 0x61, 0x1d, 0x52, 0x1d, 0xe3, 0x4d, 0xd0, 0x83, 0xbb, 0xa2, 0x31, 0x68, 0x50, 0x91, + 0x43, 0x18, 0x77, 0xc4, 0x02, 0xae, 0x8e, 0xf3, 0x46, 0xbc, 0x9d, 0x47, 0x23, 0x12, 0x1a, 0xa1, + 0x56, 0x39, 0x39, 0x9e, 0x1d, 0x97, 0x40, 0x54, 0xe2, 0xc8, 0x6b, 0x50, 0xf2, 0x7b, 0xac, 0xde, + 0x4e, 0xa7, 0x5a, 0xba, 0x69, 0xbd, 0x5a, 0xaa, 0x4d, 0xcb, 0xba, 0x96, 0x36, 0x25, 0x1c, 0x35, + 0x05, 0xb9, 0x05, 0xe3, 0x61, 0x7f, 0x87, 0x8d, 0x63, 0xb5, 0xcc, 0x1b, 0x36, 0x25, 0x89, 0xc7, + 0xeb, 0x02, 0x8c, 0x0a, 0x4f, 0xde, 0x80, 0x4a, 0x40, 0x1b, 0xfd, 0x20, 0xa4, 0x6c, 0x60, 0xab, + 0xc0, 0x79, 0x5f, 0x92, 0xe4, 0x15, 0x8c, 0x51, 0x68, 0xd2, 0xd9, 0xbf, 0x3d, 0x0e, 0x03, 0x9d, + 0x4c, 0x5e, 0x87, 0x8a, 0xac, 0xef, 0x7d, 0xbf, 0x15, 0xf2, 0x89, 0x57, 0xaa, 0x4d, 0x31, 0x3e, + 0x0b, 0x31, 0x18, 0x4d, 0x1a, 0xd2, 0x84, 0x42, 0x78, 0x47, 0xea, 0xa4, 0xfb, 0x4f, 0xdf, 0x99, + 0xf5, 0x3b, 0x7a, 0xa5, 0x8c, 0x9d, 0x1c, 0xcf, 0x16, 0xea, 0x77, 0xb0, 0x10, 0xde, 0x61, 0xda, + 0xa8, 0xe5, 0x46, 0xf9, 0x69, 0xa3, 0x15, 0x37, 0xd2, 0x72, 0xb8, 0x36, 0x5a, 0x71, 0x23, 0x64, + 0x22, 0x98, 0x96, 0x6d, 0x47, 0x51, 0x8f, 0x2f, 0x89, 0x5c, 0xb4, 0xec, 0xea, 0xf6, 0xf6, 0x96, + 0x96, 0xc5, 0x17, 0x20, 0x83, 0x20, 0x97, 0x42, 0xbe, 0x6e, 0xb1, 0x1e, 0x17, 0x48, 0x3f, 0x38, + 0x92, 0x2b, 0xeb, 0x41, 0x7e, 0x2b, 0xcb, 0x0f, 0x8e, 0xb4, 0x70, 0x39, 0x90, 0x1a, 0x81, 0xa6, + 0x68, 0xde, 0xf0, 0xe6, 0x6e, 0xc8, 0x17, 0x52, 0x3e, 0x0d, 0x5f, 0x5a, 0xae, 0xa7, 0x1a, 0xbe, + 0xb4, 0x5c, 0x47, 0x2e, 0x85, 0x0d, 0x68, 0xe0, 0x1c, 0xc8, 0x45, 0x98, 0xc3, 0x80, 0xa2, 0x73, + 0x90, 0x1c, 0x50, 0x74, 0x0e, 0x90, 0x89, 0x60, 0x92, 0xfc, 0x30, 0xe4, 0x6b, 0x2e, 0x17, 0x49, + 0x9b, 0xf5, 0x7a, 0x52, 0xd2, 0x66, 0xbd, 0x8e, 0x4c, 0x04, 0x9f, 0xa4, 0x8d, 0x90, 0x2f, 0xd8, + 0x7c, 0x26, 0xe9, 0x62, 0x4a, 0xd2, 0xca, 0x62, 0x1d, 0x99, 0x08, 0xfb, 0x1b, 0x16, 0x4c, 0x2a, + 0x14, 0x53, 0x02, 0x21, 0x39, 0x84, 0x92, 0x1a, 0x4c, 0x69, 0x8b, 0xe4, 0xb9, 0x69, 0x69, 0x55, + 0xa5, 0x20, 0xa8, 0xa5, 0xd9, 0x1f, 0xc0, 0x15, 0x0d, 0xa5, 0x3d, 0x3f, 0x74, 0xf9, 0xd4, 0xa2, + 0xbb, 0x64, 0x1e, 0xca, 0x0d, 0xdf, 0xdb, 0x75, 0x5b, 0xeb, 0x4e, 0x4f, 0xee, 0x61, 0x7a, 0xf3, + 0x5b, 0x54, 0x08, 0x8c, 0x69, 0xc8, 0x8b, 0x30, 0xb2, 0x47, 0x8f, 0xe4, 0x66, 0x56, 0x91, 0xa4, + 0x23, 0x6b, 0xf4, 0x08, 0x19, 0xfc, 0x2f, 0x94, 0xbe, 0xf5, 0xed, 0xd9, 0xe7, 0xbe, 0xf6, 0x9f, + 0x6e, 0x3e, 0x67, 0xff, 0x8b, 0x02, 0xbc, 0x90, 0x29, 0xb3, 0x1e, 0x39, 0x51, 0x3f, 0x24, 0xbf, + 0x69, 0xc1, 0x15, 0x27, 0x0b, 0x2f, 0xbb, 0xe6, 0x9d, 0xfc, 0xba, 0x26, 0xc1, 0xbe, 0xf6, 0xa2, + 0xac, 0x74, 0x76, 0x8f, 0x60, 0x76, 0xa5, 0x58, 0x47, 0xb1, 0xdd, 0x3c, 0xec, 0x39, 0x0d, 0x2a, + 0x5b, 0xaf, 0x3b, 0x6a, 0x43, 0x21, 0x30, 0xa6, 0x61, 0xbb, 0x43, 0x93, 0xee, 0x3a, 0xfd, 0x8e, + 0xd0, 0x88, 0xa5, 0x78, 0x77, 0x58, 0x12, 0x60, 0x54, 0x78, 0xa3, 0xd3, 0xfe, 0xad, 0x05, 0x97, + 0x32, 0xb4, 0x02, 0xeb, 0xf5, 0x7e, 0xd0, 0x91, 0x03, 0xa4, 0x7b, 0xfd, 0x01, 0xde, 0x47, 0x06, + 0x27, 0xdf, 0xb4, 0x60, 0xca, 0x50, 0x13, 0x0b, 0x7d, 0x69, 0x6e, 0xe4, 0xb4, 0x75, 0x26, 0x18, + 0xd7, 0xae, 0x49, 0xf1, 0x53, 0x29, 0x04, 0xa6, 0xab, 0x60, 0xff, 0x9e, 0x05, 0x69, 0x22, 0xe2, + 0xc0, 0x85, 0x7e, 0x48, 0x03, 0xd6, 0x4f, 0x75, 0xda, 0x08, 0xa8, 0x5a, 0x09, 0x2f, 0xcf, 0x89, + 0x33, 0x03, 0xab, 0xc5, 0x1c, 0x3b, 0x21, 0xcd, 0xed, 0xbf, 0x3e, 0x27, 0x28, 0xd6, 0xe8, 0x51, + 0x9d, 0x76, 0x28, 0xe3, 0x51, 0x23, 0x27, 0xc7, 0xb3, 0x17, 0x1e, 0x24, 0x18, 0x60, 0x8a, 0x21, + 0x13, 0xd1, 0x73, 0xc2, 0xf0, 0xc0, 0x0f, 0x9a, 0x52, 0x44, 0xe1, 0xcc, 0x22, 0xb6, 0x12, 0x0c, + 0x30, 0xc5, 0xd0, 0xfe, 0xd7, 0x16, 0x8c, 0xd7, 0x9c, 0xc6, 0x9e, 0xbf, 0xbb, 0xcb, 0x8c, 0x86, + 0x66, 0x3f, 0x10, 0x46, 0x97, 0x18, 0x20, 0xbd, 0x12, 0x97, 0x24, 0x1c, 0x35, 0x05, 0xd9, 0x86, + 0x31, 0xd1, 0x1d, 0xb2, 0x52, 0x3f, 0x61, 0x54, 0x4a, 0x9f, 0x95, 0xf8, 0x70, 0xb0, 0xb3, 0xd2, + 0x9c, 0x38, 0x2b, 0xcd, 0xdd, 0xf3, 0xa2, 0x4d, 0x76, 0xe4, 0x70, 0xbd, 0x56, 0x0d, 0x4e, 0x8e, + 0x67, 0xc7, 0x96, 0x39, 0x0f, 0x94, 0xbc, 0x98, 0x7d, 0xd1, 0x75, 0x0e, 0x95, 0x38, 0x3e, 0xe1, + 0xca, 0xb1, 0x7d, 0xb1, 0x1e, 0xa3, 0xd0, 0xa4, 0xb3, 0xbf, 0x04, 0xc5, 0x45, 0xa7, 0xd1, 0xa6, + 0xe4, 0x41, 0x5a, 0x0d, 0x54, 0x6e, 0xbf, 0x9a, 0xd5, 0x5b, 0x5a, 0x25, 0x98, 0x1d, 0x36, 0x39, + 0x4c, 0x59, 0xd8, 0x7f, 0x60, 0xc1, 0xb5, 0xc5, 0x4e, 0x3f, 0x8c, 0x68, 0xf0, 0x8e, 0x9c, 0x57, + 0xdb, 0xb4, 0xdb, 0xeb, 0x38, 0x11, 0x25, 0x5f, 0x86, 0x12, 0x3b, 0xa7, 0x36, 0x9d, 0xc8, 0x91, + 0x12, 0x87, 0x77, 0x05, 0x9f, 0x99, 0x8c, 0x9a, 0xd5, 0x61, 0x73, 0xe7, 0x7d, 0xda, 0x88, 0xd6, + 0x69, 0xe4, 0xc4, 0x96, 0x64, 0x0c, 0x43, 0xcd, 0x95, 0x1c, 0xc2, 0x68, 0xd8, 0xa3, 0x0d, 0xd9, + 0xd1, 0x0f, 0x9f, 0x7e, 0x25, 0xa4, 0xdb, 0x50, 0xef, 0xd1, 0x46, 0x6c, 0x90, 0xb3, 0x7f, 0xc8, + 0x25, 0xda, 0xff, 0xcf, 0x82, 0x17, 0x86, 0xb4, 0xfb, 0xbe, 0x1b, 0x46, 0xe4, 0xbd, 0x81, 0xb6, + 0xcf, 0x9d, 0xae, 0xed, 0xac, 0x34, 0x6f, 0xb9, 0x9e, 0x62, 0x0a, 0x62, 0xb4, 0xfb, 0xab, 0x50, + 0x74, 0x23, 0xda, 0x55, 0x07, 0xa3, 0x2f, 0x3c, 0x7d, 0xc3, 0x87, 0xb4, 0xa5, 0x36, 0xa9, 0x4e, + 0xe6, 0xf7, 0x98, 0x3c, 0x14, 0x62, 0xed, 0x7f, 0x63, 0x01, 0x9b, 0x0e, 0x4d, 0x57, 0x9a, 0xab, + 0xa3, 0xd1, 0x51, 0x4f, 0x1d, 0x90, 0x94, 0xf2, 0x1d, 0xdd, 0x3e, 0xea, 0xb1, 0xa3, 0xfc, 0xa4, + 0x26, 0x64, 0x00, 0xe4, 0xa4, 0xe4, 0x4b, 0x30, 0x16, 0xf2, 0x4d, 0x42, 0x2a, 0xda, 0x65, 0x59, + 0x68, 0x4c, 0x6c, 0x1d, 0x8f, 0x8e, 0x67, 0x4f, 0xe5, 0xff, 0x98, 0xd3, 0xbc, 0x45, 0x39, 0x94, + 0x5c, 0x99, 0x6a, 0xee, 0xd2, 0x30, 0x74, 0x5a, 0x54, 0xae, 0x14, 0xad, 0x9a, 0xd7, 0x05, 0x18, + 0x15, 0xde, 0xfe, 0x3b, 0x16, 0xb0, 0x2a, 0x46, 0x0e, 0x13, 0xb1, 0xc1, 0x8e, 0x63, 0x1b, 0x7c, + 0xa9, 0x08, 0x80, 0x1c, 0xbc, 0x17, 0x87, 0x2c, 0x15, 0x41, 0x94, 0xd8, 0x50, 0x05, 0x08, 0x63, + 0x16, 0xe4, 0xb3, 0x30, 0xd1, 0xa4, 0x3d, 0xea, 0x35, 0xa9, 0xd7, 0x70, 0xa9, 0x18, 0xb4, 0x72, + 0x6d, 0xfa, 0xe4, 0x78, 0x76, 0x62, 0xc9, 0x80, 0x63, 0x82, 0xca, 0xfe, 0x43, 0x0b, 0x2e, 0x6b, + 0x76, 0x75, 0x1a, 0xe9, 0x65, 0xf5, 0xb3, 0x16, 0x80, 0x66, 0x1e, 0x56, 0x47, 0xf9, 0x14, 0xd8, + 0xcc, 0x61, 0x0a, 0x98, 0x9d, 0x10, 0x2f, 0x3c, 0x0d, 0x0e, 0xd1, 0x10, 0x4b, 0xbe, 0x00, 0x13, + 0xfb, 0x7e, 0xa7, 0xdf, 0xa5, 0xeb, 0x7e, 0xdf, 0x8b, 0xc2, 0xea, 0x08, 0xaf, 0xc6, 0x6c, 0x56, + 0x3f, 0x3d, 0x8c, 0xe9, 0x6a, 0x97, 0x25, 0xdb, 0x09, 0x03, 0x18, 0x62, 0x82, 0x95, 0xfd, 0x05, + 0xe0, 0x42, 0x5d, 0xaf, 0x4f, 0x37, 0x3d, 0xf2, 0x12, 0x14, 0x69, 0x10, 0xf8, 0x81, 0x3c, 0x06, + 0xe9, 0x09, 0x79, 0x97, 0x01, 0x51, 0xe0, 0xc8, 0x2b, 0x4c, 0xe7, 0xba, 0x1d, 0xda, 0xe4, 0xf3, + 0xa9, 0x54, 0xbb, 0xa0, 0xe6, 0xd3, 0x32, 0x87, 0xa2, 0xc4, 0xda, 0x73, 0x30, 0xbe, 0xc8, 0x84, + 0xd0, 0x80, 0xf1, 0x35, 0x5d, 0x50, 0x93, 0x09, 0x17, 0x94, 0x72, 0x35, 0x6d, 0xc3, 0x95, 0xc5, + 0x80, 0x32, 0x45, 0x70, 0xa7, 0xd6, 0x6f, 0xec, 0xd1, 0x48, 0x1c, 0x12, 0x43, 0xf2, 0x39, 0x98, + 0xf4, 0xb9, 0x46, 0xba, 0xef, 0x37, 0xf6, 0x5c, 0xaf, 0x25, 0x2d, 0x80, 0x2b, 0x92, 0xcb, 0xe4, + 0xa6, 0x89, 0xc4, 0x24, 0xad, 0xfd, 0xdf, 0x0a, 0x30, 0xb1, 0x18, 0xf8, 0x9e, 0x5a, 0x6d, 0xcf, + 0x40, 0x53, 0x46, 0x09, 0x4d, 0x99, 0x83, 0xcf, 0xc0, 0xac, 0xff, 0x30, 0x2d, 0x49, 0x3e, 0xd2, + 0xcb, 0x5c, 0x1c, 0x19, 0xb7, 0x73, 0x96, 0xcb, 0x79, 0xc7, 0x83, 0x9d, 0x54, 0x02, 0xf6, 0x7f, + 0xb7, 0x60, 0xda, 0x24, 0x7f, 0x06, 0x8a, 0x39, 0x4c, 0x2a, 0xe6, 0x8d, 0x7c, 0xdb, 0x3b, 0x44, + 0x1b, 0x7f, 0x63, 0x2c, 0xd9, 0x4e, 0x36, 0x00, 0xe4, 0x5b, 0x16, 0x4c, 0x1c, 0x18, 0x00, 0xd9, + 0xd8, 0x8d, 0xfc, 0xf6, 0x48, 0x3e, 0xea, 0x3f, 0xae, 0xd6, 0xb3, 0x09, 0x7d, 0x94, 0xfa, 0x8f, + 0x89, 0x9a, 0x30, 0x73, 0x2a, 0x6c, 0xb4, 0x69, 0xb3, 0xdf, 0x51, 0x76, 0xb6, 0xee, 0xd2, 0xba, + 0x84, 0xa3, 0xa6, 0x20, 0xef, 0xc1, 0xc5, 0x86, 0xef, 0x35, 0xfa, 0x41, 0x40, 0xbd, 0xc6, 0xd1, + 0x16, 0xf7, 0x9a, 0x4b, 0xa5, 0x3e, 0x27, 0x8b, 0x5d, 0x5c, 0x4c, 0x13, 0x3c, 0xca, 0x02, 0xe2, + 0x20, 0x23, 0xe1, 0xe1, 0x09, 0x99, 0xda, 0xe5, 0xae, 0x86, 0x92, 0xe9, 0xe1, 0xe1, 0x60, 0x54, + 0x78, 0xf2, 0x00, 0xae, 0x85, 0x11, 0x33, 0x80, 0xbd, 0xd6, 0x12, 0x75, 0x9a, 0x1d, 0xd7, 0x63, + 0xe6, 0xa8, 0xef, 0x35, 0x43, 0xee, 0x2f, 0x18, 0xa9, 0xbd, 0x70, 0x72, 0x3c, 0x7b, 0xad, 0x9e, + 0x4d, 0x82, 0xc3, 0xca, 0x92, 0x2f, 0xc1, 0x4c, 0xd8, 0x6f, 0x34, 0x68, 0x18, 0xee, 0xf6, 0x3b, + 0x6f, 0xf9, 0x3b, 0xe1, 0xaa, 0x1b, 0x32, 0x5b, 0xfa, 0xbe, 0xdb, 0x75, 0x23, 0xee, 0x06, 0x28, + 0xd6, 0x6e, 0x9c, 0x1c, 0xcf, 0xce, 0xd4, 0x87, 0x52, 0xe1, 0x63, 0x38, 0x10, 0x84, 0xab, 0x42, + 0xf9, 0x0d, 0xf0, 0x1e, 0xe7, 0xbc, 0x67, 0x4e, 0x8e, 0x67, 0xaf, 0x2e, 0x67, 0x52, 0xe0, 0x90, + 0x92, 0x6c, 0x04, 0x23, 0xb7, 0x4b, 0xbf, 0xe2, 0x7b, 0x94, 0x9f, 0xe8, 0x8d, 0x11, 0xdc, 0x96, + 0x70, 0xd4, 0x14, 0xe4, 0xfd, 0x78, 0x26, 0xb2, 0xe5, 0x22, 0x4f, 0xe6, 0x67, 0xd7, 0x70, 0x97, + 0x4f, 0x8e, 0x67, 0xa7, 0xdf, 0x31, 0x38, 0xb1, 0x25, 0x87, 0x09, 0xde, 0xf6, 0xef, 0x16, 0x80, + 0x0c, 0xaa, 0x08, 0xb2, 0x06, 0x63, 0x4e, 0x23, 0x72, 0xf7, 0xa9, 0x74, 0x65, 0xbf, 0x94, 0xb5, + 0x4f, 0x09, 0x51, 0x48, 0x77, 0x29, 0x9b, 0x21, 0x34, 0xd6, 0x2b, 0x0b, 0xbc, 0x28, 0x4a, 0x16, + 0xc4, 0x87, 0x8b, 0x1d, 0x27, 0x8c, 0xd4, 0x5c, 0x6d, 0xb2, 0x26, 0x4b, 0xc5, 0xfa, 0xa7, 0x4f, + 0xd7, 0x28, 0x56, 0xa2, 0x76, 0x85, 0xcd, 0xdc, 0xfb, 0x69, 0x46, 0x38, 0xc8, 0x9b, 0xfc, 0x34, + 0xdf, 0xf0, 0x85, 0xa1, 0xa3, 0x76, 0xda, 0xb5, 0x5c, 0x36, 0x7c, 0xc1, 0x33, 0xb1, 0xd9, 0x4b, + 0x31, 0x68, 0x88, 0xb4, 0xff, 0xf9, 0x38, 0x8c, 0x2f, 0x2d, 0xac, 0x6c, 0x3b, 0xe1, 0xde, 0x29, + 0xdc, 0xe1, 0x6c, 0x76, 0x48, 0x63, 0x25, 0xbd, 0xbe, 0x95, 0x11, 0x83, 0x9a, 0x82, 0x7c, 0x04, + 0x65, 0x47, 0x85, 0x1d, 0xe4, 0x36, 0xb1, 0x96, 0xc7, 0x91, 0x56, 0xb2, 0x34, 0x3d, 0xfd, 0x12, + 0x84, 0xb1, 0x40, 0xf2, 0x35, 0x0b, 0x2a, 0xaa, 0x2a, 0x48, 0x77, 0xa5, 0xbf, 0x31, 0x8f, 0x00, + 0x52, 0xcc, 0x54, 0x78, 0xfc, 0x0c, 0x00, 0x9a, 0x22, 0x07, 0xcc, 0xc3, 0xe2, 0x69, 0xcc, 0x43, + 0x72, 0x00, 0xe5, 0x03, 0x37, 0x6a, 0xf3, 0x8d, 0xa0, 0x3a, 0xc6, 0xa7, 0xc4, 0xf2, 0xd3, 0xd7, + 0x9a, 0xb1, 0x8b, 0x7b, 0xec, 0x1d, 0x25, 0x00, 0x63, 0x59, 0x64, 0x5e, 0x08, 0xe6, 0x61, 0x1b, + 0xae, 0x42, 0xca, 0xc9, 0x02, 0x1c, 0x81, 0x31, 0x0d, 0xeb, 0xe2, 0x09, 0xf6, 0xaf, 0x4e, 0x3f, + 0xe8, 0xb3, 0x75, 0x25, 0x7d, 0x80, 0x39, 0x38, 0xc6, 0x14, 0x47, 0xd1, 0x59, 0xef, 0x18, 0x32, + 0x30, 0x21, 0x91, 0xcd, 0xd9, 0x83, 0x36, 0xf5, 0xa4, 0x13, 0x5f, 0xcf, 0xd9, 0x77, 0xda, 0xd4, + 0x43, 0x8e, 0x21, 0x1f, 0x09, 0x9b, 0x5a, 0xd8, 0x9c, 0xdc, 0x7b, 0x9f, 0x8b, 0x1f, 0x3d, 0xb6, + 0x63, 0x6b, 0x17, 0x94, 0x31, 0x2d, 0xfe, 0xa3, 0x21, 0x8f, 0x99, 0xaf, 0xbe, 0x77, 0xf7, 0xd0, + 0x8d, 0xaa, 0x15, 0x5e, 0x43, 0xad, 0x79, 0x36, 0x39, 0x14, 0x25, 0x56, 0x78, 0x9c, 0xd8, 0x24, + 0x08, 0xab, 0x13, 0xc9, 0x63, 0x8d, 0x98, 0x29, 0x21, 0x2a, 0xbc, 0xfd, 0xef, 0x2c, 0xa8, 0xb0, + 0x25, 0xab, 0x96, 0xd9, 0x2b, 0x30, 0x16, 0x39, 0x41, 0x4b, 0x7a, 0x63, 0x0c, 0x11, 0xdb, 0x1c, + 0x8a, 0x12, 0x4b, 0x3c, 0x28, 0x46, 0x4e, 0xb8, 0xa7, 0x2c, 0x98, 0x7b, 0x4f, 0xdf, 0x07, 0x52, + 0x71, 0xc4, 0xc6, 0x0b, 0xfb, 0x17, 0xa2, 0x10, 0x43, 0x5e, 0x85, 0x12, 0xdb, 0x64, 0x96, 0x9d, + 0x50, 0x79, 0xd1, 0x26, 0x98, 0xa2, 0x58, 0x96, 0x30, 0xd4, 0x58, 0xfb, 0x6f, 0x17, 0x60, 0x74, + 0x49, 0xd8, 0xb2, 0x63, 0xa1, 0xdf, 0x0f, 0x1a, 0x54, 0xda, 0x34, 0x39, 0x8c, 0x13, 0xe3, 0x5b, + 0xe7, 0x3c, 0x0d, 0x6b, 0x92, 0xff, 0x47, 0x29, 0x8b, 0x7c, 0xd3, 0x82, 0x0b, 0x51, 0xe0, 0x78, + 0xe1, 0xae, 0x1f, 0x74, 0x85, 0x13, 0x46, 0x74, 0x51, 0x0e, 0x46, 0xed, 0x76, 0x82, 0x6f, 0x3d, + 0xa2, 0xbd, 0xda, 0x55, 0x59, 0x8d, 0x0b, 0x49, 0x1c, 0xa6, 0xea, 0x60, 0xff, 0x9a, 0x05, 0x10, + 0xd7, 0x9e, 0x7c, 0xdd, 0x82, 0x49, 0xc7, 0x74, 0x49, 0xcb, 0x3e, 0xda, 0xcc, 0xcf, 0x4b, 0xc8, + 0xd9, 0xd6, 0x2e, 0xb2, 0x53, 0x4e, 0x02, 0x84, 0x49, 0xc1, 0xf6, 0x1b, 0x50, 0xbc, 0xbb, 0x4f, + 0x3d, 0x6e, 0x2d, 0x84, 0xd2, 0x93, 0x94, 0x76, 0x9f, 0x29, 0x0f, 0x13, 0x6a, 0x0a, 0xfb, 0x3d, + 0xb8, 0x70, 0xf7, 0x90, 0x36, 0xfa, 0x91, 0x1f, 0x08, 0x8f, 0x13, 0x79, 0x0b, 0x48, 0x48, 0x83, + 0x7d, 0xb7, 0x41, 0x17, 0x1a, 0x0d, 0x76, 0x7a, 0xdb, 0x88, 0xf7, 0x9f, 0x19, 0xc9, 0x89, 0xd4, + 0x07, 0x28, 0x30, 0xa3, 0x94, 0xfd, 0x4f, 0x2c, 0xa8, 0x18, 0x0e, 0x7d, 0xb6, 0xfb, 0xb4, 0x16, + 0xeb, 0xe2, 0x6c, 0x27, 0xbb, 0x6a, 0x2d, 0x97, 0x90, 0x81, 0x60, 0x19, 0xab, 0x46, 0x0d, 0xc2, + 0x58, 0xe0, 0x13, 0x5c, 0xed, 0xf6, 0x6f, 0x59, 0x10, 0x97, 0x63, 0x2b, 0x78, 0x27, 0xae, 0xa7, + 0xb1, 0x82, 0x25, 0x5f, 0x89, 0x25, 0x1f, 0xc1, 0xb5, 0x64, 0xc3, 0xb9, 0x27, 0xef, 0xec, 0x5e, + 0x52, 0x61, 0xce, 0x66, 0x73, 0xc2, 0x61, 0x22, 0xec, 0x87, 0x50, 0x5c, 0x71, 0xfa, 0x2d, 0x7a, + 0xaa, 0xf3, 0x35, 0x5b, 0xfd, 0x01, 0x75, 0x3a, 0x91, 0xb2, 0xa0, 0xe4, 0xea, 0x47, 0x09, 0x43, + 0x8d, 0xb5, 0x7f, 0x73, 0x14, 0x2a, 0x46, 0xb8, 0x90, 0xa9, 0xf4, 0x80, 0xf6, 0xfc, 0xb4, 0x19, + 0x82, 0xb4, 0xe7, 0x23, 0xc7, 0xb0, 0x69, 0x17, 0xd0, 0x7d, 0x37, 0x14, 0x2b, 0x35, 0x31, 0xed, + 0x50, 0xc2, 0x51, 0x53, 0x90, 0x59, 0x28, 0x36, 0x69, 0x2f, 0x6a, 0x73, 0x25, 0x34, 0x5a, 0x2b, + 0xb3, 0xaa, 0x2e, 0x31, 0x00, 0x0a, 0x38, 0x23, 0xd8, 0xa5, 0x51, 0xa3, 0xcd, 0x1d, 0x2e, 0x65, + 0x41, 0xb0, 0xcc, 0x00, 0x28, 0xe0, 0x19, 0x7e, 0xef, 0xe2, 0xf9, 0xfb, 0xbd, 0xc7, 0x72, 0xf6, + 0x7b, 0x93, 0x1e, 0x5c, 0x0a, 0xc3, 0xf6, 0x56, 0xe0, 0xee, 0x3b, 0x11, 0x8d, 0x67, 0xce, 0xf8, + 0x59, 0xe4, 0x5c, 0x3b, 0x39, 0x9e, 0xbd, 0x54, 0xaf, 0xaf, 0xa6, 0xb9, 0x60, 0x16, 0x6b, 0x52, + 0x87, 0x2b, 0xae, 0x17, 0xd2, 0x46, 0x3f, 0xa0, 0xf7, 0x5a, 0x9e, 0x1f, 0xd0, 0x55, 0x3f, 0x64, + 0xec, 0x64, 0x7c, 0x5e, 0x07, 0x73, 0xee, 0x65, 0x11, 0x61, 0x76, 0x59, 0xfb, 0x7b, 0x16, 0x4c, + 0x98, 0x91, 0x4f, 0x66, 0x85, 0x40, 0x7b, 0x69, 0xb9, 0x2e, 0x74, 0x4a, 0x7e, 0x3b, 0xc7, 0xaa, + 0xe6, 0x19, 0x5b, 0xd1, 0x31, 0x0c, 0x0d, 0x99, 0xa7, 0x48, 0x13, 0x79, 0x09, 0x8a, 0xbb, 0x3e, + 0xdb, 0xd8, 0x46, 0x92, 0xbe, 0xae, 0x65, 0x06, 0x44, 0x81, 0xb3, 0x7f, 0x60, 0x81, 0x21, 0x81, + 0xfc, 0xa2, 0x05, 0x93, 0x4c, 0xc8, 0x5a, 0xb0, 0x93, 0x68, 0xdb, 0x66, 0x3e, 0x6d, 0xd3, 0x6c, + 0x63, 0xdf, 0x56, 0x02, 0x8c, 0x49, 0xe1, 0xe4, 0xcf, 0x40, 0xd9, 0x69, 0x36, 0x03, 0x1a, 0x86, + 0xda, 0xd3, 0xc9, 0xa3, 0x07, 0x0b, 0x0a, 0x88, 0x31, 0x9e, 0x2d, 0xd1, 0x76, 0x73, 0x37, 0x64, + 0xb3, 0x5e, 0x1e, 0xe9, 0xf5, 0x12, 0x65, 0x42, 0x18, 0x1c, 0x35, 0x85, 0xfd, 0x4b, 0xa3, 0x90, + 0x94, 0x4d, 0x9a, 0x30, 0xb5, 0x17, 0xec, 0x2c, 0xf2, 0x08, 0xc7, 0x27, 0x89, 0x35, 0x5d, 0x3a, + 0x39, 0x9e, 0x9d, 0x5a, 0x4b, 0x72, 0xc0, 0x34, 0x4b, 0x29, 0x65, 0x8d, 0x1e, 0x45, 0xce, 0xce, + 0x27, 0x51, 0xa4, 0x4a, 0x8a, 0xc9, 0x01, 0xd3, 0x2c, 0xc9, 0x1b, 0x50, 0xd9, 0x0b, 0x76, 0x94, + 0x02, 0x48, 0x07, 0x78, 0xd6, 0x62, 0x14, 0x9a, 0x74, 0xac, 0x0b, 0xf7, 0x82, 0x1d, 0xa6, 0x30, + 0x55, 0xfe, 0x90, 0xee, 0xc2, 0x35, 0x09, 0x47, 0x4d, 0x41, 0x7a, 0x40, 0xf6, 0x54, 0xef, 0xe9, + 0x78, 0x8e, 0xd4, 0x53, 0xa7, 0x0f, 0x07, 0x5d, 0x65, 0x1b, 0xee, 0xda, 0x00, 0x1f, 0xcc, 0xe0, + 0x4d, 0xbe, 0x00, 0xd7, 0xf6, 0x82, 0x1d, 0xb9, 0x8d, 0x6c, 0x05, 0xae, 0xd7, 0x70, 0x7b, 0x89, + 0x5c, 0xa1, 0x59, 0x59, 0xdd, 0x6b, 0x6b, 0xd9, 0x64, 0x38, 0xac, 0xbc, 0xfd, 0xf7, 0xd8, 0x1a, + 0x37, 0xd2, 0x3a, 0x9e, 0x14, 0x43, 0x0d, 0x61, 0xbc, 0x4d, 0x9d, 0x26, 0x0d, 0x94, 0x71, 0xbb, + 0x9a, 0xc3, 0x12, 0xe1, 0x0c, 0x63, 0x3b, 0x5c, 0xfc, 0x0f, 0x51, 0x49, 0xb2, 0x37, 0x61, 0x4c, + 0xc0, 0x4e, 0x71, 0x70, 0xd6, 0x5b, 0x66, 0xe1, 0x31, 0x2e, 0xe9, 0xef, 0x58, 0x50, 0xe6, 0xce, + 0x98, 0x16, 0x3b, 0x5c, 0xe9, 0x22, 0x23, 0x8f, 0xd9, 0x65, 0x43, 0x18, 0x17, 0xb6, 0x81, 0x8a, + 0x16, 0xe4, 0xd0, 0x70, 0x91, 0xc8, 0x19, 0x37, 0x5c, 0x18, 0x21, 0x21, 0x2a, 0x49, 0xf6, 0xcf, + 0x15, 0x60, 0xec, 0x9e, 0xd7, 0xeb, 0xff, 0xc8, 0x27, 0x13, 0xae, 0xc3, 0x28, 0x3b, 0x39, 0x27, + 0x73, 0x5e, 0x27, 0x6a, 0x2f, 0x9b, 0xf9, 0xae, 0xd5, 0x64, 0xbe, 0x2b, 0x3a, 0x07, 0x2a, 0x4e, + 0x25, 0xca, 0x18, 0x09, 0x04, 0x1d, 0x18, 0xbd, 0xef, 0x7a, 0x7b, 0xa7, 0x9b, 0x4e, 0x61, 0xc3, + 0xef, 0x0d, 0x4c, 0xa7, 0x3a, 0x03, 0xa2, 0xc0, 0xa9, 0x35, 0x33, 0x92, 0xbd, 0x66, 0xec, 0x9f, + 0xb1, 0xe0, 0xe2, 0x3a, 0xed, 0xfa, 0xee, 0x57, 0x9c, 0x38, 0xcc, 0xc6, 0x0a, 0xb5, 0xdd, 0x48, + 0x46, 0x64, 0x74, 0xa1, 0x55, 0x37, 0x42, 0x06, 0x7f, 0x82, 0x59, 0xcb, 0x33, 0x52, 0x98, 0x7a, + 0xdd, 0x88, 0xf5, 0x5c, 0x1c, 0x40, 0x53, 0x08, 0x8c, 0x69, 0xec, 0xdf, 0xb6, 0x60, 0x5c, 0x54, + 0x82, 0x2a, 0xde, 0xd6, 0x10, 0xde, 0x6d, 0x28, 0xf2, 0x72, 0x52, 0x43, 0xaf, 0xe4, 0x70, 0x84, + 0x67, 0xec, 0x84, 0xb9, 0xc7, 0x7f, 0xa2, 0x10, 0xc0, 0xcc, 0xf1, 0xae, 0x73, 0xb8, 0xa0, 0x23, + 0x8c, 0xda, 0x1c, 0x5f, 0xe7, 0x50, 0x94, 0x58, 0xfb, 0x37, 0x46, 0xa0, 0xa4, 0x9c, 0x95, 0xe4, + 0x57, 0x2c, 0xa8, 0x38, 0x9e, 0xe7, 0x47, 0x8e, 0xf0, 0xe5, 0x89, 0xb5, 0xf0, 0xc5, 0xa7, 0xaf, + 0xa5, 0x92, 0x30, 0xb7, 0x10, 0x73, 0xbf, 0xeb, 0x45, 0xc1, 0x51, 0xbc, 0x85, 0x18, 0x18, 0x34, + 0x2b, 0x41, 0xbe, 0x0a, 0x63, 0x1d, 0x67, 0x87, 0x76, 0xd4, 0xd2, 0x78, 0x98, 0x63, 0x75, 0xee, + 0x73, 0xc6, 0xa2, 0x26, 0xba, 0x87, 0x04, 0x10, 0xa5, 0xd4, 0x99, 0x9f, 0x84, 0xe9, 0x74, 0xad, + 0xc9, 0xb4, 0x31, 0xcc, 0x62, 0x64, 0x2f, 0x27, 0x94, 0xa3, 0x5a, 0x17, 0x85, 0x37, 0xad, 0x99, + 0x3f, 0x0f, 0x15, 0x43, 0xcc, 0x59, 0x8a, 0xda, 0x6f, 0x43, 0x65, 0x9d, 0x46, 0x81, 0xdb, 0xe0, + 0x0c, 0x9e, 0x34, 0xb9, 0x4e, 0xa5, 0x9f, 0x7f, 0x9e, 0x4f, 0x56, 0xc6, 0x33, 0x24, 0x1f, 0x01, + 0xf4, 0x02, 0xbf, 0x4b, 0xa3, 0x36, 0xed, 0xab, 0xc1, 0xce, 0xc1, 0xe6, 0xdc, 0xd2, 0x3c, 0x85, + 0x57, 0x29, 0xfe, 0x8f, 0x86, 0x3c, 0xfb, 0x16, 0x14, 0xd7, 0xfb, 0x11, 0x3d, 0x7c, 0xb2, 0xaa, + 0xb0, 0xbf, 0x08, 0x13, 0x9c, 0x74, 0xd5, 0xef, 0x30, 0x2d, 0xc4, 0x5a, 0xda, 0x65, 0xff, 0xd3, + 0x87, 0x37, 0x4e, 0x84, 0x02, 0xc7, 0x56, 0x40, 0xdb, 0xef, 0x34, 0x69, 0x20, 0xfb, 0x43, 0x8f, + 0xef, 0x2a, 0x87, 0xa2, 0xc4, 0xda, 0x3f, 0x5b, 0x80, 0x0a, 0x2f, 0x28, 0xb5, 0xc7, 0x11, 0x8c, + 0xb7, 0x85, 0x1c, 0xd9, 0x25, 0x39, 0x04, 0xa5, 0xcc, 0xda, 0x1b, 0xbb, 0xb1, 0x00, 0xa0, 0x92, + 0xc7, 0x44, 0x1f, 0x38, 0x6e, 0xc4, 0x44, 0x17, 0xce, 0x57, 0xf4, 0x3b, 0x42, 0x0c, 0x2a, 0x79, + 0xf6, 0xff, 0x98, 0x02, 0xd8, 0xf0, 0x9b, 0x54, 0x76, 0xc2, 0x0c, 0x14, 0xdc, 0xa6, 0xec, 0x5e, + 0x90, 0x85, 0x0a, 0xf7, 0x96, 0xb0, 0xe0, 0x36, 0xf5, 0x78, 0x15, 0x86, 0xaa, 0xf6, 0x37, 0xa0, + 0xd2, 0x74, 0xc3, 0x5e, 0xc7, 0x39, 0xda, 0xc8, 0x30, 0x16, 0x97, 0x62, 0x14, 0x9a, 0x74, 0xe4, + 0x35, 0x99, 0xa9, 0x21, 0x0c, 0xc5, 0x6a, 0x2a, 0x53, 0xa3, 0xc4, 0xaa, 0x67, 0x24, 0x69, 0xbc, + 0x09, 0x13, 0xca, 0x4f, 0xcd, 0xa5, 0x14, 0x79, 0x29, 0x1d, 0xc1, 0xdf, 0x36, 0x70, 0x98, 0xa0, + 0x1c, 0xf0, 0xaa, 0x8f, 0x3d, 0x7b, 0xaf, 0xfa, 0xe7, 0x60, 0x52, 0xfd, 0xe5, 0xfb, 0x5d, 0xf5, + 0x32, 0xaf, 0xbd, 0x3e, 0xc4, 0x6c, 0x9b, 0x48, 0x4c, 0xd2, 0x92, 0x9f, 0x80, 0x62, 0xaf, 0xed, + 0x84, 0x54, 0xfa, 0xb7, 0x95, 0x93, 0xa9, 0xb8, 0xc5, 0x80, 0x8f, 0x8e, 0x67, 0xcb, 0xac, 0xa7, + 0xf8, 0x1f, 0x14, 0x84, 0xe4, 0x36, 0xc0, 0x8e, 0xdf, 0xf7, 0x9a, 0x4e, 0x70, 0x74, 0x6f, 0x49, + 0xc6, 0xc4, 0xb4, 0x55, 0x52, 0xd3, 0x18, 0x34, 0xa8, 0xcc, 0x24, 0x95, 0xf2, 0xe3, 0x93, 0x54, + 0xc8, 0x17, 0xa1, 0xcc, 0xe3, 0x87, 0xb4, 0xb9, 0x10, 0x49, 0xef, 0xf4, 0x59, 0x42, 0x4d, 0x7a, + 0x7b, 0xad, 0x2b, 0x26, 0x18, 0xf3, 0x23, 0x5f, 0x02, 0xd8, 0x75, 0x3d, 0x37, 0x6c, 0x73, 0xee, + 0x95, 0x33, 0x73, 0xd7, 0xed, 0x5c, 0xd6, 0x5c, 0xd0, 0xe0, 0x48, 0xde, 0x83, 0x8b, 0x34, 0x8c, + 0xdc, 0xae, 0x13, 0xd1, 0xa6, 0x4e, 0x60, 0xab, 0xf2, 0x90, 0xa9, 0x8e, 0xe0, 0xde, 0x4d, 0x13, + 0x3c, 0xca, 0x02, 0xe2, 0x20, 0x23, 0xf2, 0x26, 0x94, 0x7a, 0x81, 0xdf, 0x62, 0x27, 0xca, 0xea, + 0x0c, 0xef, 0xc6, 0xeb, 0xea, 0x00, 0xb4, 0x25, 0xe1, 0x8f, 0x8c, 0xdf, 0xa8, 0xa9, 0xc9, 0x1f, + 0x59, 0x70, 0x31, 0xa0, 0xc2, 0xbd, 0x1b, 0xea, 0x8a, 0x5d, 0xe1, 0x7a, 0xa1, 0x91, 0xc7, 0xbd, + 0x1e, 0xb5, 0xd8, 0xe7, 0x30, 0x2d, 0x45, 0x6c, 0x88, 0x54, 0xb5, 0x7e, 0x00, 0xff, 0x28, 0x0b, + 0xf8, 0x33, 0xbf, 0x3f, 0x3b, 0x3b, 0x78, 0xc9, 0x4c, 0x33, 0x67, 0x2b, 0xef, 0xaf, 0xff, 0xfe, + 0xec, 0xb4, 0xfa, 0x1f, 0x77, 0xda, 0x40, 0x23, 0x99, 0x7e, 0xef, 0xf9, 0xcd, 0x7b, 0x5b, 0x32, + 0x8c, 0xa0, 0xf5, 0xfb, 0x16, 0x03, 0xa2, 0xc0, 0x91, 0x57, 0xa1, 0xd4, 0x74, 0x68, 0xd7, 0xf7, + 0x68, 0xb3, 0x3a, 0x19, 0x3b, 0xe7, 0x96, 0x24, 0x0c, 0x35, 0x96, 0x74, 0x60, 0xcc, 0xe5, 0xa6, + 0x7e, 0xf5, 0x02, 0x9f, 0x3d, 0x39, 0x9c, 0x2f, 0xc4, 0xd1, 0x41, 0xa4, 0x42, 0x8a, 0xdf, 0x28, + 0x65, 0x90, 0x1e, 0x8c, 0xfb, 0xfd, 0x88, 0x8b, 0x9b, 0xe2, 0xe2, 0x72, 0x08, 0x52, 0x6c, 0x0a, + 0x86, 0xe2, 0xd6, 0x88, 0xfc, 0x83, 0x4a, 0x0c, 0xeb, 0x89, 0x46, 0xdb, 0xed, 0x34, 0x03, 0xea, + 0x55, 0xa7, 0xb9, 0x4f, 0x83, 0xf7, 0xc4, 0xa2, 0x84, 0xa1, 0xc6, 0x92, 0x3f, 0x07, 0x93, 0x7e, + 0x3f, 0xe2, 0x8b, 0x9c, 0x8d, 0x7f, 0x58, 0xbd, 0xc8, 0xc9, 0xb9, 0xb7, 0x7c, 0xd3, 0x44, 0x60, + 0x92, 0x8e, 0x29, 0xdb, 0xb6, 0x1f, 0x46, 0xec, 0x0f, 0x57, 0xb6, 0x57, 0x93, 0xca, 0x76, 0xd5, + 0xc0, 0x61, 0x82, 0x92, 0x7c, 0xcb, 0x82, 0x8b, 0xdd, 0xb4, 0x89, 0x5e, 0xbd, 0xc6, 0x7b, 0xa6, + 0x9e, 0x87, 0x29, 0x97, 0x62, 0x2d, 0x02, 0xd7, 0x03, 0x60, 0x1c, 0xac, 0x04, 0xcf, 0x00, 0x0f, + 0x8f, 0xbc, 0x46, 0x3b, 0xf0, 0xbd, 0x64, 0xf5, 0x9e, 0xe7, 0xd5, 0xfb, 0x62, 0x4e, 0xab, 0x2c, + 0x4b, 0x44, 0xed, 0xf9, 0x93, 0xe3, 0xd9, 0x2b, 0x99, 0x28, 0xcc, 0xae, 0xd4, 0xcc, 0x12, 0x5c, + 0xcd, 0x5e, 0xa9, 0x4f, 0xb2, 0x29, 0x47, 0x4c, 0x9b, 0x72, 0x19, 0x9e, 0x1f, 0x5a, 0x29, 0xa6, + 0xf3, 0x95, 0x01, 0x62, 0x25, 0x75, 0xfe, 0x80, 0xc1, 0x70, 0x01, 0x26, 0xcc, 0xab, 0x81, 0x3c, + 0x74, 0x61, 0xdc, 0x7a, 0x20, 0x1f, 0x41, 0xd9, 0xaf, 0xe7, 0x1e, 0xba, 0xd8, 0xac, 0x0f, 0x84, + 0x2e, 0x34, 0x08, 0x63, 0x81, 0x4f, 0x0a, 0x5d, 0xfc, 0xc2, 0x08, 0xc4, 0xe5, 0xc8, 0x6b, 0x50, + 0xa2, 0x5e, 0xb3, 0xe7, 0xbb, 0x5e, 0x94, 0x8e, 0x00, 0xdd, 0x95, 0x70, 0xd4, 0x14, 0x46, 0xa0, + 0xa3, 0xf0, 0xd8, 0x40, 0x47, 0x13, 0xa6, 0x1c, 0x9e, 0xf6, 0x12, 0xbb, 0xa9, 0x47, 0xce, 0xec, + 0x97, 0x5b, 0x48, 0x72, 0xc0, 0x34, 0x4b, 0x26, 0x25, 0x8c, 0x8b, 0x72, 0x29, 0xa3, 0x67, 0x96, + 0x52, 0x4f, 0x72, 0xc0, 0x34, 0x4b, 0xf2, 0x1e, 0x54, 0x1b, 0x3c, 0xd1, 0x50, 0xb4, 0xf1, 0xde, + 0xee, 0x86, 0x1f, 0x6d, 0x05, 0x34, 0xa4, 0x9e, 0x08, 0x23, 0x94, 0x6a, 0x37, 0x65, 0x2f, 0x54, + 0x17, 0x87, 0xd0, 0xe1, 0x50, 0x0e, 0xf6, 0x7f, 0x28, 0x80, 0x52, 0x6a, 0x3f, 0xda, 0xce, 0x18, + 0x62, 0xc3, 0x58, 0x40, 0x43, 0x75, 0x65, 0xa3, 0x2c, 0xf6, 0x17, 0xe4, 0x10, 0x94, 0x18, 0xa6, + 0xed, 0xe9, 0xa1, 0x1b, 0x2d, 0xfa, 0x4d, 0x65, 0x29, 0x73, 0x6d, 0x7f, 0x57, 0xc2, 0x50, 0x63, + 0xed, 0xbf, 0x6a, 0xc1, 0x24, 0x6b, 0x65, 0xa7, 0x43, 0x3b, 0xf5, 0x88, 0xf6, 0x42, 0x12, 0x42, + 0x31, 0x64, 0x3f, 0xf2, 0x3b, 0xd9, 0xc4, 0x99, 0x4c, 0xb4, 0x67, 0xf8, 0x70, 0x98, 0x10, 0x14, + 0xb2, 0xec, 0xff, 0x55, 0x80, 0xb2, 0xee, 0xec, 0x53, 0x38, 0x86, 0x6e, 0xc7, 0x17, 0x57, 0xc4, + 0x0a, 0xab, 0x1a, 0x97, 0x56, 0x98, 0x79, 0xbb, 0xe0, 0x1d, 0x89, 0xab, 0x08, 0xfa, 0x06, 0x0b, + 0x79, 0x2d, 0xe9, 0x68, 0xbc, 0x6a, 0x7a, 0xaf, 0x0c, 0x7a, 0xe9, 0x71, 0x3c, 0x84, 0x32, 0xff, + 0xb1, 0xac, 0xae, 0xb5, 0xe6, 0x32, 0xc7, 0x1e, 0x2a, 0x96, 0x22, 0xa4, 0xa0, 0xff, 0x62, 0x2c, + 0x2c, 0x75, 0x1d, 0xb5, 0x78, 0xaa, 0xeb, 0xa8, 0xb7, 0x60, 0x94, 0x7a, 0xfd, 0x2e, 0x4f, 0xa3, + 0x29, 0xf3, 0xed, 0x6d, 0xf4, 0xae, 0xd7, 0xef, 0x26, 0x5b, 0xc6, 0x49, 0xec, 0x7f, 0x69, 0x01, + 0x33, 0x92, 0x56, 0x16, 0xc9, 0x5f, 0x84, 0x52, 0x28, 0x55, 0xb3, 0xec, 0xea, 0x1f, 0xd3, 0x51, + 0x6d, 0x09, 0x7f, 0x74, 0x3c, 0x3b, 0xc9, 0x89, 0x15, 0x00, 0x75, 0x11, 0xd2, 0x81, 0x49, 0xee, + 0xfe, 0x50, 0x7a, 0x42, 0x3a, 0xac, 0xee, 0x9c, 0x32, 0x19, 0xd5, 0x2c, 0x2a, 0xac, 0x8b, 0x04, + 0x08, 0x93, 0xcc, 0xed, 0x7f, 0x35, 0x0a, 0x86, 0x97, 0xe0, 0x14, 0x53, 0xe4, 0x83, 0x94, 0x4f, + 0x68, 0x3d, 0x17, 0x9f, 0x90, 0x72, 0xb4, 0x88, 0x65, 0x97, 0x74, 0x03, 0xb1, 0x4a, 0xb5, 0x69, + 0xa7, 0x27, 0x27, 0x98, 0xae, 0xd4, 0x2a, 0xed, 0xf4, 0x90, 0x63, 0x74, 0x1a, 0xcf, 0xe8, 0xd0, + 0x34, 0x9e, 0x36, 0x14, 0x5b, 0x4e, 0xbf, 0x45, 0x65, 0x48, 0x23, 0x07, 0xf7, 0x1f, 0x0f, 0x66, + 0x0b, 0xf7, 0x1f, 0xff, 0x89, 0x42, 0x00, 0x9b, 0xe1, 0x6d, 0xe5, 0x85, 0x97, 0xe7, 0xdb, 0x1c, + 0x66, 0xb8, 0x76, 0xec, 0x8b, 0x19, 0xae, 0xff, 0x62, 0x2c, 0x8c, 0x99, 0xbf, 0x0d, 0x91, 0xc3, + 0x2e, 0xa3, 0xb2, 0xf7, 0xf2, 0xc8, 0x53, 0xe2, 0x0c, 0x85, 0xf9, 0x2b, 0xff, 0xa0, 0x12, 0x63, + 0xcf, 0x43, 0xc5, 0xb8, 0xd8, 0xc9, 0x86, 0x41, 0xa7, 0x4f, 0x1b, 0xc3, 0xb0, 0xe4, 0x44, 0x0e, + 0x72, 0x8c, 0xfd, 0x77, 0x47, 0x40, 0x1f, 0x43, 0xcc, 0x0c, 0x24, 0xa7, 0x61, 0xdc, 0xa1, 0x4a, + 0xa4, 0x57, 0xfa, 0x1e, 0x4a, 0x2c, 0x3b, 0xb9, 0x77, 0x69, 0xd0, 0xd2, 0x86, 0x8f, 0xd4, 0x51, + 0xfa, 0xe4, 0xbe, 0x6e, 0x22, 0x31, 0x49, 0xcb, 0x2c, 0x8d, 0xae, 0xe3, 0xb9, 0xbb, 0x34, 0x8c, + 0xd2, 0x11, 0xc5, 0x75, 0x09, 0x47, 0x4d, 0x41, 0x56, 0xe0, 0x62, 0x48, 0xa3, 0xcd, 0x03, 0x8f, + 0x06, 0x3a, 0xed, 0x53, 0xe6, 0x01, 0x3f, 0xaf, 0xce, 0x66, 0xf5, 0x34, 0x01, 0x0e, 0x96, 0x21, + 0x4b, 0x30, 0x2d, 0x53, 0x70, 0x75, 0x06, 0xa5, 0xd4, 0x3d, 0xfa, 0x2a, 0x7d, 0x3d, 0x85, 0xc7, + 0x81, 0x12, 0x8c, 0xcb, 0xae, 0xe3, 0x76, 0xfa, 0x01, 0x8d, 0xb9, 0x8c, 0x25, 0xb9, 0x2c, 0xa7, + 0xf0, 0x38, 0x50, 0x82, 0x27, 0x2a, 0x74, 0x9c, 0x56, 0x58, 0x1d, 0x37, 0x12, 0x15, 0x18, 0x00, + 0x05, 0xdc, 0xfe, 0xa7, 0x16, 0x4c, 0x22, 0x8d, 0x82, 0xa3, 0x85, 0x5d, 0x76, 0x4a, 0x8f, 0x8e, + 0xc8, 0xaf, 0x5b, 0x30, 0xed, 0xf9, 0x4d, 0xba, 0xe0, 0x45, 0xae, 0x02, 0xe6, 0x77, 0x49, 0x93, + 0xcb, 0xda, 0x48, 0xb1, 0x17, 0xd9, 0xbc, 0x69, 0x28, 0x0e, 0x54, 0xc3, 0xbe, 0x06, 0x57, 0x32, + 0x19, 0xd8, 0xdf, 0x1e, 0x91, 0xcd, 0xd0, 0x83, 0xff, 0x36, 0x14, 0x3b, 0x3c, 0xb3, 0xd9, 0xfa, + 0x84, 0x17, 0xef, 0x78, 0x5f, 0x89, 0xd4, 0x67, 0xc1, 0x89, 0x2c, 0x41, 0x25, 0x60, 0x32, 0x64, + 0xde, 0xb9, 0x98, 0x8a, 0x76, 0x7c, 0xad, 0x5f, 0xa3, 0x1e, 0x25, 0xff, 0xa2, 0x59, 0x8c, 0x7c, + 0x08, 0xe3, 0x3b, 0xe2, 0x2e, 0xa1, 0xb4, 0x50, 0x73, 0x58, 0xb2, 0xf2, 0x72, 0x22, 0xdf, 0x89, + 0xd5, 0x4d, 0xc5, 0x47, 0xf1, 0x4f, 0x54, 0x12, 0xc9, 0x11, 0x94, 0x1c, 0x35, 0xa6, 0xa3, 0x79, + 0xa5, 0x06, 0x24, 0xe6, 0x8f, 0xb0, 0x8f, 0xf4, 0x18, 0x6a, 0x71, 0xf6, 0x77, 0x2c, 0x80, 0xf8, + 0x29, 0x01, 0x72, 0x08, 0xa5, 0xf0, 0x4e, 0xe2, 0xc0, 0x92, 0x47, 0x12, 0xa8, 0xe4, 0x68, 0x24, + 0x95, 0x49, 0x08, 0x6a, 0x69, 0x4f, 0x3a, 0xad, 0x7c, 0xb3, 0x08, 0xba, 0xd4, 0x39, 0x1d, 0x56, + 0x5e, 0x61, 0x86, 0x67, 0x2b, 0xbe, 0xba, 0xa9, 0xe9, 0x90, 0x43, 0x51, 0x62, 0x99, 0xf1, 0xa9, + 0x32, 0x5a, 0xa4, 0x26, 0xe2, 0x9d, 0xab, 0x92, 0x5f, 0x50, 0x63, 0xb3, 0x8e, 0x3f, 0xc5, 0x67, + 0x72, 0xfc, 0x19, 0xcb, 0xff, 0xf8, 0x73, 0x0b, 0xc6, 0x03, 0xbf, 0x43, 0x17, 0x70, 0x43, 0xba, + 0x5c, 0xf5, 0xb1, 0x18, 0x05, 0x18, 0x15, 0x9e, 0xbc, 0x01, 0x95, 0x7e, 0x48, 0xeb, 0x4b, 0x6b, + 0x8b, 0x01, 0x6d, 0x86, 0x32, 0x49, 0x48, 0xbb, 0xbe, 0x1f, 0xc4, 0x28, 0x34, 0xe9, 0xc8, 0x6f, + 0x59, 0x8f, 0x39, 0x61, 0x95, 0xf3, 0x52, 0x75, 0x99, 0x97, 0xc5, 0x6a, 0xd7, 0x3f, 0xe1, 0xb1, + 0xed, 0xeb, 0x16, 0x5c, 0xa8, 0x37, 0x02, 0xb7, 0x17, 0x5f, 0xfe, 0xcb, 0xfb, 0x6e, 0xe2, 0x2b, + 0x3a, 0x97, 0x36, 0x35, 0x7d, 0x93, 0xd9, 0xaf, 0xf6, 0xfb, 0x30, 0x5d, 0xa7, 0x5d, 0xa7, 0xd7, + 0xe6, 0x39, 0x56, 0x22, 0x98, 0x32, 0x0f, 0xe5, 0x50, 0xc1, 0xd2, 0x2f, 0x0b, 0x68, 0x62, 0x8c, + 0x69, 0xc8, 0xcb, 0x22, 0xf0, 0xa3, 0x12, 0x30, 0xca, 0xc2, 0xdc, 0x10, 0xd1, 0xa2, 0x10, 0x15, + 0xce, 0x3e, 0x80, 0x89, 0xb8, 0x38, 0xdd, 0x25, 0x2d, 0x98, 0x6a, 0x18, 0x69, 0x28, 0xf1, 0x03, + 0x02, 0xa7, 0xcf, 0x58, 0xe1, 0xb3, 0x70, 0x31, 0xc9, 0x04, 0xd3, 0x5c, 0xed, 0x5f, 0x2e, 0xc0, + 0x94, 0x96, 0x2c, 0x1d, 0x36, 0x1f, 0xa7, 0x83, 0x55, 0x98, 0x47, 0xde, 0x7a, 0xb2, 0x27, 0x1f, + 0x13, 0xb0, 0xfa, 0x38, 0x1d, 0xb0, 0x3a, 0x57, 0xf1, 0x03, 0x3e, 0xa8, 0xef, 0x14, 0xa0, 0xa4, + 0xb3, 0xe8, 0xdf, 0x86, 0x22, 0xb7, 0x08, 0x9f, 0x6e, 0x7b, 0xe5, 0xd6, 0x25, 0x0a, 0x4e, 0x8c, + 0x25, 0x8f, 0x43, 0x7c, 0xe2, 0xab, 0xf2, 0x65, 0x71, 0x18, 0x76, 0x82, 0x08, 0x05, 0x27, 0xb2, + 0x06, 0x23, 0xd4, 0x6b, 0xca, 0x7d, 0xf6, 0xec, 0x0c, 0xf9, 0x0b, 0x1f, 0x77, 0xbd, 0x26, 0x32, + 0x2e, 0xfc, 0x5e, 0x29, 0x4f, 0xb5, 0x96, 0x67, 0x8e, 0xf8, 0x5e, 0x29, 0x87, 0xa2, 0xc4, 0xda, + 0xbf, 0x30, 0x02, 0x63, 0xf5, 0xfe, 0x0e, 0xb3, 0x18, 0xfe, 0x81, 0x05, 0x97, 0x0e, 0x52, 0xd7, + 0xa8, 0xe3, 0x29, 0xfb, 0x20, 0xff, 0x3b, 0xea, 0x48, 0x77, 0x6b, 0x2f, 0xc8, 0x7a, 0x5d, 0xca, + 0x40, 0x62, 0x56, 0x75, 0x12, 0x57, 0x4e, 0x47, 0xce, 0xe9, 0x72, 0xbe, 0x71, 0xb1, 0xa7, 0x90, + 0xff, 0xc5, 0x9e, 0xc9, 0x61, 0x97, 0x7a, 0xec, 0x3f, 0x1e, 0x05, 0x10, 0xa3, 0xb1, 0xd9, 0x8b, + 0x4e, 0x73, 0xda, 0x7d, 0x13, 0x26, 0xd4, 0x5b, 0x75, 0x1b, 0x71, 0xe0, 0x55, 0x3b, 0xdf, 0x57, + 0x0c, 0x1c, 0x26, 0x28, 0xc9, 0x6d, 0x00, 0xea, 0x45, 0xc1, 0x91, 0x30, 0x17, 0x46, 0x93, 0xee, + 0x86, 0xbb, 0x1a, 0x83, 0x06, 0x15, 0x99, 0x4b, 0x78, 0xe0, 0xc4, 0x75, 0x9f, 0x0b, 0x8f, 0x71, + 0x98, 0x7d, 0x0e, 0x26, 0xf5, 0xbf, 0x65, 0xb7, 0xa3, 0x12, 0xe7, 0xf4, 0x81, 0x68, 0xcb, 0x44, + 0x62, 0x92, 0x96, 0xfc, 0x24, 0x5c, 0x48, 0xa6, 0x6a, 0xcb, 0x0d, 0x56, 0xdf, 0x2f, 0x48, 0x66, + 0x78, 0x63, 0x8a, 0x9a, 0xad, 0x80, 0x66, 0x70, 0x84, 0x7d, 0x4f, 0xee, 0xb4, 0x7a, 0x05, 0x2c, + 0x71, 0x28, 0x4a, 0x2c, 0xeb, 0x42, 0x56, 0x92, 0x06, 0x02, 0xce, 0xb7, 0xd4, 0x52, 0xdc, 0x85, + 0x75, 0x03, 0x87, 0x09, 0x4a, 0x26, 0x41, 0xba, 0x1a, 0x20, 0xb9, 0xc6, 0x52, 0xfe, 0x81, 0x1e, + 0x5c, 0xf0, 0x93, 0x27, 0x35, 0x11, 0xaa, 0xfc, 0xec, 0x29, 0xe7, 0x6d, 0xa2, 0xac, 0xc8, 0x85, + 0x4e, 0x1d, 0xec, 0x52, 0xfc, 0x99, 0xa9, 0x61, 0x26, 0xeb, 0x4c, 0x24, 0xa3, 0xec, 0xc3, 0xf2, + 0x69, 0xec, 0x4b, 0x70, 0xb1, 0xde, 0xef, 0xf5, 0x3a, 0x2e, 0x6d, 0x6a, 0x17, 0x95, 0xfd, 0x53, + 0x30, 0x25, 0x6f, 0x94, 0xea, 0xbd, 0xfc, 0x4c, 0xcf, 0x8a, 0xd8, 0x7f, 0x64, 0xc1, 0x54, 0x2a, + 0xa6, 0x40, 0x3e, 0x4c, 0xef, 0xc0, 0xb9, 0x78, 0x1c, 0xcd, 0xcd, 0x57, 0xac, 0xb2, 0xcc, 0xdd, + 0xbc, 0xad, 0x72, 0x44, 0x72, 0x4b, 0xb5, 0xe2, 0x99, 0x14, 0x42, 0xa5, 0x9b, 0x89, 0x26, 0xf6, + 0xcf, 0x17, 0x20, 0x3b, 0x90, 0x43, 0xbe, 0x3a, 0xd8, 0x01, 0x6f, 0xe7, 0xd8, 0x01, 0x32, 0x92, + 0x34, 0xbc, 0x0f, 0xbc, 0x64, 0x1f, 0xac, 0xe7, 0xd4, 0x07, 0x52, 0xee, 0x60, 0x4f, 0xfc, 0xa1, + 0x05, 0x95, 0xed, 0xed, 0xfb, 0xfa, 0xc4, 0x8b, 0x70, 0x35, 0x14, 0xf7, 0x88, 0x17, 0x76, 0x23, + 0x1a, 0x2c, 0xfa, 0xdd, 0x5e, 0x87, 0xea, 0x09, 0x25, 0x2f, 0xf7, 0xd6, 0x33, 0x29, 0x70, 0x48, + 0x49, 0x72, 0x0f, 0x2e, 0x99, 0x18, 0xe9, 0xb7, 0xe0, 0x2d, 0x2c, 0xca, 0xd4, 0xfe, 0x41, 0x34, + 0x66, 0x95, 0x49, 0xb3, 0x92, 0xce, 0x0b, 0xf9, 0x0a, 0xe2, 0x00, 0x2b, 0x89, 0xc6, 0xac, 0x32, + 0xf6, 0x26, 0x54, 0x8c, 0x37, 0x39, 0xc9, 0xe7, 0x61, 0xba, 0xe1, 0x77, 0x7b, 0x01, 0x0d, 0x43, + 0xd7, 0xf7, 0xee, 0xd3, 0x7d, 0xda, 0x91, 0x4d, 0xe6, 0x7e, 0x85, 0xc5, 0x14, 0x0e, 0x07, 0xa8, + 0xed, 0xff, 0x7b, 0x1d, 0xf4, 0x75, 0xd4, 0x53, 0x6c, 0x11, 0x3d, 0x1d, 0xe2, 0x2e, 0xe6, 0x1c, + 0xe2, 0xd6, 0xfa, 0x2e, 0x15, 0xe6, 0x8e, 0xe2, 0x30, 0xf7, 0x58, 0xde, 0x61, 0x6e, 0x6d, 0xf1, + 0x0d, 0x84, 0xba, 0x7f, 0xd5, 0x82, 0x09, 0xcf, 0x6f, 0x52, 0xed, 0x97, 0x1e, 0xe7, 0x66, 0xe7, + 0x7b, 0xf9, 0xe5, 0xee, 0x88, 0x90, 0xad, 0x64, 0x2f, 0x12, 0x21, 0xf4, 0x36, 0x61, 0xa2, 0x30, + 0x51, 0x0f, 0xb2, 0x6c, 0xb8, 0x31, 0xc4, 0x0d, 0xd2, 0xeb, 0x59, 0xe6, 0xff, 0x93, 0x7c, 0x12, + 0xe4, 0xd0, 0x30, 0x7c, 0xca, 0x79, 0x39, 0x21, 0x54, 0xbe, 0xa3, 0xe1, 0x6d, 0x54, 0xf7, 0xd3, + 0x63, 0x83, 0xc8, 0x86, 0x31, 0x91, 0x31, 0x21, 0x5f, 0x87, 0xe4, 0x4e, 0x70, 0x91, 0x4d, 0x81, + 0x12, 0x43, 0x22, 0x15, 0x3f, 0xaa, 0xe4, 0xf5, 0xac, 0x4b, 0x22, 0x3e, 0x95, 0x1d, 0x40, 0x22, + 0x6f, 0x99, 0xa7, 0xca, 0x89, 0xd3, 0x9c, 0x2a, 0x27, 0x87, 0x9e, 0x28, 0x7f, 0xd1, 0x82, 0x89, + 0x86, 0xf1, 0x6e, 0x4d, 0xf5, 0xd5, 0xbc, 0x1e, 0x67, 0xca, 0x7a, 0x0d, 0x47, 0x5c, 0xfd, 0x35, + 0x31, 0x98, 0x90, 0xce, 0x2f, 0x8b, 0xf2, 0x23, 0x34, 0x4f, 0x61, 0xa9, 0xdc, 0xde, 0xca, 0x61, + 0x7b, 0x48, 0x1c, 0xc9, 0xc5, 0x30, 0x0a, 0x18, 0x4a, 0x59, 0xe4, 0x23, 0x28, 0xa9, 0xa4, 0x1b, + 0x99, 0x12, 0x83, 0x79, 0xf8, 0xdc, 0x92, 0x1e, 0x75, 0x75, 0x57, 0x4e, 0x40, 0x51, 0x4b, 0x24, + 0x6d, 0x18, 0x69, 0x3a, 0x2d, 0x99, 0x1c, 0xb3, 0x9e, 0xcf, 0x0d, 0x5e, 0x25, 0x93, 0x9f, 0x8f, + 0x96, 0x16, 0x56, 0x90, 0x89, 0x20, 0x87, 0xf1, 0xf3, 0x19, 0xd3, 0xb9, 0xed, 0xbe, 0x49, 0x33, + 0x49, 0x38, 0x09, 0x06, 0x5e, 0xe3, 0x68, 0xca, 0x20, 0xc4, 0x9f, 0xe2, 0x62, 0x97, 0xf3, 0xb9, + 0x02, 0x2c, 0xde, 0xc7, 0x8c, 0x03, 0x19, 0xe4, 0x2e, 0x8c, 0x8b, 0xa7, 0x89, 0x44, 0x22, 0x4f, + 0xe5, 0xf6, 0xcc, 0xf0, 0x07, 0x8e, 0x62, 0xa5, 0x2a, 0xfe, 0x87, 0xa8, 0xca, 0x92, 0x5f, 0xb6, + 0xe0, 0x02, 0xd3, 0x3e, 0xf1, 0x5b, 0x4a, 0x55, 0x92, 0xd7, 0xfa, 0x7e, 0x10, 0xb2, 0xdd, 0x5b, + 0xad, 0x4b, 0x6d, 0xd6, 0xdf, 0x4b, 0x88, 0xc3, 0x94, 0x78, 0xf2, 0x31, 0x94, 0x42, 0xb7, 0x49, + 0x1b, 0x4e, 0x10, 0x56, 0x2f, 0x9d, 0x4f, 0x55, 0x62, 0x7f, 0xac, 0x14, 0x84, 0x5a, 0x24, 0xf9, + 0x5b, 0xfc, 0x39, 0x43, 0xf9, 0x7c, 0xad, 0x7c, 0xce, 0xf8, 0xf2, 0xb9, 0x3d, 0x67, 0x2c, 0x3c, + 0x9d, 0x49, 0x71, 0x98, 0x96, 0x4f, 0xfe, 0x8a, 0x05, 0x57, 0xc4, 0x0b, 0x1f, 0xe9, 0xe7, 0x5d, + 0xae, 0x7c, 0x42, 0x5f, 0x02, 0xcf, 0x40, 0x5a, 0xc8, 0x62, 0x89, 0xd9, 0x92, 0xf8, 0xf5, 0xed, + 0xc0, 0x8c, 0x69, 0xf0, 0x3c, 0xb0, 0xfc, 0x3c, 0xf6, 0xfa, 0x75, 0x64, 0x1e, 0x32, 0x4e, 0x80, + 0x30, 0x29, 0x98, 0xbc, 0x0e, 0x95, 0x9e, 0xdc, 0x3a, 0xdc, 0xb0, 0xcb, 0xf3, 0xc9, 0x46, 0x44, + 0xce, 0xed, 0x56, 0x0c, 0x46, 0x93, 0x86, 0x3c, 0x80, 0x4a, 0xe4, 0x77, 0x68, 0x20, 0xcf, 0x4b, + 0x55, 0x3e, 0xaf, 0x6e, 0x64, 0xad, 0x98, 0x6d, 0x4d, 0x16, 0x9f, 0xa7, 0x62, 0x58, 0x88, 0x26, + 0x1f, 0x76, 0xfe, 0x55, 0xaf, 0x01, 0x05, 0xfc, 0x78, 0xfe, 0x7c, 0xf2, 0xfc, 0x5b, 0x37, 0x91, + 0x98, 0xa4, 0x25, 0x2b, 0x70, 0xb1, 0x17, 0xb8, 0x7e, 0xe0, 0x46, 0x47, 0x8b, 0x1d, 0x27, 0x0c, + 0x39, 0x03, 0x91, 0x27, 0xaa, 0x43, 0x7c, 0x5b, 0x69, 0x02, 0x1c, 0x2c, 0x43, 0x5e, 0x85, 0x92, + 0x02, 0x56, 0x5f, 0xe0, 0x96, 0xe6, 0x84, 0xc8, 0x31, 0x15, 0x30, 0xd4, 0xd8, 0x21, 0xf7, 0xd5, + 0xaf, 0x7f, 0x92, 0xfb, 0xea, 0xa4, 0x09, 0xd7, 0x9d, 0x7e, 0xe4, 0xf3, 0xcb, 0x56, 0xc9, 0x22, + 0xdb, 0xfe, 0x1e, 0xf5, 0xaa, 0x37, 0x45, 0x6e, 0xd0, 0xc9, 0xf1, 0xec, 0xf5, 0x85, 0xc7, 0xd0, + 0xe1, 0x63, 0xb9, 0x90, 0xaf, 0x40, 0x89, 0xca, 0x3b, 0xf7, 0xd5, 0x1f, 0xcb, 0x6b, 0x9b, 0x4c, + 0xde, 0xe2, 0x57, 0x39, 0x34, 0x02, 0x86, 0x5a, 0x1e, 0xd9, 0x86, 0x4a, 0xdb, 0x0f, 0xa3, 0x85, + 0x8e, 0xeb, 0x84, 0x34, 0xac, 0xbe, 0xc8, 0x27, 0x4d, 0xa6, 0xf5, 0xb1, 0xaa, 0xc8, 0xe2, 0x39, + 0xb3, 0x1a, 0x97, 0x44, 0x93, 0x0d, 0xa1, 0x3c, 0x6c, 0xd1, 0xe7, 0x43, 0xe8, 0x7b, 0x11, 0x3d, + 0x8c, 0xaa, 0x37, 0x78, 0xc3, 0x5e, 0xc9, 0xe2, 0xbc, 0xe5, 0x37, 0xeb, 0x49, 0x6a, 0x1d, 0xb7, + 0x30, 0x81, 0x98, 0xe6, 0x49, 0xde, 0x84, 0x89, 0x9e, 0xdf, 0xac, 0xf7, 0x68, 0x63, 0xcb, 0x89, + 0x1a, 0xed, 0xea, 0x6c, 0xd2, 0x71, 0xb4, 0x65, 0xe0, 0x30, 0x41, 0x49, 0x7a, 0x30, 0xde, 0x15, + 0xb7, 0x44, 0xaa, 0x2f, 0xe5, 0x65, 0xdd, 0xcb, 0x6b, 0x27, 0x62, 0xc7, 0x94, 0x7f, 0x50, 0x89, + 0x21, 0x7f, 0xdf, 0x82, 0xa9, 0x54, 0xde, 0x63, 0xf5, 0xc7, 0x73, 0xdb, 0xb4, 0x93, 0x8c, 0x6b, + 0xaf, 0xf0, 0xee, 0x4b, 0x02, 0x1f, 0x0d, 0x82, 0x30, 0x5d, 0x23, 0xd1, 0x2f, 0xfc, 0xaa, 0x57, + 0xf5, 0xe5, 0xfc, 0xfa, 0x85, 0x33, 0x54, 0xfd, 0xc2, 0xff, 0xa0, 0x12, 0x43, 0x6e, 0xc1, 0x78, + 0xe4, 0x76, 0xa9, 0xdf, 0x8f, 0xaa, 0xaf, 0x24, 0x63, 0x4f, 0xdb, 0x02, 0x8c, 0x0a, 0x3f, 0xf3, + 0x53, 0x70, 0x71, 0xe0, 0xf0, 0x72, 0xa6, 0xfb, 0x46, 0xbf, 0xc6, 0xce, 0xef, 0x86, 0x17, 0x36, + 0xef, 0xc7, 0x94, 0xde, 0x84, 0x89, 0x86, 0x78, 0xc9, 0x53, 0x5c, 0x7a, 0x18, 0x4d, 0x7a, 0xe1, + 0x16, 0x0d, 0x1c, 0x26, 0x28, 0xed, 0x55, 0x20, 0x83, 0xaf, 0x90, 0x70, 0xf7, 0xe6, 0xa1, 0x3a, + 0x37, 0xcb, 0x5a, 0xc6, 0xee, 0x4d, 0x8d, 0x41, 0x83, 0xca, 0xfe, 0x47, 0x16, 0x4c, 0x26, 0x2c, + 0x81, 0xdc, 0x83, 0x56, 0xcb, 0x40, 0xba, 0x6e, 0x10, 0xf8, 0x81, 0xf9, 0x88, 0xa4, 0x7c, 0x3f, + 0x82, 0xdf, 0x4d, 0x5e, 0x1f, 0xc0, 0x62, 0x46, 0x09, 0xfb, 0x57, 0x46, 0x20, 0x4e, 0x22, 0xd3, + 0xd7, 0xf3, 0xad, 0xa1, 0xd7, 0xf3, 0x5f, 0x83, 0xd2, 0xfb, 0xa1, 0xef, 0x6d, 0xc5, 0x97, 0xf8, + 0xf5, 0x58, 0xbc, 0x55, 0xdf, 0xdc, 0xe0, 0x94, 0x9a, 0x82, 0x53, 0x7f, 0xb0, 0xec, 0x76, 0xa2, + 0xc1, 0xcb, 0xed, 0x6f, 0xbd, 0x2d, 0xe0, 0xa8, 0x29, 0xf8, 0x33, 0x97, 0xfb, 0x54, 0xbb, 0x67, + 0xe3, 0x67, 0x2e, 0x19, 0x10, 0x05, 0x8e, 0xcc, 0x43, 0x59, 0x7b, 0x77, 0xa5, 0xb3, 0x59, 0xf7, + 0x94, 0xf6, 0x02, 0x63, 0x4c, 0xc3, 0xcd, 0x3c, 0xe9, 0x8a, 0x94, 0x4e, 0x84, 0x7a, 0x1e, 0x06, + 0x7a, 0xca, 0xb9, 0x29, 0x74, 0xbb, 0x02, 0xa3, 0x16, 0x69, 0x26, 0x1a, 0x16, 0x4f, 0x99, 0x68, + 0x68, 0xff, 0xb5, 0x11, 0x18, 0x7f, 0x48, 0x03, 0xfe, 0x28, 0xc7, 0x2d, 0x18, 0xdf, 0x17, 0x3f, + 0xd3, 0xd9, 0xd2, 0x92, 0x02, 0x15, 0x9e, 0x75, 0xcd, 0x4e, 0xdf, 0xed, 0x34, 0x97, 0xe2, 0x85, + 0xa2, 0xbb, 0xa6, 0xa6, 0x10, 0x18, 0xd3, 0xb0, 0x02, 0x2d, 0x66, 0x12, 0x77, 0xbb, 0x6e, 0x94, + 0xbe, 0x85, 0xba, 0xa2, 0x10, 0x18, 0xd3, 0x90, 0x57, 0x60, 0xac, 0xe5, 0x46, 0xdb, 0x4e, 0x2b, + 0x1d, 0x0b, 0x5a, 0xe1, 0x50, 0x94, 0x58, 0x1e, 0x4c, 0x70, 0xa3, 0xed, 0x80, 0x72, 0xf7, 0xe1, + 0xc0, 0xb5, 0xa9, 0x15, 0x03, 0x87, 0x09, 0x4a, 0x5e, 0x25, 0x5f, 0xb6, 0x4c, 0x3a, 0xf9, 0xe3, + 0x2a, 0x29, 0x04, 0xc6, 0x34, 0x6c, 0x8a, 0x35, 0xfc, 0x6e, 0xcf, 0xed, 0xc8, 0x5c, 0x30, 0x63, + 0x8a, 0x2d, 0x4a, 0x38, 0x6a, 0x0a, 0x46, 0xcd, 0xb4, 0x04, 0x5b, 0xe1, 0xe9, 0x57, 0xfb, 0xb6, + 0x24, 0x1c, 0x35, 0x85, 0xfd, 0x10, 0x26, 0xc5, 0x62, 0x59, 0xec, 0x38, 0x6e, 0x77, 0x65, 0x91, + 0xdc, 0x1d, 0x48, 0x78, 0xbc, 0x95, 0x91, 0xf0, 0x78, 0x25, 0x51, 0x68, 0x30, 0xf1, 0xd1, 0xfe, + 0x5e, 0x01, 0x4a, 0xcf, 0xf0, 0xe1, 0xd3, 0x5e, 0xe2, 0xe1, 0xd3, 0xbc, 0x9f, 0xbf, 0xcc, 0x7a, + 0xf4, 0xf4, 0x30, 0xf5, 0xe8, 0xe9, 0x56, 0x9e, 0x39, 0xc0, 0x8f, 0x7d, 0xf0, 0xf4, 0x07, 0x16, + 0x5c, 0x56, 0xa4, 0x5c, 0x6f, 0xd4, 0x5c, 0x8f, 0x47, 0x91, 0xcf, 0xbf, 0x9b, 0x3f, 0x4a, 0x74, + 0xf3, 0xbb, 0xf9, 0x35, 0xd9, 0x6c, 0xc7, 0xd0, 0xd7, 0xb8, 0xff, 0xc0, 0x82, 0x6a, 0x56, 0x81, + 0x67, 0xf0, 0xe2, 0xeb, 0x87, 0xc9, 0x17, 0x5f, 0x1f, 0x9e, 0x4f, 0xcb, 0x87, 0xbc, 0xfc, 0xfa, + 0x83, 0x21, 0xed, 0xe6, 0xcf, 0xac, 0x76, 0xd4, 0x8e, 0x62, 0xe5, 0x15, 0x9f, 0x11, 0x22, 0xb2, + 0xb7, 0xa6, 0x0e, 0x8c, 0x85, 0x3c, 0xe4, 0x2a, 0xa7, 0xc0, 0x6a, 0x1e, 0xfb, 0x0c, 0xe3, 0x27, + 0xfd, 0x6b, 0xfc, 0x37, 0x4a, 0x19, 0xf6, 0x7f, 0xb6, 0x60, 0xe2, 0x19, 0x3e, 0xeb, 0xeb, 0x27, + 0x07, 0xf9, 0xad, 0xfc, 0x06, 0x79, 0xc8, 0xc0, 0xfe, 0xc7, 0xeb, 0x90, 0x78, 0x41, 0x97, 0x7c, + 0x08, 0x65, 0x65, 0xe4, 0xa9, 0xbb, 0x05, 0x6f, 0xe5, 0xe7, 0x92, 0x8f, 0xb7, 0x19, 0x05, 0x09, + 0x31, 0x96, 0x97, 0x0a, 0x72, 0x17, 0x4e, 0x15, 0xe4, 0xfe, 0x74, 0x9f, 0xf5, 0xcc, 0x3e, 0x82, + 0x8f, 0x9e, 0xcb, 0x11, 0xfc, 0x7a, 0xee, 0x47, 0xf0, 0x17, 0x9f, 0xf1, 0x11, 0xdc, 0xf0, 0x72, + 0x16, 0x9f, 0xc2, 0xcb, 0xf9, 0x21, 0x5c, 0xde, 0x8f, 0x37, 0x7f, 0x3d, 0x93, 0xe4, 0xeb, 0xa4, + 0xb7, 0x32, 0x0f, 0xde, 0xcc, 0x90, 0x09, 0x23, 0xea, 0x45, 0x86, 0xd9, 0xa0, 0x2f, 0xf0, 0x5e, + 0x7e, 0x98, 0xc1, 0x0e, 0x33, 0x85, 0xa4, 0xdd, 0x55, 0xe3, 0xa7, 0x70, 0x57, 0xfd, 0xe3, 0xa1, + 0xdf, 0xa7, 0x29, 0x9d, 0xef, 0xf7, 0x69, 0x9e, 0x3f, 0xf3, 0xb7, 0x69, 0x5e, 0x8e, 0xfd, 0xec, + 0x22, 0xb1, 0x22, 0xdb, 0x29, 0xfe, 0x1b, 0xe9, 0xe0, 0x1d, 0xf0, 0xae, 0xff, 0x72, 0xbe, 0x56, + 0x4f, 0x0e, 0x01, 0xbc, 0xca, 0x53, 0x04, 0xf0, 0x52, 0x5e, 0xc6, 0x89, 0x9c, 0xbc, 0x8c, 0x1e, + 0x4c, 0xbb, 0x5d, 0xa7, 0x45, 0xb7, 0xfa, 0x9d, 0x8e, 0xc8, 0x4a, 0x0d, 0xab, 0x93, 0x9c, 0x77, + 0x66, 0x9a, 0xe1, 0x7d, 0xbf, 0xe1, 0x74, 0xd2, 0x2f, 0x46, 0xeb, 0x34, 0xfd, 0x7b, 0x29, 0x4e, + 0x38, 0xc0, 0x9b, 0x4d, 0x58, 0x7e, 0x8d, 0x97, 0x46, 0xac, 0xb7, 0x79, 0x94, 0x48, 0x7e, 0xe4, + 0x6d, 0x35, 0x06, 0xa3, 0x49, 0x43, 0xd6, 0xa0, 0xdc, 0xf4, 0x42, 0x99, 0x8a, 0x3e, 0xc5, 0x95, + 0xd9, 0x67, 0x98, 0x0a, 0x5c, 0xda, 0xa8, 0xeb, 0x24, 0xf4, 0xeb, 0x19, 0x37, 0xc4, 0x35, 0x1e, + 0xe3, 0xf2, 0x64, 0x9d, 0x33, 0x93, 0x4f, 0xc6, 0x89, 0xe0, 0xcd, 0xcd, 0x21, 0xbe, 0xb1, 0xa5, + 0x0d, 0xf5, 0xc4, 0xdd, 0xa4, 0x14, 0x27, 0xdf, 0x7e, 0x8b, 0x39, 0x18, 0x4f, 0xd8, 0x5e, 0x7c, + 0xec, 0x13, 0xb6, 0xfc, 0x69, 0x88, 0xa8, 0xa3, 0xfd, 0xdb, 0x37, 0x72, 0x7b, 0x1a, 0x22, 0x4e, + 0x8b, 0x90, 0x4f, 0x43, 0xc4, 0x00, 0x34, 0x45, 0x92, 0xcd, 0x61, 0x7e, 0xfe, 0x4b, 0x5c, 0x69, + 0x9c, 0xdd, 0x6b, 0x6f, 0xba, 0x86, 0x2f, 0x3f, 0xd6, 0x35, 0x3c, 0xe0, 0xca, 0xbe, 0x72, 0x06, + 0x57, 0x76, 0x9b, 0x5f, 0xda, 0x5f, 0x59, 0x94, 0x31, 0x81, 0x1c, 0x0c, 0x3a, 0x7e, 0x39, 0x4d, + 0xa4, 0x99, 0xf0, 0x9f, 0x28, 0x04, 0x90, 0x2d, 0xb8, 0xdc, 0xf3, 0x9b, 0x03, 0x6e, 0x71, 0x1e, + 0x04, 0x88, 0xdf, 0x57, 0xb8, 0xbc, 0x95, 0x41, 0x83, 0x99, 0x25, 0xb9, 0x7a, 0x8e, 0xe1, 0xfc, + 0xf5, 0x87, 0xa2, 0x54, 0xcf, 0x31, 0x18, 0x4d, 0x9a, 0xb4, 0x63, 0xf8, 0xf9, 0x73, 0x73, 0x0c, + 0xcf, 0x3c, 0x03, 0xc7, 0xf0, 0x0b, 0xa7, 0x76, 0x0c, 0x7f, 0x0c, 0x97, 0x7a, 0x7e, 0x73, 0xc9, + 0x0d, 0x83, 0x3e, 0x4f, 0x1f, 0xaf, 0xf5, 0x9b, 0x2d, 0x1a, 0x71, 0xcf, 0x72, 0xe5, 0xf6, 0x6d, + 0xb3, 0x92, 0xe2, 0x0b, 0xc2, 0x73, 0xf2, 0x0b, 0xc2, 0x7c, 0xa1, 0xa6, 0x4a, 0xf1, 0x03, 0x13, + 0xcf, 0xb3, 0xc9, 0x40, 0x62, 0x96, 0x1c, 0xd3, 0x2f, 0x7d, 0xf3, 0xd9, 0xf8, 0xa5, 0x3f, 0x0f, + 0xa5, 0xb0, 0xdd, 0x8f, 0x9a, 0xfe, 0x81, 0xc7, 0x83, 0x0f, 0x65, 0xfd, 0x51, 0x89, 0x52, 0x5d, + 0xc2, 0x1f, 0x1d, 0xcf, 0x4e, 0xab, 0xdf, 0x86, 0x4b, 0x41, 0x42, 0xc8, 0xb7, 0x87, 0xa4, 0xdc, + 0xda, 0xe7, 0x99, 0x72, 0x7b, 0xed, 0x4c, 0xe9, 0xb6, 0x59, 0xce, 0xf7, 0x97, 0x7e, 0xe8, 0x9c, + 0xef, 0xbf, 0x6e, 0xc1, 0xe4, 0xbe, 0xe9, 0xbf, 0x91, 0x01, 0x82, 0x1c, 0xc2, 0x8f, 0x09, 0xb7, + 0x50, 0xcd, 0x66, 0xca, 0x2e, 0x01, 0x7a, 0x94, 0x06, 0x60, 0xb2, 0x26, 0x19, 0xa1, 0xd1, 0x97, + 0x3f, 0xad, 0xd0, 0xe8, 0xc7, 0x5c, 0x99, 0xa9, 0x0c, 0x1f, 0x1e, 0x35, 0xc8, 0x37, 0x8b, 0x48, + 0x29, 0x46, 0x9d, 0x44, 0x64, 0xca, 0x7b, 0xfa, 0x28, 0xc4, 0xef, 0x11, 0xb8, 0x90, 0xfa, 0x40, + 0xc6, 0x67, 0xd5, 0x8b, 0x47, 0xc2, 0xb3, 0x77, 0x23, 0xfd, 0xe2, 0xd1, 0xa4, 0xa2, 0x4f, 0xbc, + 0x7a, 0x94, 0x78, 0x96, 0xa8, 0x70, 0xae, 0xcf, 0x12, 0x8d, 0x3c, 0x9b, 0x67, 0x89, 0xa6, 0xcf, + 0xe3, 0x59, 0xa2, 0x8b, 0x67, 0x7a, 0x96, 0xc8, 0x78, 0x16, 0x6a, 0xf4, 0x09, 0xcf, 0x42, 0x2d, + 0xc0, 0x94, 0xca, 0x6b, 0xa4, 0xf2, 0xbd, 0x19, 0xe1, 0x6d, 0xd6, 0x5f, 0x70, 0x5c, 0x4c, 0xa2, + 0x31, 0x4d, 0x4f, 0xbe, 0x61, 0x41, 0xd1, 0xe3, 0x25, 0xc7, 0xf2, 0x7a, 0x8b, 0x30, 0x39, 0xb5, + 0xf8, 0x69, 0x41, 0xbe, 0x00, 0xa8, 0xb2, 0x53, 0x8a, 0x1c, 0xf6, 0x48, 0xfd, 0x40, 0x51, 0x03, + 0xf2, 0x1e, 0x54, 0xfd, 0xdd, 0xdd, 0x8e, 0xef, 0x34, 0xe3, 0xb7, 0x93, 0x94, 0x3b, 0x5c, 0xe4, + 0x86, 0xeb, 0x47, 0x30, 0x36, 0x87, 0xd0, 0xe1, 0x50, 0x0e, 0xec, 0xb8, 0x37, 0x15, 0x46, 0x7e, + 0x40, 0x9b, 0xf1, 0xd1, 0xb4, 0xcc, 0xdb, 0x4c, 0x73, 0x6f, 0x73, 0x3d, 0x29, 0x47, 0xb4, 0x5e, + 0x0f, 0x4a, 0x0a, 0x8b, 0xe9, 0x6a, 0x91, 0x00, 0xae, 0xf6, 0xb2, 0x4e, 0xc6, 0xa1, 0xcc, 0xc6, + 0x7c, 0xdc, 0xf9, 0x5c, 0x2d, 0xdd, 0xab, 0x99, 0x67, 0xeb, 0x10, 0x87, 0x70, 0x36, 0x5f, 0x55, + 0x2a, 0x3d, 0x9b, 0x57, 0x95, 0x92, 0x9f, 0xb5, 0x99, 0x7c, 0xe6, 0x9f, 0xb5, 0x21, 0x7f, 0x9c, + 0xf9, 0x00, 0x98, 0x38, 0x50, 0xb6, 0x72, 0x9f, 0x13, 0x3f, 0x74, 0x8f, 0x80, 0xfd, 0x43, 0x0b, + 0x66, 0xc4, 0xcc, 0xcb, 0xfa, 0xec, 0xa5, 0xcc, 0x5b, 0xcc, 0x3b, 0x62, 0xc2, 0xe3, 0xb3, 0xf5, + 0x84, 0x54, 0xee, 0xc8, 0x7f, 0x4c, 0x4d, 0xc8, 0xaf, 0x66, 0x18, 0x4f, 0x53, 0x79, 0xb9, 0x68, + 0xb2, 0x1f, 0x8f, 0xba, 0x74, 0x72, 0x1a, 0x7b, 0xe9, 0x9f, 0x0d, 0xf5, 0x20, 0x11, 0x5e, 0xbd, + 0xbf, 0x74, 0x4e, 0x1e, 0x24, 0xf3, 0x85, 0xab, 0xb3, 0xf8, 0x91, 0x66, 0x7e, 0xce, 0x12, 0x8f, + 0x50, 0x0e, 0x7d, 0x2a, 0x75, 0xc7, 0x34, 0x1a, 0x72, 0x79, 0xac, 0x34, 0x56, 0xc4, 0xe6, 0x9b, + 0xad, 0x7f, 0xc3, 0x82, 0xcb, 0x59, 0x4a, 0x32, 0xa3, 0x4a, 0x5f, 0x4e, 0x56, 0x29, 0x47, 0xb7, + 0xb7, 0x59, 0xa1, 0x7c, 0xde, 0xfe, 0xfa, 0xf7, 0x63, 0x86, 0xdf, 0x3e, 0xa2, 0xbd, 0x3f, 0xf9, + 0x5a, 0x56, 0xde, 0xef, 0x7a, 0x26, 0xbe, 0x7b, 0x55, 0xfc, 0xb4, 0xbe, 0x7b, 0x35, 0xf6, 0x49, + 0xbe, 0x7b, 0x35, 0xfe, 0xa9, 0x7d, 0xf7, 0xaa, 0x74, 0xca, 0xef, 0x5e, 0x95, 0x7f, 0x38, 0xbf, + 0x7b, 0x65, 0xff, 0x1f, 0x0b, 0xa6, 0x7f, 0xa4, 0x3e, 0x2f, 0xfd, 0xbf, 0x8d, 0x48, 0xfe, 0x33, + 0xfc, 0xae, 0xf4, 0x41, 0x32, 0xce, 0x89, 0xf9, 0xb7, 0x78, 0x48, 0xbc, 0xf3, 0x03, 0xc8, 0x72, + 0xa5, 0x9c, 0xee, 0xe6, 0x6e, 0x22, 0xe1, 0xad, 0x70, 0xea, 0x84, 0xb7, 0x5f, 0x2a, 0x0c, 0x76, + 0x31, 0xb7, 0x36, 0xbe, 0xfe, 0x6c, 0xbe, 0x9c, 0x7a, 0x39, 0xeb, 0xcb, 0xa9, 0xa9, 0x2f, 0xa5, + 0xa6, 0xbf, 0x9c, 0x59, 0x38, 0xc7, 0x2f, 0x67, 0x4e, 0x42, 0xe5, 0x5d, 0xb7, 0xa7, 0xbd, 0x20, + 0x73, 0xdf, 0xfd, 0xfe, 0x8d, 0xe7, 0x7e, 0xe7, 0xfb, 0x37, 0x9e, 0xfb, 0xde, 0xf7, 0x6f, 0x3c, + 0xf7, 0xb5, 0x93, 0x1b, 0xd6, 0x77, 0x4f, 0x6e, 0x58, 0xbf, 0x73, 0x72, 0xc3, 0xfa, 0xde, 0xc9, + 0x0d, 0xeb, 0xbf, 0x9c, 0xdc, 0xb0, 0xfe, 0xe6, 0x7f, 0xbd, 0xf1, 0xdc, 0xbb, 0x25, 0xd5, 0xb6, + 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xba, 0x38, 0x7a, 0x05, 0xc2, 0x8d, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -4173,6 +4237,99 @@ func (m *Condition) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContainerNode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContainerNode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContainerNode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Dependencies) > 0 { + for iNdEx := len(m.Dependencies) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Dependencies[iNdEx]) + copy(dAtA[i:], m.Dependencies[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Dependencies[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Container.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ContainerSetTemplate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContainerSetTemplate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContainerSetTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Containers) > 0 { + for iNdEx := len(m.Containers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Containers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.VolumeMounts) > 0 { + for iNdEx := len(m.VolumeMounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VolumeMounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + return len(dAtA) - i, nil +} + func (m *ContinueOn) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -7420,6 +7577,20 @@ func (m *Template) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ContainerSet != nil { + { + size, err := m.ContainerSet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xc2 + } if m.Data != nil { { size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) @@ -9574,42 +9745,80 @@ func (m *ClusterWorkflowTemplate) Size() (n int) { } var l int _ = l - l = m.ObjectMeta.Size() + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ClusterWorkflowTemplateList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *Condition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() + l = len(m.Status) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ClusterWorkflowTemplateList) Size() (n int) { +func (m *ContainerNode) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ListMeta.Size() + l = m.Container.Size() n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() + if len(m.Dependencies) > 0 { + for _, s := range m.Dependencies { + l = len(s) n += 1 + l + sovGenerated(uint64(l)) } } return n } -func (m *Condition) Size() (n int) { +func (m *ContainerSetTemplate) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) + if len(m.VolumeMounts) > 0 { + for _, e := range m.VolumeMounts { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Containers) > 0 { + for _, e := range m.Containers { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -10964,6 +11173,10 @@ func (m *Template) Size() (n int) { l = m.Data.Size() n += 2 + l + sovGenerated(uint64(l)) } + if m.ContainerSet != nil { + l = m.ContainerSet.Size() + n += 2 + l + sovGenerated(uint64(l)) + } return n } @@ -11658,6 +11871,38 @@ func (this *Condition) String() string { }, "") return s } +func (this *ContainerNode) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ContainerNode{`, + `Container:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Container), "Container", "v1.Container", 1), `&`, ``, 1) + `,`, + `Dependencies:` + fmt.Sprintf("%v", this.Dependencies) + `,`, + `}`, + }, "") + return s +} +func (this *ContainerSetTemplate) String() string { + if this == nil { + return "nil" + } + repeatedStringForVolumeMounts := "[]VolumeMount{" + for _, f := range this.VolumeMounts { + repeatedStringForVolumeMounts += fmt.Sprintf("%v", f) + "," + } + repeatedStringForVolumeMounts += "}" + repeatedStringForContainers := "[]ContainerNode{" + for _, f := range this.Containers { + repeatedStringForContainers += strings.Replace(strings.Replace(f.String(), "ContainerNode", "ContainerNode", 1), `&`, ``, 1) + "," + } + repeatedStringForContainers += "}" + s := strings.Join([]string{`&ContainerSetTemplate{`, + `VolumeMounts:` + repeatedStringForVolumeMounts + `,`, + `Containers:` + repeatedStringForContainers + `,`, + `}`, + }, "") + return s +} func (this *ContinueOn) String() string { if this == nil { return "nil" @@ -12634,6 +12879,7 @@ func (this *Template) String() string { `Memoize:` + strings.Replace(this.Memoize.String(), "Memoize", "Memoize", 1) + `,`, `Timeout:` + fmt.Sprintf("%v", this.Timeout) + `,`, `Data:` + strings.Replace(this.Data.String(), "Data", "Data", 1) + `,`, + `ContainerSet:` + strings.Replace(this.ContainerSet.String(), "ContainerSetTemplate", "ContainerSetTemplate", 1) + `,`, `}`, }, "") return s @@ -14740,7 +14986,217 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Factor", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Factor", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Factor == nil { + m.Factor = &intstr.IntOrString{} + } + if err := m.Factor.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxDuration", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MaxDuration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Cache) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Cache: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Cache: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConfigMap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConfigMap == nil { + m.ConfigMap = &v1.ConfigMapKeySelector{} + } + if err := m.ConfigMap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterWorkflowTemplate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterWorkflowTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14767,18 +15223,15 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Factor == nil { - m.Factor = &intstr.IntOrString{} - } - if err := m.Factor.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxDuration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14788,23 +15241,24 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.MaxDuration = string(dAtA[iNdEx:postIndex]) + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -14830,7 +15284,7 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { } return nil } -func (m *Cache) Unmarshal(dAtA []byte) error { +func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14853,15 +15307,15 @@ func (m *Cache) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Cache: wiretype end group for non-group") + return fmt.Errorf("proto: ClusterWorkflowTemplateList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Cache: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ClusterWorkflowTemplateList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConfigMap", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14888,10 +15342,41 @@ func (m *Cache) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ConfigMap == nil { - m.ConfigMap = &v1.ConfigMapKeySelector{} + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.ConfigMap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ClusterWorkflowTemplate{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14919,7 +15404,7 @@ func (m *Cache) Unmarshal(dAtA []byte) error { } return nil } -func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { +func (m *Condition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14942,17 +15427,17 @@ func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ClusterWorkflowTemplate: wiretype end group for non-group") + return fmt.Errorf("proto: Condition: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ClusterWorkflowTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Condition: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14962,30 +15447,29 @@ func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Type = ConditionType(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14995,24 +15479,55 @@ func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Status = k8s_io_apimachinery_pkg_apis_meta_v1.ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -15038,7 +15553,7 @@ func (m *ClusterWorkflowTemplate) Unmarshal(dAtA []byte) error { } return nil } -func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { +func (m *ContainerNode) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -15061,15 +15576,15 @@ func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ClusterWorkflowTemplateList: wiretype end group for non-group") + return fmt.Errorf("proto: ContainerNode: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ClusterWorkflowTemplateList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContainerNode: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -15096,15 +15611,15 @@ func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Container.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15114,25 +15629,23 @@ func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, ClusterWorkflowTemplate{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Dependencies = append(m.Dependencies, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -15158,7 +15671,7 @@ func (m *ClusterWorkflowTemplateList) Unmarshal(dAtA []byte) error { } return nil } -func (m *Condition) Unmarshal(dAtA []byte) error { +func (m *ContainerSetTemplate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -15181,17 +15694,17 @@ func (m *Condition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Condition: wiretype end group for non-group") + return fmt.Errorf("proto: ContainerSetTemplate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Condition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContainerSetTemplate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field VolumeMounts", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15201,61 +15714,31 @@ func (m *Condition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = ConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF + m.VolumeMounts = append(m.VolumeMounts, v1.VolumeMount{}) + if err := m.VolumeMounts[len(m.VolumeMounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Status = k8s_io_apimachinery_pkg_apis_meta_v1.ConditionStatus(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Containers", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15265,23 +15748,25 @@ func (m *Condition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Message = string(dAtA[iNdEx:postIndex]) + m.Containers = append(m.Containers, ContainerNode{}) + if err := m.Containers[len(m.Containers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -26739,6 +27224,42 @@ func (m *Template) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 40: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ContainerSet == nil { + m.ContainerSet = &ContainerSetTemplate{} + } + if err := m.ContainerSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index 192f512d6904..520794282bdc 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -203,6 +203,18 @@ message Condition { optional string message = 3; } +message ContainerNode { + optional k8s.io.api.core.v1.Container container = 1; + + repeated string dependencies = 2; +} + +message ContainerSetTemplate { + repeated ContainerNode containers = 4; + + repeated k8s.io.api.core.v1.VolumeMount volumeMounts = 3; +} + // ContinueOn defines if a workflow should continue even if a task or step fails/errors. // It can be specified if the workflow should continue when the pod errors, fails or both. message ContinueOn { @@ -1102,6 +1114,9 @@ message Template { // Container is the main container image to run in the pod optional k8s.io.api.core.v1.Container container = 12; + // ContainerSet groups multiple containers within a single pod. + optional ContainerSetTemplate containerSet = 40; + // Script runs a portion of code against an interpreter optional ScriptTemplate script = 13; diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 3d4af05826a3..9deaaddcdf3b 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -28,6 +28,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ClusterWorkflowTemplate": schema_pkg_apis_workflow_v1alpha1_ClusterWorkflowTemplate(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ClusterWorkflowTemplateList": schema_pkg_apis_workflow_v1alpha1_ClusterWorkflowTemplateList(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Condition": schema_pkg_apis_workflow_v1alpha1_Condition(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerNode": schema_pkg_apis_workflow_v1alpha1_ContainerNode(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerSetTemplate": schema_pkg_apis_workflow_v1alpha1_ContainerSetTemplate(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContinueOn": schema_pkg_apis_workflow_v1alpha1_ContinueOn(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Counter": schema_pkg_apis_workflow_v1alpha1_Counter(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.CreateS3BucketOptions": schema_pkg_apis_workflow_v1alpha1_CreateS3BucketOptions(ref), @@ -860,6 +862,306 @@ func schema_pkg_apis_workflow_v1alpha1_Condition(ref common.ReferenceCallback) c } } +func schema_pkg_apis_workflow_v1alpha1_ContainerNode(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "image": { + SchemaProps: spec.SchemaProps{ + Description: "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + Type: []string{"string"}, + Format: "", + }, + }, + "command": { + SchemaProps: spec.SchemaProps{ + Description: "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "args": { + SchemaProps: spec.SchemaProps{ + Description: "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "workingDir": { + SchemaProps: spec.SchemaProps{ + Description: "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "ports": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "containerPort", + "protocol", + }, + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.ContainerPort"), + }, + }, + }, + }, + }, + "envFrom": { + SchemaProps: spec.SchemaProps{ + Description: "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + }, + }, + }, + }, + }, + "env": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of environment variables to set in the container. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvVar"), + }, + }, + }, + }, + }, + "resources": { + SchemaProps: spec.SchemaProps{ + Description: "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.ResourceRequirements"), + }, + }, + "volumeMounts": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Pod volumes to mount into the container's filesystem. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeMount"), + }, + }, + }, + }, + }, + "volumeDevices": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "volumeDevices is the list of block devices to be used by the container.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + }, + }, + }, + }, + }, + "livenessProbe": { + SchemaProps: spec.SchemaProps{ + Description: "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "readinessProbe": { + SchemaProps: spec.SchemaProps{ + Description: "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "startupProbe": { + SchemaProps: spec.SchemaProps{ + Description: "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "lifecycle": { + SchemaProps: spec.SchemaProps{ + Description: "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", + Ref: ref("k8s.io/api/core/v1.Lifecycle"), + }, + }, + "terminationMessagePath": { + SchemaProps: spec.SchemaProps{ + Description: "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "terminationMessagePolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "imagePullPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + Type: []string{"string"}, + Format: "", + }, + }, + "securityContext": { + SchemaProps: spec.SchemaProps{ + Description: "Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", + Ref: ref("k8s.io/api/core/v1.SecurityContext"), + }, + }, + "stdin": { + SchemaProps: spec.SchemaProps{ + Description: "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "stdinOnce": { + SchemaProps: spec.SchemaProps{ + Description: "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + Type: []string{"boolean"}, + Format: "", + }, + }, + "tty": { + SchemaProps: spec.SchemaProps{ + Description: "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "dependencies": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"name"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount"}, + } +} + +func schema_pkg_apis_workflow_v1alpha1_ContainerSetTemplate(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "containers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerNode"), + }, + }, + }, + }, + }, + "volumeMounts": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeMount"), + }, + }, + }, + }, + }, + }, + Required: []string{"containers"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerNode", "k8s.io/api/core/v1.VolumeMount"}, + } +} + func schema_pkg_apis_workflow_v1alpha1_ContinueOn(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3965,6 +4267,12 @@ func schema_pkg_apis_workflow_v1alpha1_Template(ref common.ReferenceCallback) co Ref: ref("k8s.io/api/core/v1.Container"), }, }, + "containerSet": { + SchemaProps: spec.SchemaProps{ + Description: "ContainerSet groups multiple containers within a single pod.", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerSetTemplate"), + }, + }, "script": { SchemaProps: spec.SchemaProps{ Description: "Script runs a portion of code against an interpreter", @@ -4204,7 +4512,7 @@ func schema_pkg_apis_workflow_v1alpha1_Template(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactLocation", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Data", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ExecutorConfig", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Inputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Memoize", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metadata", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metrics", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Outputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ParallelSteps", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ResourceTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RetryStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ScriptTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SuspendTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Synchronization", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.UserContainer", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.HostAlias", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactLocation", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ContainerSetTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Data", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ExecutorConfig", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Inputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Memoize", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metadata", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metrics", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Outputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ParallelSteps", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ResourceTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RetryStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ScriptTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SuspendTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Synchronization", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.UserContainer", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.HostAlias", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, } } diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go index 678fb02d69c2..18d374419b4c 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types.go @@ -26,14 +26,15 @@ type TemplateType string // Possible template types const ( - TemplateTypeContainer TemplateType = "Container" - TemplateTypeSteps TemplateType = "Steps" - TemplateTypeScript TemplateType = "Script" - TemplateTypeResource TemplateType = "Resource" - TemplateTypeDAG TemplateType = "DAG" - TemplateTypeSuspend TemplateType = "Suspend" - TemplateTypeData TemplateType = "Data" - TemplateTypeUnknown TemplateType = "Unknown" + TemplateTypeContainer TemplateType = "Container" + TemplateTypeContainerSet TemplateType = "ContainerSet" + TemplateTypeSteps TemplateType = "Steps" + TemplateTypeScript TemplateType = "Script" + TemplateTypeResource TemplateType = "Resource" + TemplateTypeDAG TemplateType = "DAG" + TemplateTypeSuspend TemplateType = "Suspend" + TemplateTypeData TemplateType = "Data" + TemplateTypeUnknown TemplateType = "Unknown" ) // NodePhase is a label for the condition of a node at the current time. @@ -63,6 +64,7 @@ type NodeType string // Node types const ( NodeTypePod NodeType = "Pod" + NodeTypeContainer NodeType = "Container" NodeTypeSteps NodeType = "Steps" NodeTypeStepGroup NodeType = "StepGroup" NodeTypeDAG NodeType = "DAG" @@ -510,6 +512,9 @@ type Template struct { // Container is the main container image to run in the pod Container *apiv1.Container `json:"container,omitempty" protobuf:"bytes,12,opt,name=container"` + // ContainerSet groups multiple containers within a single pod. + ContainerSet *ContainerSetTemplate `json:"containerSet,omitempty" protobuf:"bytes,40,opt,name=containerSet"` + // Script runs a portion of code against an interpreter Script *ScriptTemplate `json:"script,omitempty" protobuf:"bytes,13,opt,name=script"` @@ -2131,6 +2136,9 @@ func (tmpl *Template) GetType() TemplateType { if tmpl.Container != nil { return TemplateTypeContainer } + if tmpl.ContainerSet != nil { + return TemplateTypeContainerSet + } if tmpl.Steps != nil { return TemplateTypeSteps } @@ -2155,7 +2163,7 @@ func (tmpl *Template) GetType() TemplateType { // IsPodType returns whether or not the template is a pod type func (tmpl *Template) IsPodType() bool { switch tmpl.GetType() { - case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: + case TemplateTypeContainer, TemplateTypeContainerSet, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: return true } return false @@ -2164,12 +2172,56 @@ func (tmpl *Template) IsPodType() bool { // IsLeaf returns whether or not the template is a leaf func (tmpl *Template) IsLeaf() bool { switch tmpl.GetType() { - case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: + case TemplateTypeContainer, TemplateTypeContainerSet, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: return true } return false } +func (tmpl *Template) IsMainContainerName(containerName string) bool { + for _, c := range tmpl.GetMainContainerNames() { + if c == containerName { + return true + } + } + return false +} + +func (tmpl *Template) GetMainContainerNames() []string { + if tmpl != nil && tmpl.ContainerSet != nil { + out := make([]string, 0) + for _, c := range tmpl.ContainerSet.GetContainers() { + out = append(out, c.Name) + } + return out + } else { + return []string{"main"} + } +} + +func (tmpl *Template) HasSequencedContainers() bool { + return tmpl != nil && tmpl.ContainerSet.HasSequencedContainers() +} + +func (tmpl *Template) GetVolumeMounts() []apiv1.VolumeMount { + if tmpl.Container != nil { + return tmpl.Container.VolumeMounts + } else if tmpl.Script != nil { + return tmpl.Script.VolumeMounts + } else if tmpl.ContainerSet != nil { + return tmpl.ContainerSet.VolumeMounts + } + return nil +} + +func (tmpl *Template) HasOutput() bool { + return tmpl.Container != nil || tmpl.ContainerSet.HasContainerNamed("main") || tmpl.Script != nil || tmpl.Data != nil +} + +func (tmpl *Template) HasLogs() bool { + return tmpl.HasOutput() || tmpl.Resource != nil +} + // DAGTemplate is a template subtype for directed acyclic graph templates type DAGTemplate struct { // Target are one or more names of targets to execute in a DAG diff --git a/pkg/apis/workflow/v1alpha1/workflow_types_test.go b/pkg/apis/workflow/v1alpha1/workflow_types_test.go index f51ace8847f8..0bfe32159971 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types_test.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types_test.go @@ -625,3 +625,94 @@ func TestTemplate_GetSidecarNames(t *testing.T) { } assert.ElementsMatch(t, []string{"sidecar-0"}, m.GetSidecarNames()) } + +func TestTemplate_IsMainContainerNamed(t *testing.T) { + t.Run("Default", func(t *testing.T) { + x := &Template{} + assert.True(t, x.IsMainContainerName("main")) + }) + t.Run("ContainerSet", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{Containers: []ContainerNode{{Container: corev1.Container{Name: "foo"}}}}} + assert.False(t, x.IsMainContainerName("main")) + assert.True(t, x.IsMainContainerName("foo")) + }) +} + +func TestTemplate_GetMainContainer(t *testing.T) { + t.Run("Default", func(t *testing.T) { + x := &Template{} + assert.Equal(t, []string{"main"}, x.GetMainContainerNames()) + }) + t.Run("ContainerSet", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{Containers: []ContainerNode{{Container: corev1.Container{Name: "foo"}}}}} + assert.Equal(t, []string{"foo"}, x.GetMainContainerNames()) + }) +} + +func TestTemplate_HasSequencedContainers(t *testing.T) { + t.Run("Default", func(t *testing.T) { + x := &Template{} + assert.False(t, x.HasSequencedContainers()) + }) + t.Run("ContainerSet", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{Containers: []ContainerNode{{Dependencies: []string{""}}}}} + assert.True(t, x.HasSequencedContainers()) + }) +} + +func TestTemplate_GetVolumeMounts(t *testing.T) { + t.Run("Default", func(t *testing.T) { + x := &Template{} + assert.Empty(t, x.GetVolumeMounts()) + }) + t.Run("Container", func(t *testing.T) { + x := &Template{Container: &corev1.Container{VolumeMounts: []corev1.VolumeMount{{}}}} + assert.NotEmpty(t, x.GetVolumeMounts()) + }) + t.Run("ContainerSet", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{VolumeMounts: []corev1.VolumeMount{{}}}} + assert.NotEmpty(t, x.GetVolumeMounts()) + }) + t.Run("Script", func(t *testing.T) { + x := &Template{Script: &ScriptTemplate{Container: corev1.Container{VolumeMounts: []corev1.VolumeMount{{}}}}} + assert.NotEmpty(t, x.GetVolumeMounts()) + }) +} + +func TestTemplate_HasOutputs(t *testing.T) { + t.Run("Default", func(t *testing.T) { + x := &Template{} + assert.False(t, x.HasOutput()) + assert.False(t, x.HasLogs()) + }) + t.Run("Container", func(t *testing.T) { + x := &Template{Container: &corev1.Container{}} + assert.True(t, x.HasOutput()) + assert.True(t, x.HasLogs()) + }) + t.Run("ContainerSet", func(t *testing.T) { + t.Run("NoMain", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{}} + assert.False(t, x.HasOutput()) + assert.False(t, x.HasLogs()) + }) + t.Run("Main", func(t *testing.T) { + x := &Template{ContainerSet: &ContainerSetTemplate{Containers: []ContainerNode{{Container: corev1.Container{Name: "main"}}}}} + assert.True(t, x.HasOutput()) + assert.True(t, x.HasLogs()) + }) + }) + t.Run("Script", func(t *testing.T) { + x := &Template{Script: &ScriptTemplate{}} + assert.True(t, x.HasOutput()) + }) + t.Run("Data", func(t *testing.T) { + x := &Template{Data: &Data{}} + assert.True(t, x.HasOutput()) + }) + t.Run("Resource", func(t *testing.T) { + x := &Template{Resource: &ResourceTemplate{}} + assert.False(t, x.HasOutput()) + assert.True(t, x.HasLogs()) + }) +} diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go index 2dc26a9615ac..a02455c5220a 100644 --- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go @@ -452,6 +452,58 @@ func (in Conditions) DeepCopy() Conditions { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerNode) DeepCopyInto(out *ContainerNode) { + *out = *in + in.Container.DeepCopyInto(&out.Container) + if in.Dependencies != nil { + in, out := &in.Dependencies, &out.Dependencies + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerNode. +func (in *ContainerNode) DeepCopy() *ContainerNode { + if in == nil { + return nil + } + out := new(ContainerNode) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSetTemplate) DeepCopyInto(out *ContainerSetTemplate) { + *out = *in + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make([]ContainerNode, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSetTemplate. +func (in *ContainerSetTemplate) DeepCopy() *ContainerSetTemplate { + if in == nil { + return nil + } + out := new(ContainerSetTemplate) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContinueOn) DeepCopyInto(out *ContinueOn) { *out = *in @@ -2071,6 +2123,11 @@ func (in *Template) DeepCopyInto(out *Template) { *out = new(v1.Container) (*in).DeepCopyInto(*out) } + if in.ContainerSet != nil { + in, out := &in.ContainerSet, &out.ContainerSet + *out = new(ContainerSetTemplate) + (*in).DeepCopyInto(*out) + } if in.Script != nil { in, out := &in.Script, &out.Script *out = new(ScriptTemplate) diff --git a/ui/src/app/workflows/components/workflow-dag/genres.ts b/ui/src/app/workflows/components/workflow-dag/genres.ts index 55214110e66f..c1e8ae963437 100644 --- a/ui/src/app/workflows/components/workflow-dag/genres.ts +++ b/ui/src/app/workflows/components/workflow-dag/genres.ts @@ -1,5 +1,6 @@ export const genres = { Pod: true, + Container: true, Steps: true, DAG: true, Retry: true, diff --git a/ui/src/app/workflows/components/workflow-details/workflow-details.tsx b/ui/src/app/workflows/components/workflow-details/workflow-details.tsx index 0ff42e757f0c..d476d23ee703 100644 --- a/ui/src/app/workflows/components/workflow-details/workflow-details.tsx +++ b/ui/src/app/workflows/components/workflow-details/workflow-details.tsx @@ -264,7 +264,7 @@ export const WorkflowDetails = ({history, location, match}: RouteComponentProps< node={selectedNode} workflow={workflow} links={links} - onShowContainerLogs={(_, container) => setSidePanel(`logs:${nodeId}:${container}`)} + onShowContainerLogs={(x, container) => setSidePanel(`logs:${x}:${container}`)} onShowEvents={() => setSidePanel(`events:${nodeId}`)} onShowYaml={() => setSidePanel(`yaml:${nodeId}`)} archived={false} diff --git a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx index a778e1e932b3..3f570871f8a6 100644 --- a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx +++ b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx @@ -48,7 +48,16 @@ export const WorkflowLogsViewer = ({workflow, nodeId, container, archived}: Work .map(x => ({value: x.id, label: (x.displayName || x.name) + ' (' + x.id + ')'})) ); - const containers = ['main', 'init', 'wait']; + const node = workflow.status.nodes[nodeId]; + const templates = execSpec(workflow).templates.filter(t => !node || t.name === node.templateName); + + const containers = ['init', 'wait'].concat( + templates + .map(t => (t.containerSet.graph || t.containerSet.sequence || [{name: 'main'}]).concat(t.sidecars || [])) + .reduce((a, v) => a.concat(v), []) + .map(c => c.name) + ); + return (

Logs

@@ -57,11 +66,11 @@ export const WorkflowLogsViewer = ({workflow, nodeId, container, archived}: Work Logs for archived workflows may be overwritten by a more recent workflow with the same name.

)} -

+

{' '} x.value === podName) || {}).label} onSelect={(_, item) => setPodName(item.value)} /> /{' '} -

+
{selectedContainer === 'init' && (

diff --git a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx index 5d305c112ac5..9cc1a63e669b 100644 --- a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx +++ b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx @@ -118,7 +118,10 @@ const WorkflowNodeSummary = (props: Props) => { ); } if (props.node.type === 'Retry') { - attributes.push({title: 'FAIL HOSTS', value:

{failHosts(props.node, props.workflow)}
}); + attributes.push({ + title: 'FAIL HOSTS', + value:
{failHosts(props.node, props.workflow)}
+ }); } if (props.node.resourcesDuration) { attributes.push({ @@ -132,7 +135,7 @@ const WorkflowNodeSummary = (props: Props) => {
{}
- {props.onShowYaml && }{' '} + {props.node.type !== 'Container' && props.onShowYaml && }{' '} {props.node.type === 'Pod' && props.onShowContainerLogs && ( showLogs()} @@ -148,20 +151,27 @@ const WorkflowNodeSummary = (props: Props) => { EVENTS )}{' '} - + {props.node.type === 'Container' && props.onShowContainerLogs && ( + + )}{' '} + {props.node.type === 'Pod' && ( + + )}
); @@ -311,7 +321,7 @@ class WorkflowNodeContainers extends React.Component
@@ -320,8 +330,10 @@ class WorkflowNodeContainers extends React.Component ); } - const container = - (this.state.selectedSidecar && template.sidecars && template.sidecars.find(item => item.name === this.state.selectedSidecar)) || template.container || template.script; + const containers = (template.containerSet ? template.containerSet.graph || template.containerSet.sequence : []).concat(template.sidecars || []); + + const container = (this.state.selectedSidecar && containers.find(item => item.name === this.state.selectedSidecar)) || template.container || template.script; + return (
{this.state.selectedSidecar && this.setState({selectedSidecar: null})} />} @@ -331,10 +343,10 @@ class WorkflowNodeContainers extends React.Component - {!this.state.selectedSidecar && template.sidecars && template.sidecars.length > 0 && ( + {!this.state.selectedSidecar && (

SIDECARS:

- {template.sidecars.map(sidecar => ( + {containers.map(sidecar => (
this.setState({selectedSidecar: sidecar.name})}> {sidecar.name}
@@ -412,23 +424,28 @@ export const WorkflowNodeInfo = (props: Props) => (
) - }, - { - title: 'CONTAINERS', - key: 'containers', - content: - }, - { - title: 'INPUTS/OUTPUTS', - key: 'inputs-outputs', - content: ( - <> - - - - ) } - ]} + ].concat( + props.node.type !== 'Container' + ? [ + { + title: 'CONTAINERS', + key: 'containers', + content: + }, + { + title: 'INPUTS/OUTPUTS', + key: 'inputs-outputs', + content: ( + <> + + + + ) + } + ] + : [] + )} />
); diff --git a/ui/src/models/workflows.ts b/ui/src/models/workflows.ts index a941932ef85d..e1d68cecaebd 100644 --- a/ui/src/models/workflows.ts +++ b/ui/src/models/workflows.ts @@ -293,6 +293,10 @@ export interface SidecarOptions { mirrorVolumeMounts?: boolean; } +export interface ContainerNode extends kubernetes.Container { + dependencies?: string[]; +} + /** * Template is a reusable and composable unit of execution in a workflow */ @@ -310,6 +314,11 @@ export interface Template { * Container is the main container image to run in the pod */ container?: kubernetes.Container; + + containerSet?: { + sequence: kubernetes.Container[]; + graph: ContainerNode[]; + }; /** * Deamon will allow a workflow to proceed to the next step so long as the container reaches readiness */ @@ -415,7 +424,7 @@ export interface Workflow { export const execSpec = (w: Workflow) => Object.assign({}, w.status.storedWorkflowTemplateSpec, w.spec); -export type NodeType = 'Pod' | 'Steps' | 'StepGroup' | 'DAG' | 'Retry' | 'Skipped' | 'TaskGroup' | 'Suspend'; +export type NodeType = 'Pod' | 'Container' | 'Steps' | 'StepGroup' | 'DAG' | 'Retry' | 'Skipped' | 'TaskGroup' | 'Suspend'; export interface NodeStatus { /** diff --git a/workflow/common/util.go b/workflow/common/util.go index 536170ea1597..bf1634e9d0ef 100644 --- a/workflow/common/util.go +++ b/workflow/common/util.go @@ -34,17 +34,9 @@ import ( // user specified volumeMounts in the template, and returns the deepest volumeMount // (if any). A return value of nil indicates the path is not under any volumeMount. func FindOverlappingVolume(tmpl *wfv1.Template, path string) *apiv1.VolumeMount { - var volMounts []apiv1.VolumeMount - if tmpl.Container != nil { - volMounts = tmpl.Container.VolumeMounts - } else if tmpl.Script != nil { - volMounts = tmpl.Script.VolumeMounts - } else { - return nil - } var volMnt *apiv1.VolumeMount deepestLen := 0 - for _, mnt := range volMounts { + for _, mnt := range tmpl.GetVolumeMounts() { if path != mnt.MountPath && !strings.HasPrefix(path, mnt.MountPath+"/") { continue } diff --git a/workflow/controller/container_set_template.go b/workflow/controller/container_set_template.go new file mode 100644 index 000000000000..dc15bbc08d6c --- /dev/null +++ b/workflow/controller/container_set_template.go @@ -0,0 +1,51 @@ +package controller + +import ( + "context" + "fmt" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/common" +) + +func (woc *wfOperationCtx) executeContainerSet(ctx context.Context, nodeName string, templateScope string, tmpl *wfv1.Template, orgTmpl wfv1.TemplateReferenceHolder, opts *executeTemplateOpts) (*wfv1.NodeStatus, error) { + node := woc.wf.GetNodeByName(nodeName) + if node == nil { + node = woc.initializeExecutableNode(nodeName, wfv1.NodeTypePod, templateScope, tmpl, orgTmpl, opts.boundaryID, wfv1.NodePending) + } + + if woc.getContainerRuntimeExecutor() != common.ContainerRuntimeExecutorEmissary && tmpl.HasSequencedContainers() { + woc.markNodePhase(nodeName, wfv1.NodeFailed, fmt.Sprintf("template has sequenced containers, so you must use the emissary executor rather than %q, learn more: https://argoproj.github.io/argo-workflows/workflow-executors/#emissary-emissary", woc.getContainerRuntimeExecutor())) + return woc.wf.GetNodeByName(nodeName), nil + } + + _, err := woc.createWorkflowPod(ctx, nodeName, tmpl.ContainerSet.GetContainers(), tmpl, &createWorkflowPodOpts{ + includeScriptOutput: tmpl.HasOutput(), + onExitPod: opts.onExitTemplate, + executionDeadline: opts.executionDeadline, + }) + if err != nil { + return woc.requeueIfTransientErr(err, node.Name) + } + + // we only complete the graph if we actually managed to create the pod, + // which prevents creating many pending nodes that could never be scheduled + for _, c := range tmpl.ContainerSet.GetContainers() { + ctxNodeName := fmt.Sprintf("%s.%s", nodeName, c.Name) + ctrNode := woc.wf.GetNodeByName(ctxNodeName) + if ctrNode == nil { + _ = woc.initializeNode(ctxNodeName, wfv1.NodeTypeContainer, templateScope, orgTmpl, node.ID, wfv1.NodePending) + } + } + for _, c := range tmpl.ContainerSet.GetGraph() { + ctrNodeName := fmt.Sprintf("%s.%s", nodeName, c.Name) + if len(c.Dependencies) == 0 { + woc.addChildNode(nodeName, ctrNodeName) + } + for _, v := range c.Dependencies { + woc.addChildNode(fmt.Sprintf("%s.%s", nodeName, v), ctrNodeName) + } + } + + return node, nil +} diff --git a/workflow/controller/container_set_template_test.go b/workflow/controller/container_set_template_test.go new file mode 100644 index 000000000000..c4e4de5c21b2 --- /dev/null +++ b/workflow/controller/container_set_template_test.go @@ -0,0 +1,242 @@ +package controller + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/common" +) + +func TestContainerSetTemplate(t *testing.T) { + wf := unmarshalWF(` +metadata: + name: pod +spec: + entrypoint: main + templates: + - name: main + volumes: + - name: workspace + emptyDir: { } + containerSet: + volumeMounts: + - name: workspace + mountPath: /workspace + containers: + - name: ctr-0 + image: argoproj/argosay:v2 +`) + cancel, controller := newController(wf) + defer cancel() + + woc := newWorkflowOperationCtx(wf, controller) + woc.operate(context.Background()) + + assert.Equal(t, wfv1.WorkflowRunning, woc.wf.Status.Phase) + assert.Len(t, woc.wf.Status.Nodes, 2) + + pod, err := getPod(woc, "pod") + assert.NoError(t, err) + + socket := corev1.HostPathSocket + assert.ElementsMatch(t, []corev1.Volume{ + { + Name: "podmetadata", + VolumeSource: corev1.VolumeSource{DownwardAPI: &corev1.DownwardAPIVolumeSource{ + Items: []corev1.DownwardAPIVolumeFile{{ + Path: "annotations", + FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.annotations"}, + }}, + }}, + }, + {Name: "docker-sock", VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: "/var/run/docker.sock", Type: &socket}}}, + {Name: "workspace", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}, + }, pod.Spec.Volumes) + + assert.Empty(t, pod.Spec.InitContainers) + + assert.Len(t, pod.Spec.Containers, 2) + for _, c := range pod.Spec.Containers { + switch c.Name { + case common.WaitContainerName: + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "podmetadata", MountPath: "/argo/podmetadata"}, + {Name: "docker-sock", MountPath: "/var/run/docker.sock", ReadOnly: true}, + }, c.VolumeMounts) + case "ctr-0": + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "workspace", MountPath: "/workspace"}, + }, c.VolumeMounts) + default: + t.Fatalf(c.Name) + } + } +} + +func TestContainerSetTemplateWithInputArtifacts(t *testing.T) { + wf := unmarshalWF(` +metadata: + name: pod +spec: + entrypoint: main + templates: + - name: main + inputs: + artifacts: + - name: in-0 + path: /in/in-0 + raw: + data: hi + - name: in-1 + path: /workspace/in-1 + raw: + data: hi + volumes: + - name: workspace + emptyDir: { } + containerSet: + volumeMounts: + - name: workspace + mountPath: /workspace + containers: + - name: main + image: argoproj/argosay:v2 +`) + cancel, controller := newController(wf) + defer cancel() + + woc := newWorkflowOperationCtx(wf, controller) + woc.operate(context.Background()) + + assert.Equal(t, wfv1.WorkflowRunning, woc.wf.Status.Phase) + assert.Len(t, woc.wf.Status.Nodes, 2) + + pod, err := getPod(woc, "pod") + assert.NoError(t, err) + + socket := corev1.HostPathSocket + assert.ElementsMatch(t, []corev1.Volume{ + { + Name: "podmetadata", + VolumeSource: corev1.VolumeSource{DownwardAPI: &corev1.DownwardAPIVolumeSource{ + Items: []corev1.DownwardAPIVolumeFile{{ + Path: "annotations", + FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.annotations"}, + }}, + }}, + }, + {Name: "docker-sock", VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: "/var/run/docker.sock", Type: &socket}}}, + {Name: "workspace", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}, + {Name: "input-artifacts", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}, + }, pod.Spec.Volumes) + + if assert.Len(t, pod.Spec.InitContainers, 1) { + c := pod.Spec.InitContainers[0] + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "podmetadata", MountPath: "/argo/podmetadata"}, + {Name: "input-artifacts", MountPath: "/argo/inputs/artifacts"}, + {Name: "workspace", MountPath: "/mainctrfs/workspace"}, + }, c.VolumeMounts) + } + + assert.Len(t, pod.Spec.Containers, 2) + for _, c := range pod.Spec.Containers { + switch c.Name { + case common.WaitContainerName: + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "podmetadata", MountPath: "/argo/podmetadata"}, + {Name: "docker-sock", MountPath: "/var/run/docker.sock", ReadOnly: true}, + {Name: "workspace", MountPath: "/mainctrfs/workspace"}, + {Name: "input-artifacts", MountPath: "/mainctrfs/in/in-0", SubPath: "in-0"}, + }, c.VolumeMounts) + case "main": + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "workspace", MountPath: "/workspace"}, + {Name: "input-artifacts", MountPath: "/in/in-0", SubPath: "in-0"}, + }, c.VolumeMounts) + default: + t.Fatalf(c.Name) + } + } +} + +func TestContainerSetTemplateWithOutputArtifacts(t *testing.T) { + wf := unmarshalWF(` +metadata: + name: pod +spec: + entrypoint: main + templates: + - name: main + volumes: + - name: workspace + emptyDir: { } + containerSet: + volumeMounts: + - name: workspace + mountPath: /workspace + containers: + - name: main + image: argoproj/argosay:v2 + outputs: + artifacts: + - name: in-0 + path: /in/in-0 + raw: + data: hi + - name: in-1 + path: /workspace/in-1 + raw: + data: hi +`) + cancel, controller := newController(wf) + defer cancel() + + woc := newWorkflowOperationCtx(wf, controller) + woc.operate(context.Background()) + + assert.Equal(t, wfv1.WorkflowRunning, woc.wf.Status.Phase) + assert.Len(t, woc.wf.Status.Nodes, 2) + + pod, err := getPod(woc, "pod") + assert.NoError(t, err) + + socket := corev1.HostPathSocket + assert.ElementsMatch(t, []corev1.Volume{ + { + Name: "podmetadata", + VolumeSource: corev1.VolumeSource{DownwardAPI: &corev1.DownwardAPIVolumeSource{ + Items: []corev1.DownwardAPIVolumeFile{{ + Path: "annotations", + FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.annotations"}, + }}, + }}, + }, + {Name: "docker-sock", VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: "/var/run/docker.sock", Type: &socket}}}, + {Name: "workspace", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}, + }, pod.Spec.Volumes) + + assert.Len(t, pod.Spec.InitContainers, 0) + + assert.Len(t, pod.Spec.Containers, 2) + for _, c := range pod.Spec.Containers { + switch c.Name { + case common.WaitContainerName: + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "podmetadata", MountPath: "/argo/podmetadata"}, + {Name: "docker-sock", MountPath: "/var/run/docker.sock", ReadOnly: true}, + {Name: "workspace", MountPath: "/mainctrfs/workspace"}, + }, c.VolumeMounts) + case "main": + assert.ElementsMatch(t, []corev1.VolumeMount{ + {Name: "workspace", MountPath: "/workspace"}, + }, c.VolumeMounts) + default: + t.Fatalf(c.Name) + } + } +} diff --git a/workflow/controller/exec_control.go b/workflow/controller/exec_control.go index 1649178f38ba..97d21644d7a6 100644 --- a/workflow/controller/exec_control.go +++ b/workflow/controller/exec_control.go @@ -73,26 +73,22 @@ func (woc *wfOperationCtx) applyExecutionControl(ctx context.Context, pod *apiv1 woc.log.Warnf("Failed to unmarshal execution control from pod %s", pod.Name) } } - containerName := common.WaitContainerName - // A resource template does not have a wait container, - // instead the only container is the main container (which is running argoexec) - if len(pod.Spec.Containers) == 1 { - containerName = common.MainContainerName - } - if woc.wf.Spec.Shutdown != "" { - if _, onExitPod := pod.Labels[common.LabelKeyOnExit]; !woc.wf.Spec.Shutdown.ShouldExecute(onExitPod) { - podExecCtl.Deadline = &time.Time{} - woc.log.Infof("Applying shutdown deadline for pod %s", pod.Name) - return woc.updateExecutionControl(ctx, pod.Name, podExecCtl, containerName) + for _, c := range woc.findTemplate(pod).GetMainContainerNames() { + if woc.wf.Spec.Shutdown != "" { + if _, onExitPod := pod.Labels[common.LabelKeyOnExit]; !woc.wf.Spec.Shutdown.ShouldExecute(onExitPod) { + podExecCtl.Deadline = &time.Time{} + woc.log.Infof("Applying shutdown deadline for pod %s", pod.Name) + return woc.updateExecutionControl(ctx, pod.Name, podExecCtl, c) + } } - } - if woc.workflowDeadline != nil { - if podExecCtl.Deadline == nil || woc.workflowDeadline.Before(*podExecCtl.Deadline) { - podExecCtl.Deadline = woc.workflowDeadline - woc.log.Infof("Applying sooner Workflow Deadline for pod %s at: %v", pod.Name, woc.workflowDeadline) - return woc.updateExecutionControl(ctx, pod.Name, podExecCtl, containerName) + if woc.workflowDeadline != nil { + if podExecCtl.Deadline == nil || woc.workflowDeadline.Before(*podExecCtl.Deadline) { + podExecCtl.Deadline = woc.workflowDeadline + woc.log.Infof("Applying sooner Workflow Deadline for pod %s at: %v", pod.Name, woc.workflowDeadline) + return woc.updateExecutionControl(ctx, pod.Name, podExecCtl, c) + } } } diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go index dc80b6cd424a..3ed644931a70 100644 --- a/workflow/controller/operator.go +++ b/workflow/controller/operator.go @@ -1131,7 +1131,7 @@ func (woc *wfOperationCtx) assessNodeStatus(pod *apiv1.Pod, node *wfv1.NodeStatu if node.IsDaemoned() { newPhase = wfv1.NodeSucceeded } else { - newPhase, message = inferFailedReason(pod) + newPhase, message = woc.inferFailedReason(pod) woc.log.WithField("displayName", node.DisplayName).WithField("templateName", node.TemplateName). WithField("pod", pod.Name).Infof("Pod failed: %s", message) } @@ -1168,6 +1168,32 @@ func (woc *wfOperationCtx) assessNodeStatus(pod *apiv1.Pod, node *wfv1.NodeStatu WithField("pod", pod.Name).Error(message) } + for _, c := range pod.Status.ContainerStatuses { + ctrNodeName := fmt.Sprintf("%s.%s", node.Name, c.Name) + if woc.wf.GetNodeByName(ctrNodeName) == nil { + continue + } + switch { + case c.State.Waiting != nil: + woc.markNodePhase(ctrNodeName, wfv1.NodePending) + case c.State.Running != nil: + woc.markNodePhase(ctrNodeName, wfv1.NodeRunning) + case c.State.Terminated != nil: + exitCode := int(c.State.Terminated.ExitCode) + message := fmt.Sprintf("%s (exit code %d): %s", c.State.Terminated.Reason, exitCode, c.State.Terminated.Message) + switch exitCode { + case 0: + woc.markNodePhase(ctrNodeName, wfv1.NodeSucceeded) + case 64: + // special emissary exit code indicating the emissary errors, rather than the sub-process failure, + // (unless the sub-process coincidentally exits with code 64 of course) + woc.markNodePhase(ctrNodeName, wfv1.NodeError, message) + default: + woc.markNodePhase(ctrNodeName, wfv1.NodeFailed, message) + } + } + } + if newDaemonStatus != nil { if !*newDaemonStatus { // if the daemon status switched to false, we prefer to just unset daemoned status field @@ -1278,25 +1304,28 @@ func getPendingReason(pod *apiv1.Pod) string { // inferFailedReason returns metadata about a Failed pod to be used in its NodeStatus // Returns a tuple of the new phase and message -func inferFailedReason(pod *apiv1.Pod) (wfv1.NodePhase, string) { +func (woc *wfOperationCtx) inferFailedReason(pod *apiv1.Pod) (wfv1.NodePhase, string) { if pod.Status.Message != "" { // Pod has a nice error message. Use that. return wfv1.NodeFailed, pod.Status.Message } + tmpl := woc.findTemplate(pod) + // We only get one message to set for the overall node status. // If multiple containers failed, in order of preference: // init, main (annotated), main (exit code), wait, sidecars order := func(n string) int { - order, ok := map[string]int{ - common.InitContainerName: 0, - common.MainContainerName: 1, - common.WaitContainerName: 2, - }[n] - if ok { - return order + switch { + case n == common.InitContainerName: + return 0 + case tmpl.IsMainContainerName(n): + return 1 + case n == common.WaitContainerName: + return 2 + default: + return 3 } - return 3 } ctrs := append(pod.Status.InitContainerStatuses, pod.Status.ContainerStatuses...) @@ -1326,12 +1355,12 @@ func inferFailedReason(pod *apiv1.Pod) (wfv1.NodePhase, string) { msg = fmt.Sprintf("%s: %s", msg, t.Message) } - switch ctr.Name { - case common.InitContainerName: + switch { + case ctr.Name == common.InitContainerName: return wfv1.NodeError, msg - case common.MainContainerName: + case tmpl.IsMainContainerName(ctr.Name): return wfv1.NodeFailed, msg - case common.WaitContainerName: + case ctr.Name == common.WaitContainerName: return wfv1.NodeError, msg default: if t.ExitCode == 137 || t.ExitCode == 143 { @@ -1721,6 +1750,8 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string, switch processedTmpl.GetType() { case wfv1.TemplateTypeContainer: node, err = woc.executeContainer(ctx, nodeName, templateScope, processedTmpl, orgTmpl, opts) + case wfv1.TemplateTypeContainerSet: + node, err = woc.executeContainerSet(ctx, nodeName, templateScope, processedTmpl, orgTmpl, opts) case wfv1.TemplateTypeSteps: node, err = woc.executeSteps(ctx, nodeName, newTmplCtx, templateScope, processedTmpl, orgTmpl, opts) case wfv1.TemplateTypeScript: @@ -1924,6 +1955,15 @@ func (woc *wfOperationCtx) hasDaemonNodes() bool { return false } +func (woc *wfOperationCtx) findTemplate(pod *apiv1.Pod) *wfv1.Template { + nodeName := pod.Annotations[common.AnnotationKeyNodeName] + node := woc.wf.GetNodeByName(nodeName) + if node == nil { + return nil // I don't expect this to happen in production, just in tests + } + return woc.wf.GetTemplateByName(node.TemplateName) +} + func (woc *wfOperationCtx) markWorkflowRunning(ctx context.Context) { woc.markWorkflowPhase(ctx, wfv1.WorkflowRunning, "") } @@ -2201,7 +2241,7 @@ func (woc *wfOperationCtx) executeContainer(ctx context.Context, nodeName string } woc.log.Debugf("Executing node %s with container template: %v\n", nodeName, tmpl) - _, err = woc.createWorkflowPod(ctx, nodeName, *tmpl.Container, tmpl, &createWorkflowPodOpts{ + _, err = woc.createWorkflowPod(ctx, nodeName, []apiv1.Container{*tmpl.Container}, tmpl, &createWorkflowPodOpts{ includeScriptOutput: includeScriptOutput, onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline, @@ -2217,9 +2257,9 @@ func (woc *wfOperationCtx) executeContainer(ctx context.Context, nodeName string func (woc *wfOperationCtx) getOutboundNodes(nodeID string) []string { node := woc.wf.Status.Nodes[nodeID] switch node.Type { - case wfv1.NodeTypePod, wfv1.NodeTypeSkipped, wfv1.NodeTypeSuspend: + case wfv1.NodeTypeSkipped, wfv1.NodeTypeSuspend: return []string{node.ID} - case wfv1.NodeTypeTaskGroup: + case wfv1.NodeTypeContainer, wfv1.NodeTypePod, wfv1.NodeTypeTaskGroup: if len(node.Children) == 0 { return []string{node.ID} } @@ -2236,13 +2276,7 @@ func (woc *wfOperationCtx) getOutboundNodes(nodeID string) []string { } outbound := make([]string, 0) for _, outboundNodeID := range node.OutboundNodes { - outNode := woc.wf.Status.Nodes[outboundNodeID] - if outNode.Type == wfv1.NodeTypePod { - outbound = append(outbound, outboundNodeID) - } else { - subOutIDs := woc.getOutboundNodes(outboundNodeID) - outbound = append(outbound, subOutIDs...) - } + outbound = append(outbound, woc.getOutboundNodes(outboundNodeID)...) } return outbound } @@ -2339,7 +2373,7 @@ func (woc *wfOperationCtx) executeScript(ctx context.Context, nodeName string, t mainCtr := tmpl.Script.Container mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) - _, err = woc.createWorkflowPod(ctx, nodeName, mainCtr, tmpl, &createWorkflowPodOpts{ + _, err = woc.createWorkflowPod(ctx, nodeName, []apiv1.Container{mainCtr}, tmpl, &createWorkflowPodOpts{ includeScriptOutput: includeScriptOutput, onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline, @@ -2488,7 +2522,7 @@ func (woc *wfOperationCtx) processAggregateNodeOutputs(tmpl *wfv1.Template, scop resultsList = append(resultsList, item) } } - if tmpl.GetType() == wfv1.TemplateTypeScript || tmpl.GetType() == wfv1.TemplateTypeContainer { + if tmpl.HasOutput() { resultsJSON, err := json.Marshal(resultsList) if err != nil { return err @@ -2631,7 +2665,7 @@ func (woc *wfOperationCtx) executeResource(ctx context.Context, nodeName string, mainCtr := woc.newExecContainer(common.MainContainerName, tmpl) mainCtr.Command = []string{"argoexec", "resource", tmpl.Resource.Action} - _, err := woc.createWorkflowPod(ctx, nodeName, *mainCtr, tmpl, &createWorkflowPodOpts{onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline}) + _, err := woc.createWorkflowPod(ctx, nodeName, []apiv1.Container{*mainCtr}, tmpl, &createWorkflowPodOpts{onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline}) if err != nil { return woc.requeueIfTransientErr(err, node.Name) } @@ -2654,7 +2688,7 @@ func (woc *wfOperationCtx) executeData(ctx context.Context, nodeName string, tem mainCtr := woc.newExecContainer(common.MainContainerName, tmpl) mainCtr.Command = []string{"argoexec", "data", string(dataTemplate)} - _, err = woc.createWorkflowPod(ctx, nodeName, *mainCtr, tmpl, &createWorkflowPodOpts{onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline, includeScriptOutput: true}) + _, err = woc.createWorkflowPod(ctx, nodeName, []apiv1.Container{*mainCtr}, tmpl, &createWorkflowPodOpts{onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline, includeScriptOutput: true}) if err != nil { return woc.requeueIfTransientErr(err, node.Name) } diff --git a/workflow/controller/operator_test.go b/workflow/controller/operator_test.go index 3d5449d8a839..8cb873e31b5a 100644 --- a/workflow/controller/operator_test.go +++ b/workflow/controller/operator_test.go @@ -298,16 +298,11 @@ func TestGlobalParams(t *testing.T) { // TestSidecarWithVolume verifies ia sidecar can have a volumeMount reference to both existing or volumeClaimTemplate volumes func TestSidecarWithVolume(t *testing.T) { - cancel, controller := newController() + wf := unmarshalWF(sidecarWithVol) + cancel, controller := newController(wf) defer cancel() ctx := context.Background() - wfcset := controller.wfclientset.ArgoprojV1alpha1().Workflows("") - wf := unmarshalWF(sidecarWithVol) - wf, err := wfcset.Create(ctx, wf, metav1.CreateOptions{}) - assert.NoError(t, err) - wf, err = wfcset.Get(ctx, wf.ObjectMeta.Name, metav1.GetOptions{}) - assert.NoError(t, err) woc := newWorkflowOperationCtx(wf, controller) woc.operate(ctx) assert.Equal(t, wfv1.WorkflowRunning, woc.wf.Status.Phase) @@ -5319,7 +5314,7 @@ func TestPodFailureWithContainerWaitingState(t *testing.T) { var pod apiv1.Pod testutil.MustUnmarshallYAML(podWithFailed, &pod) assert.NotNil(t, pod) - nodeStatus, msg := inferFailedReason(&pod) + nodeStatus, msg := newWoc().inferFailedReason(&pod) assert.Equal(t, wfv1.NodeError, nodeStatus) assert.Contains(t, msg, "Pod failed before") } @@ -5371,6 +5366,12 @@ status: var podWithMainContainerOOM = ` apiVersion: v1 kind: Pod +spec: + containers: + - name: main + env: + - name: ARGO_CONTAINER_NAME + value: main status: containerStatuses: - containerID: containerd://3e8c564c13893914ec81a2c105188fa5d34748576b368e709dbc2e71cbf23c5b @@ -5427,7 +5428,7 @@ func TestPodFailureWithContainerOOM(t *testing.T) { for _, tt := range tests { testutil.MustUnmarshallYAML(tt.podDetail, &pod) assert.NotNil(t, pod) - nodeStatus, msg := inferFailedReason(&pod) + nodeStatus, msg := newWoc().inferFailedReason(&pod) assert.Equal(t, tt.phase, nodeStatus) assert.Contains(t, msg, "OOMKilled") } diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 673411f02938..f68c24e3da85 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -137,7 +137,7 @@ type createWorkflowPodOpts struct { executionDeadline time.Time } -func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName string, mainCtr apiv1.Container, tmpl *wfv1.Template, opts *createWorkflowPodOpts) (*apiv1.Pod, error) { +func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName string, mainCtrs []apiv1.Container, tmpl *wfv1.Template, opts *createWorkflowPodOpts) (*apiv1.Pod, error) { nodeID := woc.wf.NodeID(nodeName) // we must check to see if the pod exists rather than just optimistically creating the pod and see if we get @@ -164,14 +164,19 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin tmpl = tmpl.DeepCopy() wfSpec := woc.execWf.Spec.DeepCopy() - mainCtr.Name = common.MainContainerName - // Allow customization of main container resources. - if isResourcesSpecified(woc.controller.Config.MainContainer) { - mainCtr.Resources = *woc.controller.Config.MainContainer.Resources.DeepCopy() - } - // Container resources in workflow spec takes precedence over the main container's configuration in controller. - if isResourcesSpecified(tmpl.Container) && tmpl.Container.Name == common.MainContainerName { - mainCtr.Resources = *tmpl.Container.Resources.DeepCopy() + for i, c := range mainCtrs { + if c.Name == "" { + c.Name = common.MainContainerName + } + // Allow customization of main container resources. + if isResourcesSpecified(woc.controller.Config.MainContainer) { + c.Resources = *woc.controller.Config.MainContainer.Resources.DeepCopy() + } + // Container resources in workflow spec takes precedence over the main container's configuration in controller. + if isResourcesSpecified(tmpl.Container) && tmpl.Container.Name == common.MainContainerName { + c.Resources = *tmpl.Container.Resources.DeepCopy() + } + mainCtrs[i] = c } var activeDeadlineSeconds *int64 @@ -258,7 +263,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin // each container sequentially in the order that they appear in this list. For PNS we want the // wait container to start before the main, so that it always has the chance to see the main // container's PID and root filesystem. - pod.Spec.Containers = append(pod.Spec.Containers, mainCtr) + pod.Spec.Containers = append(pod.Spec.Containers, mainCtrs...) // Add init container only if it needs input artifacts. This is also true for // script templates (which needs to populate the script) @@ -747,7 +752,7 @@ func addSchedulingConstraints(pod *apiv1.Pod, wfSpec *wfv1.WorkflowSpec, tmpl *w // These are either specified in the workflow.spec.volumes or the workflow.spec.volumeClaimTemplate section func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Template, pvcs []apiv1.Volume) error { switch tmpl.GetType() { - case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript, wfv1.TemplateTypeData: + case wfv1.TemplateTypeContainer, wfv1.TemplateTypeContainerSet, wfv1.TemplateTypeScript, wfv1.TemplateTypeData: default: return nil } @@ -798,17 +803,9 @@ func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Templat return nil } - if tmpl.Container != nil { - err := addVolumeRef(tmpl.Container.VolumeMounts) - if err != nil { - return err - } - } - if tmpl.Script != nil { - err := addVolumeRef(tmpl.Script.VolumeMounts) - if err != nil { - return err - } + err := addVolumeRef(tmpl.GetVolumeMounts()) + if err != nil { + return err } for _, container := range tmpl.InitContainers { @@ -890,13 +887,7 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T // We also add the user supplied mount paths to the init container, // in case the executor needs to load artifacts to this volume // instead of the artifacts volume - tmplVolumeMounts := []apiv1.VolumeMount{} - if tmpl.Container != nil { - tmplVolumeMounts = tmpl.Container.VolumeMounts - } else if tmpl.Script != nil { - tmplVolumeMounts = tmpl.Script.Container.VolumeMounts - } - for _, mnt := range tmplVolumeMounts { + for _, mnt := range tmpl.GetVolumeMounts() { mnt.MountPath = filepath.Join(common.ExecutorMainFilesystemDir, mnt.MountPath) initCtr.VolumeMounts = append(initCtr.VolumeMounts, mnt) } @@ -906,47 +897,37 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T } } - mainCtrIndex := -1 - for i, ctr := range pod.Spec.Containers { - switch ctr.Name { - case common.MainContainerName: - mainCtrIndex = i - } - } - if mainCtrIndex == -1 { - panic("Could not find main container in pod spec") - } - mainCtr := &pod.Spec.Containers[mainCtrIndex] - - for _, art := range tmpl.Inputs.Artifacts { - if art.Path == "" { - return errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s did not specify a path", art.Name) - } - if !art.HasLocationOrKey() && art.Optional { - woc.log.Infof("skip volume mount of %s (%s): optional artifact was not provided", - art.Name, art.Path) - continue - } - overlap := common.FindOverlappingVolume(tmpl, art.Path) - if overlap != nil { - // artifact path overlaps with a mounted volume. do not mount the - // artifacts emptydir to the main container. init would have copied - // the artifact to the user's volume instead - woc.log.Debugf("skip volume mount of %s (%s): overlaps with mount %s at %s", - art.Name, art.Path, overlap.Name, overlap.MountPath) + for i, c := range pod.Spec.Containers { + if c.Name != common.MainContainerName { continue } - volMount := apiv1.VolumeMount{ - Name: artVol.Name, - MountPath: art.Path, - SubPath: art.Name, - } - if mainCtr.VolumeMounts == nil { - mainCtr.VolumeMounts = make([]apiv1.VolumeMount, 0) + for _, art := range tmpl.Inputs.Artifacts { + if art.Path == "" { + return errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s did not specify a path", art.Name) + } + if !art.HasLocationOrKey() && art.Optional { + woc.log.Infof("skip volume mount of %s (%s): optional artifact was not provided", + art.Name, art.Path) + continue + } + overlap := common.FindOverlappingVolume(tmpl, art.Path) + if overlap != nil { + // artifact path overlaps with a mounted volume. do not mount the + // artifacts emptydir to the main container. init would have copied + // the artifact to the user's volume instead + woc.log.Debugf("skip volume mount of %s (%s): overlaps with mount %s at %s", + art.Name, art.Path, overlap.Name, overlap.MountPath) + continue + } + volMount := apiv1.VolumeMount{ + Name: artVol.Name, + MountPath: art.Path, + SubPath: art.Name, + } + c.VolumeMounts = append(c.VolumeMounts, volMount) } - mainCtr.VolumeMounts = append(mainCtr.VolumeMounts, volMount) + pod.Spec.Containers[i] = c } - pod.Spec.Containers[mainCtrIndex] = *mainCtr return nil } @@ -959,28 +940,30 @@ func addOutputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.Template) { if tmpl.GetType() == wfv1.TemplateTypeResource || tmpl.GetType() == wfv1.TemplateTypeData { return } - mainCtrIndex := -1 + waitCtrIndex := -1 - var mainCtr *apiv1.Container for i, ctr := range pod.Spec.Containers { switch ctr.Name { - case common.MainContainerName: - mainCtrIndex = i case common.WaitContainerName: waitCtrIndex = i } } - if mainCtrIndex == -1 || waitCtrIndex == -1 { - panic("Could not find main or wait container in pod spec") + if waitCtrIndex == -1 { + log.Info("Could not find wait container in pod spec") + return } - mainCtr = &pod.Spec.Containers[mainCtrIndex] waitCtr := &pod.Spec.Containers[waitCtrIndex] - for _, mnt := range mainCtr.VolumeMounts { - mnt.MountPath = filepath.Join(common.ExecutorMainFilesystemDir, mnt.MountPath) - // ReadOnly is needed to be false for overlapping volume mounts - mnt.ReadOnly = false - waitCtr.VolumeMounts = append(waitCtr.VolumeMounts, mnt) + for _, c := range pod.Spec.Containers { + if c.Name != common.MainContainerName { + continue + } + for _, mnt := range c.VolumeMounts { + mnt.MountPath = filepath.Join(common.ExecutorMainFilesystemDir, mnt.MountPath) + // ReadOnly is needed to be false for overlapping volume mounts + mnt.ReadOnly = false + waitCtr.VolumeMounts = append(waitCtr.VolumeMounts, mnt) + } } pod.Spec.Containers[waitCtrIndex] = *waitCtr } @@ -1094,16 +1077,10 @@ func addScriptStagingVolume(pod *apiv1.Pod) { // addInitContainers adds all init containers to the pod spec of the step // Optionally volume mounts from the main container to the init containers func addInitContainers(pod *apiv1.Pod, tmpl *wfv1.Template) { - if len(tmpl.InitContainers) == 0 { - return - } mainCtr := findMainContainer(pod) - if mainCtr == nil { - panic("Unable to locate main container") - } for _, ctr := range tmpl.InitContainers { log.Debugf("Adding init container %s", ctr.Name) - if ctr.MirrorVolumeMounts != nil && *ctr.MirrorVolumeMounts { + if mainCtr != nil && ctr.MirrorVolumeMounts != nil && *ctr.MirrorVolumeMounts { mirrorVolumeMounts(mainCtr, &ctr.Container) } pod.Spec.InitContainers = append(pod.Spec.InitContainers, ctr.Container) @@ -1113,16 +1090,10 @@ func addInitContainers(pod *apiv1.Pod, tmpl *wfv1.Template) { // addSidecars adds all sidecars to the pod spec of the step. // Optionally volume mounts from the main container to the sidecar func addSidecars(pod *apiv1.Pod, tmpl *wfv1.Template) { - if len(tmpl.Sidecars) == 0 { - return - } mainCtr := findMainContainer(pod) - if mainCtr == nil { - panic("Unable to locate main container") - } for _, sidecar := range tmpl.Sidecars { log.Debugf("Adding sidecar container %s", sidecar.Name) - if sidecar.MirrorVolumeMounts != nil && *sidecar.MirrorVolumeMounts { + if mainCtr != nil && sidecar.MirrorVolumeMounts != nil && *sidecar.MirrorVolumeMounts { mirrorVolumeMounts(mainCtr, &sidecar.Container) } pod.Spec.Containers = append(pod.Spec.Containers, sidecar.Container) @@ -1256,15 +1227,12 @@ func createSecretVal(volMap map[string]apiv1.Volume, secret *apiv1.SecretKeySele // findMainContainer finds main container func findMainContainer(pod *apiv1.Pod) *apiv1.Container { - var mainCtr *apiv1.Container for _, ctr := range pod.Spec.Containers { - if ctr.Name != common.MainContainerName { - continue + if common.MainContainerName == ctr.Name { + return &ctr } - mainCtr = &ctr - break } - return mainCtr + return nil } // mirrorVolumeMounts mirrors volumeMounts of source container to target container diff --git a/workflow/controller/workflowpod_test.go b/workflow/controller/workflowpod_test.go index a30b916a200f..f69466d2cd61 100644 --- a/workflow/controller/workflowpod_test.go +++ b/workflow/controller/workflowpod_test.go @@ -139,7 +139,7 @@ func TestScriptTemplateWithoutVolumeOptionalArtifact(t *testing.T) { mainCtr := tmpl.Script.Container mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) ctx := context.Background() - pod, err := woc.createWorkflowPod(ctx, tmpl.Name, mainCtr, tmpl, &createWorkflowPodOpts{}) + pod, err := woc.createWorkflowPod(ctx, tmpl.Name, []apiv1.Container{mainCtr}, tmpl, &createWorkflowPodOpts{}) assert.NoError(t, err) // Note: pod.Spec.Containers[0] is wait assert.Contains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) @@ -154,7 +154,7 @@ func TestScriptTemplateWithoutVolumeOptionalArtifact(t *testing.T) { woc = newWoc(*wf) mainCtr = tmpl.Script.Container mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) - pod, err = woc.createWorkflowPod(ctx, tmpl.Name, mainCtr, tmpl, &createWorkflowPodOpts{includeScriptOutput: true}) + pod, err = woc.createWorkflowPod(ctx, tmpl.Name, []apiv1.Container{mainCtr}, tmpl, &createWorkflowPodOpts{includeScriptOutput: true}) assert.NoError(t, err) assert.NotContains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) assert.Contains(t, pod.Spec.Containers[1].VolumeMounts, customVolumeMount) @@ -566,20 +566,20 @@ func Test_createWorkflowPod_emissary(t *testing.T) { t.Run("NoCommand", func(t *testing.T) { woc := newWoc() woc.controller.containerRuntimeExecutor = common.ContainerRuntimeExecutorEmissary - _, err := woc.createWorkflowPod(context.Background(), "", apiv1.Container{}, &wfv1.Template{}, &createWorkflowPodOpts{}) + _, err := woc.createWorkflowPod(context.Background(), "", []apiv1.Container{{}}, &wfv1.Template{}, &createWorkflowPodOpts{}) assert.Error(t, err) }) t.Run("CommandNoArgs", func(t *testing.T) { woc := newWoc() woc.controller.containerRuntimeExecutor = common.ContainerRuntimeExecutorEmissary - pod, err := woc.createWorkflowPod(context.Background(), "", apiv1.Container{Command: []string{"foo"}}, &wfv1.Template{}, &createWorkflowPodOpts{}) + pod, err := woc.createWorkflowPod(context.Background(), "", []apiv1.Container{{Command: []string{"foo"}}}, &wfv1.Template{}, &createWorkflowPodOpts{}) assert.NoError(t, err) assert.Equal(t, []string{"/var/run/argo/argoexec", "emissary", "--", "foo"}, pod.Spec.Containers[1].Command) }) t.Run("NoCommandWithImageIndex", func(t *testing.T) { woc := newWoc() woc.controller.containerRuntimeExecutor = common.ContainerRuntimeExecutorEmissary - pod, err := woc.createWorkflowPod(context.Background(), "", apiv1.Container{Image: "my-image"}, &wfv1.Template{}, &createWorkflowPodOpts{}) + pod, err := woc.createWorkflowPod(context.Background(), "", []apiv1.Container{{Image: "my-image"}}, &wfv1.Template{}, &createWorkflowPodOpts{}) if assert.NoError(t, err) { assert.Equal(t, []string{"/var/run/argo/argoexec", "emissary", "--", "my-cmd"}, pod.Spec.Containers[1].Command) assert.Equal(t, []string{"my-args"}, pod.Spec.Containers[1].Args) @@ -588,7 +588,7 @@ func Test_createWorkflowPod_emissary(t *testing.T) { t.Run("NoCommandWithArgsWithImageIndex", func(t *testing.T) { woc := newWoc() woc.controller.containerRuntimeExecutor = common.ContainerRuntimeExecutorEmissary - pod, err := woc.createWorkflowPod(context.Background(), "", apiv1.Container{Image: "my-image", Args: []string{"foo"}}, &wfv1.Template{}, &createWorkflowPodOpts{}) + pod, err := woc.createWorkflowPod(context.Background(), "", []apiv1.Container{{Image: "my-image", Args: []string{"foo"}}}, &wfv1.Template{}, &createWorkflowPodOpts{}) if assert.NoError(t, err) { assert.Equal(t, []string{"/var/run/argo/argoexec", "emissary", "--", "my-cmd"}, pod.Spec.Containers[1].Command) assert.Equal(t, []string{"foo"}, pod.Spec.Containers[1].Args) @@ -1189,19 +1189,19 @@ func TestPodSpecPatch(t *testing.T) { ctx := context.Background() woc := newWoc(*wf) mainCtr := woc.execWf.Spec.Templates[0].Container - pod, _ := woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ := woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.800", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) wf = unmarshalWF(helloWorldWfWithWFPatch) woc = newWoc(*wf) mainCtr = woc.execWf.Spec.Templates[0].Container - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.800", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) wf = unmarshalWF(helloWorldWfWithWFYAMLPatch) woc = newWoc(*wf) mainCtr = woc.execWf.Spec.Templates[0].Container - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.800", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) assert.Equal(t, "104857600", pod.Spec.Containers[1].Resources.Limits.Memory().AsDec().String()) @@ -1224,7 +1224,7 @@ func TestMainContainerCustomization(t *testing.T) { ctx := context.Background() woc.controller.Config.MainContainer = mainCtrSpec mainCtr := woc.execWf.Spec.Templates[0].Container - pod, _ := woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ := woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.800", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) // The main container's resources should be changed since the existing @@ -1234,7 +1234,7 @@ func TestMainContainerCustomization(t *testing.T) { woc.controller.Config.MainContainer = mainCtrSpec mainCtr = woc.execWf.Spec.Templates[0].Container mainCtr.Resources = apiv1.ResourceRequirements{Limits: apiv1.ResourceList{}} - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.200", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) // Workflow spec's main container takes precedence over config in controller @@ -1250,7 +1250,7 @@ func TestMainContainerCustomization(t *testing.T) { apiv1.ResourceMemory: resource.MustParse("512Mi"), }, } - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.900", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) // If the name of the container in the workflow spec is not "main", @@ -1271,7 +1271,7 @@ func TestMainContainerCustomization(t *testing.T) { apiv1.ResourceMemory: resource.MustParse("512Mi"), }, } - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "0.100", pod.Spec.Containers[1].Resources.Limits.Cpu().AsDec().String()) } @@ -1331,7 +1331,7 @@ func TestHybridWfVolumesWindows(t *testing.T) { ctx := context.Background() mainCtr := woc.execWf.Spec.Templates[0].Container - pod, _ := woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ := woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "\\\\.\\pipe\\docker_engine", pod.Spec.Containers[0].VolumeMounts[1].MountPath) assert.Equal(t, false, pod.Spec.Containers[0].VolumeMounts[1].ReadOnly) assert.Equal(t, (*apiv1.HostPathType)(nil), pod.Spec.Volumes[1].HostPath.Type) @@ -1343,7 +1343,7 @@ func TestHybridWfVolumesLinux(t *testing.T) { ctx := context.Background() mainCtr := woc.execWf.Spec.Templates[0].Container - pod, _ := woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ := woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "/var/run/docker.sock", pod.Spec.Containers[0].VolumeMounts[1].MountPath) assert.Equal(t, true, pod.Spec.Containers[0].VolumeMounts[1].ReadOnly) assert.Equal(t, &hostPathSocket, pod.Spec.Volumes[1].HostPath.Type) @@ -1370,7 +1370,7 @@ func TestPropagateMaxDuration(t *testing.T) { woc := newWoc() deadline := time.Now() ctx := context.Background() - pod, err := woc.createWorkflowPod(ctx, tmpl.Name, *tmpl.Container, tmpl, &createWorkflowPodOpts{executionDeadline: deadline}) + pod, err := woc.createWorkflowPod(ctx, tmpl.Name, []apiv1.Container{*tmpl.Container}, tmpl, &createWorkflowPodOpts{executionDeadline: deadline}) assert.NoError(t, err) out, err := json.Marshal(map[string]time.Time{"deadline": deadline}) if assert.NoError(t, err) { @@ -1430,14 +1430,14 @@ func TestPodMetadata(t *testing.T) { ctx := context.Background() woc := newWoc(*wf) mainCtr := woc.execWf.Spec.Templates[0].Container - pod, _ := woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ := woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "foo", pod.ObjectMeta.Annotations["workflow-level-pod-annotation"]) assert.Equal(t, "bar", pod.ObjectMeta.Labels["workflow-level-pod-label"]) wf = unmarshalWF(wfWithPodMetadataAndTemplateMetadata) woc = newWoc(*wf) mainCtr = woc.execWf.Spec.Templates[0].Container - pod, _ = woc.createWorkflowPod(ctx, wf.Name, *mainCtr, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) + pod, _ = woc.createWorkflowPod(ctx, wf.Name, []apiv1.Container{*mainCtr}, &wf.Spec.Templates[0], &createWorkflowPodOpts{}) assert.Equal(t, "fizz", pod.ObjectMeta.Annotations["workflow-level-pod-annotation"]) assert.Equal(t, "buzz", pod.ObjectMeta.Labels["workflow-level-pod-label"]) assert.Equal(t, "hello", pod.ObjectMeta.Annotations["template-level-pod-annotation"]) diff --git a/workflow/executor/executor.go b/workflow/executor/executor.go index c5d1b488f890..1ffc53efe717 100644 --- a/workflow/executor/executor.go +++ b/workflow/executor/executor.go @@ -137,7 +137,6 @@ func (we *WorkflowExecutor) HandleError(ctx context.Context) { // LoadArtifacts loads artifacts from location to a container path func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { log.Infof("Start loading input artifacts...") - for _, art := range we.Template.Inputs.Artifacts { log.Infof("Downloading artifact: %s", art.Name) @@ -523,7 +522,7 @@ func (we *WorkflowExecutor) SaveParameters(ctx context.Context) error { // SaveLogs saves logs func (we *WorkflowExecutor) SaveLogs(ctx context.Context) (*wfv1.Artifact, error) { - if !we.Template.ArchiveLocation.IsArchiveLogs() { + if !we.Template.ArchiveLocation.IsArchiveLogs() || !we.Template.HasLogs() { return nil, nil } log.Infof("Saving logs") @@ -677,8 +676,8 @@ func (we *WorkflowExecutor) CaptureScriptResult(ctx context.Context) error { log.Infof("No Script output reference in workflow. Capturing script output ignored") return nil } - if we.Template.Script == nil && we.Template.Container == nil { - log.Infof("Template type is neither of Script or Container. Capturing script output ignored") + if !we.Template.HasOutput() { + log.Infof("Template type is neither of Script, Container, or Pod. Capturing script output ignored") return nil } log.Infof("Capturing script output") @@ -711,8 +710,8 @@ func (we *WorkflowExecutor) CaptureScriptResult(ctx context.Context) error { // CaptureScriptExitCode will add the exit code of a script template as output exit code func (we *WorkflowExecutor) CaptureScriptExitCode(ctx context.Context) error { - if we.Template.Script == nil && we.Template.Container == nil { - log.Infof("Template type is neither of Script or Container. Capturing exit code ignored") + if !we.Template.HasOutput() { + log.Infof("Template type is neither of Script, Container, or Pod. Capturing exit code ignored") return nil } log.Infof("Capturing script exit code") @@ -923,7 +922,7 @@ func chmod(artPath string, mode int32, recurse bool) error { // Also monitors for updates in the pod annotations which may change (e.g. terminate) // Upon completion, kills any sidecars after it finishes. func (we *WorkflowExecutor) Wait(ctx context.Context) error { - containerNames := []string{common.MainContainerName} + containerNames := we.Template.GetMainContainerNames() annotationUpdatesCh := we.monitorAnnotations(ctx) go we.monitorDeadline(ctx, containerNames, annotationUpdatesCh) err := waitutil.Backoff(ExecutorRetry, func() (bool, error) { @@ -1054,6 +1053,7 @@ func (we *WorkflowExecutor) monitorDeadline(ctx context.Context, containerNames if we.ExecutionControl != nil && we.ExecutionControl.Deadline != nil { if time.Now().UTC().After(*we.ExecutionControl.Deadline) { var message string + // Zero value of the deadline indicates an intentional cancel vs. a timeout. We treat // timeouts as a failure and the pod should be annotated with that error if we.ExecutionControl.Deadline.IsZero() { diff --git a/workflow/util/util.go b/workflow/util/util.go index 7d231ddb3f46..20fc0c24d22b 100644 --- a/workflow/util/util.go +++ b/workflow/util/util.go @@ -1044,7 +1044,7 @@ func GetNodeType(tmpl *wfv1.Template) wfv1.NodeType { return wfv1.NodeTypeRetry } switch tmpl.GetType() { - case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript, wfv1.TemplateTypeResource, wfv1.TemplateTypeData: + case wfv1.TemplateTypeContainer, wfv1.TemplateTypeContainerSet, wfv1.TemplateTypeScript, wfv1.TemplateTypeResource, wfv1.TemplateTypeData: return wfv1.NodeTypePod case wfv1.TemplateTypeDAG: return wfv1.NodeTypeDAG diff --git a/workflow/validate/validate.go b/workflow/validate/validate.go index ff269298402d..cc218afd9789 100644 --- a/workflow/validate/validate.go +++ b/workflow/validate/validate.go @@ -434,18 +434,18 @@ func (ctx *templateValidationCtx) validateTemplateHolder(tmplHolder wfv1.Templat // validateTemplateType validates that only one template type is defined func validateTemplateType(tmpl *wfv1.Template) error { numTypes := 0 - for _, tmplType := range []interface{}{tmpl.Container, tmpl.Steps, tmpl.Script, tmpl.Resource, tmpl.DAG, tmpl.Suspend, tmpl.Data} { + for _, tmplType := range []interface{}{tmpl.Container, tmpl.ContainerSet, tmpl.Steps, tmpl.Script, tmpl.Resource, tmpl.DAG, tmpl.Suspend, tmpl.Data} { if !reflect.ValueOf(tmplType).IsNil() { numTypes++ } } switch numTypes { case 0: - return errors.Errorf(errors.CodeBadRequest, "templates.%s template type unspecified. choose one of: container, steps, script, resource, dag, suspend, template, template ref", tmpl.Name) + return errors.Errorf(errors.CodeBadRequest, "templates.%s template type unspecified. choose one of: container, containerSet, steps, script, resource, dag, suspend, template, template ref", tmpl.Name) case 1: // Do nothing default: - return errors.Errorf(errors.CodeBadRequest, "templates.%s multiple template types specified. choose one of: container, steps, script, resource, dag, suspend, template, template ref", tmpl.Name) + return errors.Errorf(errors.CodeBadRequest, "templates.%s multiple template types specified. choose one of: container, containerSet, steps, script, resource, dag, suspend, template, template ref", tmpl.Name) } return nil } @@ -800,7 +800,7 @@ func (ctx *templateValidationCtx) addOutputsToScope(tmpl *wfv1.Template, prefix if tmpl.Daemon != nil && *tmpl.Daemon { scope[fmt.Sprintf("%s.ip", prefix)] = true } - if tmpl.Script != nil || tmpl.Container != nil || tmpl.Data != nil { + if tmpl.HasOutput() { scope[fmt.Sprintf("%s.outputs.result", prefix)] = true scope[fmt.Sprintf("%s.exitCode", prefix)] = true } @@ -834,7 +834,7 @@ func (ctx *templateValidationCtx) addOutputsToScope(tmpl *wfv1.Template, prefix switch tmpl.GetType() { // Not that we don't also include TemplateTypeContainer here, even though it uses `outputs.result` it uses // `outputs.parameters` as its aggregator. - case wfv1.TemplateTypeScript: + case wfv1.TemplateTypeScript, wfv1.TemplateTypeContainerSet: scope[fmt.Sprintf("%s.outputs.result", prefix)] = true scope[fmt.Sprintf("%s.exitCode", prefix)] = true default: @@ -891,7 +891,7 @@ func validateOutputs(scope map[string]interface{}, tmpl *wfv1.Template) error { if param.ValueFrom != nil { tmplType := tmpl.GetType() switch tmplType { - case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript: + case wfv1.TemplateTypeContainer, wfv1.TemplateTypeContainerSet, wfv1.TemplateTypeScript: if param.ValueFrom.Path == "" { return errors.Errorf(errors.CodeBadRequest, "%s.path must be specified for %s templates", paramRef, tmplType) } @@ -928,18 +928,9 @@ func (ctx *templateValidationCtx) validateBaseImageOutputs(tmpl *wfv1.Template) for _, out := range tmpl.Outputs.Artifacts { if common.FindOverlappingVolume(tmpl, out.Path) == nil { // output is in the base image layer. need to verify there are no volume mounts under it - if tmpl.Container != nil { - for _, volMnt := range tmpl.Container.VolumeMounts { - if strings.HasPrefix(volMnt.MountPath, out.Path+"/") { - return errors.Errorf(errors.CodeBadRequest, "templates.%s.outputs.artifacts.%s: %s", tmpl.Name, out.Name, errMsg) - } - } - } - if tmpl.Script != nil { - for _, volMnt := range tmpl.Script.VolumeMounts { - if strings.HasPrefix(volMnt.MountPath, out.Path+"/") { - return errors.Errorf(errors.CodeBadRequest, "templates.%s.outputs.artifacts.%s: %s", tmpl.Name, out.Name, errMsg) - } + for _, volMnt := range tmpl.GetVolumeMounts() { + if strings.HasPrefix(volMnt.MountPath, out.Path+"/") { + return errors.Errorf(errors.CodeBadRequest, "templates.%s.outputs.artifacts.%s: %s", tmpl.Name, out.Name, errMsg) } } }