Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Devcontainers v2 #398

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 68 additions & 19 deletions .devcontainer/Containerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM registry.access.redhat.com/ubi9/nodejs-22:9.5-1730543890

WORKDIR /opt/app-root/src

ARG USERNAME=default
ARG NPM_GLOBAL=/usr/local/share/npm-global

Expand All @@ -10,35 +12,82 @@ USER root

RUN umask 0002

# DEVX: install zsh, oh-my-zsh, vim, jq
RUN dnf install -y zsh && \
curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh | bash && \
sed -i '/^default:/s|:/bin/bash|:/bin/zsh|' /etc/passwd && \
dnf install -y vim jq

ENV ZSH_DISABLE_COMPFIX="true"

# npm configs + perms
RUN groupadd npm && \
usermod -a -G npm ${USERNAME} && \
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) && \
usermod -a -G npm root && \
chown -R ${USERNAME}:npm /usr/local/ && \
mkdir -p /opt/app-root/src/.npm && chown -R ${USERNAME}:npm /opt/app-root/src/ && \
dnf install -y vim
mkdir -p /opt/app-root/src/.npm && chown -R ${USERNAME}:npm /opt/app-root/src/

# install kubectl
ADD install-kubectl.sh /tmp
RUN /tmp/install-kubectl.sh; \
rm /tmp/install-kubectl.sh

# # install kubseal
# ADD install-kubeseal.sh /tmp
# RUN /tmp/install-kubeseal.sh; \
# rm /tmp/install-kubeseal.sh

USER default
# # # install docker as a dependency of kind
# # # only need the CLI and runtime, binding to host docker socket for access to host docker context
# RUN dnf -y install dnf-plugins-core; \
# dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo; \
# dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

RUN umask 0002 && \
mkdir -p ${NPM_GLOBAL} && \
touch /usr/local/etc/npmrc
# # install kind
# ADD install-kind.sh /tmp
# RUN /tmp/install-kind.sh; \
# rm /tmp/install-kind.sh

USER root
# # symlink oc because cannot install stable stream without RH auth
# RUN ln -sf /usr/local/bin/kubectl /usr/local/bin/oc

# USER default

# ADD shell-completions.sh /tmp
# RUN /tmp/shell-completions.sh && \
# zsh -c "source ~/.zshrc"

# RUN umask 0002 && \
# mkdir -p ${NPM_GLOBAL} && \
# touch /usr/local/etc/npmrc

# USER root

# RUN chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc && \
# chmod g+s ${NPM_GLOBAL} && \
# npm config -g set prefix ${NPM_GLOBAL}

# # install linting tools
# RUN dnf install -y python3-pip

# RUN bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) && \
# mv /opt/app-root/src/actionlint /usr/local/bin

RUN chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc && \
chmod g+s ${NPM_GLOBAL} && \
npm config -g set prefix ${NPM_GLOBAL}
# USER default

USER default
# RUN pip install yamllint

ARG NODE_MODULES="tslint-to-eslint-config typescript"
RUN npm install -g eslint && \
npm install -g ${NODE_MODULES} && \
npm cache clean --force > /dev/null 2>&1
# ARG NODE_MODULES="tslint-to-eslint-config typescript"
# RUN npm install -g eslint && \
# npm install -g markdownlint-cli2 && \
# npm install -g ${NODE_MODULES} && \
# npm cache clean --force > /dev/null 2>&1

WORKDIR /workspaces/ui
# WORKDIR /workspaces/ui

ENTRYPOINT ["npm", "install"]
# # ENTRYPOINT ["/tmp/shell-completions.sh", "&&", "source /opt/app-root/.zshrc", "&&", "npm", "install"]
# # ENTRYPOINT ["source /opt/app-root/.zshrc", "&&", "npm", "install"]
# ENTRYPOINT ["npm", "install"]

