From b2ce29fa858c155b1b52ad9945728175870d2fb4 Mon Sep 17 00:00:00 2001 From: Mariandi Stylianou Date: Wed, 29 Jan 2025 13:35:43 +0200 Subject: [PATCH 1/2] chore: add .devcontainer configuration --- .devcontainer/.gitignore | 2 + .devcontainer/Dockerfile | 4 ++ .devcontainer/devcontainer.json | 68 +++++++++++++++++++ .../customisation.template/custom-packages.sh | 11 +++ .../customisation.template/custom.zshrc.sh | 9 +++ .../oh-my-zsh-settings.zshrc.sh | 67 ++++++++++++++++++ .devcontainer/scripts/init.bash | 13 ++++ devcontainer-template/README.md | 54 +++++++++++++++ package.json | 3 +- 9 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/.gitignore create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/files/customisation.template/custom-packages.sh create mode 100644 .devcontainer/files/customisation.template/custom.zshrc.sh create mode 100644 .devcontainer/files/customisation.template/oh-my-zsh-settings.zshrc.sh create mode 100644 .devcontainer/scripts/init.bash create mode 100644 devcontainer-template/README.md diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore new file mode 100644 index 000000000..1e9dcf40e --- /dev/null +++ b/.devcontainer/.gitignore @@ -0,0 +1,2 @@ +# Ignore changes to customisation files as intended to be user modifiable without pushing changes to repo +customisation diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..6d2093c4c --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,4 @@ +FROM atomlearning/devcontainer-base:latest + +### Reset user to ensure non-privileged user downstream +USER user diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..df3f8e088 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,68 @@ +{ + "name": "components", + "build": { + "dockerfile": "Dockerfile", + "options": ["--pull"], + "args": { + "INSTALL_JS_STACK": "yes", + "JS_STACK_N_VERSION": "v9.2.0", + "JS_STACK_NODE_VERSION": "20.11" + } + }, + + "forwardPorts": [], + "portsAttributes": {}, + "runArgs": ["--add-host=kubernetes:host-gateway"], + + "remoteUser": "user", + "containerUser": "root", + "updateRemoteUserUID": false, + "userEnvProbe": "loginInteractiveShell", + "containerEnv": {}, + "remoteEnv": { + "ATOM_REMOTE_DEV_IS_MK2": "yes", + // Make VS Code the default editor in terminals for convenience + "EDITOR": "code -w", + // Use our custom SSH Auth proxy for SSH key forwarding e.g. for commit signing + "SSH_AUTH_SOCK": "/home/user/.ssh/atom-ssh-auth-proxy/server.sock" + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind", + "workspaceFolder": "${localWorkspaceFolder}", + "mounts": [ + "source=/home/user/.devcontainer-state/${devcontainerId},target=/home/user/.state,type=bind", + "source=devcontainer-caches,target=/home/user/.cache,type=volume", + "source=/home/user/.config/git,target=/home/user/.config/git,type=bind,readonly", + "source=/etc/rancher/k3s/k3s.yaml,target=/run/secrets/rancher-k3s.yaml,type=bind,readonly", + "source=/home/user/.atom-env-info,target=/home/user/.atom-env-info,type=bind,readonly", + "source=/home/user/.ssh/atom-ssh-auth-proxy/server.sock,target=/home/user/.ssh/atom-ssh-auth-proxy/server.sock,type=bind", + "source=/home/user/.gnupg,target=/home/user/.gnupg,type=bind" + ], + "initializeCommand": "bash '${localWorkspaceFolder}/.devcontainer/scripts/init.bash' '${devcontainerId}' '${localWorkspaceFolder}'", + "postStartCommand": "/usr/local/bin/container-hooks.bash postStart '${containerWorkspaceFolder}'", + + "features": {}, + + "customizations": { + "vscode": { + "extensions": ["esbenp.prettier-vscode","EditorConfig.EditorConfig","dbaeumer.vscode-eslint",], + "settings": { + // General VS Code + "editor.formatOnSave": true, + "editor.formatOnPaste": false, + "editor.formatOnSaveMode": "file", + "dev.containers.copyGitConfig": false, + + // Exclude big, generated directories from VS Code's filewatcher to avoid it hogging file watch handles + "files.watcherExclude": { + "**/__pycache__/**": true, + "**/.cache/**": true, + "**/.venv/**": true, + "**/.yarn/unplugged/**": true, + "**/dist/**": true, + "**/node_modules/**": true + } + } + } + } +} diff --git a/.devcontainer/files/customisation.template/custom-packages.sh b/.devcontainer/files/customisation.template/custom-packages.sh new file mode 100644 index 000000000..68349a870 --- /dev/null +++ b/.devcontainer/files/customisation.template/custom-packages.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Use this script, which is run as root, to install any custom packages +# This should be done with extreme caution as it could easily break your environment in weird ways +# Packages should only be installed here if pretty much they only apply to you/one other user +# Other packages should be put into the main Dockerfile and under Git. +# +# Apt is the available package manager. `apt-get update` must be run before attempting any package installs +# +# Rebuild the container after making changes to this script for it to take effect + diff --git a/.devcontainer/files/customisation.template/custom.zshrc.sh b/.devcontainer/files/customisation.template/custom.zshrc.sh new file mode 100644 index 000000000..f0e201a31 --- /dev/null +++ b/.devcontainer/files/customisation.template/custom.zshrc.sh @@ -0,0 +1,9 @@ +# Add any other .zshrc scripting (e.g. aliases) +# +# .zshrc construction: +# 1. files/user-before-omz.zshrc.sh (cannot be user edited) +# 2. customisation/oh-my-zsh-settings.zshrc.sh +# 3. files/user-omz-init.zshrc.sh (cannot be user edited) +# 4. customisation/custom.zshrc.sh (you are here) +# + diff --git a/.devcontainer/files/customisation.template/oh-my-zsh-settings.zshrc.sh b/.devcontainer/files/customisation.template/oh-my-zsh-settings.zshrc.sh new file mode 100644 index 000000000..0944e6dea --- /dev/null +++ b/.devcontainer/files/customisation.template/oh-my-zsh-settings.zshrc.sh @@ -0,0 +1,67 @@ +# Edit Oh My ZSH settings here. Rebuild container after editing to take effect +# +# .zshrc construction: +# 1. files/user-before-omz.zshrc.sh (cannot be user edited) +# 2. customisation/oh-my-zsh-settings.zshrc.sh (you are here) +# 3. files/user-omz-init.zshrc.sh (cannot be user edited) +# 4. customisation/custom.zshrc.sh +# +# Based on default .zshrc from oh-my-zsh commit 9ba6daa1b5d0b60c89525d679eb30fe3ed9947de + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time Oh My Zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +ZSH_THEME="robbyrussell" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment the following line if pasting URLs and other text is messed up. +# DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git jump) + diff --git a/.devcontainer/scripts/init.bash b/.devcontainer/scripts/init.bash new file mode 100644 index 000000000..e3a5d66cb --- /dev/null +++ b/.devcontainer/scripts/init.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +ID="${1}" +LOCAL_WORKSPACE="${2}" + +# This is a hack that does two things: creates the backing directory for ~/.state; and copy the customisation template into place to be available for the user to edit + +mkdir -p "/home/user/.devcontainer-state/${ID}" + +cd "${LOCAL_WORKSPACE}/.devcontainer" +if [ ! -d customisation ]; then + cp -r files/customisation.template customisation +fi diff --git a/devcontainer-template/README.md b/devcontainer-template/README.md new file mode 100644 index 000000000..eea883475 --- /dev/null +++ b/devcontainer-template/README.md @@ -0,0 +1,54 @@ +devcontainer-template +===================== +Dev Container template for Atom repositories. + +To get started, just copy the `.devcontainer` directory into the root of your repository. + +Customising the template +------------------------ +Once you've added the .devcontainer template to your repository, you'll want to customise it for the languages, tools, etc. needed for working in that repo. +Below if the things you should customise before starting to use the Dev Container and how to make various customisations. + +### Required +* In `devcontainer.json`, edit `name` as the name of the Dev Container displayed on the UI. Usually this is the name of the repository e.g. `atom-core` +* If you want to install the Atom JS and/or Python stacks, add the appropriate variables such as `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` to `build.arg` in `devcontainer.json`. See the ONBUILD section of [devcontainer-base/README.md](../devcontainer-base/README.md) for details on these variables. +* Add any VS Code extensions that everyone using the repository should have installed (e.g. relevant language extensions) to `customisations.vscode.extensions` in `devcontainer.json`. These should be the extension IDs, which can be copied from the extension's page within VS Code +* Similarly add any VS Code settings that should be set a particular way (e.g. formatter settigs) to `customizations.vscode.settings` in `devcontainer.json`. Easiest way to get the correct format is to set the setting in your env via the VS Code settings UI and then click the cog next to the setting and choose "Copy Setting as JSON". The existing VS Code settings within the template are recommended but not required to be kept. + +Once you've made your desire changes, you can then enter the Dev Container for everything to be setup (lower-left green bar in VS Code -> Reopen in container) + +### Do not edit +Typically you should not, and not need to, edit the files under `file` and `scripts`. Discuss with @Atom-Learning/Devops before doing so + +Additionally: +* In `devcontainer.json`: + * As a general rule, don't want single value settings (strings) and only append to map/list settings + * Only add new environment variables in `remoteEnv`, don't remove any existing ones. By convention, leave an empty line between the template ones and any new variables. + * Don't change `workspaceMount` or `workspaceFolder`. If you want to add new bind mounts, don't remove any of the existing ones. + * Don't change the `initializeCommand` or the `postStartCommand`. If you want to run a shell script as a postStart hook (useful for running setup commands that need access to the repository itself), see below. + +### Adding additional software +If you only need the Atom JS and/or Python stack, these can be installed via the `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` Docker build arguments. See above and [devcontainer-base/README.md](../devcontainer-base/README.md). +For other tools etc, this requires editing the Dockerfile. + +Add the needed `RUN`, `COPY`, `ARG`, etc. instructions to install the software you desire. Make sure the final instruction in the file is always the included `USER user`. + +Tips: +* Most software should be available in the Ubuntu repositories. You can run `apt search ` to search what is available under what name. You can then install it in the Dockerfile with `apt-get install ` +* When installing with `apt-get`, it is recommended to always do an `apt-get update` in the same `RUN` instruction and to use `-y --no-install-recommends` in the `apt-get install` command. E.g. `RUN apt-get update && apt-get install -y --no-install-recommends ` (usually `TOOLNAME_VERSION`) before the `RUN` instruction, replace the version in the `RUN` instruction with `${}`, and then specify the version in `devcontainer.json` `build.args`. + +### Dev Container Features +Dev Containers have a mechanism called "features" for installing pre-made bundles of software. These can be installed by adding the feature name and config to `features` in `devcontainer.json`. The list of available features can be found at https://containers.dev/features. Generally speaking, features are only worth installing for very complex pieces of software or those that run services in the background like `desktop-lite`. Directly installing via the Dockerfile is preferable in most cases as it gives us much more control and oversight into what/how things are being installed and setup, which is important for future maintainability. + +### Advanced - Adding a Dev Container postStart hook +If you want to add a postStart hook to the Dev Container to run a shell script, this process is slightly different for our setup to allow the base container to define it's own postStart hook. A postStart hook can be useful for running a shell script once the Dev Container has started to do setup steps that require access to the repository itself. For example, installing a tool who's code live within the repo itself. + +Steps: +1. Add the shell script inside `files`, usually called `postStart-hook.bash`. This script will be sourced so don't include a `#!` at the top. +2. Add a `COPY` instruction in the Dockerfile to copy this file to `/opt/atom-devcontainer/hooks/postStart.d/` within the container. Number it with an index greater than 1. For example: `COPY files/postStart-hook.bash /opt/atom-devcontainer/hooks/postStart.d/2-.bash` + +This file when then be sourced by the built-in postStart hook after it's done it's postStart setup. + +### Useful references +* https://containers.dev/implementors/json_reference/ - very useful for editing devcontainer.json diff --git a/package.json b/package.json index 4cdd87a2a..0a411b583 100644 --- a/package.json +++ b/package.json @@ -58,5 +58,6 @@ "packageManager": "yarn@4.4.0", "engines": { "node": "20.x" - } + }, + "version": "4.3.1" } From bb845405074026ddc4258fa768afe28b4a1b1a32 Mon Sep 17 00:00:00 2001 From: Mariandi Stylianou Date: Wed, 29 Jan 2025 13:10:37 +0000 Subject: [PATCH 2/2] chore: remove readme --- devcontainer-template/README.md | 54 --------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 devcontainer-template/README.md diff --git a/devcontainer-template/README.md b/devcontainer-template/README.md deleted file mode 100644 index eea883475..000000000 --- a/devcontainer-template/README.md +++ /dev/null @@ -1,54 +0,0 @@ -devcontainer-template -===================== -Dev Container template for Atom repositories. - -To get started, just copy the `.devcontainer` directory into the root of your repository. - -Customising the template ------------------------- -Once you've added the .devcontainer template to your repository, you'll want to customise it for the languages, tools, etc. needed for working in that repo. -Below if the things you should customise before starting to use the Dev Container and how to make various customisations. - -### Required -* In `devcontainer.json`, edit `name` as the name of the Dev Container displayed on the UI. Usually this is the name of the repository e.g. `atom-core` -* If you want to install the Atom JS and/or Python stacks, add the appropriate variables such as `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` to `build.arg` in `devcontainer.json`. See the ONBUILD section of [devcontainer-base/README.md](../devcontainer-base/README.md) for details on these variables. -* Add any VS Code extensions that everyone using the repository should have installed (e.g. relevant language extensions) to `customisations.vscode.extensions` in `devcontainer.json`. These should be the extension IDs, which can be copied from the extension's page within VS Code -* Similarly add any VS Code settings that should be set a particular way (e.g. formatter settigs) to `customizations.vscode.settings` in `devcontainer.json`. Easiest way to get the correct format is to set the setting in your env via the VS Code settings UI and then click the cog next to the setting and choose "Copy Setting as JSON". The existing VS Code settings within the template are recommended but not required to be kept. - -Once you've made your desire changes, you can then enter the Dev Container for everything to be setup (lower-left green bar in VS Code -> Reopen in container) - -### Do not edit -Typically you should not, and not need to, edit the files under `file` and `scripts`. Discuss with @Atom-Learning/Devops before doing so - -Additionally: -* In `devcontainer.json`: - * As a general rule, don't want single value settings (strings) and only append to map/list settings - * Only add new environment variables in `remoteEnv`, don't remove any existing ones. By convention, leave an empty line between the template ones and any new variables. - * Don't change `workspaceMount` or `workspaceFolder`. If you want to add new bind mounts, don't remove any of the existing ones. - * Don't change the `initializeCommand` or the `postStartCommand`. If you want to run a shell script as a postStart hook (useful for running setup commands that need access to the repository itself), see below. - -### Adding additional software -If you only need the Atom JS and/or Python stack, these can be installed via the `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` Docker build arguments. See above and [devcontainer-base/README.md](../devcontainer-base/README.md). -For other tools etc, this requires editing the Dockerfile. - -Add the needed `RUN`, `COPY`, `ARG`, etc. instructions to install the software you desire. Make sure the final instruction in the file is always the included `USER user`. - -Tips: -* Most software should be available in the Ubuntu repositories. You can run `apt search ` to search what is available under what name. You can then install it in the Dockerfile with `apt-get install ` -* When installing with `apt-get`, it is recommended to always do an `apt-get update` in the same `RUN` instruction and to use `-y --no-install-recommends` in the `apt-get install` command. E.g. `RUN apt-get update && apt-get install -y --no-install-recommends ` (usually `TOOLNAME_VERSION`) before the `RUN` instruction, replace the version in the `RUN` instruction with `${}`, and then specify the version in `devcontainer.json` `build.args`. - -### Dev Container Features -Dev Containers have a mechanism called "features" for installing pre-made bundles of software. These can be installed by adding the feature name and config to `features` in `devcontainer.json`. The list of available features can be found at https://containers.dev/features. Generally speaking, features are only worth installing for very complex pieces of software or those that run services in the background like `desktop-lite`. Directly installing via the Dockerfile is preferable in most cases as it gives us much more control and oversight into what/how things are being installed and setup, which is important for future maintainability. - -### Advanced - Adding a Dev Container postStart hook -If you want to add a postStart hook to the Dev Container to run a shell script, this process is slightly different for our setup to allow the base container to define it's own postStart hook. A postStart hook can be useful for running a shell script once the Dev Container has started to do setup steps that require access to the repository itself. For example, installing a tool who's code live within the repo itself. - -Steps: -1. Add the shell script inside `files`, usually called `postStart-hook.bash`. This script will be sourced so don't include a `#!` at the top. -2. Add a `COPY` instruction in the Dockerfile to copy this file to `/opt/atom-devcontainer/hooks/postStart.d/` within the container. Number it with an index greater than 1. For example: `COPY files/postStart-hook.bash /opt/atom-devcontainer/hooks/postStart.d/2-.bash` - -This file when then be sourced by the built-in postStart hook after it's done it's postStart setup. - -### Useful references -* https://containers.dev/implementors/json_reference/ - very useful for editing devcontainer.json