├── LICENSE ├── README.md ├── olm-operator.sh └── redhat-operator-index.md /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenShift4 Offline Operator Mirror and Upgrade 2 | 3 | > :heavy_exclamation_mark: *Red Hat support cannot assist with problems with this Repo*. 4 | 5 | This script will create a custom operator catalog based on the desired operators and mirror the images to a local registry, useful for air-gapped (disconnected) or restricted networks. Tested with OpenShift 4.6.3. 6 | 7 | What is the purpose of this? 8 | 9 | Because the current catalog build and mirror (https://docs.openshift.com/container-platform/4.6/operators/olm-restricted-networks.html) takes 1-5 hours to create and more than 50% of the catalog is not usable offline anyways. This tool allows you to create a custom catalog with only the operators you need/want. 10 | 11 | 12 | ## Prerequisites 13 | Be sure you have registry authentication tokens setup, it makes life easier. 14 | https://access.redhat.com/RegistryAuthentication 15 | https://access.redhat.com/terms-based-registry/ 16 | 17 | 18 | ## Requirements 19 | 20 | It is assumed you already have a registry setup locally to mirror operator content to. See the section Local Docker Registry for an example implementation. 21 | 22 | This tool was tested with the following versions of the runtime and utilities: 23 | 24 | 1. RHEL 8.2 25 | 2. Podman v1.9.3 (If you use anything below 1.8, you might run into issues with multi-arch manifests) 26 | 3. Skopeo 1.0.0 (If you use anything below 1.0 you might have issue with the newer manifests) 27 | 4. OPM CLI 28 | 29 | Please note this ideally works best with operators that meet the following criteria: 30 | 31 | 1. Have a ClusterServiceVersion (CSV) in the manifest that contains a full list of related images 32 | 2. The related images are tagged with a SHA 33 | 34 | For a full list of operators that work offline please see link below 35 | 36 | 37 | ## Installing OPM CLI 38 | 1. `oc image extract registry.redhat.io/openshift4/ose-operator-registry:v4.6 --registry-config='~/openshift/pull-secret-full.json' --path /usr/bin/opm:. --confirm` 39 | 2. `sudo chmod +x opm` 40 | 3. `sudo mv opm /usr/local/bin` 41 | 42 | ## Running the script 43 | 44 | 1. `git clone` this repository 45 | 2. Install the tools listed in the requirements section 46 | 3. Login to your offline registry using podman (This is the registry where you will be publishing the catalog and related images) 47 | 4. Login to registry.redhat.io using podman 48 | 5. Modify variables to suit your environment in the script olm-operator.sh. 49 | 6. Launch the script passing an argument to do either a mirror or an upgrade. See for list of supported offline operators that can be mirrored. 50 | 51 | ```Shell 52 | ./olm-operator.sh mirror|upgrade 53 | ``` 54 | 55 | 7. Disable default operator source. This only needs to be done once for a cluster. 56 | ```Shell 57 | oc patch OperatorHub cluster --type json -p '[{"op": "add", "path": "/spec/disableAllDefaultSources", "value": true}]' 58 | ``` 59 | 8. Apply the two yaml files in the `redhat-operator-index-manifests` folder via `oc apply -f`. The image content source policy will create a new MCO render, which will start a rolling reboot of your cluster nodes. You have to wait until that is complete before attempting to install operators from the catalog. 60 | 61 | 62 | ## Script Notes 63 | 64 | Placeholders have been left for other Operator catalogs. 65 | 66 | ## Local Docker Registry 67 | 68 | If you need a to create a local secured registry, follow the instructions from this link: 69 | 70 | 71 | ## Acknowledgements 72 | 73 | PRs welcome! 74 | -------------------------------------------------------------------------------- /olm-operator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # Disconnected Operator Catalog Mirror and Minor Upgrade 3 | # Variables to set, suit to your installation 4 | 5 | export OCP_RELEASE=4.6 6 | export OCP_RELEASE_FULL=$OCP_RELEASE.3 7 | export ARCHITECTURE=x86_64 8 | export SIGNATURE_BASE64_FILE="signature-sha256-$OCP_RELEASE_FULL.yaml" 9 | export OCP_PULLSECRET_AUTHFILE='../../pull-secret-full.json' 10 | export LOCAL_REGISTRY=registry.pod2.dcain.lab:5000 11 | export LOCAL_REGISTRY_MIRROR_TAG=/ocp4/openshift4 12 | export LOCAL_REGISTRY_INDEX_TAG=olm-index/redhat-operator-index:v$OCP_RELEASE 13 | export LOCAL_REGISTRY_IMAGE_TAG=olm 14 | 15 | # Set these values to true for the catalog and miror to be created 16 | export RH_OP='true' 17 | export CERT_OP='false' 18 | export COMM_OP='false' 19 | export MARKETPLACE_OP='false' 20 | 21 | export RH_OP_INDEX="registry.redhat.io/redhat/redhat-operator-index:v${OCP_RELEASE}" 22 | export CERT_OP_INDEX="registry.redhat.io/redhat/certified-operator-index:v${OCP_RELEASE}" 23 | export COMM_OP_INDEX="registry.redhat.io/redhat/community-operator-index:v${OCP_RELEASE}" 24 | export MARKETPLACE_OP_INDEX="registry.redhat.io/redhat-marketplace-index:v${OCP_RELEASE}" 25 | export RH_OP_PACKAGES='advanced-cluster-management,cluster-logging,kubevirt-hyperconverged,local-storage-operator,ocs-operator,performance-addon-operator,ptp-operator,sriov-network-operator' 26 | 27 | if [ $# -lt 1 ] 28 | then 29 | echo "Usage : $0 mirror|mirror-olm|upgrade" 30 | exit 31 | fi 32 | 33 | mirror () { 34 | # Mirror redhat-operator index image 35 | 36 | if [ "${RH_OP}" = true ] 37 | then 38 | opm index prune --from-index $RH_OP_INDEX --packages $RH_OP_PACKAGES --tag $LOCAL_REGISTRY/$LOCAL_REGISTRY_INDEX_TAG 39 | GODEBUG=x509ignoreCN=0 podman push --tls-verify=false $LOCAL_REGISTRY/$LOCAL_REGISTRY_INDEX_TAG --authfile $OCP_PULLSECRET_AUTHFILE 40 | GODEBUG=x509ignoreCN=0 oc adm catalog mirror $LOCAL_REGISTRY/$LOCAL_REGISTRY_INDEX_TAG $LOCAL_REGISTRY/$LOCAL_REGISTRY_IMAGE_TAG --registry-config=$OCP_PULLSECRET_AUTHFILE 41 | 42 | cat > redhat-operator-index-manifests/catalogsource.yaml << EOF 43 | apiVersion: operators.coreos.com/v1alpha1 44 | kind: CatalogSource 45 | metadata: 46 | name: my-operator-catalog 47 | namespace: openshift-marketplace 48 | spec: 49 | sourceType: grpc 50 | image: $LOCAL_REGISTRY/$LOCAL_REGISTRY_INDEX_TAG 51 | displayName: Temp Lab 52 | publisher: templab 53 | updateStrategy: 54 | registryPoll: 55 | interval: 30m 56 | EOF 57 | 58 | echo "" 59 | echo "To apply the Red Hat Operators catalog mirror configuration to your cluster, do the following once per cluster:" 60 | echo "oc apply -f ./redhat-operator-index-manifests/imageContentSourcePolicy.yaml" 61 | echo "oc apply -f ./redhat-operator-index-manifests/catalogsource.yaml" 62 | fi 63 | 64 | if [ "${CERT_OP}" = true ] 65 | then 66 | "echo 1" 67 | fi 68 | 69 | if [ "${COMM_OP}" = true ] 70 | then 71 | "echo 2" 72 | fi 73 | 74 | if [ "${MARKETPLACE_OP}" = true ] 75 | then 76 | "echo 3" 77 | fi 78 | 79 | } 80 | 81 | mirror-olm () { 82 | # hack for broken operators 83 | 84 | for packagemanifest in $(oc get packagemanifest -n openshift-marketplace -o name) ; do 85 | for package in $(oc get $packagemanifest -o jsonpath='{.status.channels[*].currentCSVDesc.relatedImages}' | sed "s/ /\n/g" | tr -d '[],' | sed 's/"/ /g') ; do 86 | skopeo copy docker://$package docker://$LOCAL_REGISTRY/$LOCAL_REGISTRY_IMAGE_TAG/openshift4-$(basename $package) --all --authfile $OCP_PULLSECRET_AUTHFILE 87 | done 88 | done 89 | 90 | } 91 | 92 | upgrade () { 93 | # output ConfigMap for disconnected upgrade, issue guidance on mirroring 94 | 95 | DIGEST="$(oc adm release info quay.io/openshift-release-dev/ocp-release:${OCP_RELEASE_FULL}-${ARCHITECTURE} | sed -n 's/Pull From: .*@//p')" 96 | DIGEST_ALGO="${DIGEST%%:*}" 97 | DIGEST_ENCODED="${DIGEST#*:}" 98 | SIGNATURE_BASE64=$(curl -s "https://mirror.openshift.com/pub/openshift-v4/signatures/openshift/release/${DIGEST_ALGO}=${DIGEST_ENCODED}/signature-1" | base64 -w0 && echo) 99 | 100 | cat > $SIGNATURE_BASE64_FILE << EOF 101 | apiVersion: v1 102 | kind: ConfigMap 103 | metadata: 104 | name: release-image-${OCP_RELEASE_FULL} 105 | namespace: openshift-config-managed 106 | labels: 107 | release.openshift.io/verification-signatures: "" 108 | binaryData: 109 | ${DIGEST_ALGO}-${DIGEST_ENCODED}: ${SIGNATURE_BASE64} 110 | EOF 111 | 112 | echo "" 113 | echo "To apply the image signature ConfigMap for $OCP_RELEASE_FULL, issue:" 114 | echo "oc apply -f $SIGNATURE_BASE64_FILE" 115 | 116 | echo "" 117 | echo "To start mirroring content for OpenShift $OCP_RELEASE_FULL, issue:" 118 | echo "oc adm release mirror --registry-config $OCP_PULLSECRET_AUTHFILE --from=quay.io/openshift-release-dev/ocp-release@$DIGEST --to=$LOCAL_REGISTRY$LOCAL_REGISTRY_MIRROR_TAG --to-release-image=$LOCAL_REGISTRY$LOCAL_REGISTRY_MIRROR_TAG:${OCP_RELEASE_FULL}-${ARCHITECTURE}" 119 | 120 | echo "" 121 | echo "To initiate the upgrade on the cluster to $OCP_RELEASE_FULL, issue:" 122 | echo "oc adm upgrade --allow-explicit-upgrade --to-image $LOCAL_REGISTRY$LOCAL_REGISTRY_MIRROR_TAG@$DIGEST" 123 | } 124 | 125 | case "$1" in 126 | mirror) 127 | mirror 128 | ;; 129 | mirror-olm) 130 | mirror-olm 131 | ;; 132 | upgrade) 133 | upgrade 134 | ;; 135 | *) 136 | echo $"Usage: $0 mirror|mirror-olm|upgrade" 137 | exit 1 138 | esac 139 | 140 | exit 0 141 | -------------------------------------------------------------------------------- /redhat-operator-index.md: -------------------------------------------------------------------------------- 1 | # Pruning or looking at index images 2 | This is a helpful utility to see all the operators that can be mirrored, from the bastion system: 3 | 4 | 1. `curl https://github.com/fullstorydev/grpcurl/releases/download/v1.7.0/grpcurl_1.7.0_linux_x86_64.tar.gz` 5 | 2. `tar -xvzf grpcurl_1.7.0_linux_x86_64.tar.gz` 6 | 3. `mv grpcurl /usr/local/bin` 7 | 3. `podman run --authfile pull-secret-full.json -p50051:50051 -it registry.redhat.io/redhat/redhat-operator-index:v4.6` 8 | 9 | ## Looking at the Index using grpcurl 10 | Using another terminal window on the bastion system: 11 | 12 | 1. `grpcurl -plaintext localhost:50051 api.Registry/ListPackages > packages.out` 13 | 2. `cat packages.out` 14 | --------------------------------------------------------------------------------