EXPOSE 3000/tcp
# EXPOSE 3000/tcp
# EXPOSE 6443/tcp
12 changes: 8 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"DavidAnson.vscode-markdownlint",
"ms-vscode-remote.remote-containers"
"ms-vscode-remote.remote-containers",
"foxundermoon.shell-format",
"timonwong.shellcheck"
],
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
"terminal.integrated.shell.linux": "/bin/zsh"
}
}
},
"forwardPorts": [3000],
"forwardPorts": [3000, 6443],
"mounts": [
"type=bind,source=${localWorkspaceFolder}/.env,target=/workspace/ui/.env,consistency=cached"
"type=bind,source=${localWorkspaceFolder}/.env,target=/workspace/ui/.env,consistency=cached",
"source=${env:HOME}/.kube,target=/opt/app-root/src/.kube,type=bind,consistency=cached",
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"runArgs": ["-p", "3000:3000"]
}
11 changes: 11 additions & 0 deletions .devcontainer/install-kind.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# Install the kind binary

[ "$(uname -m)" = "x86_64" ] && curl -Lo /tmp/kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-amd64
[ "$(uname -m)" = "aarch64" ] && curl -Lo /tmp/kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-arm64
chmod +x /tmp/kind
mv /tmp/kind /usr/local/bin/kind
kind completion zsh > "${HOME}/.oh-my-zsh/cache/completions/_kind"
chown -R ${USERNAME}:npm ${HOME}/.oh-my-zsh/cache/completions/_kind
21 changes: 21 additions & 0 deletions .devcontainer/install-kubectl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# Install the kubectl binary

ARCH=$(uname -m)
if [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "amd64" ]; then
ARCH="amd64"
elif [ "$ARCH" == "aarch64" ] || [ "$ARCH" == "arm64" ]; then
ARCH="arm64"
else
echo "Unsupported architecture: $ARCH"
exit 1
fi

KUBECTL_VERSION=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
echo "Installing kubectl version $KUBECTL_VERSION for $ARCH..."
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl"
chmod +x kubectl
mv kubectl /usr/local/bin/
kubectl completion zsh > /opt/app-root/src/.oh-my-zsh/cache/completions/_kubectl
32 changes: 32 additions & 0 deletions .devcontainer/install-kubeseal.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# Install the kubeseal binary

set -x
set -e
set -o pipefail

# Determine architecture
ARCH=$(uname -m)
if [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "amd64" ]; then
ARCH="amd64"
elif [ "$ARCH" == "aarch64" ] || [ "$ARCH" == "arm64" ]; then
ARCH="arm64"
else
echo "Unsupported architecture: $ARCH"
exit 1
fi

KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-)
if [ -z "$KUBESEAL_VERSION" ]; then
echo "Failed to fetch the latest KUBESEAL_VERSION"
exit 1
fi

curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${ARCH}.tar.gz"
tar -xvzf "kubeseal-${KUBESEAL_VERSION}-linux-${ARCH}.tar.gz" kubeseal
chmod 755 kubeseal
mv kubeseal /usr/local/bin/kubeseal
kubeseal completion zsh > ~/.oh-my-zsh/cache/completions/_kubeseal
rm "kubeseal-${KUBESEAL_VERSION}-linux-${ARCH}.tar.gz"
16 changes: 16 additions & 0 deletions .devcontainer/shell-completions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# Misc shell completions
personal_completions_dir=/opt/app-root/src/completions
mkdir -p ${personal_completions_dir}

kubectl completion zsh > ${personal_completions_dir}/_kubectl
chmod 644 ${personal_completions_dir}/_kubectl

kind completion zsh > ${personal_completions_dir}/_kind
chmod 644 ${personal_completions_dir}/_kind

chown -R default:npm ${personal_completions_dir}

