diff --git a/Makefile b/Makefile index 29cb5a4aa..a43784bbd 100644 --- a/Makefile +++ b/Makefile @@ -181,7 +181,7 @@ vendor: $(GO) bump-%: CNAO_VERSION=${VERSION} ./hack/components/bump-$*.sh -bump-all: bump-knmstate bump-kubemacpool bump-macvtap bump-linux-bridge +bump-all: bump-knmstate bump-kubemacpool bump-macvtap bump-linux-bridge bump-multus .PHONY: \ $(E2E_SUITES) \ diff --git a/data/multus/001-multus.yaml b/data/multus/001-multus.yaml new file mode 100644 index 000000000..080e6fe91 --- /dev/null +++ b/data/multus/001-multus.yaml @@ -0,0 +1,140 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: network-attachment-definitions.k8s.cni.cncf.io +spec: + group: k8s.cni.cncf.io + scope: Namespaced + names: + plural: network-attachment-definitions + singular: network-attachment-definition + kind: NetworkAttachmentDefinition + shortNames: + - net-attach-def + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + config: + type: string +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: multus +rules: + - apiGroups: ["k8s.cni.cncf.io"] + resources: + - '*' + verbs: + - '*' + - apiGroups: + - "" + resources: + - pods + - pods/status + verbs: + - get + - update +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: multus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: multus +subjects: + - kind: ServiceAccount + name: multus + namespace: {{ .Namespace }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: multus + namespace: {{ .Namespace }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: multus + namespace: {{ .Namespace }} + labels: + tier: node + app: multus + name: multus +spec: + selector: + matchLabels: + name: kube-multus-ds-amd64 + updateStrategy: + type: RollingUpdate + template: + metadata: + labels: + tier: node + app: multus + name: kube-multus-ds-amd64 + spec: + hostNetwork: true + nodeSelector: + kubernetes.io/arch: amd64 + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: multus + containers: + - name: kube-multus + image: {{ .MultusImage }} + command: ["/entrypoint.sh"] + args: + - "--multus-conf-file=auto" + - "--cni-version=0.3.1" + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: true + volumeMounts: + - name: cni + mountPath: /host/etc/cni/net.d + - name: cnibin + mountPath: /host/opt/cni/bin + imagePullPolicy: {{ .ImagePullPolicy }} + volumes: + - name: cni + hostPath: + path: {{ .CNIConfigDir }} + - name: cnibin + hostPath: + path: {{ .CNIBinDir }} +{{ if .EnableSCC }} +--- +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: multus +allowPrivilegedContainer: true +allowHostDirVolumePlugin: true +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +users: +- system:serviceaccount:{{ .Namespace }}:multus +{{ end }} +--- diff --git a/data/multus/001-rbac.yaml b/data/multus/001-rbac.yaml deleted file mode 100644 index 9050b1c44..000000000 --- a/data/multus/001-rbac.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: multus -rules: - - apiGroups: ["k8s.cni.cncf.io"] - resources: - - '*' - verbs: - - '*' - - apiGroups: - - "" - resources: - - pods - - pods/status - verbs: - - get - - update ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: multus -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: multus -subjects: -- kind: ServiceAccount - name: multus - namespace: {{ .Namespace }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: multus - namespace: {{ .Namespace }} -{{ if .EnableSCC }} ---- -apiVersion: security.openshift.io/v1 -kind: SecurityContextConstraints -metadata: - name: multus -allowPrivilegedContainer: true -allowHostDirVolumePlugin: true -runAsUser: - type: RunAsAny -seLinuxContext: - type: RunAsAny -users: -- system:serviceaccount:{{ .Namespace }}:multus -{{ end }} diff --git a/data/multus/002-multus.yaml b/data/multus/002-multus.yaml deleted file mode 100644 index 9f5f854a0..000000000 --- a/data/multus/002-multus.yaml +++ /dev/null @@ -1,72 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: network-attachment-definitions.k8s.cni.cncf.io -spec: - group: k8s.cni.cncf.io - version: v1 - scope: Namespaced - names: - plural: network-attachment-definitions - singular: network-attachment-definition - kind: NetworkAttachmentDefinition - shortNames: - - net-attach-def - validation: - openAPIV3Schema: - properties: - spec: - properties: - config: - type: string ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: multus - namespace: {{ .Namespace }} - labels: - tier: node - app: multus -spec: - selector: - matchLabels: - name: kube-multus-ds-amd64 - template: - metadata: - labels: - name: kube-multus-ds-amd64 - tier: node - app: multus - spec: - nodeSelector: - beta.kubernetes.io/arch: amd64 - tolerations: - - operator: Exists - effect: NoSchedule - serviceAccountName: multus - containers: - - name: kube-multus - command: ["/entrypoint.sh"] - args: ["--multus-conf-file=auto","--cni-version=0.3.1"] - image: {{ .MultusImage }} - imagePullPolicy: {{ .ImagePullPolicy }} - resources: - requests: - cpu: "60m" - memory: "30Mi" - securityContext: - privileged: true - volumeMounts: - - name: cni - mountPath: /host/etc/cni/net.d - - name: cnibin - mountPath: /host/opt/cni/bin - volumes: - - name: cni - hostPath: - path: {{ .CNIConfigDir }} - - name: cnibin - hostPath: - path: {{ .CNIBinDir }} diff --git a/hack/components/bump-multus.sh b/hack/components/bump-multus.sh new file mode 100755 index 000000000..28898f4cc --- /dev/null +++ b/hack/components/bump-multus.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +set -xeo pipefail + +source hack/components/yaml-utils.sh +source hack/components/git-utils.sh + +#here we do all the object specific parametizing +function __parametize_by_object() { + for f in ./*; do + case "${f}" in + ./ClusterRoleBinding_multus.yaml) + yaml-utils::update_param ${f} subjects[0].namespace '{{ .Namespace }}' + yaml-utils::remove_single_quotes_from_yaml ${f} + ;; + ./ServiceAccount_multus.yaml) + yaml-utils::update_param ${f} metadata.namespace '{{ .Namespace }}' + yaml-utils::remove_single_quotes_from_yaml ${f} + ;; + ./DaemonSet_kube-multus-ds-amd64.yaml) + yaml-utils::update_param ${f} metadata.name 'multus' + yaml-utils::update_param ${f} metadata.namespace '{{ .Namespace }}' + yaml-utils::update_param ${f} spec.selector.matchLabels.name 'kube-multus-ds-amd64' + yaml-utils::update_param ${f} spec.template.metadata.labels.name 'kube-multus-ds-amd64' + yaml-utils::update_param ${f} spec.template.spec.containers[0].image '{{ .MultusImage }}' + yaml-utils::set_param ${f} spec.template.spec.containers[0].imagePullPolicy '{{ .ImagePullPolicy }}' + yaml-utils::delete_param ${f} spec.template.spec.containers[0].volumeMounts[2] + yaml-utils::update_param ${f} spec.template.spec.volumes[0].hostPath.path '{{ .CNIConfigDir }}' + yaml-utils::update_param ${f} spec.template.spec.volumes[1].hostPath.path '{{ .CNIBinDir }}' + yaml-utils::delete_param ${f} spec.template.spec.volumes[2] + yaml-utils::remove_single_quotes_from_yaml ${f} + ;; + esac + done +} + +echo 'Bumping multus' +MULTUS_URL=$(yaml-utils::get_component_url multus) +MULTUS_COMMIT=$(yaml-utils::get_component_commit multus) +MULTUS_REPO=$(yaml-utils::get_component_repo ${MULTUS_URL}) + +TEMP_DIR=$(git-utils::create_temp_path multus) +trap "rm -rf ${TEMP_DIR}" EXIT +MULTUS_PATH=${TEMP_DIR}/${MULTUS_REPO} + +echo 'Fetch multus sources' +git-utils::fetch_component ${MULTUS_PATH} ${MULTUS_URL} ${MULTUS_COMMIT} + +( + cd ${MULTUS_PATH} + mkdir -p config/cnao + cp images/multus-daemonset.yml config/cnao + + echo 'Split manifest per object' + cd config/cnao + $(yaml-utils::split_yaml_by_seperator . multus-daemonset.yml) + rm multus-daemonset.yml + $(yaml-utils::rename_files_by_object .) + + echo 'parametize manifests by object' + __parametize_by_object + + cat < 000-ns.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Namespace }} +EOF + + cat < SecurityContextConstraints_multus.yaml +{{ if .EnableSCC }} +--- +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: multus +allowPrivilegedContainer: true +allowHostDirVolumePlugin: true +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +users: +- system:serviceaccount:{{ .Namespace }}:multus +{{ end }} +--- +EOF + + echo 'rejoin sub-manifests to final manifest' + YAML_FILE=001-multus.yaml + touch ${YAML_FILE} + cat CustomResourceDefinition_network-attachment-definitions.k8s.cni.cncf.io.yaml >> ${YAML_FILE} && + cat ClusterRole_multus.yaml >> ${YAML_FILE} && + cat ClusterRoleBinding_multus.yaml >> ${YAML_FILE} && + cat ServiceAccount_multus.yaml >> ${YAML_FILE} && + cat DaemonSet_kube-multus-ds-amd64.yaml >> ${YAML_FILE} && + cat SecurityContextConstraints_multus.yaml >> ${YAML_FILE} +) + +echo 'copy manifests' +rm -rf data/multus/* +cp ${MULTUS_PATH}/config/cnao/000-ns.yaml data/multus/ +cp ${MULTUS_PATH}/config/cnao/001-multus.yaml data/multus/ + +echo 'Get multus image name and update it under CNAO' +MULTUS_TAG=$(git-utils::get_component_tag ${MULTUS_PATH}) +MULTUS_IMAGE=nfvpe/multus +MULTUS_IMAGE_TAGGED=${MULTUS_IMAGE}:${MULTUS_TAG} +sed -i "s#\"${MULTUS_IMAGE}:.*\"#\"${MULTUS_IMAGE_TAGGED}\"#" \ + pkg/components/components.go \ + test/releases/${CNAO_VERSION}.go diff --git a/hack/components/yaml-utils.sh b/hack/components/yaml-utils.sh index 9a56202dd..ecc3cc68f 100644 --- a/hack/components/yaml-utils.sh +++ b/hack/components/yaml-utils.sh @@ -2,21 +2,61 @@ set -xeo pipefail +function __yq() { + docker run --rm -i -v ${PWD}:/workdir mikefarah/yq yq "$@" +} + function __get_parameter_from_yaml() { - local arg=$1 - cat components.yaml | docker run -i --rm evns/yq $arg | xargs + local yaml_file=$1 + local arg=$2 + __yq r ${yaml_file} ${arg} +} + +function yaml-utils::set_param() { + local yaml_file=$1 + local path=$2 + local value="$3" + + __yq w -i ${yaml_file} ${path} "${value}" + + # yq write removes the heading --- from the yaml, so we re-add it. + yaml-utils::append_delimiter ${yaml_file} +} + +function yaml-utils::update_param() { + local yaml_file=$1 + local path=$2 + local new_value="$3" + + local old_value=$(__get_parameter_from_yaml ${yaml_file} ${path}) + if [ ! -z "${old_value}" ]; then + yaml-utils::set_param ${yaml_file} ${path} "${new_value}" + else + echo Error: ${path} is not found in ${yaml_file} + exit 1 + fi +} + +function yaml-utils::delete_param() { + local yaml_file=$1 + local path=$2 + + __yq d -i ${yaml_file} ${path} "${3}" + + # yq write removes the heading --- from the yaml, so we re-add it. + yaml-utils::append_delimiter ${yaml_file} } function yaml-utils::get_component_url() { local component=$1 - arg=.components.\"${component}\".url - __get_parameter_from_yaml $arg + arg=components.\"${component}\".url + __get_parameter_from_yaml components.yaml ${arg} } function yaml-utils::get_component_commit() { local component=$1 - arg=.components.\"${component}\".commit - __get_parameter_from_yaml $arg + arg=components.\"${component}\".commit + __get_parameter_from_yaml components.yaml ${arg} } function yaml-utils::get_component_repo() { @@ -24,3 +64,40 @@ function yaml-utils::get_component_repo() { #remove the prefix. echo ${url} | sed 's#https://\(.*\)#\1#' } + +function yaml-utils::append_delimiter() { + local yaml_file=$1 + + if [ "$(head -n 1 ${yaml_file})" != "---" ]; then + echo -e "---\n$(cat ${yaml_file})" > ${yaml_file} + fi +} + +# splits yaml to sub files by seperator '---'. +# files names are by line numbers +function yaml-utils::split_yaml_by_seperator() { + local output_dir=$1 + local source_yaml=$2 + + cd ${output_dir} + + awk '/\-\-\-/{f=NR".yaml"}; {print >f}' ${source_yaml} +} + +# changes the yaml file names to be of format kind_names +function yaml-utils::rename_files_by_object() { + local output_dir=$1 + + for f in ${output_dir}/*; do + local kind=$(__get_parameter_from_yaml ${f} kind) + local name=$(__get_parameter_from_yaml ${f} metadata.name) + mv ${f} ${output_dir}/${kind}_${name}.yaml + + done +} + +function yaml-utils::remove_single_quotes_from_yaml() { + local yaml_file=$1 + + sed -i "s/'//g" ${yaml_file} +}