mirror of
https://github.com/kairos-io/osbuilder.git
synced 2025-07-12 14:38:52 +00:00
extend osbuilder exporter job and osartifact crd spec
This commit is contained in:
parent
3b76681196
commit
2a3c0c9f33
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@ -40,45 +41,101 @@ type OSArtifactSpec struct {
|
||||
// +kubebuilder:validation:Enum:=rpi3;rpi4
|
||||
Model *Model `json:"model,omitempty"`
|
||||
|
||||
CloudConfigRef *SecretKeySelector `json:"cloudConfigRef,omitempty"`
|
||||
// +optional
|
||||
CloudConfigRef *corev1.SecretKeySelector `json:"cloudConfigRef,omitempty"`
|
||||
|
||||
Bundles []string `json:"bundles,omitempty"`
|
||||
// +optional
|
||||
Bundles []string `json:"bundles,omitempty"`
|
||||
|
||||
// +optional
|
||||
FileBundles map[string]string `json:"fileBundles,omitempty"`
|
||||
|
||||
OutputImage *OutputImage `json:"outputImage,omitempty"`
|
||||
}
|
||||
|
||||
type SecretKeySelector struct {
|
||||
Name string `json:"name"`
|
||||
// Exporter when provided it will spawn an exporter job that
|
||||
// pushes images built by the osbuilder to the provided registry.
|
||||
// +optional
|
||||
Key string `json:"key,omitempty"`
|
||||
Exporter *ExporterSpec `json:"exporter,omitempty"`
|
||||
}
|
||||
|
||||
type RegistryCloud string
|
||||
type RegistryType string
|
||||
|
||||
const (
|
||||
// RegistryCloudECR ensures that special env variables will be injected
|
||||
// RegistryTypeECR ensures that special env variables will be injected
|
||||
// into the exporter job to allow kaniko to automatically auth with the
|
||||
// ecr registry to push the images.
|
||||
RegistryCloudECR RegistryCloud = "ecr"
|
||||
// RegistryCloudOther requires from user to provide username/password secret
|
||||
RegistryTypeECR RegistryType = "ecr"
|
||||
// RegistryTypeOther requires from user to provide username/password secret
|
||||
// in order for kaniko to be able to authenticate with the container registry.
|
||||
RegistryCloudOther RegistryCloud = "other"
|
||||
RegistryTypeOther RegistryType = "other"
|
||||
)
|
||||
|
||||
type OutputImage struct {
|
||||
type ExporterSpec struct {
|
||||
// Registry is a registry spec used to push the final images built by the osbuilder.
|
||||
// +required
|
||||
Registry RegistrySpec `json:"registry"`
|
||||
|
||||
// ServiceAccount allows overriding 'default' SA bound to the exporter pods.
|
||||
// +optional
|
||||
ServiceAccount *string `json:"serviceAccount,omitempty"`
|
||||
|
||||
// ExtraEnvVars allows to append extra env vars to the exporter pods.
|
||||
// +optional
|
||||
ExtraEnvVars *[]corev1.EnvVar `json:"extraEnvVars,omitempty"`
|
||||
}
|
||||
|
||||
func (in *ExporterSpec) IsECRRegistry() bool {
|
||||
return in.Registry.Type == RegistryTypeECR
|
||||
}
|
||||
|
||||
func (in *ExporterSpec) HasDockerConfigSecret() bool {
|
||||
return in.Registry.DockerConfigSecretKeyRef != nil
|
||||
}
|
||||
|
||||
func (in *ExporterSpec) HasExtraEnvVars() bool {
|
||||
return in.ExtraEnvVars != nil && len(*in.ExtraEnvVars) > 0
|
||||
}
|
||||
|
||||
func (in *ExporterSpec) ServiceAccountName() string {
|
||||
if in.ServiceAccount == nil || len(*in.ServiceAccount) == 0 {
|
||||
// Default SA name. Always exists.
|
||||
return "default"
|
||||
}
|
||||
|
||||
return *in.ServiceAccount
|
||||
}
|
||||
|
||||
type ImageSpec struct {
|
||||
// Repository is the name of repository where image is being pushed.
|
||||
// +required
|
||||
Repository string `json:"repository"`
|
||||
|
||||
// Tag is the tag name of the image being pushed. Defaults to 'latest' if not provided.
|
||||
// +optional
|
||||
Tag string `json:"tag,omitempty"`
|
||||
}
|
||||
|
||||
type RegistrySpec struct {
|
||||
// Name is a DNS name of the registry. It has to be accessible by the pod.
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type is a kind of registry being used. Currently supported values are:
|
||||
// - ecr - Amazon Elastic Container Registry. Use only if a pod runs on
|
||||
// an eks cluster and has permissions to push to the registry.
|
||||
// - other - Any other type of the registry. It requires DockerConfigSecretKeyRef
|
||||
// to be provided in order to auth to the registry.
|
||||
// +kubebuilder:validation:Enum=ecr;other
|
||||
// +kubebuilder:default=other
|
||||
// +required
|
||||
Cloud RegistryCloud `json:"cloud"`
|
||||
Type RegistryType `json:"type"`
|
||||
|
||||
// Image defines the image details required to push image to the registry.
|
||||
// +required
|
||||
Image ImageSpec `json:"image"`
|
||||
|
||||
// DockerConfigSecretKeyRef is a reference to the secret that holds the `config.json` auth file.
|
||||
// It should be in a format that `docker login` can accept to auth to the registry.
|
||||
// +optional
|
||||
Registry string `json:"registry,omitempty"`
|
||||
// +optional
|
||||
Repository string `json:"repository,omitempty"`
|
||||
// +optional
|
||||
Tag string `json:"tag,omitempty"`
|
||||
// +optional
|
||||
DockerConfigSecretKeyRef *SecretKeySelector `json:"dockerConfigSecretKeyRef,omitempty"`
|
||||
DockerConfigSecretKeyRef *corev1.SecretKeySelector `json:"dockerConfigSecretKeyRef,omitempty"`
|
||||
}
|
||||
|
||||
type ArtifactPhase string
|
||||
|
@ -21,10 +21,58 @@ limitations under the License.
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExporterSpec) DeepCopyInto(out *ExporterSpec) {
|
||||
*out = *in
|
||||
in.Registry.DeepCopyInto(&out.Registry)
|
||||
if in.ServiceAccount != nil {
|
||||
in, out := &in.ServiceAccount, &out.ServiceAccount
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExtraEnvVars != nil {
|
||||
in, out := &in.ExtraEnvVars, &out.ExtraEnvVars
|
||||
*out = new([]v1.EnvVar)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]v1.EnvVar, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExporterSpec.
|
||||
func (in *ExporterSpec) DeepCopy() *ExporterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExporterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageSpec) DeepCopyInto(out *ImageSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSpec.
|
||||
func (in *ImageSpec) DeepCopy() *ImageSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OSArtifact) DeepCopyInto(out *OSArtifact) {
|
||||
*out = *in
|
||||
@ -94,8 +142,8 @@ func (in *OSArtifactSpec) DeepCopyInto(out *OSArtifactSpec) {
|
||||
}
|
||||
if in.CloudConfigRef != nil {
|
||||
in, out := &in.CloudConfigRef, &out.CloudConfigRef
|
||||
*out = new(SecretKeySelector)
|
||||
**out = **in
|
||||
*out = new(v1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Bundles != nil {
|
||||
in, out := &in.Bundles, &out.Bundles
|
||||
@ -109,9 +157,9 @@ func (in *OSArtifactSpec) DeepCopyInto(out *OSArtifactSpec) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.OutputImage != nil {
|
||||
in, out := &in.OutputImage, &out.OutputImage
|
||||
*out = new(OutputImage)
|
||||
if in.Exporter != nil {
|
||||
in, out := &in.Exporter, &out.Exporter
|
||||
*out = new(ExporterSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
@ -131,7 +179,7 @@ func (in *OSArtifactStatus) DeepCopyInto(out *OSArtifactStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
@ -149,36 +197,22 @@ func (in *OSArtifactStatus) DeepCopy() *OSArtifactStatus {
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OutputImage) DeepCopyInto(out *OutputImage) {
|
||||
func (in *RegistrySpec) DeepCopyInto(out *RegistrySpec) {
|
||||
*out = *in
|
||||
out.Image = in.Image
|
||||
if in.DockerConfigSecretKeyRef != nil {
|
||||
in, out := &in.DockerConfigSecretKeyRef, &out.DockerConfigSecretKeyRef
|
||||
*out = new(SecretKeySelector)
|
||||
**out = **in
|
||||
*out = new(v1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutputImage.
|
||||
func (in *OutputImage) DeepCopy() *OutputImage {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistrySpec.
|
||||
func (in *RegistrySpec) DeepCopy() *RegistrySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OutputImage)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
|
||||
func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SecretKeySelector)
|
||||
out := new(RegistrySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
@ -5,4 +5,4 @@ maintainers:
|
||||
- name: Plural
|
||||
email: support@plural.sh
|
||||
type: application
|
||||
version: 0.5.1
|
||||
version: 0.6.0
|
@ -22,13 +22,19 @@ spec:
|
||||
cloudConfigRef:
|
||||
name: {{ include "osartifact.fullname" . }}-config
|
||||
key: cloud-config.yaml
|
||||
outputImage:
|
||||
cloud: {{ .Values.exporter.cloud }}
|
||||
registry: {{ .Values.exporter.registry }}
|
||||
repository: {{ .Values.exporter.repository }}
|
||||
tag: {{ .Values.exporter.tag }}
|
||||
{{- if (eq .Values.exporter.cloud "other") }}
|
||||
passwordSecretKeyRef:
|
||||
name: {{ .Values.exporter.configSecret.name | default (printf "%s-%s" (include "osartifact.fullname" .) "config") }}
|
||||
key: {{ .Values.exporter.configSecret.key }}
|
||||
exporter:
|
||||
serviceAccount: {{ include "osartifact.fullname" . }}
|
||||
{{- with .Values.exporter.extraEnvVars }}
|
||||
extraEnvVars: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
registry:
|
||||
name: {{ .Values.exporter.registry.name }}
|
||||
type: {{ .Values.exporter.registry.type }}
|
||||
image:
|
||||
repository: {{ .Values.exporter.registry.image.repository }}
|
||||
tag: {{ .Values.exporter.registry.image.tag }}
|
||||
{{- if (eq .Values.exporter.registry.type "other") }}
|
||||
passwordSecretKeyRef:
|
||||
name: {{ .Values.exporter.registry.configSecret.name | default (printf "%s-%s" (include "osartifact.fullname" .) "config") }}
|
||||
key: {{ .Values.exporter.registry.configSecret.key }}
|
||||
{{- end }}
|
@ -95,7 +95,7 @@ stringData:
|
||||
{
|
||||
"auths": {
|
||||
"{{ .Values.exporter.registry }}": {
|
||||
"auth": {{ printf "%s:%s" .Values.exporter.username $dockerUserPassword | b64enc | quote }}
|
||||
"auth": {{ printf "%s:%s" .Values.exporter.registry.username $dockerUserPassword | b64enc | quote }}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
charts/osartifact/templates/serviceaccount.yaml
Normal file
9
charts/osartifact/templates/serviceaccount.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "osartifact.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- with .Values.exporter.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
@ -59,23 +59,34 @@ extraCloudConfig: ~
|
||||
|
||||
# Export configuration for the final ISO images
|
||||
exporter:
|
||||
# Whether container registry is an ECR instance or other. One of: "ecr", "other"
|
||||
cloud: other
|
||||
# Docker registry DNS name where we should export packed ISO images
|
||||
registry: ~
|
||||
# Name of the repository where images should be stored
|
||||
repository: plural-edge
|
||||
# Image tag that should be used when pushing to the registry
|
||||
tag: latest
|
||||
# Username used when generating docker config.json. It is only used when 'passwordSecret' is provided.
|
||||
username: plural
|
||||
# Secret that stores just the password for the docker registry user.
|
||||
# One of 'passwordSecret' or 'configSecret' must be provided.
|
||||
passwordSecret:
|
||||
serviceAccount:
|
||||
annotations: ~
|
||||
# Defines extra env vars that will be added to the exporter pob
|
||||
# extraEnvVars:
|
||||
# - name: MY_ENV_VAR
|
||||
# value: myvalue
|
||||
extraEnvVars: []
|
||||
registry:
|
||||
# Container registry DNS name where we should export packed ISO images
|
||||
name: ~
|
||||
key: password
|
||||
# Secret configuration that stores the docker config.json file with the auth information.
|
||||
# It is in the default docker format.
|
||||
configSecret:
|
||||
name: ~
|
||||
key: config.json
|
||||
# Whether container registry is an ECR instance or other. One of: "ecr", "other"
|
||||
type: other
|
||||
|
||||
image:
|
||||
# Name of the repository where images should be stored
|
||||
repository: plural-edge
|
||||
# Image tag that should be used when pushing to the registry
|
||||
tag: latest
|
||||
|
||||
# Username used when generating docker config.json. It is only used when 'passwordSecret' is provided.
|
||||
username: plural
|
||||
# Secret that stores just the password for the docker registry user.
|
||||
# One of 'passwordSecret' or 'configSecret' must be provided.
|
||||
passwordSecret:
|
||||
name: ~
|
||||
key: password
|
||||
# Secret configuration that stores the docker config.json file with the auth information.
|
||||
# It is in the default docker format.
|
||||
configSecret:
|
||||
name: ~
|
||||
key: config.json
|
@ -1,8 +1,8 @@
|
||||
apiVersion: v2
|
||||
name: osbuilder
|
||||
description: A Helm chart for osbuilder
|
||||
appVersion: 0.2.0
|
||||
version: 0.1.13
|
||||
appVersion: 0.3.0
|
||||
version: 0.1.14
|
||||
dependencies:
|
||||
- name: cert-manager
|
||||
version: v1.16.3
|
||||
|
@ -48,13 +48,226 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
cloudConfigRef:
|
||||
description: SecretKeySelector selects a key of a Secret.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must be a
|
||||
valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
exporter:
|
||||
description: |-
|
||||
Exporter when provided it will spawn an exporter job that
|
||||
pushes images built by the osbuilder to the provided registry.
|
||||
properties:
|
||||
extraEnvVars:
|
||||
description: ExtraEnvVars allows to append extra env vars to the
|
||||
exporter pods.
|
||||
items:
|
||||
description: EnvVar represents an environment variable present
|
||||
in a Container.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the environment variable. Must be a
|
||||
C_IDENTIFIER.
|
||||
type: string
|
||||
value:
|
||||
description: |-
|
||||
Variable references $(VAR_NAME) are expanded
|
||||
using the previously defined environment variables in the container and
|
||||
any service environment variables. If a variable cannot be resolved,
|
||||
the reference in the input string will be unchanged. Double $$ are reduced
|
||||
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
|
||||
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
|
||||
Escaped references will never be expanded, regardless of whether the variable
|
||||
exists or not.
|
||||
Defaults to "".
|
||||
type: string
|
||||
valueFrom:
|
||||
description: Source for the environment variable's value.
|
||||
Cannot be used if value is not empty.
|
||||
properties:
|
||||
configMapKeyRef:
|
||||
description: Selects a key of a ConfigMap.
|
||||
properties:
|
||||
key:
|
||||
description: The key to select.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the ConfigMap or its
|
||||
key must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
fieldRef:
|
||||
description: |-
|
||||
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
|
||||
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: Version of the schema the FieldPath
|
||||
is written in terms of, defaults to "v1".
|
||||
type: string
|
||||
fieldPath:
|
||||
description: Path of the field to select in the
|
||||
specified API version.
|
||||
type: string
|
||||
required:
|
||||
- fieldPath
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
resourceFieldRef:
|
||||
description: |-
|
||||
Selects a resource of the container: only resources limits and requests
|
||||
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
|
||||
properties:
|
||||
containerName:
|
||||
description: 'Container name: required for volumes,
|
||||
optional for env vars'
|
||||
type: string
|
||||
divisor:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Specifies the output format of the
|
||||
exposed resources, defaults to "1"
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
resource:
|
||||
description: 'Required: resource to select'
|
||||
type: string
|
||||
required:
|
||||
- resource
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
secretKeyRef:
|
||||
description: Selects a key of a secret in the pod's
|
||||
namespace
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key
|
||||
must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
registry:
|
||||
description: Registry is a registry spec used to push the final
|
||||
images built by the osbuilder.
|
||||
properties:
|
||||
dockerConfigSecretKeyRef:
|
||||
description: |-
|
||||
DockerConfigSecretKeyRef is a reference to the secret that holds the `config.json` auth file.
|
||||
It should be in a format that `docker login` can accept to auth to the registry.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must
|
||||
be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
image:
|
||||
description: Image defines the image details required to push
|
||||
image to the registry.
|
||||
properties:
|
||||
repository:
|
||||
description: Repository is the name of repository where
|
||||
image is being pushed.
|
||||
type: string
|
||||
tag:
|
||||
description: Tag is the tag name of the image being pushed.
|
||||
Defaults to 'latest' if not provided.
|
||||
type: string
|
||||
required:
|
||||
- repository
|
||||
type: object
|
||||
name:
|
||||
description: Name is a DNS name of the registry. It has to
|
||||
be accessible by the pod.
|
||||
type: string
|
||||
type:
|
||||
default: other
|
||||
description: "Type is a kind of registry being used. Currently
|
||||
supported values are:\n\t- ecr \t- Amazon Elastic Container
|
||||
Registry. Use only if a pod runs on\n\t\t\t an eks cluster
|
||||
and has permissions to push to the registry.\n\t- other
|
||||
- Any other type of the registry. It requires DockerConfigSecretKeyRef\n\t\t\t
|
||||
\ to be provided in order to auth to the registry."
|
||||
enum:
|
||||
- ecr
|
||||
- other
|
||||
type: string
|
||||
required:
|
||||
- image
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
serviceAccount:
|
||||
description: ServiceAccount allows overriding 'default' SA bound
|
||||
to the exporter pods.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- registry
|
||||
type: object
|
||||
fileBundles:
|
||||
additionalProperties:
|
||||
@ -70,32 +283,6 @@ spec:
|
||||
- rpi3
|
||||
- rpi4
|
||||
type: string
|
||||
outputImage:
|
||||
properties:
|
||||
cloud:
|
||||
default: other
|
||||
enum:
|
||||
- ecr
|
||||
- other
|
||||
type: string
|
||||
dockerConfigSecretKeyRef:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
registry:
|
||||
type: string
|
||||
repository:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
required:
|
||||
- cloud
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: OSArtifactStatus defines the observed state of OSArtifact
|
||||
|
@ -1,5 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: '{{ include "helm-chart.serviceAccountName" . }}'
|
||||
namespace: '{{.Release.Namespace}}'
|
||||
name: '{{ include "helm-chart.serviceAccountName" . }}'
|
||||
namespace: '{{.Release.Namespace}}'
|
||||
|
@ -48,13 +48,226 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
cloudConfigRef:
|
||||
description: SecretKeySelector selects a key of a Secret.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must be a
|
||||
valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
exporter:
|
||||
description: |-
|
||||
Exporter when provided it will spawn an exporter job that
|
||||
pushes images built by the osbuilder to the provided registry.
|
||||
properties:
|
||||
extraEnvVars:
|
||||
description: ExtraEnvVars allows to append extra env vars to the
|
||||
exporter pods.
|
||||
items:
|
||||
description: EnvVar represents an environment variable present
|
||||
in a Container.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the environment variable. Must be a
|
||||
C_IDENTIFIER.
|
||||
type: string
|
||||
value:
|
||||
description: |-
|
||||
Variable references $(VAR_NAME) are expanded
|
||||
using the previously defined environment variables in the container and
|
||||
any service environment variables. If a variable cannot be resolved,
|
||||
the reference in the input string will be unchanged. Double $$ are reduced
|
||||
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
|
||||
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
|
||||
Escaped references will never be expanded, regardless of whether the variable
|
||||
exists or not.
|
||||
Defaults to "".
|
||||
type: string
|
||||
valueFrom:
|
||||
description: Source for the environment variable's value.
|
||||
Cannot be used if value is not empty.
|
||||
properties:
|
||||
configMapKeyRef:
|
||||
description: Selects a key of a ConfigMap.
|
||||
properties:
|
||||
key:
|
||||
description: The key to select.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the ConfigMap or its
|
||||
key must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
fieldRef:
|
||||
description: |-
|
||||
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
|
||||
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: Version of the schema the FieldPath
|
||||
is written in terms of, defaults to "v1".
|
||||
type: string
|
||||
fieldPath:
|
||||
description: Path of the field to select in the
|
||||
specified API version.
|
||||
type: string
|
||||
required:
|
||||
- fieldPath
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
resourceFieldRef:
|
||||
description: |-
|
||||
Selects a resource of the container: only resources limits and requests
|
||||
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
|
||||
properties:
|
||||
containerName:
|
||||
description: 'Container name: required for volumes,
|
||||
optional for env vars'
|
||||
type: string
|
||||
divisor:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Specifies the output format of the
|
||||
exposed resources, defaults to "1"
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
resource:
|
||||
description: 'Required: resource to select'
|
||||
type: string
|
||||
required:
|
||||
- resource
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
secretKeyRef:
|
||||
description: Selects a key of a secret in the pod's
|
||||
namespace
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key
|
||||
must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
registry:
|
||||
description: Registry is a registry spec used to push the final
|
||||
images built by the osbuilder.
|
||||
properties:
|
||||
dockerConfigSecretKeyRef:
|
||||
description: |-
|
||||
DockerConfigSecretKeyRef is a reference to the secret that holds the `config.json` auth file.
|
||||
It should be in a format that `docker login` can accept to auth to the registry.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must
|
||||
be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
image:
|
||||
description: Image defines the image details required to push
|
||||
image to the registry.
|
||||
properties:
|
||||
repository:
|
||||
description: Repository is the name of repository where
|
||||
image is being pushed.
|
||||
type: string
|
||||
tag:
|
||||
description: Tag is the tag name of the image being pushed.
|
||||
Defaults to 'latest' if not provided.
|
||||
type: string
|
||||
required:
|
||||
- repository
|
||||
type: object
|
||||
name:
|
||||
description: Name is a DNS name of the registry. It has to
|
||||
be accessible by the pod.
|
||||
type: string
|
||||
type:
|
||||
default: other
|
||||
description: "Type is a kind of registry being used. Currently
|
||||
supported values are:\n\t- ecr \t- Amazon Elastic Container
|
||||
Registry. Use only if a pod runs on\n\t\t\t an eks cluster
|
||||
and has permissions to push to the registry.\n\t- other
|
||||
- Any other type of the registry. It requires DockerConfigSecretKeyRef\n\t\t\t
|
||||
\ to be provided in order to auth to the registry."
|
||||
enum:
|
||||
- ecr
|
||||
- other
|
||||
type: string
|
||||
required:
|
||||
- image
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
serviceAccount:
|
||||
description: ServiceAccount allows overriding 'default' SA bound
|
||||
to the exporter pods.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- registry
|
||||
type: object
|
||||
fileBundles:
|
||||
additionalProperties:
|
||||
@ -70,32 +283,6 @@ spec:
|
||||
- rpi3
|
||||
- rpi4
|
||||
type: string
|
||||
outputImage:
|
||||
properties:
|
||||
cloud:
|
||||
default: other
|
||||
enum:
|
||||
- ecr
|
||||
- other
|
||||
type: string
|
||||
dockerConfigSecretKeyRef:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
registry:
|
||||
type: string
|
||||
repository:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
required:
|
||||
- cloud
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: OSArtifactStatus defines the observed state of OSArtifact
|
||||
|
@ -51,7 +51,7 @@ const (
|
||||
artifactExporterIndexAnnotation = "build.kairos.io/export-index"
|
||||
ready = "Ready"
|
||||
)
|
||||
const threeHours = int32(10800)
|
||||
const threeHours = int32(3 * 60 * 60)
|
||||
|
||||
var (
|
||||
requeue = ctrl.Result{RequeueAfter: requeueAfter}
|
||||
@ -260,7 +260,7 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
|
||||
return ctrl.Result{}, fmt.Errorf("failed to locate artifact pvc")
|
||||
}
|
||||
|
||||
if artifact.Spec.OutputImage != nil {
|
||||
if artifact.Spec.Exporter != nil {
|
||||
idx := fmt.Sprintf("%d", 1)
|
||||
|
||||
job := indexedJobs[idx]
|
||||
@ -280,7 +280,8 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
|
||||
BackoffLimit: ptr(int32(1)),
|
||||
Template: corev1.PodTemplateSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
||||
ServiceAccountName: artifact.Spec.Exporter.ServiceAccountName(),
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
InitContainers: []corev1.Container{
|
||||
{
|
||||
Name: "init-container",
|
||||
@ -303,13 +304,18 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
|
||||
},
|
||||
}
|
||||
|
||||
tag := artifact.Spec.Exporter.Registry.Image.Tag
|
||||
if len(tag) == 0 {
|
||||
tag = "latest"
|
||||
}
|
||||
|
||||
container := corev1.Container{
|
||||
Name: "exporter",
|
||||
Image: "gcr.io/kaniko-project/executor:latest",
|
||||
Args: []string{
|
||||
"--context=/artifacts/",
|
||||
"--dockerfile=/artifacts/Dockerfile",
|
||||
fmt.Sprintf("--destination=%s/%s:%s", artifact.Spec.OutputImage.Registry, artifact.Spec.OutputImage.Repository, artifact.Spec.OutputImage.Tag),
|
||||
fmt.Sprintf("--destination=%s/%s:%s", artifact.Spec.Exporter.Registry.Name, artifact.Spec.Exporter.Registry.Image.Repository, tag),
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{
|
||||
@ -318,19 +324,30 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
|
||||
SubPath: "artifacts",
|
||||
},
|
||||
},
|
||||
Env: []corev1.EnvVar{},
|
||||
}
|
||||
|
||||
if artifact.Spec.OutputImage != nil && artifact.Spec.OutputImage.Cloud == osbuilder.RegistryCloudECR {
|
||||
container.Env = []corev1.EnvVar{
|
||||
// Append EKS specific env vars if using ECR registry
|
||||
if artifact.Spec.Exporter.IsECRRegistry() {
|
||||
container.Env = append(container.Env, []corev1.EnvVar{
|
||||
{Name: "AWS_SDK_LOAD_CONFIG", Value: "true"},
|
||||
{Name: "AWS_EC2_METADATA_DISABLED", Value: "true"},
|
||||
}
|
||||
}...)
|
||||
}
|
||||
|
||||
if artifact.Spec.OutputImage != nil && artifact.Spec.OutputImage.DockerConfigSecretKeyRef != nil {
|
||||
if err := r.Get(ctx, client.ObjectKey{Namespace: artifact.Namespace, Name: artifact.Spec.OutputImage.DockerConfigSecretKeyRef.Name}, &corev1.Secret{}); err != nil {
|
||||
// Append extra env vars
|
||||
if artifact.Spec.Exporter.HasExtraEnvVars() {
|
||||
container.Env = append(container.Env, *artifact.Spec.Exporter.ExtraEnvVars...)
|
||||
}
|
||||
|
||||
// Mount custom config.json file from secret
|
||||
if artifact.Spec.Exporter.HasDockerConfigSecret() {
|
||||
name := artifact.Spec.Exporter.Registry.DockerConfigSecretKeyRef.Name
|
||||
key := artifact.Spec.Exporter.Registry.DockerConfigSecretKeyRef.Key
|
||||
|
||||
if err := r.Get(ctx, client.ObjectKey{Namespace: artifact.Namespace, Name: name}, &corev1.Secret{}); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
logger.Info(fmt.Sprintf("Secret %s/%s not found", artifact.Namespace, artifact.Spec.OutputImage.DockerConfigSecretKeyRef.Name))
|
||||
logger.Info(fmt.Sprintf("Secret %s/%s not found", artifact.Namespace, name))
|
||||
return requeue, nil
|
||||
}
|
||||
return ctrl.Result{}, err
|
||||
@ -343,10 +360,10 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
|
||||
Name: "docker-secret",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
Secret: &corev1.SecretVolumeSource{
|
||||
SecretName: artifact.Spec.OutputImage.DockerConfigSecretKeyRef.Name,
|
||||
SecretName: name,
|
||||
Items: []corev1.KeyToPath{{
|
||||
Key: artifact.Spec.OutputImage.DockerConfigSecretKeyRef.Key,
|
||||
Path: artifact.Spec.OutputImage.DockerConfigSecretKeyRef.Key,
|
||||
Key: key,
|
||||
Path: "config.json",
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user