From e6a0ce708c5760f1ebc2b924bd4942084e6cdc54 Mon Sep 17 00:00:00 2001 From: caroldelwing Date: Tue, 17 Dec 2024 10:29:19 -0300 Subject: [PATCH] Scar Migration - PEM-6444 (#4968) * fix: patch release * docs: add custom security group ingress rules section PCP-1906 (#4781) * docs: add custom security group ingress rules section PCP-1906 * docs: change existing heading * docs: specify aws iaas * docs: VM Migration Assistant (#4737) * docs: VM Migration Assistant draft * docs: fix broken links * doc: heading change * doc: information architecture improvements * doc: minor sub-category change * doc: restructure and additional content * doc: tidy up and additional overview options * doc: some peer review changes * doc: final draft additions * doc: format changes * doc: fix broken RBAC anchor * Apply suggestions from code review * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * doc: adding one line suggestions Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> * ci: auto-formatting prettier issues * docs: resolve longer content suggestions * ci: auto-formatting prettier issues * docs: warm and cold migration steps * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * docs: virt-customize ConfigMap example * docs: Restructure IA * docs: change to headers from tabs * docs: DOC-1490 DOC-1494 Self-Hosted Updates (#4792) * docs: DOC-1490 * docs: added a prereq to install pages * docs: 1494 * docs: apply suggestions from code review Co-authored-by: Lenny Chen <55669665+lennessyy@users.noreply.github.com> * docs: Apply suggestions from code review --------- Co-authored-by: Lenny Chen <55669665+lennessyy@users.noreply.github.com> * docs: resolve vale comments * docs: longform flag * docs: lingering ableist word * docs: resolve Romain's comments * docs: code review suggestions Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> * docs: change lingering tabs to headers * docs: access service console * ci: auto-formatting prettier issues * docs: resolve prettier issue * docs: upgrade Docusaurus 3.6.3 (#4799) * chore: upgrade docusarus * chore: DOC-1495 upgrade docusaurus --------- Co-authored-by: vault-token-factory-spectrocloud[bot] <133815545+vault-token-factory-spectrocloud[bot]@users.noreply.github.com> Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> Co-authored-by: benradstone Co-authored-by: Lenny Chen <55669665+lennessyy@users.noreply.github.com> * docs: Update VM Migration Assistant pack parameters table (#4810) * docs: update pack parameter table * ci: auto-formatting prettier issues * Apply suggestions from code review * ci: auto-formatting prettier issues --------- Co-authored-by: benradstone * docs: add message brokers section PEM-6141 (#4818) * docs: add palette communication section PEM-6141 * docs: fix vale * Apply suggestions from code review Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> * ci: auto-formatting prettier issues * docs: clarify management plane clusters --------- Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> Co-authored-by: addetz * docs: add feature gate to the vm clone guide DOC-1491 (#4827) * docs: add feature gate to the vm clone guide DOC-1491 * docs: change capitalisation of kubevirt * docs: change capitalisation of kubevirt * docs: Palette 4.5.b API docs (#4842) * Palette 4.5.b API docs * ci: auto-formatting API changes --------- Co-authored-by: karl-cardenas-coding Co-authored-by: Karl Cardenas * docs: proxy certificates for earthly builds (#4807) * docs: add docs about proxy certs during build * docs: adjust subheadings * Apply suggestions from code review * docs: update deprecation description * docs: feedback --------- Co-authored-by: Lenny Chen * docs: update cluster profile update guides PEM-6443 (#4859) * docs: update cluster profile update guides PEM-6443 * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * docs: rectify misspelling * ci: auto-formatting prettier issues * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * Update docs/docs-content/profiles/cluster-profiles/modify-cluster-profiles/update-cluster-profile.md Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> * ci: auto-formatting prettier issues --------- Co-authored-by: vault-token-factory-spectrocloud[bot] <133815545+vault-token-factory-spectrocloud[bot]@users.noreply.github.com> Co-authored-by: addetz Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> * docs: add cluster-wide resources backup options PEM-5124 (#4860) * docs: add cluster-wide resources backup options PEM-5124 * docs: add deletion policy flag PEM-5124 * docs: remove tabs * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions --------- Co-authored-by: vault-token-factory-spectrocloud[bot] <133815545+vault-token-factory-spectrocloud[bot]@users.noreply.github.com> * docs: multi-node airgap documentation (#4281) * docs: multi-node airgap documentation * docs: update progress * docs: add delete and scale docs * docs: add prereqs for deletion * docs: add draft * docs: add host unlinking instructions * docs: minor edit * docs: edits * docs: adjust page order * docs: adjust page order * docs: address review feedback * docs: add prerequisites * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * docs: fix broken anchors * docs: proofread * webp convert * docs: add links on index page * docs: typo * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * Optimised images with calibre/image-actions * docs: small change * docs: plural * docs: clarify leader nodes * docs: simplify * Apply suggestions from code review Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> * ci: auto-formatting prettier issues * docs: edit * docs: add warning about local path provisioner --------- Co-authored-by: Lenny Chen Co-authored-by: vault-token-factory-spectrocloud[bot] <133815545+vault-token-factory-spectrocloud[bot]@users.noreply.github.com> Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> Co-authored-by: lennessyy * docs: PE-5647: Allow skipping of node drains when running cluster upgrades for single-node clusters. (#4851) * docs: add instructions for skipping node draining * docs: update parameters * docs: add agent mode * docs: minodr changes from JIRA * docs: adjust page order * docs: add note about always on selectors * docs: small edits * Update docs/docs-content/clusters/edge/cluster-management/skip-draining.md --------- Co-authored-by: Lenny Chen * docs: Adjust wording and examples (#4896) * Adjust wording and examples * ci: auto-formatting prettier issues * docs: update patch * docs: add edits --------- Co-authored-by: kreeuwijk Co-authored-by: Lenny Chen * docs: add scar migration guide * docs: convert image * docs: add partials * docs: fix broken link * Optimised images with calibre/image-actions * docs: update palette keyword * docs: remove duplicate entry * docs: Apply suggestions from code review Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> * docs: address review suggestions * docs: address additional suggestions --------- Co-authored-by: Karl Cardenas Co-authored-by: Adelina Simion <43963729+addetz@users.noreply.github.com> Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> Co-authored-by: vault-token-factory-spectrocloud[bot] <133815545+vault-token-factory-spectrocloud[bot]@users.noreply.github.com> Co-authored-by: Karl Cardenas <29551334+karl-cardenas-coding@users.noreply.github.com> Co-authored-by: benradstone Co-authored-by: Lenny Chen <55669665+lennessyy@users.noreply.github.com> Co-authored-by: addetz Co-authored-by: Ravikumar Kondepati Co-authored-by: karl-cardenas-coding Co-authored-by: Lenny Chen Co-authored-by: lennessyy Co-authored-by: Kevin Reeuwijk Co-authored-by: kreeuwijk --- _partials/self-hosted/_scar-migration.mdx | 396 ++++++++++++++++++ .../system-management/scar-migration.md | 16 + .../system-management/scar-migration.md | 16 + ...sion_system-management_scar-migration.webp | Bin 0 -> 10548 bytes 4 files changed, 428 insertions(+) create mode 100644 _partials/self-hosted/_scar-migration.mdx create mode 100644 docs/docs-content/enterprise-version/system-management/scar-migration.md create mode 100644 docs/docs-content/vertex/system-management/scar-migration.md create mode 100644 static/assets/docs/images/enterprise-version_system-management_scar-migration.webp diff --git a/_partials/self-hosted/_scar-migration.mdx b/_partials/self-hosted/_scar-migration.mdx new file mode 100644 index 0000000000..c3cfb5bddb --- /dev/null +++ b/_partials/self-hosted/_scar-migration.mdx @@ -0,0 +1,396 @@ +--- +partial_category: self-hosted +partial_name: scar-migration +--- + +The {props.edition} installation process requires users to configure and maintain an HTTP server to host {props.edition} manifests. This +server is known as the Spectro Cloud Artifact Regisry (SCAR). Alternatively, users now have the option to migrate these +manifests to the same OCI registry that hosts the {props.edition} images and packs. This migration is handled by a service +called Specman, which fetches the manifests from the OCI registry and serves them via an internal HTTP server. + +The migration process involves two main steps: + +- Pushing the {props.edition} manifests to the OCI registry. +- Updating the SCAR endpoint to point to the new internal HTTP server. + +Once the migration is complete, there is no longer a need to maintain a separate file server exclusively for hosting the +{props.edition} manifests. + +This guide will direct you through the steps required to push the {props.edition} manifests to the OCI registry and update the +SCAR endpoint. + +## Prerequisites + +- A deployed self-hosted {props.edition} that uses a customer-managed SCAR to host {props.edition} + manifests. +- Access to the {props.edition} cluster kubeconfig file to verify the SCAR endpoint. + + :::tip + + If you deployed {props.edition} using the Palette CLI, you can download the kubeconfig file from the {props.edition} cluster details + page in the system console. Navigate to the **Enterprise Cluster Migration** page and click on the **Admin + Kubeconfig** link to download the kubeconfig file. If you deployed {props.edition} to an existing Kubernetes cluster, contact + your cluster administrator to obtain the kubeconfig file. For instructions on using the kubeconfig file to access your + cluster, refer to the . + + ::: + +- Access to the file server that hosts the {props.edition} manifests. +- The {props.edition} cluster must have been upgraded to version `4.5.13` or later. This is required for the SCAR migration to + function properly. +- Access to the {props.edition} system console. +- Ensure the following software is installed and available in the environment hosting the file server. For example, if + you deployed an airgapped instance of {props.edition} to VMware using an , these tools must be available on your airgap support VM. + + - [tar](https://www.gnu.org/software/tar/) + - [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) - Required only for AWS + ECR. + - [ORAS](https://oras.land/docs/installation/) v1.0.0 + + :::warning + + This specific version of ORAS is explicitly required for pushing packs to OCI registries. + + ::: + +- Ensure the following software is installed and available locally on your workstation. + - [curl](https://curl.se/docs/install.html) + - [jq](https://jqlang.github.io/jq/download/) + - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/) + +## Migrate SCAR + +1. In a terminal with connectivity to your {props.edition} cluster, delete any existing secrets named `spectro-manifest-registry-secrets` in the `hubble-system` namespace. + + ```shell + kubectl delete secret spectro-manifest-registry-secrets --nampespace hubble-system + ``` + + ```text hideClipboard + secret "spectro-manifest-registry-secrets" deleted + ``` + +2. Next, open a terminal window in the environment hosting the file server and navigate to the folder where the {props.edition} + manifests are stored. For example, if you deployed an airgapped instance of {props.edition} to VMware using an , navigate to the `/var/www/html/` + directory. + + ```shell + cd /var/www/html/ + ``` + + Alternatively, if you deployed {props.edition} in an airgapped Kubernetes environment using , navigate to the directory served by the file server you configured. + +3. Compress the folder contents into an archive file called `manifests.tgz`. Issue the following command to create the + archive. + + ```shell + tar -czvf manifests.tgz . + ``` + +4. After compressing the files, authenticate with the OCI registry that hosts the {props.edition} images and packs. + + :::tip + + If you deployed an airgapped instance of {props.edition} to VMware using an , the OCI registry address is provided by the `airgap-setup.sh` script output. Alternatively, if you + deployed {props.edition} to an existing Kubernetes cluster using , contact your cluster administrator for the OCI + registry configuration. + + ::: + + + + + + Use `oras` to log in to your OCI registry. Replace the values below with your environment configuration. For + additional information about CLI flags and examples, check out the + [oras login](https://oras.land/docs/commands/oras_login) documentation. Replace `` with the address + of your Harbor registry without the `https://` prefix, and `` and `` with your + Harbor credentials. + + ```shell + oras login --username --password + ``` + + If you are using a Harbor registry with a self-signed certificate, you must add the `--insecure` flag according to the following example. + + ```shell + oras login --insecure --username --password + ``` + + If the login is successful, you will receive the following confirmation message. + + ```hideClipboard + Login Succeeded + ``` + + + + + + Authenticate to your ECR registry using the `aws ecr get-login-password` command. This command generates an ECR + authorization token, which is then passed to the `oras login` command with `AWS` as username. Replace `` + with the AWS region where your ECR registry is configured, and `` with your AWS account ID. + + ```bash + aws ecr get-login-password --region | oras login --username AWS --password-stdin .dkr.ecr..amazonaws.com + ``` + + If the login is successful, you will receive the following confirmation message. + + ```hideClipboard + Login Succeeded + ``` + + + + + +5. Push the `manifests.tgz` file to your OCI registry. + + + + + Issue the following command to push the `manifests.tgz` file to your Harbor registry. Replace `` with the address of your Harbor registry. + + ```shell + oras push /spectro-packs/spectro-manifests/manifest:0.0.0 manifests.tgz + ``` + + + + + + Issue the following command to push the `manifests.tgz` file to your ECR registry. Replace `` with the AWS region where your ECR registry is configured and `` with your AWS account ID. + + ```shell + oras push .dkr.ecr..amazonaws.com/spectro-packs/spectro-manifests/manifest:0.0.0 manifests.tgz + ``` + + + + + +6. Next, login to the {props.edition} system console and select **Administration** from the left **Main Menu**. + +7. Select the **Pack Registries** tab, click the **three-dot Menu** at the end of the OCI registry row, and then select **Edit**. + +8. Check the **Contains Spectro Manifests** box, click **Validate**, and then click **Confirm**. + + ![View of the 'Contains Spectro Manifests' OCI registry box.](/enterprise-version_system-management_scar-migration.webp) + +9. In a terminal with connectivity to your {props.edition} cluster, issue the following command to verify that the `Specman` + service is fetching the content pushed to the OCI registry in step **5** of this guide, with the tag `0.0.0`. + + ```shell + kubectl logs --namespace hubble-system specman-0 + ``` + + ```text hideClipboard + time="2024-12-06T12:43:14Z" level=info msg="Syncing with OCI repo" + time="2024-12-06T12:43:14Z" level=info msg="tags[4.5.11 4.5.13 0.0.0]" + time="2024-12-06T12:43:14Z" level=info msg="Downloading 0.0.0" + time="2024-12-06T12:43:14Z" level=info msg="tags[4.5.11 4.5.13 0.0.0]" + time="2024-12-06T12:43:14Z" level=info msg="Downloading 0.0.0" + time="2024-12-06T12:43:14Z" level=info msg="listing dir /tmp/0.0.03808764833" + time="2024-12-06T12:43:14Z" level=info msg="filename: manifests.tgz, isDir: false" + time="2024-12-06T12:43:14Z" level=info msg="Persisting 0.0.0" + ``` + +10. The final step to complete the migration involves updating the SCAR endpoint to the internal HTTP server endpoint + that now serves the {props.edition} manifests: `https://specman-service.hubble-system.svc.cluster.local:8443`. Issue the + following command to create the script responsible for updating the endpoint. + + ```shell + cat << 'EOF1' > scar-registry-update.sh + #!/bin/bash + ############################################################################### + # Usage: + # ./ec-scar-registry-update.sh https:// admin + ############################################################################### + # + + set -u + set -x + + export ENDPOINT=$1 + export SYSTEM_ADMIN_USERNAME=$2 + export SYSTEM_ADMIN_PASSWORD=$3 + + export SCAR_ENDPOINT=https://specman-service.hubble-system.svc.cluster.local:8443 + export SCAR_USERNAME= + export SCAR_PASSWORD= + + auth_request() { + cat <` with the address of your {props.edition} instance and + `` with the system administrator password. + + ```shell + ./scar-registry-update.sh admin + ``` + + Consider the following example for reference. + + ```shell hideClipboard + ./scar-registry-update.sh https://example.spectrocloud.com admin examplepassword + ``` + + The following message confirms that the script has completed its tasks. + + ```text hideClipboard + Wait for 5 minutes for the sync process to complete. + ``` + You have now migrated SCAR to the OCI registry that hosts the {props.edition} images and packs. In subsequent releases, the {props.edition} airgap installation binary will handle pushing the new manifest to the OCI registry. + +## Validate + +Use the following steps to verify that the endpoint was updated successfully. + +1. Export your {props.edition} credentials as environment variables. Replace `` with the +address of your {props.edition} cluster and `` with the system administrator password. + + ```shell + export ENDPOINT= + export PASSWORD= + ``` + +2. Log in to the Palette System API using the `/v1/auth/syslogin` endpoint. The response will contain the authentication token that you will use in the next request. + + ```shell + AUTH_TOKEN=$(curl --location "${ENDPOINT}/v1/auth/syslogin" \ + --header 'Content-Type: application/json' \ + --data '{ + "username": "admin", + "password": "'${PASSWORD}'" + }' | jq ."Authorization") + ``` + + :::tip + + If your cluster is using the default self-signed certificate, you can use the `--insecure` flag with the `curl` commands + to bypass the certificate check. + + ::: + +3. Use the `/v1/system/config/scar` endpoint to confirm that the SCAR endpoint has been correctly updated. + + ```shell + curl --location "${ENDPOINT}/v1/system/config/scar" \ + --header "Cookie: Authorization=${AUTH_TOKEN}" + ``` + + The output should contain the updated SCAR endpoint. + + ```text hideClipboard + {"endpoint":"https://specman-service.hubble-system.svc.cluster.local:8443"} + ``` \ No newline at end of file diff --git a/docs/docs-content/enterprise-version/system-management/scar-migration.md b/docs/docs-content/enterprise-version/system-management/scar-migration.md new file mode 100644 index 0000000000..d7dacd64ae --- /dev/null +++ b/docs/docs-content/enterprise-version/system-management/scar-migration.md @@ -0,0 +1,16 @@ +--- +sidebar_label: "Migrate SCAR to OCI Registry" +title: "Migrate Customer-Managed SCAR to OCI Registry" +description: + "Learn how to migrate the Spectro Cloud Artifact Regisry (SCAR) content to the OCI registry used to host packs and + images." +icon: "" +hide_table_of_contents: false +sidebar_position: 125 +tags: ["enterprise", "management", "scar"] +keywords: ["self-hosted", "enterprise"] +--- + +import ScarMigration from "../../../../_partials/self-hosted/_scar-migration.mdx"; + + diff --git a/docs/docs-content/vertex/system-management/scar-migration.md b/docs/docs-content/vertex/system-management/scar-migration.md new file mode 100644 index 0000000000..b42ef7eed9 --- /dev/null +++ b/docs/docs-content/vertex/system-management/scar-migration.md @@ -0,0 +1,16 @@ +--- +sidebar_label: "Migrate SCAR to OCI Registry" +title: "Migrate Customer-Managed SCAR to OCI Registry" +description: + "Learn how to migrate the Spectro Cloud Artifact Regisry (SCAR) content to the OCI registry used to host packs and + images." +icon: "" +hide_table_of_contents: false +sidebar_position: 125 +tags: ["vertex", "management", "scar"] +keywords: ["self-hosted", "vertex"] +--- + +import ScarMigration from "../../../../_partials/self-hosted/_scar-migration.mdx"; + + diff --git a/static/assets/docs/images/enterprise-version_system-management_scar-migration.webp b/static/assets/docs/images/enterprise-version_system-management_scar-migration.webp new file mode 100644 index 0000000000000000000000000000000000000000..f0db661997a156486e67a43c42f51aa54dc32b97 GIT binary patch literal 10548 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
crC{e+PP(k-j-1 zcZe$8?8I1r@qL5GiPG-HrzR?^5}0S}p$ZjRdG*ja}1H?ZL5_!E63PXi-y0=k!tALAu?dE>CD z9ePvvzPA?DFSDefsZnM;r=A*Fe^h8gzrvQ1u=N^5liCq_KKd^&10J>K^uR77N>h{` zvsCDQjW*qIb?D{@jSHIvPYdYxf?G}HJJUvmd?WBNG?(QYqqm<1;f+L+#u+o8{F+B| z{HTgfr}GsLb(SR|KFEtA3j6Dg{!mRY{H~kBGsx@A;r^-R6yFIh+^RE$Poh0ofUb&^ zqS4uaWc;$WI+0D1*kyj05SE;>yj#_TrkX_ZThH`{Q3t^_Wzq!q1qV{8-4Fq(sHm8i z=;E6d&o^cb;#>^V?VyCHW`yXnlpzRB$3;d0pj$2lFW#ezI6C8;cc_4XI|GN=1yq_! zx3@j^F{#C;Q`T}cxF<#tUkT6Z&C$Y}GyjGLGff}-rSDp$p|xV{rL^D@ui+fv7}OiL zON z+W-Kpid%a81j}D#+Jn!T{ZNS})AWHf&fl7vGZaUTvum*4(!s**xDDJy8Fr={@2x}i zO8g+%2jr(Q#zF`ugFJc4cW?%x?W^ct1QD>XY0SffltIY2BPJjwfrGVodwRatB?2uJ zRX(pVXD3b%@5-Bs19b1~8tAj;c&c8WwH`hP_Sx|a&7X#bWh@I@DWKq5^k#l~%XS&K zG*tF#=EW$|jUL`nR*9gLlJ(O=uvNFAgFpI=197@O{JC2C)&HO;>E-7Y*z8*yNfW+_ zbwyqtQdLi!)f`T`V6U97e7tv7`!tF@h=XUUlm?pLZHi#y;w~(-e7%V`;AJMtyqTc% z2c}&<6pQnlsQ~-AvrS6{Qh%MIVVd{?J$Rk$t)#tHk{Z4=zbS@nouvH#~=RjdO!?y@Jw!ltz`+!?hno^|C%q zc0w=^4)ds9^%s;=BG3CJP`E2gK$n}FBr8nL&s=fBQ1`D3`kQ9CHnM1yXOxoj=kuiv zj?b^N5rWsZMZ1bqS|N?gPTZ?b`U4#e5#J%8bj}izMaAEpjUF%8dd0pf=jkq}oLE9D zxYad3b{`63X}Cbusv%uk$dj zB3mE(fhn`kye(`d1r#1FwA5M*n-3}~*k;yftIw8rcw%Me`7T@fMyy9K0d3E?1Cayx zU60unODDyLxDHnbp+COp9)uXhw3NnYZ)y86Mxv#RHw@f)9wFVZ;~{$4??t20lK!eD zMtaaHOY=OP)^TqXW*7--U<$Gq6nsg3$$_Y@x5%#s+5VJfrN-H>OD?PF)H`IOFMaXG zIichZ;(@*K2j&i})s>5&XdwX^90!CnVUPH1si}N$F`UG%z*jpsbD3^S!)F3rU4E)b zmnAf}YDXeFRkIM)6v~NHE0*yxQPIsQ-ie9mUq)!AcU*I&Rv)TaEZ~Z+KX;jJ?oPV` z3hc(T?%0~%~c)B2L!d- zn;G+Ztdm+l#XB!%@A7W5-DDU4TAG%1PeAa=SS-IU4WMQrF{NRdmwhc=!GERrbRhlp z3gdihDKo;ZO9?~f9z8INJ95B0yZnc~fDV6VlAqcM+1Ie)qwu+>I|k%6Y2)ydYJK}Y zbH3;N#%=E@Skv;Maw54`8O4M(|HX(1n#KFG?7(cTJfS>KIMnBG2TJG`?=t~bqPjac5dN14J@hHuViWhYX z1nkeGm&6X`-Gyo`b&}G}9m~$%7kSkhC#z_%^kY)d{}M!S{N?(sQJb_w1|1L$|GMBb zu71F9nj+T8;rSCT*<@V|*;!fh0dhatTS9MRwHAXOsKaE>l4@nA+Ym}}pkv^T-p35x x7d8f0w2dv_dY2=Ofj%hjF(|gNtV@|#*9QPt`XLpZDlIzY5R=#qJzE+A{uj1!rR4ws literal 0 HcmV?d00001