├── .gitignore ├── 99-openshift-machineconfig-master-dummy-networks.yaml ├── 99_master-chronyd-mask.yaml ├── 99_master-node-sizing-enabled-env.yaml.in ├── LICENSE ├── OWNERS ├── README.md ├── build-patched-kao-kcmo-images.sh ├── ci.sh ├── ci_microshift.sh ├── cluster-kube-apiserver-operator.patch ├── cluster-kube-controller-manager-operator.patch ├── cluster-network-03-config.yaml ├── crc-bundle-info.json.sample ├── createdisk-library.sh ├── createdisk.sh ├── crio-wipe.service ├── cvo-overrides-after-first-run.yaml ├── cvo-overrides.yaml ├── docs └── self-sufficient-bundle.md ├── gen-bundle-image.sh ├── host-libvirt-net.xml.template ├── image-mode └── microshift │ ├── build.sh │ └── config │ ├── Containerfile.bootc-rhel9 │ └── config.toml.template ├── images └── openshift-ci │ ├── Dockerfile │ ├── google-cloud-sdk.repo │ └── mock-nss.sh ├── install-config.yaml ├── kubevirt-hostpath-provisioner-csi ├── csi-driver-hostpath-provisioner.yaml ├── csi-driver │ ├── csi-kubevirt-hostpath-provisioner.yaml │ └── kustomization.yaml ├── csi-sc.yaml ├── external-provisioner-rbac.yaml ├── kubevirt-hostpath-security-constraints-csi.yaml └── namespace.yaml ├── login.html.patch ├── microshift.sh ├── node-sizing-enabled.env ├── oauth_cr.yaml ├── pki └── 2015-RH-IT-Root-CA.crt ├── pull-secret.yaml ├── qemu-guest-agent.service ├── qemuga-vsock.te ├── registry_pvc.yaml ├── repos └── mirror-microshift.repo ├── routes-controller.yaml.in ├── security-notice.yaml ├── shellcheck.sh ├── snc-library.sh ├── snc.sh ├── systemd ├── crc-check-cloud-env.sh ├── crc-cluster-status.service ├── crc-cluster-status.sh ├── crc-dnsmasq.service ├── crc-pullsecret.service ├── crc-pullsecret.sh ├── crc-routes-controller.service ├── crc-routes-controller.sh ├── crc-systemd-common.sh ├── dnsmasq.sh.template ├── ocp-cluster-ca.service ├── ocp-cluster-ca.sh ├── ocp-clusterid.service ├── ocp-clusterid.sh ├── ocp-custom-domain.service ├── ocp-custom-domain.sh ├── ocp-growfs.service ├── ocp-growfs.sh ├── ocp-mco-sshkey.service ├── ocp-mco-sshkey.sh ├── ocp-userpasswords.service └── ocp-userpasswords.sh ├── test-metadata-generation.sh └── tools.sh /.gitignore: -------------------------------------------------------------------------------- 1 | id_ecdsa_crc 2 | id_ecdsa_crc.pub 3 | crc-tmp-install-data 4 | 99_master-node-sizing-enabled-env.yaml 5 | openshift-baremetal-install 6 | pull-secret 7 | oc 8 | yq 9 | openshift-clients/ 10 | podman-remote/ 11 | .sw[a-p] 12 | crc-cluster-kube-apiserver-operator 13 | crc-cluster-kube-controller-manager-operator 14 | systemd/crc-dnsmasq.sh 15 | -------------------------------------------------------------------------------- /99-openshift-machineconfig-master-dummy-networks.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: machineconfiguration.openshift.io/v1 2 | kind: MachineConfig 3 | metadata: 4 | labels: 5 | machineconfiguration.openshift.io/role: master 6 | name: 99-openshift-machineconfig-master-dummy-networks 7 | spec: 8 | config: 9 | ignition: 10 | version: 3.2.0 11 | systemd: 12 | units: 13 | - contents: | 14 | [Unit] 15 | Description=Create dummy network 16 | After=NetworkManager.service 17 | 18 | [Service] 19 | Type=oneshot 20 | RemainAfterExit=yes 21 | ExecStart=/bin/nmcli conn add type dummy ifname eth10 autoconnect yes save yes con-name internalEtcd ip4 192.168.126.11/24 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | enabled: true 26 | name: dummy-network.service 27 | networkd: {} 28 | passwd: {} 29 | storage: {} 30 | osImageURL: "" 31 | 32 | -------------------------------------------------------------------------------- /99_master-chronyd-mask.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: machineconfiguration.openshift.io/v1 2 | kind: MachineConfig 3 | metadata: 4 | labels: 5 | machineconfiguration.openshift.io/role: master 6 | name: chronyd-mask 7 | spec: 8 | config: 9 | ignition: 10 | version: 3.2.0 11 | systemd: 12 | units: 13 | - name: chronyd.service 14 | mask: true 15 | -------------------------------------------------------------------------------- /99_master-node-sizing-enabled-env.yaml.in: -------------------------------------------------------------------------------- 1 | apiVersion: machineconfiguration.openshift.io/v1 2 | kind: MachineConfig 3 | metadata: 4 | labels: 5 | machineconfiguration.openshift.io/role: master 6 | name: 99-node-sizing-for-crc 7 | spec: 8 | config: 9 | ignition: 10 | version: 3.2.0 11 | storage: 12 | files: 13 | - contents: 14 | source: data:text/plain;charset=utf-8;base64,${DYNAMIC_DATA} 15 | overwrite: true 16 | mode: 0420 17 | path: /etc/node-sizing-enabled.env 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - cfergeau 3 | - praveenkumar 4 | - anjannath 5 | - guillaumerose 6 | - gbraad 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Single node cluster (snc) scripts for OpenShift 4 2 | 3 | **NOTE:** Please select the respective branch to create a bundle for a specific OpenShift release (ie. to create a 4.15.x OpenShift bundle, choose the release-4.15 branch) 4 | 5 | ## How to use? 6 | - Clone this repo `git clone https://github.com/code-ready/snc.git` 7 | - `cd ` 8 | - `./snc.sh` 9 | 10 | ## How to create disk image? 11 | - Once your `snc.sh` script run successfully. 12 | - `./createdisk.sh crc-tmp-install-data` 13 | 14 | ## Monitoring 15 | 16 | The installation is a [long process](https://github.com/openshift/installer/blob/master/docs/user/overview.md#cluster-installation-process). It can take up to 45 mins. 17 | You can monitor the progress of the installation with `kubectl`. 18 | 19 | ``` 20 | $ export KUBECONFIG=/crc-tmp-install-data/auth/kubeconfig 21 | $ kubectl get pods --all-namespaces 22 | ``` 23 | 24 | ## Building SNC for OKD 4 25 | - Before running `./snc.sh`, you need to create a pull secret file, and set a couple of environment variables to override the default behavior. 26 | - Select the OKD 4 release that you want to build from: [https://origin-release.apps.ci.l2s4.p1.openshiftapps.com](https://origin-release.apps.ci.l2s4.p1.openshiftapps.com) 27 | - For example, to build release: 4.5.0-0.okd-2020-08-12-020541 28 | 29 | ```bash 30 | # Create a pull secret file 31 | 32 | cat << EOF > /tmp/pull_secret.json 33 | {"auths":{"fake":{"auth": "Zm9vOmJhcgo="}}} 34 | EOF 35 | 36 | # Set environment for OKD build 37 | export OKD_VERSION=4.5.0-0.okd-2020-08-12-020541 38 | export OPENSHIFT_PULL_SECRET_PATH="/tmp/pull_secret.json" 39 | 40 | # Build the Single Node cluster 41 | ./snc.sh 42 | ``` 43 | 44 | - When the build is complete, create the disk image as described below. 45 | 46 | ``` 47 | export BUNDLED_PULL_SECRET_PATH="/tmp/pull_secret.json" 48 | ./createdisk.sh crc-tmp-install-data 49 | ``` 50 | 51 | ## Creating container image for bundles 52 | 53 | After running snc.sh/createdisk.sh, the generated bundles can be uploaded to a container registry using this command: 54 | 55 | ``` 56 | ./gen-bundle-image.sh 57 | ``` 58 | 59 | Note: a GPG key is needed to sign the bundles before they are wrapped in a container image. 60 | 61 | ## Troubleshooting 62 | 63 | OpenShift installer will create 1 VM. It is sometimes useful to ssh inside the VM. 64 | Add the following lines in your `~/.ssh/config` file. You can then do `ssh master`. 65 | 66 | ``` 67 | Host master 68 | Hostname 192.168.126.11 69 | User core 70 | IdentityFile /id_ecdsa_crc 71 | StrictHostKeyChecking no 72 | UserKnownHostsFile /dev/null 73 | ``` 74 | 75 | ## Environment Variables 76 | 77 | The following environment variables can be used to change the default values of bundle generation. 78 | 79 | SNC_GENERATE_MACOS_BUNDLE : if set to 0, bundle generation for MacOS is disabled, any other value will enable it. 80 | SNC_GENERATE_WINDOWS_BUNDLE : if set to 0, bundle generation for Windows is disabled, any other value will enable it. 81 | SNC_GENERATE_LINUX_BUNDLE : if set to 0, bundle generation for Linux is disabled, any other value will enable it. 82 | 83 | Please note the SNC project is “as-is” on this Github repository. At this time, it is not an offically supported Red Hat solution. 84 | -------------------------------------------------------------------------------- /build-patched-kao-kcmo-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is used by crc developer or internal CI to build patched KAO/KCMO images with 4 | # 1 year certificates and then push them to quay.io/crcont. The provided pull secret should allow 5 | # push access to `quay.io/crcont` before providing to this script. 6 | # - Since this script uses rhpkg and kinit commands, it is only tested on linux. 7 | # - As of now this script works with 4.12 nightly because only the `rhaos-4.12-rhel-8` branch 8 | # has been created in dist-git and tested. 9 | # - This script is suppose to run standalone without cloning the snc repo so some code is repeated. 10 | # Usage: 11 | # If you want to build latest candidate stream for 4.12 12 | # - ./build-patched-kao-kcmo-images.sh 13 | # If you want to build specific version of 4.12.0-ec.3 14 | # - OPENSHIFT_VERSION=4.12.0-ec.3 ./build-patched-kao-kcmo-images.sh 15 | 16 | set -exuo pipefail 17 | 18 | export LC_ALL=C.UTF-8 19 | export LANG=C.UTF-8 20 | 21 | rm -fr crc-cluster-kube-apiserver-operator 22 | rm -fr crc-cluster-kube-controller-manager-operator 23 | rm -fr crc-routes-controller 24 | 25 | readonly OCP_VERSION=4.18 26 | 27 | function check_pull_secret() { 28 | if [ -z "${OPENSHIFT_PULL_SECRET_PATH-}" ]; then 29 | echo "OpenShift pull secret file path must be specified through the OPENSHIFT_PULL_SECRET_PATH environment variable" 30 | exit 1 31 | elif [ ! -f ${OPENSHIFT_PULL_SECRET_PATH} ]; then 32 | echo "Provided OPENSHIFT_PULL_SECRET_PATH (${OPENSHIFT_PULL_SECRET_PATH}) does not exists" 33 | exit 1 34 | fi 35 | } 36 | 37 | check_pull_secret 38 | 39 | HOST_ARCH=$(uname -m) 40 | MIRROR=${MIRROR:-https://mirror.openshift.com/pub/openshift-v4/$HOST_ARCH/clients/ocp} 41 | 42 | # If user defined the OPENSHIFT_VERSION environment variable then use it. 43 | if test -n "${OPENSHIFT_VERSION-}"; then 44 | OPENSHIFT_RELEASE_VERSION=${OPENSHIFT_VERSION} 45 | echo "Using release ${OPENSHIFT_RELEASE_VERSION} from OPENSHIFT_VERSION" 46 | else 47 | OPENSHIFT_RELEASE_VERSION="$(curl -L "${MIRROR}"/candidate-${OCP_VERSION}/release.txt | sed -n 's/^ *Version: *//p')" 48 | if test -n "${OPENSHIFT_RELEASE_VERSION}"; then 49 | echo "Using release ${OPENSHIFT_RELEASE_VERSION} from the mirror" 50 | else 51 | echo "Unable to determine an OpenShift release version. You may want to set the OPENSHIFT_VERSION environment variable explicitly." 52 | exit 1 53 | fi 54 | fi 55 | 56 | function release_image_for_arch() { 57 | local arch=$1 58 | local mirror=$(echo ${MIRROR} | sed "s;/$HOST_ARCH/;/$arch/;g") 59 | curl -L "${mirror}/${OPENSHIFT_RELEASE_VERSION}/release.txt" 2>/dev/null| sed -n 's/^Pull From: //p' 60 | } 61 | 62 | if test -z "${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE-}"; then 63 | OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE="$(release_image_for_arch $HOST_ARCH)" 64 | elif test -n "${OPENSHIFT_VERSION-}"; then 65 | echo "Both OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE and OPENSHIFT_VERSION are set, OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE will take precedence" 66 | echo "OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE: $OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE" 67 | echo "OPENSHIFT_VERSION: $OPENSHIFT_VERSION" 68 | fi 69 | echo "Setting OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE to ${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE}" 70 | 71 | mkdir -p openshift-clients/linux 72 | OC=./openshift-clients/linux/oc 73 | if [ -f "$OC" ]; then 74 | current_oc_version=$(${OC} version --client -o json |jq -r .releaseClientVersion) 75 | fi 76 | echo "OC version: ${current_oc_version-}" 77 | if [ "${current_oc_version-}" = "${OPENSHIFT_RELEASE_VERSION}" ]; then 78 | echo "No need to download oc, local oc is already version ${OPENSHIFT_RELEASE_VERSION}" 79 | else 80 | curl -L "${MIRROR}/${OPENSHIFT_RELEASE_VERSION}/openshift-client-linux-${OPENSHIFT_RELEASE_VERSION}.tar.gz" | tar -zx -C openshift-clients/linux oc 81 | fi 82 | 83 | function patch_and_push_image() { 84 | local image_name=$1 85 | image=$(${OC} adm release info -a ${OPENSHIFT_PULL_SECRET_PATH} ${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE} --image-for=${image_name}) 86 | vcs_ref=$(${OC} image info -a ${OPENSHIFT_PULL_SECRET_PATH} ${image} -ojson | jq -r '.config.config.Labels."vcs-ref"') 87 | version=$(${OC} image info -a ${OPENSHIFT_PULL_SECRET_PATH} ${image} -ojson | jq -r '.config.config.Labels.version') 88 | release=$(${OC} image info -a ${OPENSHIFT_PULL_SECRET_PATH} ${image} -ojson | jq -r '.config.config.Labels.release') 89 | # If brew build already exist for the release don't rebuild it again 90 | if ! brew buildinfo crc-${image_name}-container-${version}-${release} | grep "State: COMPLETE" ; then 91 | rhpkg clone containers/crc-${image_name} 92 | pushd crc-${image_name} 93 | git remote add upstream https://pkgs.devel.redhat.com/git/containers/ose-${image_name} 94 | # Just fetch the upstream/rhaos-${OCP_VERSION}-rhel-9 instead of all the branches and tags from upstream 95 | git fetch upstream rhaos-${OCP_VERSION}-rhel-9 --no-tags 96 | git checkout --track origin/rhaos-${OCP_VERSION}-rhel-9 97 | git merge --no-ff -m "Merge commit ${vcs_ref} into rhaos-${OCP_VERSION}-rhel-9" -m "MaxFileSize: 104857600" ${vcs_ref} 98 | git push origin HEAD 99 | rhpkg container-build --target crc-1-rhel-9-candidate 100 | popd 101 | fi 102 | # Operator images created using rhel-9 tags have `rhel9-operator` as part of image name so replacing `operator` with it. 103 | # https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion 104 | rhel9_image_name="${image_name/operator/rhel9-operator}" 105 | skopeo copy --dest-authfile ${OPENSHIFT_PULL_SECRET_PATH} --all --src-cert-dir=pki/ docker://registry-proxy.engineering.redhat.com/rh-osbs/openshift-crc-${rhel9_image_name}:${version}-${release} docker://quay.io/crcont/openshift-crc-${image_name}:${openshift_version} 106 | } 107 | 108 | function create_patched_release_image_for_arch() { 109 | local upstream_registry=$1 110 | local arch=$2 111 | local release_image="$(release_image_for_arch ${arch})" 112 | 113 | # As of now, `oc adm release new` is not able to parse images which have 114 | # multiple arch manifest file so we first need to get the digest of the 115 | # image for ${yq_arch} and then use that digest with `oc adm release new`_ 116 | kao_image_digest=$(${OC} image info -a ${OPENSHIFT_PULL_SECRET_PATH} ${upstream_registry}/openshift-crc-cluster-kube-apiserver-operator:${openshift_version} --filter-by-os=linux/${arch} -ojson | jq -r .digest) 117 | kcmo_image_digest=$(${OC} image info -a ${OPENSHIFT_PULL_SECRET_PATH} ${upstream_registry}/openshift-crc-cluster-kube-controller-manager-operator:${openshift_version} --filter-by-os=linux/${arch} -ojson | jq -r .digest) 118 | 119 | ${OC} adm release new -a ${OPENSHIFT_PULL_SECRET_PATH} --from-release=${release_image} \ 120 | cluster-kube-apiserver-operator=${upstream_registry}/openshift-crc-cluster-kube-apiserver-operator@${kao_image_digest} \ 121 | cluster-kube-controller-manager-operator=${upstream_registry}/openshift-crc-cluster-kube-controller-manager-operator@${kcmo_image_digest} \ 122 | --to-image=${upstream_registry}/ocp-release:${openshift_version}-${arch} 123 | } 124 | 125 | function create_new_release_with_patched_images() { 126 | local upstream_registry="quay.io/crcont" 127 | 128 | podman rmi -i ${upstream_registry}/ocp-release:${openshift_version} 129 | podman manifest create ${upstream_registry}/ocp-release:${openshift_version} 130 | for arch in amd64 arm64; do \ 131 | create_patched_release_image_for_arch ${upstream_registry} ${arch} 132 | podman manifest add ${upstream_registry}/ocp-release:${openshift_version} docker://${upstream_registry}/ocp-release:${openshift_version}-${arch} 133 | done 134 | podman manifest push --authfile ${OPENSHIFT_PULL_SECRET_PATH} --all ${upstream_registry}/ocp-release:${openshift_version} docker://${upstream_registry}/ocp-release:${openshift_version} 135 | } 136 | 137 | function update_base_image() { 138 | local brew_repo=$1 139 | local base_image=$2 140 | 141 | rhpkg clone containers/${brew_repo} 142 | pushd ${brew_repo} 143 | git checkout --track origin/crc-1-rhel-9 144 | base_image_of_repo=$(grep "^FROM openshift/openshift-enterprise-base" Dockerfile | sed 's/^FROM //') 145 | if [ ${base_image} != ${base_image_of_repo} ]; then 146 | sed -i "s!^FROM openshift/openshift-enterprise-base.*!FROM $base_image!" Dockerfile 147 | git add Dockerfile 148 | git commit -m "Use OpenShift ${openshift_version} base image" 149 | git push origin 150 | rhpkg container-build 151 | fi 152 | popd 153 | 154 | skopeo copy --dest-authfile ${OPENSHIFT_PULL_SECRET_PATH} --all --src-cert-dir=pki/ docker://registry-proxy.engineering.redhat.com/rh-osbs/${brew_repo}:latest docker://quay.io/crcont/${brew_repo#crc-}:${openshift_version} 155 | skopeo copy --dest-authfile ${OPENSHIFT_PULL_SECRET_PATH} --all --src-cert-dir=pki/ docker://registry-proxy.engineering.redhat.com/rh-osbs/${brew_repo}:latest docker://quay.io/crcont/${brew_repo#crc-}:latest 156 | } 157 | 158 | openshift_version=$(${OC} adm release info -a ${OPENSHIFT_PULL_SECRET_PATH} ${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE} -ojsonpath='{.config.config.Labels.io\.openshift\.release}') 159 | 160 | patch_and_push_image cluster-kube-apiserver-operator 161 | patch_and_push_image cluster-kube-controller-manager-operator 162 | create_new_release_with_patched_images 163 | 164 | # In case there is no change in the openshift component then KAO repo is not present locally 165 | # and need to be fetched. 166 | if [ ! -f crc-cluster-kube-apiserver-operator/Dockerfile ]; then 167 | rhpkg clone --branch rhaos-${OCP_VERSION}-rhel-9 containers/crc-cluster-kube-apiserver-operator 168 | fi 169 | 170 | base_image=$(grep "^FROM openshift/openshift-enterprise-base" crc-cluster-kube-apiserver-operator/Dockerfile | sed 's/^FROM //') 171 | 172 | update_base_image crc-routes-controller "${base_image}" 173 | -------------------------------------------------------------------------------- /ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -exuo pipefail 4 | 5 | sudo yum install -y podman make golang rsync 6 | 7 | cat > /tmp/ignoretests.txt << EOF 8 | [sig-apps] Daemon set [Serial] should rollback without unnecessary restarts [Conformance] [Suite:openshift/conformance/serial/minimal] [Suite:k8s] 9 | [sig-cli] Kubectl client Kubectl cluster-info should check if Kubernetes control plane services is included in cluster-info [Conformance] [Suite:openshift/conformance/parallel/minimal] [Suite:k8s] 10 | [sig-scheduling] SchedulerPreemption [Serial] validates basic preemption works [Conformance] [Suite:openshift/conformance/serial/minimal] [Suite:k8s] 11 | [sig-scheduling] SchedulerPreemption [Serial] validates lower priority pod preemption by critical pod [Conformance] [Suite:openshift/conformance/serial/minimal] [Suite:k8s] 12 | [k8s.io] [sig-node] NoExecuteTaintManager Multiple Pods [Serial] evicts pods with minTolerationSeconds [Disruptive] [Conformance] [Suite:k8s] 13 | [k8s.io] [sig-node] NoExecuteTaintManager Single Pod [Serial] removing taint cancels eviction [Disruptive] [Conformance] [Suite:k8s] 14 | [sig-api-machinery] AdmissionWebhook [Privileged:ClusterAdmin] should mutate custom resource with pruning [Conformance] [Suite:openshift/conformance/parallel/minimal] [Suite:k8s] 15 | [sig-api-machinery] AdmissionWebhook [Privileged:ClusterAdmin] should mutate pod and apply defaults after mutation [Conformance] [Suite:openshift/conformance/parallel/minimal] [Suite:k8s] 16 | [sig-api-machinery] Aggregator Should be able to support the 1.17 Sample API Server using the current Aggregator [Conformance] [Suite:openshift/conformance/parallel/minimal] [Suite:k8s] 17 | [sig-apps] Daemon set [Serial] should rollback without unnecessary restarts [Conformance] [Skipped:SingleReplicaTopology] [Suite:openshift/conformance/serial/minimal] [Suite:k8s] 18 | [sig-network] Proxy version v1 A set of valid responses are returned for both pod and service ProxyWithPath [Conformance] [Suite:openshift/conformance/parallel/minimal] [Suite:k8s] 19 | EOF 20 | 21 | ./shellcheck.sh 22 | ./snc.sh 23 | 24 | echo "### Extracting openshift-tests binary" 25 | mkdir /tmp/os-test 26 | export TESTS_IMAGE=$(oc --kubeconfig=crc-tmp-install-data/auth/kubeconfig adm release info -a "${HOME}"/pull-secret --image-for=tests) 27 | oc image extract -a "${HOME}"/pull-secret "${TESTS_IMAGE}" --path=/usr/bin/openshift-tests:/tmp/os-test/. 28 | chmod +x /tmp/os-test/openshift-tests 29 | sudo mv /tmp/os-test/openshift-tests /usr/local/bin/ 30 | 31 | # Run createdisk script 32 | export CRC_ZSTD_EXTRA_FLAGS="-10 --long" 33 | ./createdisk.sh crc-tmp-install-data 34 | 35 | function destroy_cluster () { 36 | # Destroy the cluster 37 | local snc_product_name=crc 38 | sudo virsh destroy ${snc_product_name} || true 39 | sudo virsh undefine ${snc_product_name} --nvram || true 40 | sudo virsh vol-delete --pool ${snc_product_name} ${snc_product_name}.qcow2 || true 41 | sudo virsh vol-delete --pool ${snc_product_name} rhcos-live.iso || true 42 | sudo virsh pool-destroy ${snc_product_name} || true 43 | sudo virsh pool-undefine ${snc_product_name} || true 44 | sudo virsh net-destroy ${snc_product_name} || true 45 | sudo virsh net-undefine ${snc_product_name} || true 46 | } 47 | 48 | destroy_cluster 49 | # Unset the kubeconfig which is set by snc 50 | unset KUBECONFIG 51 | 52 | # Delete the dnsmasq config created by snc 53 | # otherwise snc set the domain entry with 192.168.126.11 54 | # and crc set it in another file 192.168.130.11 so 55 | # better to remove the dnsmasq config after running snc 56 | sudo rm -fr /etc/NetworkManager/dnsmasq.d/* 57 | sudo systemctl reload NetworkManager 58 | 59 | git clone https://github.com/code-ready/crc.git 60 | pushd crc 61 | podman run --rm -v ${PWD}:/data:Z registry.ci.openshift.org/openshift/release:rhel-8-release-golang-1.23-openshift-4.19 /bin/bash -c "cd /data && make cross" 62 | sudo mv out/linux-amd64/crc /usr/local/bin/ 63 | popd 64 | 65 | crc config set bundle crc_libvirt_*.crcbundle 66 | crc setup 67 | crc start --disk-size 80 -m 24000 -c 10 -p "${HOME}"/pull-secret --log-level debug 68 | 69 | mkdir -p crc-tmp-install-data/test-artifacts 70 | export KUBECONFIG="${HOME}"/.crc/machines/crc/kubeconfig 71 | openshift-tests run kubernetes/conformance --dry-run | grep -F -v -f /tmp/ignoretests.txt | openshift-tests run -o crc-tmp-install-data/test-artifacts/e2e.log --junit-dir crc-tmp-install-data/test-artifacts/junit --disable-monitor alert-summary-serializer,metrics-endpoints-down,metrics-api-availability,monitoring-statefulsets-recreation,pod-network-avalibility,legacy-test-framework-invariants,api-unreachable-from-client-metrics,clusteroperator-collector -f - 72 | rc=$? 73 | echo "${rc}" > /tmp/test-return 74 | set -e 75 | echo "### Done! (${rc})" 76 | -------------------------------------------------------------------------------- /ci_microshift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -exuo pipefail 4 | 5 | sudo yum install -y make golang 6 | 7 | ./shellcheck.sh 8 | ./microshift.sh 9 | 10 | # Set the zstd compression level to 10 to have faster 11 | # compression while keeping a reasonable bundle size. 12 | export CRC_ZSTD_EXTRA_FLAGS="-10" 13 | ./createdisk.sh crc-tmp-install-data 14 | 15 | # Delete the crc domain which created by snc so it can created 16 | # for crc test 17 | sudo virsh undefine crc --nvram 18 | 19 | git clone https://github.com/crc-org/crc.git 20 | pushd crc 21 | podman run --rm -v ${PWD}:/data:Z registry.ci.openshift.org/openshift/release:rhel-8-release-golang-1.23-openshift-4.19 /bin/bash -c "cd /data && make cross" 22 | sudo mv out/linux-amd64/crc /usr/local/bin/ 23 | popd 24 | 25 | crc config set bundle crc_microshift_libvirt_*.crcbundle 26 | crc config set preset microshift 27 | crc setup 28 | crc start -p "${HOME}"/pull-secret --log-level debug 29 | 30 | rc=$? 31 | echo "${rc}" > /tmp/test-return 32 | set -e 33 | echo "### Done! (${rc})" 34 | -------------------------------------------------------------------------------- /cluster-kube-apiserver-operator.patch: -------------------------------------------------------------------------------- 1 | diff --git a/pkg/operator/certrotationcontroller/certrotationcontroller.go b/pkg/operator/certrotationcontroller/certrotationcontroller.go 2 | index 1bf5d3224..a28ce71ed 100644 3 | --- a/pkg/operator/certrotationcontroller/certrotationcontroller.go 4 | +++ b/pkg/operator/certrotationcontroller/certrotationcontroller.go 5 | @@ -129,8 +129,8 @@ func newCertRotationController( 6 | certrotation.RotatedSigningCASecret{ 7 | Namespace: operatorclient.OperatorNamespace, 8 | Name: "aggregator-client-signer", 9 | - Validity: 30 * rotationDay, 10 | - Refresh: 15 * rotationDay, 11 | + Validity: 365 * rotationDay, 12 | + Refresh: 180 * rotationDay, 13 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 14 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 15 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 16 | @@ -148,8 +148,8 @@ func newCertRotationController( 17 | certrotation.RotatedSelfSignedCertKeySecret{ 18 | Namespace: operatorclient.TargetNamespace, 19 | Name: "aggregator-client", 20 | - Validity: 30 * rotationDay, 21 | - Refresh: 15 * rotationDay, 22 | + Validity: 365 * rotationDay, 23 | + Refresh: 180 * rotationDay, 24 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 25 | CertCreator: &certrotation.ClientRotation{ 26 | UserInfo: &user.DefaultInfo{Name: "system:openshift-aggregator"}, 27 | @@ -188,8 +188,8 @@ func newCertRotationController( 28 | certrotation.RotatedSelfSignedCertKeySecret{ 29 | Namespace: operatorclient.TargetNamespace, 30 | Name: "kubelet-client", 31 | - Validity: 30 * rotationDay, 32 | - Refresh: 15 * rotationDay, 33 | + Validity: 365 * rotationDay, 34 | + Refresh: 180 * rotationDay, 35 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 36 | CertCreator: &certrotation.ClientRotation{ 37 | UserInfo: &user.DefaultInfo{Name: "system:kube-apiserver", Groups: []string{"kube-master"}}, 38 | @@ -228,8 +228,8 @@ func newCertRotationController( 39 | certrotation.RotatedSelfSignedCertKeySecret{ 40 | Namespace: operatorclient.TargetNamespace, 41 | Name: "localhost-serving-cert-certkey", 42 | - Validity: 30 * rotationDay, 43 | - Refresh: 15 * rotationDay, 44 | + Validity: 365 * rotationDay, 45 | + Refresh: 180 * rotationDay, 46 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 47 | CertCreator: &certrotation.ServingRotation{ 48 | Hostnames: func() []string { return []string{"localhost", "127.0.0.1"} }, 49 | @@ -268,8 +268,8 @@ func newCertRotationController( 50 | certrotation.RotatedSelfSignedCertKeySecret{ 51 | Namespace: operatorclient.TargetNamespace, 52 | Name: "service-network-serving-certkey", 53 | - Validity: 30 * rotationDay, 54 | - Refresh: 15 * rotationDay, 55 | + Validity: 365 * rotationDay, 56 | + Refresh: 180 * rotationDay, 57 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 58 | CertCreator: &certrotation.ServingRotation{ 59 | Hostnames: ret.serviceNetwork.GetHostnames, 60 | @@ -309,8 +309,8 @@ func newCertRotationController( 61 | certrotation.RotatedSelfSignedCertKeySecret{ 62 | Namespace: operatorclient.TargetNamespace, 63 | Name: "external-loadbalancer-serving-certkey", 64 | - Validity: 30 * rotationDay, 65 | - Refresh: 15 * rotationDay, 66 | + Validity: 365 * rotationDay, 67 | + Refresh: 180 * rotationDay, 68 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 69 | CertCreator: &certrotation.ServingRotation{ 70 | Hostnames: ret.externalLoadBalancer.GetHostnames, 71 | @@ -350,8 +350,8 @@ func newCertRotationController( 72 | certrotation.RotatedSelfSignedCertKeySecret{ 73 | Namespace: operatorclient.TargetNamespace, 74 | Name: "internal-loadbalancer-serving-certkey", 75 | - Validity: 30 * rotationDay, 76 | - Refresh: 15 * rotationDay, 77 | + Validity: 365 * rotationDay, 78 | + Refresh: 180 * rotationDay, 79 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 80 | CertCreator: &certrotation.ServingRotation{ 81 | Hostnames: ret.internalLoadBalancer.GetHostnames, 82 | @@ -410,8 +410,8 @@ func newCertRotationController( 83 | certrotation.RotatedSigningCASecret{ 84 | Namespace: operatorclient.OperatorNamespace, 85 | Name: "kube-control-plane-signer", 86 | - Validity: 60 * defaultRotationDay, 87 | - Refresh: 30 * defaultRotationDay, 88 | + Validity: 2 * 365 * defaultRotationDay, 89 | + Refresh: 365 * defaultRotationDay, 90 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 91 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 92 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 93 | @@ -429,8 +429,8 @@ func newCertRotationController( 94 | certrotation.RotatedSelfSignedCertKeySecret{ 95 | Namespace: operatorclient.GlobalMachineSpecifiedConfigNamespace, 96 | Name: "kube-controller-manager-client-cert-key", 97 | - Validity: 30 * rotationDay, 98 | - Refresh: 15 * rotationDay, 99 | + Validity: 365 * rotationDay, 100 | + Refresh: 180 * rotationDay, 101 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 102 | CertCreator: &certrotation.ClientRotation{ 103 | UserInfo: &user.DefaultInfo{Name: "system:kube-controller-manager"}, 104 | @@ -450,8 +450,8 @@ func newCertRotationController( 105 | certrotation.RotatedSigningCASecret{ 106 | Namespace: operatorclient.OperatorNamespace, 107 | Name: "kube-control-plane-signer", 108 | - Validity: 60 * defaultRotationDay, 109 | - Refresh: 30 * defaultRotationDay, 110 | + Validity: 2 * 365 * defaultRotationDay, 111 | + Refresh: 365 * defaultRotationDay, 112 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 113 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 114 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 115 | @@ -469,8 +469,8 @@ func newCertRotationController( 116 | certrotation.RotatedSelfSignedCertKeySecret{ 117 | Namespace: operatorclient.GlobalMachineSpecifiedConfigNamespace, 118 | Name: "kube-scheduler-client-cert-key", 119 | - Validity: 30 * rotationDay, 120 | - Refresh: 15 * rotationDay, 121 | + Validity: 365 * rotationDay, 122 | + Refresh: 180 * rotationDay, 123 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 124 | CertCreator: &certrotation.ClientRotation{ 125 | UserInfo: &user.DefaultInfo{Name: "system:kube-scheduler"}, 126 | @@ -490,8 +490,8 @@ func newCertRotationController( 127 | certrotation.RotatedSigningCASecret{ 128 | Namespace: operatorclient.OperatorNamespace, 129 | Name: "kube-control-plane-signer", 130 | - Validity: 60 * defaultRotationDay, 131 | - Refresh: 30 * defaultRotationDay, 132 | + Validity: 2 * 365 * defaultRotationDay, 133 | + Refresh: 365 * defaultRotationDay, 134 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 135 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 136 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 137 | @@ -509,8 +509,8 @@ func newCertRotationController( 138 | certrotation.RotatedSelfSignedCertKeySecret{ 139 | Namespace: operatorclient.TargetNamespace, 140 | Name: "control-plane-node-admin-client-cert-key", 141 | - Validity: 30 * rotationDay, 142 | - Refresh: 15 * rotationDay, 143 | + Validity: 365 * rotationDay, 144 | + Refresh: 180 * rotationDay, 145 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 146 | CertCreator: &certrotation.ClientRotation{ 147 | UserInfo: &user.DefaultInfo{Name: "system:control-plane-node-admin", Groups: []string{"system:masters"}}, 148 | @@ -530,8 +530,8 @@ func newCertRotationController( 149 | certrotation.RotatedSigningCASecret{ 150 | Namespace: operatorclient.OperatorNamespace, 151 | Name: "kube-control-plane-signer", 152 | - Validity: 60 * defaultRotationDay, 153 | - Refresh: 30 * defaultRotationDay, 154 | + Validity: 2 * 365 * defaultRotationDay, 155 | + Refresh: 365 * defaultRotationDay, 156 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 157 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 158 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 159 | @@ -549,8 +549,8 @@ func newCertRotationController( 160 | certrotation.RotatedSelfSignedCertKeySecret{ 161 | Namespace: operatorclient.TargetNamespace, 162 | Name: "check-endpoints-client-cert-key", 163 | - Validity: 30 * rotationDay, 164 | - Refresh: 15 * rotationDay, 165 | + Validity: 365 * rotationDay, 166 | + Refresh: 180 * rotationDay, 167 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 168 | CertCreator: &certrotation.ClientRotation{ 169 | UserInfo: &user.DefaultInfo{Name: "system:serviceaccount:openshift-kube-apiserver:check-endpoints"}, 170 | @@ -592,9 +592,9 @@ func newCertRotationController( 171 | // This needs to live longer then control plane certs so there is high chance that if a cluster breaks 172 | // because of expired certs these are still valid to use for collecting data using localhost-recovery 173 | // endpoint with long lived serving certs for localhost. 174 | - Validity: 120 * defaultRotationDay, 175 | - // We rotate sooner so certs are always valid for 90 days (30 days more then kube-control-plane-signer) 176 | - Refresh: 30 * defaultRotationDay, 177 | + Validity: 3 * 365 * defaultRotationDay, 178 | + // We rotate sooner so certs are always valid for 90 days (365 days more then kube-control-plane-signer) 179 | + Refresh: 365 * defaultRotationDay, 180 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 181 | CertCreator: &certrotation.ClientRotation{ 182 | UserInfo: &user.DefaultInfo{ 183 | 184 | -------------------------------------------------------------------------------- /cluster-kube-controller-manager-operator.patch: -------------------------------------------------------------------------------- 1 | diff --git a/bindata/assets/config/defaultconfig.yaml b/bindata/assets/config/defaultconfig.yaml 2 | index d22e9f9e..a9076801 100644 3 | --- a/bindata/assets/config/defaultconfig.yaml 4 | +++ b/bindata/assets/config/defaultconfig.yaml 5 | @@ -27,7 +27,7 @@ extendedArguments: 6 | - "-bootstrapsigner" 7 | - "-tokencleaner" 8 | cluster-signing-duration: 9 | - - "720h" 10 | + - "8760h" 11 | secure-port: 12 | - "10257" 13 | cert-dir: 14 | diff --git a/pkg/operator/certrotationcontroller/certrotationcontroller.go b/pkg/operator/certrotationcontroller/certrotationcontroller.go 15 | index 0d328e24..01941a28 100644 16 | --- a/pkg/operator/certrotationcontroller/certrotationcontroller.go 17 | +++ b/pkg/operator/certrotationcontroller/certrotationcontroller.go 18 | @@ -85,8 +85,8 @@ func newCertRotationController( 19 | Namespace: operatorclient.OperatorNamespace, 20 | // this is not a typo, this is the signer of the signer 21 | Name: "csr-signer-signer", 22 | - Validity: 60 * rotationDay, 23 | - Refresh: 30 * rotationDay, 24 | + Validity: 2 * 365 * rotationDay, 25 | + Refresh: 365 * rotationDay, 26 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 27 | Informer: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets(), 28 | Lister: kubeInformersForNamespaces.InformersFor(operatorclient.OperatorNamespace).Core().V1().Secrets().Lister(), 29 | @@ -104,8 +104,8 @@ func newCertRotationController( 30 | certrotation.RotatedSelfSignedCertKeySecret{ 31 | Namespace: operatorclient.OperatorNamespace, 32 | Name: "csr-signer", 33 | - Validity: 30 * rotationDay, 34 | - Refresh: 15 * rotationDay, 35 | + Validity: 2 * 365 * rotationDay, 36 | + Refresh: 365 * rotationDay, 37 | RefreshOnlyWhenExpired: refreshOnlyWhenExpired, 38 | CertCreator: &certrotation.SignerRotation{ 39 | SignerName: "kube-csr-signer", 40 | 41 | -------------------------------------------------------------------------------- /cluster-network-03-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.openshift.io/v1 2 | kind: Network 3 | metadata: 4 | name: cluster 5 | spec: 6 | defaultNetwork: 7 | type: OpenShiftSDN 8 | openshiftSDNConfig: 9 | mtu: 1400 10 | -------------------------------------------------------------------------------- /crc-bundle-info.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | # Version of the bundle, used to denote format changes 3 | # Major is only increased changes incompatible with previous versions 4 | # Minor is increased for backwards-compatible changes 5 | # 6 | # Version history: 7 | # - 1.1: addition of 'name' 8 | # - 1.2: addition of 'storage.fileList' 9 | # - 1.3: remove of 'clusterInfo.kubeadminPasswordFile' 10 | # - 1.4: addition of 'arch' 11 | # - 1.5: remove of 'node[0].kernelCmdLine', 'node[0].initramfs', 'node[0].kernel' 12 | "version": "1.5", 13 | # Type of this bundle content 14 | # Currently the only valid type is 'snc' (which stands for 'single-node-cluster') 15 | "type": "snc", 16 | # Name of the bundle 17 | "name": "crc_libvirt_4.6.1", 18 | # Bundle arch (This follows https://gist.github.com/lizkes/975ab2d1b5f9d5fdee5d3fa665bcfde6 with amd64/arm64 being used at the moment) 19 | "arch": "amd64", 20 | "buildInfo": { 21 | # Time this bundle was built 22 | "buildTime": "2019-04-23T14:55:32+00:00", 23 | # Output of 'openshift-install version' from the installer used to generate the bundle 24 | "openshiftInstallerVersion": "./openshift-install v0.16.1\nbuilt from commit e3fceacc975953f56cb09931e6be015a36eb6075", 25 | # Output of 'git describe' or 'git rev-parse' of the 'snc' script 26 | # repository used when generating the bundle 27 | "sncVersion": "git9662" 28 | }, 29 | "clusterInfo": { 30 | # Version of OpenShift installed in the virtual machine 31 | "openshiftVersion": "4.1.11" 32 | # Name of the openshift cluster stored in the bundle 33 | "clusterName": "crc", 34 | # Base domain name used for the openshift cluster 35 | "baseDomain": "testing", 36 | # Subdomain where the apps will go 37 | "appsDomain": "apps-crc.testing", 38 | # Name of a file containing an SSH private key which can be used to connect to 39 | # the cluster nodes 40 | "sshPrivateKeyFile": "id_ecdsa_crc", 41 | # Name of the kubeconfig file stored in the bundle 42 | "kubeConfig": "kubeconfig", 43 | # pull secret that can be used to fetch OpenShift container images (optional) 44 | # "openshiftPullSecret": "default-pull-secret" 45 | }, 46 | "nodes": [ 47 | { 48 | # Type of the node, can be 'master', 'worker' or both 49 | "kind": [ 50 | "master", 51 | "worker" 52 | ], 53 | # Hostname of the node 54 | "hostname": "crc-88lpx-master-0", 55 | # Disk image used by the node, the 'storage' object will contain more 56 | # details about its format 57 | "diskImage": "crc.qcow2" 58 | # Internal IP for which etcd certs are valid 59 | "internalIP": "192.168.126.11" 60 | } 61 | ], 62 | "storage": { 63 | # List of virtual machine disk images in the bundle 64 | "diskImages": [ 65 | { 66 | # Name of the disk image file 67 | "name": "crc.qcow2", 68 | # Format of the disk image, valid formats are 'qcow2', 'vmdk', 'vhdx' 69 | "format": "qcow2" 70 | "size": "9129426944" 71 | "sha256sum": "49766122a0834d62c1a24fb4e0de30cd7a39b8112083aa5e01fc26f16c15aed3" 72 | } 73 | ], 74 | # Information about the other files present in the bundle 75 | # In version 1.2, this only lists the files which are not mentioned 76 | # anywhere else in this file 77 | "fileList": [ 78 | { 79 | # Name of the file 80 | "name": "oc" 81 | # What kind of file this is, valid types are 'oc-executable', 'podman-executable' 82 | "type": "oc-executable" 83 | "size": "72728632" 84 | "sha256sum": "983f0883a6dffd601afa663d10161bfd8033fd6d45cf587a9cb22e9a681d6047" 85 | } 86 | ] 87 | }, 88 | "driverInfo": { 89 | # Name of driver the bundle supports, valid drivers are 'libvirt', 'hyperkit', 'virtualbox', 'hyperv' 90 | "name": "libvirt" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /createdisk-library.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -exuo pipefail 4 | 5 | function get_dest_dir_suffix { 6 | local version=$1 7 | DEST_DIR_SUFFIX="${version}_${yq_ARCH}" 8 | if [ -n "${PULL_NUMBER-}" ]; then 9 | DEST_DIR_SUFFIX="${DEST_DIR_SUFFIX}_${PULL_NUMBER}" 10 | fi 11 | } 12 | 13 | # This removes extra os tree layers, log files, ... from the image 14 | function cleanup_vm_image() { 15 | local vm_name=$1 16 | local vm_ip=$2 17 | 18 | # Shutdown and Start the VM to get the latest ostree layer. If packages 19 | # have been added/removed since last boot, the VM will reboot in a different ostree layer. 20 | shutdown_vm ${vm_name} 21 | start_vm ${vm_name} ${vm_ip} 22 | 23 | # Remove miscellaneous unneeded data from rpm-ostree 24 | ${SSH} core@${vm_ip} -- 'sudo rpm-ostree cleanup --rollback --base --repomd' 25 | 26 | # Remove logs. 27 | # Note: With `sudo journalctl --rotate --vacuum-time=1s`, it doesn't 28 | # remove all the journal logs so separate commands are used here. 29 | ${SSH} core@${vm_ip} -- 'sudo journalctl --rotate' 30 | ${SSH} core@${vm_ip} -- 'sudo journalctl --vacuum-time=1s' 31 | ${SSH} core@${vm_ip} -- 'sudo find /var/log/ -iname "*.log" -exec rm -f {} \;' 32 | 33 | # Shutdown and Start the VM after removing base deployment tree 34 | # This is required because kernel commandline changed, namely 35 | # ostree=/ostree/boot.1/fedora-coreos/$hash/0 which switches 36 | # between boot.0 and boot.1 when cleanup is run 37 | shutdown_vm ${vm_name} 38 | start_vm ${vm_name} ${vm_ip} 39 | } 40 | 41 | function sparsify { 42 | local baseDir=$1 43 | local srcFile=$2 44 | local destFile=$3 45 | 46 | export LIBGUESTFS_BACKEND=direct 47 | # Check which partition is labeled as `root` 48 | partition=$(${VIRT_FILESYSTEMS} -a $baseDir/$srcFile -l --partitions | sort -rk4 -n | sed -n 1p | cut -f1 -d' ') 49 | # check if the base image has the lvm named as `rhel/root` 50 | if ${VIRT_FILESYSTEMS} --lvs -a ${baseDir}/${srcFile} | grep -q "rhel/root"; then 51 | partition="/dev/rhel/root" 52 | fi 53 | 54 | # https://bugzilla.redhat.com/show_bug.cgi?id=1837765 55 | export LIBGUESTFS_MEMSIZE=2048 56 | # Interact with guestfish directly 57 | eval $(echo nokey | ${GUESTFISH} --keys-from-stdin --listen ) 58 | if [ $? -ne 0 ]; then 59 | echo "${GUESTFISH} failed to start, aborting" 60 | exit 1 61 | fi 62 | 63 | ${GUESTFISH} --remote <$destDir/crc-bundle-info.json 139 | } 140 | 141 | function eventually_add_pull_secret { 142 | local destDir=$1 143 | 144 | if [ "${BUNDLED_PULL_SECRET_PATH-}" != "" ] 145 | then 146 | cat "$BUNDLED_PULL_SECRET_PATH" > "$destDir/default-pull-secret" 147 | cat $destDir/crc-bundle-info.json \ 148 | | ${JQ} '.clusterInfo.openshiftPullSecret = "default-pull-secret"' \ 149 | >$destDir/crc-bundle-info.json.tmp 150 | mv $destDir/crc-bundle-info.json.tmp $destDir/crc-bundle-info.json 151 | fi 152 | } 153 | 154 | function copy_additional_files { 155 | local srcDir=$1 156 | local destDir=$2 157 | local vm_name=$3 158 | 159 | # Copy the kubeconfig file 160 | cp $1/auth/kubeconfig $destDir/ 161 | 162 | # Copy the master public key 163 | cp id_ecdsa_crc $destDir/ 164 | chmod 400 $destDir/id_ecdsa_crc 165 | 166 | # Copy oc client 167 | cp openshift-clients/linux/oc $destDir/ 168 | 169 | cp podman-remote/linux/podman-remote $destDir/ 170 | 171 | update_json_description $srcDir $destDir $vm_name 172 | 173 | eventually_add_pull_secret $destDir 174 | } 175 | 176 | function install_additional_packages() { 177 | local vm_ip=$1 178 | shift 179 | if [[ ${BASE_OS} = "fedora-coreos" ]]; then 180 | ${SSH} core@${vm_ip} -- 'sudo sed -i -z s/enabled=0/enabled=1/g /etc/yum.repos.d/centos.repo' 181 | ${SSH} core@${vm_ip} -- "sudo rpm-ostree install --allow-inactive $ADDITIONAL_PACKAGES" 182 | ${SSH} core@${vm_ip} -- 'sudo sed -i -z s/enabled=1/enabled=0/g /etc/yum.repos.d/centos.repo' 183 | else 184 | # Download the hyperV daemons dependency on host 185 | local pkgDir=$(mktemp -d tmp-rpmXXX) 186 | mkdir -p ${pkgDir}/packages 187 | sudo yum download --downloadonly --downloaddir ${pkgDir}/packages ${ADDITIONAL_PACKAGES} --resolve --alldeps 188 | 189 | # SCP the downloaded rpms to VM 190 | ${SCP} -r ${pkgDir}/packages core@${vm_ip}:/home/core/ 191 | 192 | # Create local repo of downloaded RPMs in the VM 193 | ${SSH} core@${vm_ip} 'sudo bash -x -s' < /etc/yum.repos.d/local.repo << EOF 198 | [local] 199 | name=Local repo 200 | baseurl=file:///home/core/packages/ 201 | enabled=1 202 | gpgcheck=0 203 | EOF'" 204 | # Install these rpms to VM 205 | ${SSH} core@${vm_ip} -- "sudo rpm-ostree install $ADDITIONAL_PACKAGES" 206 | 207 | # Remove the packages and repo from VM 208 | ${SSH} core@${vm_ip} -- sudo rm -fr /home/core/packages 209 | ${SSH} core@${vm_ip} -- sudo rm -fr /etc/yum.repos.d/local.repo 210 | 211 | # Cleanup up packages 212 | rm -fr ${pkgDir} 213 | fi 214 | } 215 | 216 | function prepare_hyperV() { 217 | local vm_ip=$1 218 | 219 | ADDITIONAL_PACKAGES+=" hyperv-daemons" 220 | 221 | # Adding Hyper-V vsock support 222 | ${SSH} core@${vm_ip} 'sudo bash -x -s' < /etc/udev/rules.d/90-crc-vsock.rules 224 | EOF 225 | } 226 | 227 | function prepare_qemu_guest_agent() { 228 | local vm_ip=$1 229 | 230 | # f36+ default selinux policy blocks usage of qemu-guest-agent over vsock, we have to install 231 | # our own selinux rules to allow this. 232 | # 233 | # we need to disable pipefail for the `checkmodule | grep check` as we expect `checkmodule` 234 | # to fail on rhel8. 235 | set +o pipefail 236 | if ! checkmodule -c 19 2>&1 |grep 'invalid option' >/dev/null; then 237 | # RHEL8 checkmodule does not have this arg 238 | MOD_VERSION_ARG="-c 19" 239 | fi 240 | set -o pipefail 241 | /usr/bin/checkmodule ${MOD_VERSION_ARG-} -M -m -o qemuga-vsock.mod qemuga-vsock.te 242 | /usr/bin/semodule_package -o qemuga-vsock.pp -m qemuga-vsock.mod 243 | 244 | ${SCP} qemuga-vsock.pp core@${vm_ip}: 245 | ${SSH} core@${vm_ip} 'sudo semodule -i qemuga-vsock.pp && rm qemuga-vsock.pp' 246 | ${SCP} qemu-guest-agent.service core@${vm_ip}: 247 | ${SSH} core@${vm_ip} 'sudo mv -Z qemu-guest-agent.service /etc/systemd/system/' 248 | ${SSH} core@${vm_ip} 'sudo systemctl daemon-reload' 249 | ${SSH} core@${vm_ip} 'sudo systemctl enable qemu-guest-agent.service' 250 | } 251 | 252 | function generate_vfkit_bundle { 253 | local srcDir=$1 254 | local destDir=$2 255 | 256 | generate_macos_bundle "vfkit" "$@" 257 | 258 | ${QEMU_IMG} convert -f qcow2 -O raw $srcDir/${SNC_PRODUCT_NAME}.qcow2 $destDir/${SNC_PRODUCT_NAME}.img 259 | add_disk_info_to_json_description "${destDir}" "${SNC_PRODUCT_NAME}.img" "raw" 260 | 261 | create_tarball "$destDir" 262 | } 263 | 264 | function generate_macos_bundle { 265 | local bundleType=$1 266 | local srcDir=$2 267 | local destDir=$3 268 | 269 | 270 | mkdir -p "$destDir" 271 | cp $srcDir/kubeconfig $destDir/ 272 | cp $srcDir/id_ecdsa_crc $destDir/ 273 | 274 | # Copy oc client 275 | cp openshift-clients/mac/oc $destDir/ 276 | 277 | cp podman-remote/mac/podman $destDir/ 278 | 279 | ocSize=$(du -b $destDir/oc | awk '{print $1}') 280 | ocSha256Sum=$(sha256sum $destDir/oc | awk '{print $1}') 281 | 282 | podmanSize=$(du -b $destDir/podman | awk '{print $1}') 283 | podmanSha256Sum=$(sha256sum $destDir/podman | awk '{print $1}') 284 | 285 | # Update the bundle metadata info 286 | cat $srcDir/crc-bundle-info.json \ 287 | | ${JQ} ".name = \"${destDir}\"" \ 288 | | ${JQ} ".storage.fileList[0].name = \"oc\"" \ 289 | | ${JQ} '.storage.fileList[0].type = "oc-executable"' \ 290 | | ${JQ} ".storage.fileList[0].size = \"${ocSize}\"" \ 291 | | ${JQ} ".storage.fileList[0].sha256sum = \"${ocSha256Sum}\"" \ 292 | | ${JQ} ".storage.fileList[1].name = \"podman\"" \ 293 | | ${JQ} '.storage.fileList[1].type = "podman-executable"' \ 294 | | ${JQ} ".storage.fileList[1].size = \"${podmanSize}\"" \ 295 | | ${JQ} ".storage.fileList[1].sha256sum = \"${podmanSha256Sum}\"" \ 296 | | ${JQ} ".driverInfo.name = \"${bundleType}\"" \ 297 | >$destDir/crc-bundle-info.json 298 | } 299 | 300 | function add_disk_info_to_json_description { 301 | local destDir=$1 302 | local imageFilename=$2 303 | local imageFormat=$3 304 | 305 | diskSize=$(du -b $destDir/$imageFilename | awk '{print $1}') 306 | diskSha256Sum=$(sha256sum $destDir/$imageFilename | awk '{print $1}') 307 | 308 | 309 | cat $destDir/crc-bundle-info.json \ 310 | | ${JQ} ".nodes[0].diskImage = \"${imageFilename}\"" \ 311 | | ${JQ} ".storage.diskImages[0].name = \"${imageFilename}\"" \ 312 | | ${JQ} ".storage.diskImages[0].format = \"${imageFormat}\"" \ 313 | | ${JQ} ".storage.diskImages[0].size = \"${diskSize}\"" \ 314 | | ${JQ} ".storage.diskImages[0].sha256sum = \"${diskSha256Sum}\"" >$destDir/crc-bundle-info.json.tmp 315 | mv $destDir/crc-bundle-info.json.tmp $destDir/crc-bundle-info.json 316 | } 317 | 318 | function generate_hyperv_bundle { 319 | local srcDir=$1 320 | local destDir=$2 321 | 322 | mkdir "$destDir" 323 | 324 | cp $srcDir/kubeconfig $destDir/ 325 | cp $srcDir/id_ecdsa_crc $destDir/ 326 | 327 | # Copy oc client 328 | cp openshift-clients/windows/oc.exe $destDir/ 329 | 330 | cp podman-remote/windows/podman.exe $destDir/ 331 | 332 | ocSize=$(du -b $destDir/oc.exe | awk '{print $1}') 333 | ocSha256Sum=$(sha256sum $destDir/oc.exe | awk '{print $1}') 334 | 335 | podmanSize=$(du -b $destDir/podman.exe | awk '{print $1}') 336 | podmanSha256Sum=$(sha256sum $destDir/podman.exe | awk '{print $1}') 337 | 338 | cat $srcDir/crc-bundle-info.json \ 339 | | ${JQ} ".name = \"${destDir}\"" \ 340 | | ${JQ} ".storage.fileList[0].name = \"oc.exe\"" \ 341 | | ${JQ} '.storage.fileList[0].type = "oc-executable"' \ 342 | | ${JQ} ".storage.fileList[0].size = \"${ocSize}\"" \ 343 | | ${JQ} ".storage.fileList[0].sha256sum = \"${ocSha256Sum}\"" \ 344 | | ${JQ} ".storage.fileList[1].name = \"podman.exe\"" \ 345 | | ${JQ} '.storage.fileList[1].type = "podman-executable"' \ 346 | | ${JQ} ".storage.fileList[1].size = \"${podmanSize}\"" \ 347 | | ${JQ} ".storage.fileList[1].sha256sum = \"${podmanSha256Sum}\"" \ 348 | | ${JQ} '.driverInfo.name = "hyperv"' \ 349 | >$destDir/crc-bundle-info.json 350 | 351 | ${QEMU_IMG} convert -f qcow2 -O vhdx -o subformat=dynamic $srcDir/${SNC_PRODUCT_NAME}.qcow2 $destDir/${SNC_PRODUCT_NAME}.vhdx 352 | add_disk_info_to_json_description "${destDir}" "${SNC_PRODUCT_NAME}.vhdx" vhdx 353 | 354 | create_tarball "$destDir" 355 | } 356 | 357 | function create_tarball { 358 | local dirName=$1 359 | 360 | tar cSf - --sort=name "$dirName" | ${ZSTD} --no-progress ${CRC_ZSTD_EXTRA_FLAGS} --threads=0 -o "${dirName}".crcbundle 361 | } 362 | 363 | function download_podman() { 364 | local version=$1 365 | local arch=$2 366 | 367 | mkdir -p podman-remote/linux 368 | curl -L https://github.com/containers/podman/releases/download/v${version}/podman-remote-static-linux_${arch}.tar.gz | tar -zx -C podman-remote/linux 369 | mv podman-remote/linux/bin/podman-remote-static-linux_${arch} podman-remote/linux/podman-remote 370 | chmod +x podman-remote/linux/podman-remote 371 | 372 | if [ "${SNC_GENERATE_MACOS_BUNDLE}" != "0" ]; then 373 | mkdir -p podman-remote/mac 374 | curl -L https://github.com/containers/podman/releases/download/v${version}/podman-remote-release-darwin_${arch}.zip -o podman-remote/mac/podman.zip 375 | ${UNZIP} -o -d podman-remote/mac/ podman-remote/mac/podman.zip 376 | mv podman-remote/mac/podman-${version}/usr/bin/podman podman-remote/mac 377 | chmod +x podman-remote/mac/podman 378 | fi 379 | 380 | if [ "${SNC_GENERATE_WINDOWS_BUNDLE}" != "0" ]; then 381 | mkdir -p podman-remote/windows 382 | curl -L https://github.com/containers/podman/releases/download/v${version}/podman-remote-release-windows_${arch}.zip -o podman-remote/windows/podman.zip 383 | ${UNZIP} -o -d podman-remote/windows/ podman-remote/windows/podman.zip 384 | mv podman-remote/windows/podman-${version}/usr/bin/podman.exe podman-remote/windows 385 | fi 386 | } 387 | 388 | function remove_pull_secret_from_disk() { 389 | case "${BUNDLE_TYPE}" in 390 | "microshift") 391 | ${SSH} core@${VM_IP} -- sudo rm -f /etc/crio/openshift-pull-secret 392 | ;; 393 | esac 394 | } 395 | 396 | function copy_systemd_units() { 397 | case "${BUNDLE_TYPE}" in 398 | "snc"|"okd") 399 | export APPS_DOMAIN="apps-crc.testing" 400 | envsubst '${APPS_DOMAIN}' < systemd/dnsmasq.sh.template > systemd/crc-dnsmasq.sh 401 | unset APPS_DOMAIN 402 | ;; 403 | "microshift") 404 | export APPS_DOMAIN="apps.crc.testing" 405 | envsubst '${APPS_DOMAIN}' < systemd/dnsmasq.sh.template > systemd/crc-dnsmasq.sh 406 | unset APPS_DOMAIN 407 | ;; 408 | esac 409 | 410 | ${SSH} core@${VM_IP} -- 'mkdir -p /home/core/systemd-units && mkdir -p /home/core/systemd-scripts' 411 | ${SCP} systemd/crc-*.service core@${VM_IP}:/home/core/systemd-units/ 412 | ${SCP} systemd/crc-*.sh core@${VM_IP}:/home/core/systemd-scripts/ 413 | 414 | case "${BUNDLE_TYPE}" in 415 | "snc"|"okd") 416 | ${SCP} systemd/ocp-*.service core@${VM_IP}:/home/core/systemd-units/ 417 | ${SCP} systemd/ocp-*.sh core@${VM_IP}:/home/core/systemd-scripts/ 418 | ;; 419 | esac 420 | 421 | ${SSH} core@${VM_IP} -- 'sudo cp /home/core/systemd-units/* /etc/systemd/system/ && sudo cp /home/core/systemd-scripts/* /usr/local/bin/' 422 | ${SSH} core@${VM_IP} -- 'ls /home/core/systemd-scripts/ | xargs -t -I % sudo chmod +x /usr/local/bin/%' 423 | ${SSH} core@${VM_IP} -- 'sudo restorecon -rv /usr/local/bin' 424 | 425 | ${SSH} core@${VM_IP} -- 'ls /home/core/systemd-units/*.service | xargs basename -a | xargs sudo systemctl enable' 426 | 427 | ${SSH} core@${VM_IP} -- 'rm -rf /home/core/systemd-units /home/core/systemd-scripts' 428 | } 429 | -------------------------------------------------------------------------------- /createdisk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -exuo pipefail 4 | 5 | export LC_ALL=C 6 | export LANG=C 7 | 8 | source tools.sh 9 | source createdisk-library.sh 10 | 11 | SSH="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i id_ecdsa_crc" 12 | SCP="scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i id_ecdsa_crc" 13 | 14 | INSTALL_DIR=${1:-crc-tmp-install-data} 15 | 16 | OPENSHIFT_VERSION=$(${JQ} -r .clusterInfo.openshiftVersion $INSTALL_DIR/crc-bundle-info.json) 17 | BASE_DOMAIN=$(${JQ} -r .clusterInfo.baseDomain $INSTALL_DIR/crc-bundle-info.json) 18 | BUNDLE_TYPE=$(${JQ} -r .type $INSTALL_DIR/crc-bundle-info.json) 19 | ADDITIONAL_PACKAGES="cloud-init gvisor-tap-vsock-gvforwarder" 20 | 21 | case ${BUNDLE_TYPE} in 22 | microshift) 23 | destDirPrefix="crc_${BUNDLE_TYPE}" 24 | BASE_OS=rhel 25 | ;; 26 | okd) 27 | destDirPrefix="crc_${BUNDLE_TYPE}" 28 | # Base OS is not changed for scos-okd because `/proc/cmdline` still contain fedora-coreos 29 | # https://github.com/okd-project/okd-scos/issues/18 30 | BASE_OS=fedora-coreos 31 | ;; 32 | snc) 33 | destDirPrefix="crc" 34 | BASE_OS=rhcos 35 | ;; 36 | *) 37 | echo "Unknown bundle type '$BUNDLE_TYPE'" 38 | exit 1 39 | ;; 40 | esac 41 | 42 | # SNC_PRODUCT_NAME: If user want to use other than default product name (crc) 43 | # VM_PREFIX: short VM name (set by SNC_PRODUCT_NAME) + random string generated by openshift-installer 44 | SNC_PRODUCT_NAME=${SNC_PRODUCT_NAME:-crc} 45 | VM_NAME=${SNC_PRODUCT_NAME} 46 | 47 | VM_IP=$(sudo virsh domifaddr ${VM_NAME} | tail -2 | head -1 | awk '{print $4}' | cut -d/ -f1) 48 | 49 | wait_for_ssh ${VM_NAME} ${VM_IP} 50 | 51 | if [ ${BUNDLE_TYPE} != "microshift" ]; then 52 | # Disable kubelet service 53 | ${SSH} core@${VM_IP} -- sudo systemctl disable kubelet 54 | 55 | # Stop the kubelet service so it will not reprovision the pods 56 | ${SSH} core@${VM_IP} -- sudo systemctl stop kubelet 57 | fi 58 | 59 | # Enable the system and user level podman.socket service for API V2 60 | ${SSH} core@${VM_IP} -- sudo systemctl enable podman.socket 61 | ${SSH} core@${VM_IP} -- systemctl --user enable podman.socket 62 | 63 | if [ ${BUNDLE_TYPE} == "microshift" ]; then 64 | # Pull openshift release images because as part of microshift bundle creation we 65 | # don't run microshift service which fetch these image but instead service is run 66 | # as part of crc so user have a fresh cluster instead something already provisioned 67 | # but images we cache it as part of bundle. 68 | ${SSH} core@${VM_IP} 'sudo bash -x -s' </dev/null 2>&1; then 94 | image_tag=${OPENSHIFT_VERSION} 95 | fi 96 | 97 | # create the tap device interface with specified mac address 98 | # this mac address is used to allocate a specific IP to the VM 99 | # when tap device is in use. 100 | ${SSH} core@${VM_IP} 'sudo bash -x -s' < $INSTALL_DIR/routes-controller.yaml 133 | ${SCP} $INSTALL_DIR/routes-controller.yaml core@${VM_IP}:/home/core/ 134 | ${SSH} core@${VM_IP} -- 'sudo mkdir -p /opt/crc && sudo mv /home/core/routes-controller.yaml /opt/crc/' 135 | 136 | if [ ${BUNDLE_TYPE} != "microshift" ]; then 137 | # Add internalIP as node IP for kubelet systemd unit file 138 | # More details at https://bugzilla.redhat.com/show_bug.cgi?id=1872632 139 | ${SSH} core@${VM_IP} 'sudo bash -x -s' < /etc/systemd/system/kubelet.service.d/80-nodeip.conf 141 | echo 'Environment=KUBELET_NODE_IP="${VM_IP}"' >> /etc/systemd/system/kubelet.service.d/80-nodeip.conf 142 | EOF 143 | fi 144 | 145 | if [ "${ARCH}" == "aarch64" ] && [ ${BUNDLE_TYPE} != "okd" ]; then 146 | # Install qemu-user-static-x86 package from fedora-updates repo to run x86 image on M1 147 | # Not supported by RHEL https://access.redhat.com/solutions/5654221 and not included 148 | # in any subscription repo. 149 | cat > /tmp/fedora-updates.repo <<'EOF' 150 | [fedora-updates] 151 | name=Fedora 41 - $basearch - Updates 152 | metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f41&arch=$basearch 153 | enabled=1 154 | type=rpm 155 | repo_gpgcheck=0 156 | gpgcheck=0 157 | EOF 158 | ${SCP} /tmp/fedora-updates.repo core@${VM_IP}:/tmp 159 | ${SSH} core@${VM_IP} -- "sudo mv /tmp/fedora-updates.repo /etc/yum.repos.d" 160 | ${SSH} core@${VM_IP} -- "sudo rpm-ostree install qemu-user-static-x86" 161 | fi 162 | 163 | # Beyond this point, packages added to the ADDITIONAL_PACKAGES variable won’t be installed in the guest 164 | install_additional_packages ${VM_IP} 165 | copy_systemd_units 166 | 167 | cleanup_vm_image ${VM_NAME} ${VM_IP} 168 | 169 | # Enable cloud-init service 170 | ${SSH} core@${VM_IP} -- "sudo systemctl enable cloud-init cloud-config cloud-final" 171 | 172 | # Delete all the pods except openshift-multus (which have file for crio cni config) 173 | # and lease from the etcd db so that when this bundle is use for the cluster provision, everything comes up in clean state. 174 | if [ ${BUNDLE_TYPE} != "microshift" ]; then 175 | etcd_image=$(${SSH} core@${VM_IP} -- "sudo jq -r '.spec.containers[] | select(.name == \"etcd\") | .image' /etc/kubernetes/manifests/etcd-pod.yaml") 176 | ${SSH} core@${VM_IP} -- "sudo podman run --rm --network=host --privileged --replace --name crc-etcd --detach --entrypoint etcd -v /var/lib/etcd:/store \"${etcd_image}\" --data-dir /store" 177 | sleep 5 178 | ${SSH} core@${VM_IP} 'sudo bash -x -s' << EOF 179 | podman exec crc-etcd etcdctl get /kubernetes.io/pods/ --prefix --keys-only | \ 180 | grep -v "^/kubernetes.io/pods/openshift-network" | \ 181 | xargs -I {} podman exec crc-etcd etcdctl del "{}" 182 | EOF 183 | ${SSH} core@${VM_IP} -- "sudo podman exec crc-etcd etcdctl del --prefix /kubernetes.io/leases" 184 | ${SSH} core@${VM_IP} -- "sudo podman stop crc-etcd" 185 | fi 186 | 187 | podman_version=$(${SSH} core@${VM_IP} -- 'rpm -q --qf %{version} podman') 188 | 189 | # Disable cloud-init network config 190 | ${SSH} core@${VM_IP} 'sudo bash -x -s' << EOF 191 | cat << EFF > /etc/cloud/cloud.cfg.d/05_disable-network.cfg 192 | network: 193 | config: disabled 194 | EFF 195 | EOF 196 | 197 | # Disable cloud-init hostname update 198 | ${SSH} core@${VM_IP} -- 'sudo sed -i "s/^preserve_hostname: false$/preserve_hostname: true/" /etc/cloud/cloud.cfg' 199 | 200 | # Cleanup cloud-init config 201 | ${SSH} core@${VM_IP} -- "sudo cloud-init clean --logs" 202 | 203 | # Shutdown the VM 204 | shutdown_vm ${VM_NAME} 205 | 206 | # Download podman clients 207 | download_podman $podman_version ${yq_ARCH} 208 | 209 | # libvirt image generation 210 | get_dest_dir_suffix "${OPENSHIFT_VERSION}" 211 | destDirSuffix="${DEST_DIR_SUFFIX}" 212 | 213 | libvirtDestDir="${destDirPrefix}_libvirt_${destDirSuffix}" 214 | rm -fr ${libvirtDestDir} ${libvirtDestDir}.crcbundle 215 | mkdir "$libvirtDestDir" 216 | 217 | create_qemu_image "$libvirtDestDir" 218 | copy_additional_files "$INSTALL_DIR" "$libvirtDestDir" "${VM_NAME}" 219 | if [ "${SNC_GENERATE_LINUX_BUNDLE}" != "0" ]; then 220 | create_tarball "$libvirtDestDir" 221 | fi 222 | 223 | # HyperV image generation 224 | # 225 | # This must be done after the generation of libvirt image as it reuses some of 226 | # the content of $libvirtDestDir 227 | if [ "${SNC_GENERATE_WINDOWS_BUNDLE}" != "0" ]; then 228 | hypervDestDir="${destDirPrefix}_hyperv_${destDirSuffix}" 229 | rm -fr ${hypervDestDir} ${hypervDestDir}.crcbundle 230 | generate_hyperv_bundle "$libvirtDestDir" "$hypervDestDir" 231 | fi 232 | 233 | # vfkit image generation 234 | # This must be done after the generation of libvirt image as it reuses some of 235 | # the content of $libvirtDestDir 236 | if [ "${SNC_GENERATE_MACOS_BUNDLE}" != "0" ]; then 237 | vfkitDestDir="${destDirPrefix}_vfkit_${destDirSuffix}" 238 | rm -fr ${vfkitDestDir} ${vfkitDestDir}.crcbundle 239 | generate_vfkit_bundle "$libvirtDestDir" "$vfkitDestDir" 240 | fi 241 | -------------------------------------------------------------------------------- /crio-wipe.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Dummy crio-wipe service 3 | Before=crio.service 4 | RequiresMountsFor=/var/lib/containers 5 | 6 | [Service] 7 | ExecStart=/bin/true 8 | Type=oneshot 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | 13 | -------------------------------------------------------------------------------- /cvo-overrides-after-first-run.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /spec/overrides 3 | value: 4 | - kind: Deployment 5 | group: apps 6 | name: cluster-monitoring-operator 7 | namespace: openshift-monitoring 8 | unmanaged: true 9 | - kind: ClusterOperator 10 | group: config.openshift.io 11 | name: monitoring 12 | namespace: "" 13 | unmanaged: true 14 | - kind: Deployment 15 | group: apps 16 | name: cloud-credential-operator 17 | namespace: openshift-cloud-credential-operator 18 | unmanaged: true 19 | - kind: ClusterOperator 20 | group: config.openshift.io 21 | name: cloud-credential 22 | namespace: "" 23 | unmanaged: true 24 | - kind: Deployment 25 | group: apps 26 | name: cluster-autoscaler-operator 27 | namespace: openshift-machine-api 28 | unmanaged: true 29 | - kind: ClusterOperator 30 | group: config.openshift.io 31 | name: cluster-autoscaler 32 | namespace: "" 33 | unmanaged: true 34 | - kind: Deployment 35 | group: apps 36 | name: cluster-cloud-controller-manager-operator 37 | namespace: openshift-cloud-controller-manager-operator 38 | unmanaged: true 39 | - kind: ClusterOperator 40 | group: config.openshift.io 41 | name: cloud-controller-manager 42 | namespace: "" 43 | unmanaged: true 44 | 45 | -------------------------------------------------------------------------------- /cvo-overrides.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | overrides: 3 | - kind: Deployment 4 | group: apps 5 | name: cluster-monitoring-operator 6 | namespace: openshift-monitoring 7 | unmanaged: true 8 | - kind: ClusterOperator 9 | group: config.openshift.io 10 | name: monitoring 11 | namespace: "" 12 | unmanaged: true 13 | - kind: Deployment 14 | group: apps 15 | name: cloud-credential-operator 16 | namespace: openshift-cloud-credential-operator 17 | unmanaged: true 18 | - kind: ClusterOperator 19 | group: config.openshift.io 20 | name: cloud-credential 21 | namespace: "" 22 | unmanaged: true 23 | - kind: Deployment 24 | group: apps 25 | name: cluster-autoscaler-operator 26 | namespace: openshift-machine-api 27 | unmanaged: true 28 | - kind: ClusterOperator 29 | group: config.openshift.io 30 | name: cluster-autoscaler 31 | namespace: "" 32 | unmanaged: true 33 | - kind: Deployment 34 | group: apps 35 | name: cluster-cloud-controller-manager-operator 36 | namespace: openshift-cloud-controller-manager-operator 37 | unmanaged: true 38 | - kind: ClusterOperator 39 | group: config.openshift.io 40 | name: cloud-controller-manager 41 | namespace: "" 42 | unmanaged: true 43 | 44 | -------------------------------------------------------------------------------- /docs/self-sufficient-bundle.md: -------------------------------------------------------------------------------- 1 | # Self sufficient bundles 2 | 3 | Since release 4.19.0 of OpenShift Local, the bundles generated by `snc` contain additional systemd services to provision the cluster and remove the need for 4 | an outside entity to provision the cluster, although an outside process needs to create some files on pre-defined locations inside the VM for the systemd 5 | services to do their work. 6 | 7 | ## The following table lists the systemd services and the location of files they need to provision the cluster, users of SNC need to create those files 8 | 9 | | Systemd unit | Runs for (ocp, MicroShift, both) | Input files location | Marker env variables | 10 | | :----------------------------: | :------------------------------: | :----------------------------------: | :------------------: | 11 | | `crc-cluster-status.service` | both | none | none | 12 | | `crc-pullsecret.service` | both | /opt/crc/pull-secret | none | 13 | | `crc-dnsmasq.service` | both | none | none | 14 | | `crc-routes-controller.service`| both | none | none | 15 | | `ocp-cluster-ca.service` | ocp | /opt/crc/custom-ca.crt | CRC_CLOUD=1 | 16 | | `ocp-clusterid.service` | ocp | none | none | 17 | | `ocp-custom-domain.service` | ocp | none | CRC_CLOUD=1 | 18 | | `ocp-growfs.service` | ocp | none | none | 19 | | `ocp-userpasswords.service` | ocp | /opt/crc/pass_{kubeadmin, developer} | none | 20 | 21 | In addition to the above services we have `ocp-cluster-ca.path`, `crc-pullsecret.path` and `ocp-userpasswords.path` that monitors the filesystem paths 22 | related to their `*.service` counterparts and starts the service when the paths become available. 23 | 24 | > [!NOTE] 25 | > "Marker env variable" is set using an env file, if the required env variable is not set then unit is skipped 26 | > some units are run only when CRC_CLOUD=1 is set, these are only needed when using the bundles with crc-cloud 27 | 28 | The systemd services are heavily based on the [`clustersetup.sh`](https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh) script found in the `crc-cloud` project. 29 | 30 | ## Naming convention for the systemd unit files 31 | 32 | Systemd units that are needed for both 'OpenShift' and 'MicroShift' are named as `crc-*.service`, units that are needed only for 'OpenShift' are named 33 | as `ocp-*.service` and when we add units that are only needed for 'MicroShift' they should be named as `ucp-*.service` 34 | 35 | -------------------------------------------------------------------------------- /gen-bundle-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -exuo pipefail 4 | 5 | GPG_SECRET_KEY_PASSPHRASE_PATH=${GPG_SECRET_KEY_PASSPHRASE:-gpg_key_pass} 6 | 7 | function set_bundle_variables { 8 | local version=$1 9 | local preset=$2 10 | 11 | local bundlePreset="" 12 | if [ ${preset} != 'openshift' ]; then 13 | bundlePreset="_${preset}" 14 | fi 15 | 16 | if [ ${PRESET} != 'okd' ]; then 17 | vfkit_bundle_arm64=crc${bundlePreset}_vfkit_${version}_arm64.crcbundle 18 | libvirt_bundle_arm64=crc${bundlePreset}_libvirt_${version}_arm64.crcbundle 19 | fi 20 | 21 | vfkit_bundle=crc${bundlePreset}_vfkit_${version}_amd64.crcbundle 22 | libvirt_bundle=crc${bundlePreset}_libvirt_${version}_amd64.crcbundle 23 | hyperv_bundle=crc${bundlePreset}_hyperv_${version}_amd64.crcbundle 24 | } 25 | 26 | function generate_image { 27 | local preset=$1 28 | 29 | if [ ${preset} != "okd" ]; then 30 | cat < 2 | NETWORK_NAME 3 | a29bce40-ce15-43c8-9142-fd0a3cc37f9a 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | api.CLUSTER_NAME.BASE_DOMAIN 12 | api-int.CLUSTER_NAME.BASE_DOMAIN 13 | console-openshift-console.apps-CLUSTER_NAME.BASE_DOMAIN 14 | oauth-openshift.apps-CLUSTER_NAME.BASE_DOMAIN 15 | canary-openshift-ingress-canary.apps-CLUSTER_NAME.BASE_DOMAIN 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /image-mode/microshift/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | 4 | ROOTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../" && pwd )" 5 | SCRIPTDIR=${ROOTDIR}/image-mode/microshift 6 | IMGNAME=microshift 7 | MICROSHIFT_VERSION=4.18 8 | BUILD_ARCH=$(uname -m) 9 | OSVERSION=$(awk -F: '{print $5}' /etc/system-release-cpe) 10 | LVM_SYSROOT_SIZE_MIN=10240 11 | LVM_SYSROOT_SIZE=${LVM_SYSROOT_SIZE_MIN} 12 | OCP_PULL_SECRET_FILE= 13 | AUTHORIZED_KEYS_FILE= 14 | AUTHORIZED_KEYS= 15 | USE_MIRROR_REPO= 16 | 17 | # shellcheck disable=SC2034 18 | STARTTIME="$(date +%s)" 19 | BUILDDIR=${BUILDDIR:-${ROOTDIR}/_output/image-mode} 20 | 21 | usage() { 22 | local error_message="$1" 23 | 24 | if [ -n "${error_message}" ]; then 25 | echo "ERROR: ${error_message}" 26 | echo 27 | fi 28 | 29 | echo "Usage: $(basename "$0") <-pull_secret_file path_to_file> [OPTION]..." 30 | echo "" 31 | echo " -pull_secret_file path_to_file" 32 | echo " Path to a file containing the OpenShift pull secret, which can be" 33 | echo " obtained from https://console.redhat.com/openshift/downloads#tool-pull-secret" 34 | echo "" 35 | echo "Optional arguments:" 36 | echo " -lvm_sysroot_size num_in_MB" 37 | echo " Size of the system root LVM partition. The remaining" 38 | echo " disk space will be allocated for data (default: ${LVM_SYSROOT_SIZE})" 39 | echo " -authorized_keys_file path_to_file" 40 | echo " Path to an SSH authorized_keys file to allow SSH access" 41 | echo " into the default 'redhat' account" 42 | echo " -use-unreleased-mirror-repo " 43 | echo " Use unreleased mirror repo to get release candidate and engineering preview rpms" 44 | echo " like (https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp-dev-preview/latest-4.18/el9/os/)" 45 | echo " -microshift-version " 46 | echo " Version of microshift for image generation (default: ${MICROSHIFT_VERSION}" 47 | echo " -hostname " 48 | echo " Hostname of the machine" 49 | echo " -base-domain " 50 | echo " Base domain for microshift cluster" 51 | exit 1 52 | } 53 | 54 | title() { 55 | echo -e "\E[34m\n# $1\E[00m" 56 | } 57 | 58 | # Parse the command line 59 | while [ $# -gt 0 ] ; do 60 | case $1 in 61 | -pull_secret_file) 62 | shift 63 | OCP_PULL_SECRET_FILE="$1" 64 | [ -z "${OCP_PULL_SECRET_FILE}" ] && usage "Pull secret file not specified" 65 | [ ! -s "${OCP_PULL_SECRET_FILE}" ] && usage "Empty or missing pull secret file" 66 | shift 67 | ;; 68 | -lvm_sysroot_size) 69 | shift 70 | LVM_SYSROOT_SIZE="$1" 71 | [ -z "${LVM_SYSROOT_SIZE}" ] && usage "System root LVM partition size not specified" 72 | [ "${LVM_SYSROOT_SIZE}" -lt ${LVM_SYSROOT_SIZE_MIN} ] && usage "System root LVM partition size cannot be smaller than ${LVM_SYSROOT_SIZE_MIN}MB" 73 | shift 74 | ;; 75 | -authorized_keys_file) 76 | shift 77 | AUTHORIZED_KEYS_FILE="$1" 78 | [ -z "${AUTHORIZED_KEYS_FILE}" ] && usage "Authorized keys file not specified" 79 | shift 80 | ;; 81 | -use-unreleased-mirror-repo) 82 | shift 83 | USE_UNRELEASED_MIRROR_REPO="$1" 84 | [ -z "${USE_UNRELEASED_MIRROR_REPO}" ] && usage "Mirror repo not specified" 85 | shift 86 | ;; 87 | -microshift-version) 88 | shift 89 | MICROSHIFT_VERSION="$1" 90 | [ -z "${MICROSHIFT_VERSION}" ] && usage "MicroShift version not specified" 91 | shift 92 | ;; 93 | -hostname) 94 | shift 95 | HOSTNAME="$1" 96 | [ -z "${HOSTNAME}" ] && usage "Hostname not specified" 97 | shift 98 | ;; 99 | -base-domain) 100 | shift 101 | BASE_DOMAIN="$1" 102 | [ -z "${BASE_DOMAIN}" ] && usage "Base domain not specified" 103 | shift 104 | ;; 105 | *) 106 | usage 107 | ;; 108 | esac 109 | done 110 | 111 | if [ ! -r "${OCP_PULL_SECRET_FILE}" ] ; then 112 | echo "ERROR: pull_secret_file file does not exist or not readable: ${OCP_PULL_SECRET_FILE}" 113 | exit 1 114 | fi 115 | if [ -n "${AUTHORIZED_KEYS_FILE}" ]; then 116 | if [ ! -e "${AUTHORIZED_KEYS_FILE}" ]; then 117 | echo "ERROR: authorized_keys_file does not exist: ${AUTHORIZED_KEYS_FILE}" 118 | exit 1 119 | else 120 | AUTHORIZED_KEYS=$(cat "${AUTHORIZED_KEYS_FILE}") 121 | fi 122 | fi 123 | 124 | mkdir -p "${BUILDDIR}" 125 | 126 | title "Preparing kickstart config" 127 | # Create a kickstart file from a template, compacting pull secret contents if necessary 128 | cat < "${SCRIPTDIR}/config/config.toml.template" \ 129 | | sed "s;REPLACE_HOSTNAME;${HOSTNAME};g" \ 130 | | sed "s;REPLACE_BASE_DOMAIN;${BASE_DOMAIN};g" \ 131 | | sed "s;REPLACE_LVM_SYSROOT_SIZE;${LVM_SYSROOT_SIZE};g" \ 132 | | sed "s;REPLACE_OCP_PULL_SECRET_CONTENTS;$(cat < "${OCP_PULL_SECRET_FILE}" | jq -c);g" \ 133 | | sed "s^REPLACE_CORE_AUTHORIZED_KEYS_CONTENTS^${AUTHORIZED_KEYS}^g" \ 134 | > "${BUILDDIR}"/config.toml 135 | 136 | title "Building bootc image for microshift" 137 | sudo podman build --no-cache --authfile ${OCP_PULL_SECRET_FILE} -t ${IMGNAME}:${MICROSHIFT_VERSION} \ 138 | --build-arg MICROSHIFT_VER=${MICROSHIFT_VERSION} \ 139 | --env UNRELEASED_MIRROR_REPO=${USE_UNRELEASED_MIRROR_REPO} \ 140 | -f "${SCRIPTDIR}/config/Containerfile.bootc-rhel9" 141 | 142 | # As of now we are generating the ISO to have same previous behavior 143 | # TODO: Try to use qcow2 directly for vm creation 144 | title "Creating ISO image" 145 | sudo podman run --authfile ${OCP_PULL_SECRET_FILE} --rm -it \ 146 | --privileged \ 147 | --security-opt label=type:unconfined_t \ 148 | -v /var/lib/containers/storage:/var/lib/containers/storage \ 149 | -v "${BUILDDIR}"/config.toml:/config.toml \ 150 | -v "${BUILDDIR}":/output \ 151 | registry.redhat.io/rhel9/bootc-image-builder:latest \ 152 | --local \ 153 | --type iso \ 154 | --config /config.toml \ 155 | localhost/${IMGNAME}:${MICROSHIFT_VERSION} 156 | -------------------------------------------------------------------------------- /image-mode/microshift/config/Containerfile.bootc-rhel9: -------------------------------------------------------------------------------- 1 | FROM registry.redhat.io/rhel9/rhel-bootc:9.4 2 | 3 | ARG MICROSHIFT_VER=4.18 4 | RUN if [ -z "${UNRELEASED_MIRROR_REPO}" ]; then \ 5 | dnf config-manager --set-enabled "rhocp-${MICROSHIFT_VER}-for-rhel-9-$(uname -m)-rpms" \ 6 | --set-enabled "fast-datapath-for-rhel-9-$(uname -m)-rpms"; \ 7 | else \ 8 | # This is required to update the gpgcheck for repoID 9 | # Add the specified OpenShift v4 dependencies repository to get packages like crio, runc, openvswitch ..etc. 10 | # to which microshift package depend on for the current architecture and MICROSHIFT_VER version (e.g., 4.18). 11 | repoID=$(echo "${UNRELEASED_MIRROR_REPO#*://}" | tr '/:' '_'); \ 12 | dnf config-manager --add-repo "${UNRELEASED_MIRROR_REPO}" \ 13 | --add-repo "https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/dependencies/rpms/${MICROSHIFT_VER}-el9-beta" \ 14 | --set-enabled "fast-datapath-for-rhel-9-$(uname -m)-rpms"; \ 15 | dnf config-manager --save --setopt="${repoID}".gpgcheck=0 --setopt=*-el9-beta.gpgcheck=0; \ 16 | fi 17 | RUN dnf install -y firewalld microshift microshift-release-info cloud-utils-growpart qemu-guest-agent dnsmasq && \ 18 | dnf clean all && rm -fr /etc/yum.repos.d/* 19 | 20 | # https://github.com/containers/bootc/discussions/1036 21 | # /Users is created to make sure share directory works on 22 | # mac because on linux it is /home and for windows it is /mnt 23 | # and both are symlink to `var` already 24 | RUN rm -fr /opt && ln -sf var/opt /opt && mkdir /var/opt 25 | RUN ln -sf var/Users /Users && mkdir /var/Users 26 | RUN rm -fr /usr/local && ln -sf ../var/usrlocal /usr/local && mkdir /var/usrlocal 27 | -------------------------------------------------------------------------------- /image-mode/microshift/config/config.toml.template: -------------------------------------------------------------------------------- 1 | [customizations.installer.kickstart] 2 | contents = """ 3 | lang en_US.UTF-8 4 | keyboard us 5 | timezone UTC 6 | text 7 | reboot 8 | 9 | # Configure network to use DHCP and activate on boot 10 | network --bootproto=dhcp --device=link --activate --onboot=on 11 | 12 | # Partition disk with a 1MB BIOS boot, 200M EFI, 800M boot XFS partition and 13 | # an LVM volume containing a 10GB+ system root. The remainder of the volume 14 | # will be used by the CSI driver for storing data 15 | # 16 | # For example, a 20GB disk would be partitioned in the following way: 17 | # 18 | # NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT 19 | # sda 8:0 0 20G 0 disk 20 | # ├─sda1 8:1 0 1M 0 part 21 | # ├─sda2 8:2 0 200M 0 part /boot/efi 22 | # ├─sda3 8:3 0 800M 0 part /boot 23 | # └─sda4 8:4 0 19G 0 part 24 | # └─rhel-root 253:0 0 10G 0 lvm /sysroot 25 | # 26 | zerombr 27 | clearpart --all --disklabel gpt 28 | part biosboot --fstype=biosboot --size=1 29 | part /boot/efi --fstype=efi --size=200 30 | part /boot --fstype=xfs --asprimary --size=800 31 | # Uncomment this line to add a SWAP partition of the recommended size 32 | #part swap --fstype=swap --recommended 33 | part pv.01 --grow 34 | volgroup rhel pv.01 35 | logvol / --vgname=rhel --fstype=xfs --size=REPLACE_LVM_SYSROOT_SIZE --name=root 36 | 37 | # Lock root user account 38 | rootpw --lock 39 | 40 | 41 | %post --log=/var/log/anaconda/post-install.log --erroronfail 42 | 43 | # The pull secret is mandatory for MicroShift builds on top of OpenShift, but not OKD 44 | # The /etc/crio/crio.conf.d/microshift.conf references the /etc/crio/openshift-pull-secret file 45 | cat > /etc/crio/openshift-pull-secret < /etc/microshift/config.d/00-microshift-dns.yaml < /etc/sudoers.d/microshift 59 | 60 | # Add authorized ssh keys 61 | mkdir -m 700 /home/core/.ssh 62 | cat > /home/core/.ssh/authorized_keys < /etc/hostname 70 | chmod 644 /etc/hostname 71 | 72 | # Support to boot for UEFI and legacy mode 73 | grub2-install --target=i386-pc /dev/vda 74 | 75 | # Make podman rootless available 76 | mkdir -p /home/core/.config/systemd/user/default.target.wants 77 | ln -s /usr/lib/systemd/user/podman.socket /home/core/.config/systemd/user/default.target.wants/podman.socket 78 | 79 | mkdir -p /home/core/.config/containers 80 | tee /home/core/.config/containers/containers.conf </dev/null 6 | username="${NSS_USERNAME:-$(id -un)}" 7 | uid="${NSS_UID:-$(id -u)}" 8 | 9 | groupname="${NSS_GROUPNAME:-$(id -gn)}" 10 | gid="${NSS_GID:-$(id -g)}" 11 | 12 | echo "${username}:x:${uid}:${uid}:gecos:${HOME}:/bin/bash" > "${NSS_WRAPPER_PASSWD}" 13 | echo "${groupname}:x:${gid}:" > "${NSS_WRAPPER_GROUP}" 14 | ) 15 | 16 | # wrap command 17 | export LD_PRELOAD=/usr/lib64/libnss_wrapper.so 18 | exec "$@" 19 | -------------------------------------------------------------------------------- /install-config.yaml: -------------------------------------------------------------------------------- 1 | # This file was generated using openshift-install create install-config 2 | # and then user specific information was removed as snc.sh will readd it 3 | apiVersion: v1 4 | baseDomain: testing 5 | compute: 6 | - architecture: 7 | name: worker 8 | replicas: 0 9 | controlPlane: 10 | architecture: 11 | name: master 12 | replicas: 1 13 | metadata: 14 | name: crc 15 | networking: 16 | clusterNetwork: 17 | - cidr: 10.217.0.0/22 18 | hostPrefix: 23 19 | machineNetwork: 20 | - cidr: 192.168.126.0/24 21 | serviceNetwork: 22 | - 10.217.4.0/23 23 | platform: 24 | none: {} 25 | bootstrapInPlace: 26 | installationDisk: /dev/vda 27 | capabilities: 28 | baselineCapabilitySet: None 29 | additionalEnabledCapabilities: 30 | - openshift-samples 31 | - marketplace 32 | - Console 33 | - MachineAPI 34 | - ImageRegistry 35 | - DeploymentConfig 36 | - Build 37 | - OperatorLifecycleManager 38 | - Ingress 39 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/csi-driver-hostpath-provisioner.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: CSIDriver 3 | metadata: 4 | name: kubevirt.io.hostpath-provisioner 5 | spec: 6 | attachRequired: false 7 | storageCapacity: false 8 | fsGroupPolicy: File 9 | # Supports persistent volumes. 10 | volumeLifecycleModes: 11 | - Persistent 12 | # To determine at runtime which mode a volume uses, pod info and its 13 | # "csi.storage.k8s.io/ephemeral" entry are needed. 14 | podInfoOnMount: true 15 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/csi-driver/csi-kubevirt-hostpath-provisioner.yaml: -------------------------------------------------------------------------------- 1 | # All of the individual sidecar RBAC roles get bound 2 | # to this account. 3 | kind: ServiceAccount 4 | apiVersion: v1 5 | metadata: 6 | name: csi-hostpath-provisioner-sa 7 | namespace: hostpath-provisioner 8 | --- 9 | apiVersion: rbac.authorization.k8s.io/v1 10 | kind: ClusterRoleBinding 11 | metadata: 12 | name: crc-csi-hostpathplugin-health-monitor-controller-cluster-role 13 | roleRef: 14 | apiGroup: rbac.authorization.k8s.io 15 | kind: ClusterRole 16 | name: crc-hostpath-external-health-monitor-controller-runner 17 | subjects: 18 | - kind: ServiceAccount 19 | name: csi-hostpath-provisioner-sa 20 | namespace: hostpath-provisioner 21 | --- 22 | apiVersion: rbac.authorization.k8s.io/v1 23 | kind: ClusterRoleBinding 24 | metadata: 25 | name: crc-csi-hostpathplugin-provisioner-cluster-role 26 | roleRef: 27 | apiGroup: rbac.authorization.k8s.io 28 | kind: ClusterRole 29 | name: crc-hostpath-external-provisioner-runner 30 | subjects: 31 | - kind: ServiceAccount 32 | name: csi-hostpath-provisioner-sa 33 | namespace: hostpath-provisioner 34 | --- 35 | apiVersion: rbac.authorization.k8s.io/v1 36 | kind: RoleBinding 37 | metadata: 38 | name: csi-hostpathplugin-health-monitor-controller-role 39 | roleRef: 40 | apiGroup: rbac.authorization.k8s.io 41 | kind: Role 42 | name: external-health-monitor-controller-cfg 43 | subjects: 44 | - kind: ServiceAccount 45 | name: csi-hostpath-provisioner-sa 46 | namespace: hostpath-provisioner 47 | --- 48 | apiVersion: rbac.authorization.k8s.io/v1 49 | kind: RoleBinding 50 | metadata: 51 | name: csi-hostpathplugin-provisioner-role 52 | roleRef: 53 | apiGroup: rbac.authorization.k8s.io 54 | kind: Role 55 | name: external-provisioner-cfg 56 | subjects: 57 | - kind: ServiceAccount 58 | name: csi-hostpath-provisioner-sa 59 | namespace: hostpath-provisioner 60 | --- 61 | kind: DaemonSet 62 | apiVersion: apps/v1 63 | metadata: 64 | name: csi-hostpathplugin 65 | spec: 66 | selector: 67 | matchLabels: 68 | app.kubernetes.io/instance: hostpath.csi.kubevirt.io 69 | app.kubernetes.io/part-of: csi-driver-host-path 70 | app.kubernetes.io/name: csi-hostpathplugin 71 | app.kubernetes.io/component: plugin 72 | template: 73 | metadata: 74 | labels: 75 | app.kubernetes.io/instance: hostpath.csi.kubevirt.io 76 | app.kubernetes.io/part-of: csi-driver-host-path 77 | app.kubernetes.io/name: csi-hostpathplugin 78 | app.kubernetes.io/component: plugin 79 | spec: 80 | serviceAccountName: csi-hostpath-provisioner-sa 81 | containers: 82 | - args: 83 | - --drivername=kubevirt.io.hostpath-provisioner 84 | - --v=3 85 | - --datadir=[{"name":"local","path":"/csi-data-dir"}] 86 | - --endpoint=$(CSI_ENDPOINT) 87 | - --nodeid=$(NODE_NAME) 88 | - --version=$(VERSION) 89 | env: 90 | - name: CSI_ENDPOINT 91 | value: unix:///csi/csi.sock 92 | - name: NODE_NAME 93 | valueFrom: 94 | fieldRef: 95 | apiVersion: v1 96 | fieldPath: spec.nodeName 97 | - name: PV_DIR 98 | value: /var/hpvolumes 99 | - name: VERSION 100 | value: latest 101 | image: quay.io/kubevirt/hostpath-csi-driver:latest 102 | imagePullPolicy: IfNotPresent 103 | livenessProbe: 104 | failureThreshold: 5 105 | httpGet: 106 | path: /healthz 107 | port: 9898 108 | scheme: HTTP 109 | initialDelaySeconds: 10 110 | periodSeconds: 2 111 | successThreshold: 1 112 | timeoutSeconds: 3 113 | name: hostpath-provisioner 114 | ports: 115 | - containerPort: 9898 116 | name: healthz 117 | protocol: TCP 118 | resources: {} 119 | securityContext: 120 | privileged: true 121 | terminationMessagePath: /dev/termination-log 122 | terminationMessagePolicy: File 123 | volumeMounts: 124 | - mountPath: /csi-data-dir 125 | name: csi-data-dir 126 | - mountPath: /var/lib/kubelet/plugins 127 | mountPropagation: Bidirectional 128 | name: plugins-dir 129 | - mountPath: /var/lib/kubelet/pods 130 | mountPropagation: Bidirectional 131 | name: mountpoint-dir 132 | - mountPath: /csi 133 | name: socket-dir 134 | - args: 135 | - --v=3 136 | - --csi-address=/csi/csi.sock 137 | - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-hostpath/csi.sock 138 | env: 139 | - name: KUBE_NODE_NAME 140 | valueFrom: 141 | fieldRef: 142 | apiVersion: v1 143 | fieldPath: spec.nodeName 144 | image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.2.0 145 | imagePullPolicy: IfNotPresent 146 | name: node-driver-registrar 147 | resources: {} 148 | securityContext: 149 | privileged: true 150 | terminationMessagePath: /dev/termination-log 151 | terminationMessagePolicy: File 152 | volumeMounts: 153 | - mountPath: /csi 154 | name: socket-dir 155 | - mountPath: /registration 156 | name: registration-dir 157 | - mountPath: /csi-data-dir 158 | name: csi-data-dir 159 | - args: 160 | - --csi-address=/csi/csi.sock 161 | - --health-port=9898 162 | image: registry.k8s.io/sig-storage/livenessprobe:v2.3.0 163 | imagePullPolicy: IfNotPresent 164 | name: liveness-probe 165 | resources: {} 166 | terminationMessagePath: /dev/termination-log 167 | terminationMessagePolicy: File 168 | volumeMounts: 169 | - mountPath: /csi 170 | name: socket-dir 171 | - args: 172 | - --v=5 173 | - --csi-address=/csi/csi.sock 174 | - --feature-gates=Topology=true 175 | - --enable-capacity=true 176 | - --capacity-for-immediate-binding=true 177 | - --extra-create-metadata=true 178 | - --immediate-topology=false 179 | - --strict-topology=true 180 | - --node-deployment=true 181 | env: 182 | - name: NAMESPACE 183 | valueFrom: 184 | fieldRef: 185 | apiVersion: v1 186 | fieldPath: metadata.namespace 187 | - name: POD_NAME 188 | valueFrom: 189 | fieldRef: 190 | apiVersion: v1 191 | fieldPath: metadata.name 192 | - name: NODE_NAME 193 | valueFrom: 194 | fieldRef: 195 | apiVersion: v1 196 | fieldPath: spec.nodeName 197 | image: registry.k8s.io/sig-storage/csi-provisioner:v2.2.1 198 | imagePullPolicy: IfNotPresent 199 | name: csi-provisioner 200 | resources: {} 201 | securityContext: 202 | privileged: true 203 | terminationMessagePath: /dev/termination-log 204 | terminationMessagePolicy: File 205 | volumeMounts: 206 | - mountPath: /csi 207 | name: socket-dir 208 | volumes: 209 | - hostPath: 210 | path: /var/lib/kubelet/plugins/csi-hostpath 211 | type: DirectoryOrCreate 212 | name: socket-dir 213 | - hostPath: 214 | path: /var/lib/kubelet/pods 215 | type: DirectoryOrCreate 216 | name: mountpoint-dir 217 | - hostPath: 218 | path: /var/lib/kubelet/plugins_registry 219 | type: Directory 220 | name: registration-dir 221 | - hostPath: 222 | path: /var/lib/kubelet/plugins 223 | type: Directory 224 | name: plugins-dir 225 | - hostPath: 226 | # 'path' is where PV data is persisted on host. 227 | # using /tmp is also possible while the PVs will not available after plugin container recreation or host reboot 228 | path: /var/lib/csi-hostpath-data/ 229 | type: DirectoryOrCreate 230 | name: csi-data-dir 231 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/csi-driver/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - csi-kubevirt-hostpath-provisioner.yaml 3 | images: 4 | - name: quay.io/kubevirt/hostpath-csi-driver 5 | newName: registry.redhat.io/container-native-virtualization/hostpath-csi-driver-rhel9 6 | newTag: v4.15 7 | - name: registry.k8s.io/sig-storage/csi-node-driver-registrar 8 | newName: registry.redhat.io/openshift4/ose-csi-node-driver-registrar 9 | newTag: latest 10 | - name: registry.k8s.io/sig-storage/livenessprobe 11 | newName: registry.redhat.io/openshift4/ose-csi-livenessprobe 12 | newTag: latest 13 | - name: registry.k8s.io/sig-storage/csi-provisioner 14 | newName: registry.redhat.io/openshift4/ose-csi-external-provisioner 15 | newTag: latest 16 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/csi-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: crc-csi-hostpath-provisioner 5 | annotations: 6 | storageclass.kubernetes.io/is-default-class: "true" 7 | provisioner: kubevirt.io.hostpath-provisioner 8 | parameters: 9 | storagePool: local 10 | volumeBindingMode: WaitForFirstConsumer 11 | reclaimPolicy: Retain 12 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/external-provisioner-rbac.yaml: -------------------------------------------------------------------------------- 1 | # This YAML file contains all RBAC objects that are necessary to run external 2 | # CSI provisioner. 3 | # 4 | # In production, each CSI driver deployment has to be customized: 5 | # - to avoid conflicts, use non-default namespace and different names 6 | # for non-namespaced entities like the ClusterRole 7 | # - decide whether the deployment replicates the external CSI 8 | # provisioner, in which case leadership election must be enabled; 9 | # this influences the RBAC setup, see below 10 | 11 | apiVersion: v1 12 | kind: ServiceAccount 13 | metadata: 14 | name: csi-provisioner 15 | # replace with non-default namespace name 16 | namespace: hostpath-provisioner 17 | 18 | --- 19 | kind: ClusterRole 20 | apiVersion: rbac.authorization.k8s.io/v1 21 | metadata: 22 | name: crc-hostpath-external-provisioner-runner 23 | rules: 24 | # The following rule should be uncommented for plugins that require secrets 25 | # for provisioning. 26 | # - apiGroups: [""] 27 | # resources: ["secrets"] 28 | # verbs: ["get", "list"] 29 | - apiGroups: [""] 30 | resources: ["persistentvolumes"] 31 | verbs: ["get", "list", "watch", "create", "delete"] 32 | - apiGroups: [""] 33 | resources: ["persistentvolumeclaims"] 34 | verbs: ["get", "list", "watch", "update"] 35 | - apiGroups: ["storage.k8s.io"] 36 | resources: ["storageclasses"] 37 | verbs: ["get", "list", "watch"] 38 | - apiGroups: [""] 39 | resources: ["events"] 40 | verbs: ["list", "watch", "create", "update", "patch"] 41 | - apiGroups: ["snapshot.storage.k8s.io"] 42 | resources: ["volumesnapshots"] 43 | verbs: ["get", "list"] 44 | - apiGroups: ["snapshot.storage.k8s.io"] 45 | resources: ["volumesnapshotcontents"] 46 | verbs: ["get", "list"] 47 | - apiGroups: ["storage.k8s.io"] 48 | resources: ["csinodes"] 49 | verbs: ["get", "list", "watch"] 50 | - apiGroups: [""] 51 | resources: ["nodes"] 52 | verbs: ["get", "list", "watch"] 53 | # Access to volumeattachments is only needed when the CSI driver 54 | # has the PUBLISH_UNPUBLISH_VOLUME controller capability. 55 | # In that case, external-provisioner will watch volumeattachments 56 | # to determine when it is safe to delete a volume. 57 | - apiGroups: ["storage.k8s.io"] 58 | resources: ["volumeattachments"] 59 | verbs: ["get", "list", "watch"] 60 | 61 | --- 62 | kind: ClusterRoleBinding 63 | apiVersion: rbac.authorization.k8s.io/v1 64 | metadata: 65 | name: crc-hostpath-csi-provisioner-role 66 | subjects: 67 | - kind: ServiceAccount 68 | name: csi-provisioner 69 | # replace with non-default namespace name 70 | namespace: hostpath-provisioner 71 | roleRef: 72 | kind: ClusterRole 73 | name: crc-hostpath-external-provisioner-runner 74 | apiGroup: rbac.authorization.k8s.io 75 | 76 | --- 77 | # Provisioner must be able to work with endpoints in current namespace 78 | # if (and only if) leadership election is enabled 79 | kind: Role 80 | apiVersion: rbac.authorization.k8s.io/v1 81 | metadata: 82 | # replace with non-default namespace name 83 | namespace: hostpath-provisioner 84 | name: external-provisioner-cfg 85 | rules: 86 | # Only one of the following rules for endpoints or leases is required based on 87 | # what is set for `--leader-election-type`. Endpoints are deprecated in favor of Leases. 88 | - apiGroups: [""] 89 | resources: ["endpoints"] 90 | verbs: ["get", "watch", "list", "delete", "update", "create"] 91 | - apiGroups: ["coordination.k8s.io"] 92 | resources: ["leases"] 93 | verbs: ["get", "watch", "list", "delete", "update", "create"] 94 | # Permissions for CSIStorageCapacity are only needed enabling the publishing 95 | # of storage capacity information. 96 | - apiGroups: ["storage.k8s.io"] 97 | resources: ["csistoragecapacities"] 98 | verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 99 | # The GET permissions below are needed for walking up the ownership chain 100 | # for CSIStorageCapacity. They are sufficient for deployment via 101 | # StatefulSet (only needs to get Pod) and Deployment (needs to get 102 | # Pod and then ReplicaSet to find the Deployment). 103 | - apiGroups: [""] 104 | resources: ["pods"] 105 | verbs: ["get"] 106 | - apiGroups: ["apps"] 107 | resources: ["replicasets"] 108 | verbs: ["get"] 109 | 110 | --- 111 | kind: RoleBinding 112 | apiVersion: rbac.authorization.k8s.io/v1 113 | metadata: 114 | name: csi-provisioner-role-cfg 115 | # replace with non-default namespace name 116 | namespace: hostpath-provisioner 117 | subjects: 118 | - kind: ServiceAccount 119 | name: csi-provisioner 120 | # replace with non-default namespace name 121 | namespace: hostpath-provisioner 122 | roleRef: 123 | kind: Role 124 | name: external-provisioner-cfg 125 | apiGroup: rbac.authorization.k8s.io 126 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/kubevirt-hostpath-security-constraints-csi.yaml: -------------------------------------------------------------------------------- 1 | kind: SecurityContextConstraints 2 | apiVersion: security.openshift.io/v1 3 | metadata: 4 | name: hostpath-provisioner 5 | allowPrivilegedContainer: true 6 | requiredDropCapabilities: 7 | - KILL 8 | - MKNOD 9 | - SETUID 10 | - SETGID 11 | runAsUser: 12 | type: RunAsAny 13 | seLinuxContext: 14 | type: RunAsAny 15 | fsGroup: 16 | type: RunAsAny 17 | supplementalGroups: 18 | type: RunAsAny 19 | allowHostDirVolumePlugin: true 20 | readOnlyRootFilesystem: false 21 | allowHostNetwork: true 22 | users: 23 | - system:serviceaccount:hostpath-provisioner:csi-hostpath-provisioner-sa 24 | -------------------------------------------------------------------------------- /kubevirt-hostpath-provisioner-csi/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: hostpath-provisioner 5 | -------------------------------------------------------------------------------- /login.html.patch: -------------------------------------------------------------------------------- 1 | --- login.html.reference 2021-05-03 10:05:31.067489685 +0200 2 | +++ login.html 2021-05-03 10:05:43.947556555 +0200 3 | @@ -253,6 +253,14 @@ 4 | 5 | 6 |
7 | +

8 | + 11 | + Open a terminal and run 'crc console --credentials' to get your credentials. 12 | +

13 | +
14 | +
15 | {{ if .Error }} 16 |

17 | Username 20 | 21 | 22 | - 23 | + 24 |

25 |
26 |