echo "fpath+=${personal_completions_dir}" >> $HOME/.zshrc
38 changes: 22 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ ILAB_KUBE_CONTEXT?=kind-instructlab-ui
ILAB_KUBE_NAMESPACE?=instructlab
ILAB_KUBE_CLUSTER_NAME?=instructlab-ui
CONTAINER_ENGINE?=docker
DEVCONTAINER_BINARY_EXISTS ?= $(shell command -v devcontainer)
DEVCONTAINER_BINARY_EXISTS?=$(shell command -v devcontainer)
DEVCONTAINER_DEFAULT_SHELL?=zsh
TAG=$(shell git rev-parse HEAD)
##@ Development - Helper commands for development
.PHONY: md-lint
Expand All @@ -31,7 +32,7 @@ md-lint: ## Lint markdown files
.PHONY: action-lint
action-lint: ## Lint GitHub Action workflows
$(ECHO_PREFIX) printf " %-12s .github/...\n" "[ACTION LINT]"
$(CMD_PREFIX) if ! which actionlint $(PIPE_DEV_NULL) ; then \
$(CMD_PREFIX) if ! command -v actionlint $(PIPE_DEV_NULL) ; then \
echo "Please install actionlint." ; \
echo "go install github.com/rhysd/actionlint/cmd/actionlint@latest" ; \
exit 1 ; \
Expand All @@ -40,7 +41,7 @@ action-lint: ## Lint GitHub Action workflows

.PHONY: yaml-lint
yaml-lint: ## Lint yaml files
$(CMD_PREFIX) if ! which yamllint >/dev/null 2>&1; then \
$(CMD_PREFIX) if ! command -v yamllint >/dev/null 2>&1; then \
echo "Please install yamllint." ; \
echo "See: https://yamllint.readthedocs.io/en/stable/quickstart.html" ; \
exit 1 ; \
Expand Down Expand Up @@ -97,20 +98,28 @@ start-dev-podman: ## Start UI development stack in podman
##@ Kubernetes - Kind cluster based dev environment
.PHONY: check-kind
check-kind:
$(CMD_PREFIX) if [ -z "$(shell which kind)" ]; then \
$(CMD_PREFIX) if [ -z "$(shell command -v kind)" ]; then \
echo "Please install kind and then start the kind dev environment." ; \
echo "https://kind.sigs.k8s.io/" ; \
exit 1 ; \
fi

.PHONY: check-kubectl
check-kubectl:
$(CMD_PREFIX) if [ -z "$(shell which kubectl)" ]; then \
$(CMD_PREFIX) if [ -z "$(shell command -v kubectl)" ]; then \
echo "Please install kubectl" ; \
echo "https://kubernetes.io/docs/tasks/tools/#kubectl" ; \
exit 1 ; \
fi

.PHONY: check-kubeseal
check-kubeseal:
$(CMD_PREFIX) if [ -z "$(shell command -v kubeseal)" ]; then \
echo "Please install kubeseal" ; \
echo "https://github.com/bitnami-labs/sealed-secrets?tab=readme-ov-file#kubeseal" ; \
exit 1 ; \
fi

.PHONY: load-images
load-images: ## Load images onto Kind cluster
$(CMD_PREFIX) kind load --name $(ILAB_KUBE_CLUSTER_NAME) docker-image ghcr.io/instructlab/ui/ui:main
Expand All @@ -130,8 +139,8 @@ wait-for-readiness: # Wait for operators to be ready
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) -n ingress-nginx rollout restart deployment ingress-nginx-controller
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) -n ingress-nginx rollout status deployment ingress-nginx-controller --timeout=10m

.PHONY: deploy
deploy: wait-for-readiness ## Deploy a InstructLab UI development stack onto a kubernetes cluster
.PHONY: deploy-kind
deploy-kind: wait-for-readiness ## Deploy a InstructLab UI development stack onto a kubernetes cluster
$(CMD_PREFIX) if [ ! -f .env ]; then \
echo "Please create a .env file in the root of the project." ; \
exit 1 ; \
Expand All @@ -140,20 +149,20 @@ deploy: wait-for-readiness ## Deploy a InstructLab UI development stack onto a k
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) apply -k ./deploy/k8s/overlays/kind
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) wait --for=condition=Ready pods -n $(ILAB_KUBE_NAMESPACE) --all -l app.kubernetes.io/part-of=ui --timeout=15m

.PHONY: redeploy
redeploy: ui-image load-images ## Redeploy the InstructLab UI stack onto a kubernetes cluster
.PHONY: redeploy-kind
redeploy-kind: ui-image load-images ## Redeploy the InstructLab UI stack onto a kubernetes cluster
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) -n $(ILAB_KUBE_NAMESPACE) rollout restart deploy/ui
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) -n $(ILAB_KUBE_NAMESPACE) rollout restart deploy/pathservice

.PHONY: undeploy
undeploy: ## Undeploy the InstructLab UI stack from a kubernetes cluster
.PHONY: undeploy-kind
undeploy-kind: ## Undeploy the InstructLab UI stack from a kubernetes cluster
$(CMD_PREFIX) if [ -f ./deploy/k8s/overlays/kind/.env ]; then \
rm ./deploy/k8s/overlays/kind/.env ; \
fi
$(CMD_PREFIX) kubectl --context=$(ILAB_KUBE_CONTEXT) delete namespace $(ILAB_KUBE_NAMESPACE)

.PHONY: start-dev-kind ## Run the development environment on Kind cluster
start-dev-kind: setup-kind deploy ## Setup a Kind cluster and deploy InstructLab UI on it
start-dev-kind: setup-kind load-images deploy-kind ## Setup a Kind cluster and deploy InstructLab UI on it

##@ OpenShift - UI prod and qa deployment on OpenShift
.PHONY: deploy-qa-openshift
Expand All @@ -162,7 +171,6 @@ deploy-qa-openshift: ## Deploy QA stack of the InstructLab UI on OpenShift
echo "Please create a .env file in the root of the project." ; \
exit 1 ; \
fi

$(CMD_PREFIX) yes | cp -rf .env ./deploy/k8s/overlays/openshift/qa/.env
$(CMD_PREFIX) oc apply -k ./deploy/k8s/overlays/openshift/qa
$(CMD_PREFIX) oc wait --for=condition=Ready pods -n $(ILAB_KUBE_NAMESPACE) --all -l app.kubernetes.io/part-of=ui --timeout=15m
Expand All @@ -172,7 +180,6 @@ redeploy-qa-openshift: ## Redeploy QA stack of the InstructLab UI on OpenShift
$(CMD_PREFIX) oc -n $(ILAB_KUBE_NAMESPACE) rollout restart deploy/ui
$(CMD_PREFIX) oc -n $(ILAB_KUBE_NAMESPACE) rollout restart deploy/pathservice


.PHONY: undeploy-qa-openshift
undeploy-qa-openshift: ## Undeploy QA stack of the InstructLab UI on OpenShift
$(CMD_PREFIX) oc delete -k ./deploy/k8s/overlays/openshift/qa
Expand Down Expand Up @@ -224,7 +231,7 @@ start-dev-container:
.PHONY: enter-dev-container
enter-dev-container:
$(MAKE) check-dev-container-installed
devcontainer exec --workspace-folder=./ --docker-path=${CONTAINER_ENGINE} bash
devcontainer exec --workspace-folder=./ --docker-path=${CONTAINER_ENGINE} ${DEVCONTAINER_DEFAULT_SHELL}

.PHONY: cycle-dev-container
cycle-dev-container:
Expand All @@ -240,5 +247,4 @@ cycle-dev-container:
echo "removing image with id $$image_id and all containers using that image ..."; \
${CONTAINER_ENGINE} rmi $$image_id -f; \
fi;
$(MAKE) build-dev-container
$(MAKE) start-dev-container
2 changes: 2 additions & 0 deletions deploy/k8s/overlays/kind/kind.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ nodes:
image: kindest/node:v1.30.0
- role: worker
image: kindest/node:v1.30.0
networking:
apiServerPort: 6443
Loading
Loading