From 6c5fdab45c573950c1710136b79a9111b84fb54a Mon Sep 17 00:00:00 2001 From: Tarun Pothulapati Date: Wed, 8 Jun 2022 12:15:40 +0000 Subject: [PATCH] [self-hosted] Gitpod local preview install method Fixes https://github.com/gitpod-io/gitpod/issues/9075 This PR adds a new install method called `preview` under the `install` directory. This includes a sh script i.e `entrypoint.sh` that gets loaded into a docker container in the `Dockerfile`. This `entrypoint.sh` does the following: - Checks for minimum system requirements - Generates a root certificate using `mkcerts`, and loads into the host's `/tmp/gitpod/gitpod-ca.crt`. - Renders `cert-manager` resources, self-signed Gitpod into `/var/lib/rancher/k3s/server/manifests`. - Initialises `k3s` inside the container. Signed-off-by: Tarun Pothulapati --- components/BUILD.yaml | 1 + install/preview/BUILD.yaml | 14 +++ install/preview/README.md | 27 +++++ install/preview/entrypoint.sh | 131 ++++++++++++++++++++++ install/preview/leeway.Dockerfile | 22 ++++ install/preview/manifests/messagebus.yaml | 17 +++ 6 files changed, 212 insertions(+) create mode 100644 install/preview/BUILD.yaml create mode 100644 install/preview/README.md create mode 100755 install/preview/entrypoint.sh create mode 100644 install/preview/leeway.Dockerfile create mode 100644 install/preview/manifests/messagebus.yaml diff --git a/components/BUILD.yaml b/components/BUILD.yaml index b050a8a981a47f..dec60886ca14da 100644 --- a/components/BUILD.yaml +++ b/components/BUILD.yaml @@ -13,6 +13,7 @@ packages: - :publish-api - dev:all-app - install/installer:docker + - install/preview:docker - install/kots:lint - components/gitpod-protocol:all - operations/observability/mixins:lint diff --git a/install/preview/BUILD.yaml b/install/preview/BUILD.yaml new file mode 100644 index 00000000000000..93fb8c1b414c2d --- /dev/null +++ b/install/preview/BUILD.yaml @@ -0,0 +1,14 @@ +packages: + - name: docker + type: docker + deps: + - install/installer:app + argdeps: + - imageRepoBase + srcs: + - "entrypoint.sh" + - "manifests/*.yaml" + config: + dockerfile: leeway.Dockerfile + image: + - ${imageRepoBase}/preview-install:${version} diff --git a/install/preview/README.md b/install/preview/README.md new file mode 100644 index 00000000000000..bde75075853157 --- /dev/null +++ b/install/preview/README.md @@ -0,0 +1,27 @@ +# Gitpod Preview Installation + +This repo helps users to try out and preview self-hosted Gitpod **locally** without all the things +needed for a production instance. The aim is to provide an installation mechanism as minimal and +simple as possible. + +## Installation + +```bash +docker run --privileged --name gitpod --rm -it -v /tmp/gitpod:/var/gitpod eu.gcr.io/gitpod-core-dev/build/preview-install:tar-preview-install.4 +``` + +Once the above command starts running and the pods are ready (can be checked by running `docker exec gitpod kubectl get pods`), +The URL to access your gitpod instance can be retrieved by running + +``` +docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' gitpod | sed -r 's/[.]+/-/g' | sed 's/$/.nip.io/g' +``` + +[nip.io](https://nip.io/) is just wildcard DNS for local addresses, So all off this is local, and cannot be accessed over the internet. + +As the `self-hosted` instance is self-signed, The root certificate to upload into your browser trust store to access the URL is available at +`/tmp/gitpod/gitpod-ca.crt`. + +## Known Issues + +- Prebuilds don't work as they require webhooks support over the internet. diff --git a/install/preview/entrypoint.sh b/install/preview/entrypoint.sh new file mode 100755 index 00000000000000..860d5510954b13 --- /dev/null +++ b/install/preview/entrypoint.sh @@ -0,0 +1,131 @@ +#!/bin/sh +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + + +set -ex + +# check for minimum requirements +REQUIRED_MEM_KB=$((6 * 1024 * 1024)) +total_mem_kb=$(awk '/MemTotal:/ {print $2}' /proc/meminfo) +if [ "${total_mem_kb}" -lt "${REQUIRED_MEM_KB}" ]; then + echo "Preview installation of Gitpod requires a system with at least 6GB of memory" + exit 1 +fi + +REQUIRED_CORES=4 +total_cores=$(nproc) +if [ "${total_cores}" -lt "${REQUIRED_CORES}" ]; then + echo "Preview installation of Gitpod requires a system with at least 4 CPU Cores" + exit 1 +fi + +# Get container's IP address +if [ -z "${DOMAIN}" ]; then + NODE_IP=$(hostname -i) + DOMAIN_STRING=$(echo "${NODE_IP}" | sed "s/\./-/g") + DOMAIN="${DOMAIN_STRING}.nip.io" +fi + +echo "Gitpod Domain: $DOMAIN" + +if [ -f /sys/fs/cgroup/cgroup.controllers ]; then + echo "[$(date -Iseconds)] [CgroupV2 Fix] Evacuating Root Cgroup ..." + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + mkdir -p /sys/fs/cgroup/init + busybox xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' <"/sys/fs/cgroup/cgroup.controllers" >"/sys/fs/cgroup/cgroup.subtree_control" + echo "[$(date -Iseconds)] [CgroupV2 Fix] Done" +fi + +mount --make-shared /sys/fs/cgroup +mount --make-shared /proc +mount --make-shared /var/gitpod + +# install in local store +mkcert -install +cat "${HOME}"/.local/share/mkcert/rootCA.pem >> /etc/ssl/certs/ca-certificates.crt +# also send root cert into a volume +cat "${HOME}"/.local/share/mkcert/rootCA.pem > /var/gitpod/gitpod-ca.crt + +cat << EOF > /var/lib/rancher/k3s/server/manifests/ca-pair.yaml +apiVersion: v1 +kind: Secret +metadata: + name: ca-key-pair +data: + ca.crt: $(base64 -w0 "${HOME}"/.local/share/mkcert/rootCA.pem) + tls.crt: $(base64 -w0 "${HOME}"/.local/share/mkcert/rootCA.pem) + tls.key: $(base64 -w0 "${HOME}"/.local/share/mkcert/rootCA-key.pem) +EOF + +cat << EOF > /var/lib/rancher/k3s/server/manifests/issuer.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-issuer +spec: + ca: + secretName: ca-key-pair +EOF + +echo "creating Gitpod SSL secret..." +cat << EOF > /var/lib/rancher/k3s/server/manifests/https-cert.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: https-cert +spec: + secretName: https-certificates + issuerRef: + name: ca-issuer + kind: Issuer + dnsNames: + - "$DOMAIN" + - "*.$DOMAIN" + - "*.ws.$DOMAIN" +EOF + +mkdir -p /var/lib/rancher/k3s/server/manifests/gitpod + +/gitpod-installer init > config.yaml +yq e -i '.domain = "'"${DOMAIN}"'"' config.yaml +yq e -i '.certificate.name = "https-certificates"' config.yaml +yq e -i '.certificate.kind = "secret"' config.yaml +yq e -i '.customCACert.name = "ca-key-pair"' config.yaml +yq e -i '.customCACert.kind = "secret"' config.yaml +yq e -i '.observability.logLevel = "debug"' config.yaml +yq e -i '.workspace.runtime.containerdSocket = "/run/k3s/containerd/containerd.sock"' config.yaml +yq e -i '.workspace.runtime.containerdRuntimeDir = "/var/lib/rancher/k3s/agent/containerd/io.containerd.runtime.v2.task/k8s.io/"' config.yaml + +echo "extracting images to download ahead..." +/gitpod-installer render --config config.yaml | grep 'image:' | sed 's/ *//g' | sed 's/image://g' | sed 's/\"//g' | sed 's/^-//g' | sort | uniq > /gitpod-images.txt +echo "downloading images..." +while read -r image "$(cat /gitpod-images.txt)"; do + # shellcheck disable=SC2154 + ctr images pull "$image" >/dev/null & +done + +ctr images pull "docker.io/gitpod/workspace-full:latest" >/dev/null & + +/gitpod-installer render --config config.yaml --output-split-files /var/lib/rancher/k3s/server/manifests/gitpod +for f in /var/lib/rancher/k3s/server/manifests/gitpod/*.yaml; do (cat "$f"; echo) >> /var/lib/rancher/k3s/server/gitpod.debug; done +rm /var/lib/rancher/k3s/server/manifests/gitpod/*NetworkPolicy* +for f in /var/lib/rancher/k3s/server/manifests/gitpod/*PersistentVolumeClaim*.yaml; do yq e -i '.spec.storageClassName="local-path"' "$f"; done +yq eval-all -i ". as \$item ireduce ({}; . *+ \$item)" /var/lib/rancher/k3s/server/manifests/gitpod/*_StatefulSet_messagebus.yaml /app/manifests/messagebus.yaml +for f in /var/lib/rancher/k3s/server/manifests/gitpod/*StatefulSet*.yaml; do yq e -i '.spec.volumeClaimTemplates[0].spec.storageClassName="local-path"' "$f"; done + +# removing init container from ws-daemon (systemd and Ubuntu) +yq eval-all -i 'del(.spec.template.spec.initContainers[0])' /var/lib/rancher/k3s/server/manifests/gitpod/*_DaemonSet_ws-daemon.yaml + +for f in /var/lib/rancher/k3s/server/manifests/gitpod/*.yaml; do (cat "$f"; echo) >> /var/lib/rancher/k3s/server/manifests/gitpod.yaml; done +rm -rf /var/lib/rancher/k3s/server/manifests/gitpod + +/bin/k3s server --disable traefik \ + --node-label gitpod.io/workload_meta=true \ + --node-label gitpod.io/workload_ide=true \ + --node-label gitpod.io/workload_workspace_services=true \ + --node-label gitpod.io/workload_workspace_regular=true \ + --node-label gitpod.io/workload_workspace_headless=true diff --git a/install/preview/leeway.Dockerfile b/install/preview/leeway.Dockerfile new file mode 100644 index 00000000000000..ecfcedbfde39f9 --- /dev/null +++ b/install/preview/leeway.Dockerfile @@ -0,0 +1,22 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +FROM rancher/k3s:v1.21.12-k3s1 + +ADD https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 /bin/mkcert +RUN chmod +x /bin/mkcert + +ADD https://github.com/krallin/tini/releases/download/v0.19.0/tini-static /tini +RUN chmod +x /tini + +ADD https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml /var/lib/rancher/k3s/server/manifests/cert-manager.yaml + +ADD https://github.com/mikefarah/yq/releases/download/v4.25.1/yq_linux_amd64 /bin/yq +RUN chmod +x /bin/yq + +COPY manifests/* /app/manifests/ +COPY install-installer--app/installer /gitpod-installer + +COPY entrypoint.sh /entrypoint.sh + +ENTRYPOINT [ "/tini", "--", "/entrypoint.sh" ] diff --git a/install/preview/manifests/messagebus.yaml b/install/preview/manifests/messagebus.yaml new file mode 100644 index 00000000000000..ccd5816f2905c1 --- /dev/null +++ b/install/preview/manifests/messagebus.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +spec: + volumeClaimTemplates: + - metadata: + creationTimestamp: null + labels: + app: gitpod + component: messagebus + name: messagebus + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi