diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore new file mode 100644 index 00000000000..7b1acdea530 --- /dev/null +++ b/.devcontainer/.gitignore @@ -0,0 +1,24 @@ +* + +!/conf/ +!/conf/shell/ +!/conf/shell/etc/ +!/conf/shell/etc/skel/ +!/conf/shell/var/ +!/conf/shell/var/tmp/ +!/conf/shell/var/tmp/snippets/ +!/mojo/ +!/scripts/ +!/scripts/usr/ +!/scripts/usr/local/ +!/scripts/usr/local/bin/ + +!/conf/shell/etc/skel/.profile +!/conf/shell/var/tmp/snippets/*.sh +!/mojo/devcontainer.json +!/scripts/usr/local/bin/*.sh + +!/.gitignore +!/devcontainer.json +!/Mojo.Dockerfile +!/README.md diff --git a/.devcontainer/Mojo.Dockerfile b/.devcontainer/Mojo.Dockerfile new file mode 100644 index 00000000000..d2a729805a9 --- /dev/null +++ b/.devcontainer/Mojo.Dockerfile @@ -0,0 +1,121 @@ +# ===----------------------------------------------------------------------=== # +# Copyright (c) 2024, Olivier Benz +# Copyright (c) 2024, Modular Inc. All rights reserved. +# +# Licensed under the Apache License v2.0 with LLVM Exceptions: +# https://llvm.org/LICENSE.txt +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# The Dockerfile is provided as reference. Please review the redistribution +# terms of the Mojo license in Section 1 (https://www.modular.com/legal/mojo) +# prior to distributing pre-built container images. +# ===----------------------------------------------------------------------=== # + +ARG BUILD_ON_IMAGE=glcr.b-data.ch/mojo/base +ARG MOJO_VERSION=nightly +ARG LLVM_VERSION=14 + +FROM ${BUILD_ON_IMAGE}:${MOJO_VERSION} as files + +RUN mkdir /files + +COPY conf/shell /files +COPY scripts /files + + ## Ensure file modes are correct +RUN find /files -type d -exec chmod 755 {} \; \ + && find /files -type f -exec chmod 644 {} \; \ + && find /files/usr/local/bin -type f -exec chmod 755 {} \; + +FROM docker.io/koalaman/shellcheck:stable as sci + +FROM ${BUILD_ON_IMAGE}:${MOJO_VERSION} as mojo + +ARG DEBIAN_FRONTEND=noninteractive + +ARG BUILD_ON_IMAGE +ARG LLVM_VERSION + +ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${MOJO_VERSION} \ + PARENT_IMAGE_BUILD_DATE=${BUILD_DATE} \ + LLVM_VERSION=${LLVM_VERSION} + +ENV PATH=/usr/lib/llvm-${LLVM_VERSION}/bin:$PATH + +RUN dpkgArch="$(dpkg --print-architecture)" \ + ## Ensure that common CA certificates + ## and OpenSSL libraries are up to date + && apt-get update \ + && apt-get -y install --no-install-recommends --only-upgrade \ + ca-certificates \ + openssl \ +## Install Mojo related stuff + ## Install LLVM + && apt-get -y install --no-install-recommends \ + "llvm-$LLVM_VERSION" \ + "llvm-$LLVM_VERSION-tools" \ + ## Install lit + && pip install --no-cache-dir lit \ + ## Install pre-commit + && pip install --no-cache-dir pre-commit \ +## Dev Container only + ## Install hadolint + && case "$dpkgArch" in \ + amd64) tarArch="x86_64" ;; \ + arm64) tarArch="arm64" ;; \ + *) echo "error: Architecture $dpkgArch unsupported"; exit 1 ;; \ + esac \ + && apiResponse="$(curl -sSL \ + https://api.github.com/repos/hadolint/hadolint/releases/latest)" \ + && downloadUrl="$(echo "$apiResponse" | grep -e \ + "browser_download_url.*Linux-$tarArch\"" | cut -d : -f 2,3 | tr -d \")" \ + && echo "$downloadUrl" | xargs curl -sSLo /usr/local/bin/hadolint \ + && chmod 755 /usr/local/bin/hadolint \ + ## Create backup of root directory + && cp -a /root /var/backups \ + ## Clean up + && rm -rf /var/lib/apt/lists/* + +FROM mojo + +ARG DEBIAN_FRONTEND=noninteractive + +## Update environment +ARG USE_ZSH_FOR_ROOT +ARG SET_LANG +ARG SET_TZ + +ENV LANG=${SET_LANG:-$LANG} \ + TZ=${SET_TZ:-$TZ} + + ## Change root's shell to ZSH +RUN if [ -n "$USE_ZSH_FOR_ROOT" ]; then \ + chsh -s /bin/zsh; \ + fi \ + ## Update timezone if needed + && if [ "$TZ" != "Etc/UTC" ]; then \ + echo "Setting TZ to $TZ"; \ + ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime \ + && echo "$TZ" > /etc/timezone; \ + fi \ + ## Add/Update locale if needed + && if [ "$LANG" != "en_US.UTF-8" ]; then \ + sed -i "s/# $LANG/$LANG/g" /etc/locale.gen; \ + locale-gen; \ + echo "Setting LANG to $LANG"; \ + update-locale --reset LANG="$LANG"; \ + fi + +## Copy files as late as possible to avoid cache busting +COPY --from=files /files / + +## Copy shellcheck as late as possible to avoid cache busting +COPY --from=sci --chown=root:root /bin/shellcheck /usr/local/bin + +## Unset environment variable BUILD_DATE +ENV BUILD_DATE= diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000000..87552abf7d7 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,12 @@ +# Dev Containers + +For further information, see [Development Containers](https://containers.dev). + +## Usage + +For local/remote usage with VS Code, please follow the instructions at +[Developing inside a Container](https://code.visualstudio.com/docs/devcontainers/containers). + + +For use with Github Codespaces: Open in GitHub Codespaces + diff --git a/.devcontainer/conf/shell/etc/skel/.profile b/.devcontainer/conf/shell/etc/skel/.profile new file mode 100644 index 00000000000..66283686d3a --- /dev/null +++ b/.devcontainer/conf/shell/etc/skel/.profile @@ -0,0 +1,30 @@ +# ~/.profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. + +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 + +# if running bash +if [ -n "$BASH_VERSION" ]; then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ]; then + . "$HOME/.bashrc" + fi +else + # if not running zsh + if [ -z "$ZSH_VERSION" ]; then + # set PATH so it includes user's private bin if it exists + if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" + fi + + # set PATH so it includes user's private bin if it exists + if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" + fi + fi +fi diff --git a/.devcontainer/conf/shell/var/tmp/snippets/rc.sh b/.devcontainer/conf/shell/var/tmp/snippets/rc.sh new file mode 100644 index 00000000000..49fe8b25bc0 --- /dev/null +++ b/.devcontainer/conf/shell/var/tmp/snippets/rc.sh @@ -0,0 +1,13 @@ + +# remove potentially appended $HOME/.local/bin from PATH +PATH="${PATH%:$HOME/.local/bin}" + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] && [[ "$PATH" != *"$HOME/bin"* ]] ; then + PATH="$HOME/bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] && [[ "$PATH" != *"$HOME/.local/bin"* ]] ; then + PATH="$HOME/.local/bin:$PATH" +fi diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..c27d348d338 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,64 @@ +{ + "name": "Mojo (nightly)", + "build": { + "dockerfile": "Mojo.Dockerfile", + "args": { + "MOJO_VERSION": "nightly", + "LLVM_VERSION": "14", + "USE_ZSH_FOR_ROOT": "unset-to-use-bash", + "SET_LANG": "en_US.UTF-8", + "SET_TZ": "Etc/UTC" + } + }, + + "onCreateCommand": "onCreateCommand.sh", + "postAttachCommand": "git checkout nightly && pre-commit install", + + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "configureZshAsDefaultShell": true, + "upgradePackages": false, + "username": "vscode", + "userUid": "automatic", + "userGid": "automatic" + }, + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "moby": false + } + }, + + "customizations": { + "vscode": { + "extensions": [ + "DavidAnson.vscode-markdownlint", + "eamodio.gitlens@11.7.0", + "editorconfig.editorconfig", + "exiasr.hadolint", + "GitHub.vscode-pull-request-github", + "mhutchie.git-graph", + "modular-mojotools.vscode-mojo-nightly", + "ms-azuretools.vscode-docker", + "ms-python.black-formatter", + "ms-python.python", + "ms-toolsai.jupyter", + "mutantdino.resourcemonitor", + "redhat.vscode-yaml", + "timonwong.shellcheck" + ], + "settings": { + "gitlens.showWelcomeOnInstall": false, + "gitlens.showWhatsNewAfterUpgrades": false, + "resmon.show.battery": false, + "resmon.show.cpufreq": false + } + } + }, + + // Set 'remoteUser' to 'root' to connect as root instead. + "remoteUser": "vscode", + + "remoteEnv": { + // Pip: Install packages to the user site + "PIP_USER": "1" + } +} diff --git a/.devcontainer/mojo/devcontainer.json b/.devcontainer/mojo/devcontainer.json new file mode 100644 index 00000000000..d25a778aca6 --- /dev/null +++ b/.devcontainer/mojo/devcontainer.json @@ -0,0 +1,65 @@ +{ + "name": "Mojo", + "build": { + "dockerfile": "../Mojo.Dockerfile", + "context": "..", + "args": { + "MOJO_VERSION": "24.3.0", + "LLVM_VERSION": "14", + "USE_ZSH_FOR_ROOT": "unset-to-use-bash", + "SET_LANG": "en_US.UTF-8", + "SET_TZ": "Etc/UTC" + } + }, + + "onCreateCommand": "onCreateCommand.sh", + "postAttachCommand": "git checkout main && pre-commit install", + + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "configureZshAsDefaultShell": true, + "upgradePackages": false, + "username": "vscode", + "userUid": "automatic", + "userGid": "automatic" + }, + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "moby": false + } + }, + + "customizations": { + "vscode": { + "extensions": [ + "DavidAnson.vscode-markdownlint", + "eamodio.gitlens@11.7.0", + "editorconfig.editorconfig", + "exiasr.hadolint", + "GitHub.vscode-pull-request-github", + "mhutchie.git-graph", + "modular-mojotools.vscode-mojo", + "ms-azuretools.vscode-docker", + "ms-python.black-formatter", + "ms-python.python", + "ms-toolsai.jupyter", + "mutantdino.resourcemonitor", + "redhat.vscode-yaml", + "timonwong.shellcheck" + ], + "settings": { + "gitlens.showWelcomeOnInstall": false, + "gitlens.showWhatsNewAfterUpgrades": false, + "resmon.show.battery": false, + "resmon.show.cpufreq": false + } + } + }, + + // Set 'remoteUser' to 'root' to connect as root instead. + "remoteUser": "vscode", + + "remoteEnv": { + // Pip: Install packages to the user site + "PIP_USER": "1" + } +} diff --git a/.devcontainer/scripts/usr/local/bin/onCreateCommand.sh b/.devcontainer/scripts/usr/local/bin/onCreateCommand.sh new file mode 100755 index 00000000000..c4ca5a2aad3 --- /dev/null +++ b/.devcontainer/scripts/usr/local/bin/onCreateCommand.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +##===----------------------------------------------------------------------===## +# Copyright (c) 2024, Olivier Benz +# Copyright (c) 2024, Modular Inc. All rights reserved. +# +# Licensed under the Apache License v2.0 with LLVM Exceptions: +# https://llvm.org/LICENSE.txt +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +##===----------------------------------------------------------------------===## + +set -e + +mkdir -p "$HOME/.local/bin" + +# Copy Bash-related files from root's backup directory +if [ "$(id -un)" == "root" ]; then + if [ ! -f /root/.bashrc ]; then + cp /var/backups/root/.bashrc /root; + fi + if [ ! -f /root/.profile ]; then + cp /var/backups/root/.profile /root; + fi +fi + +# Copy Zsh-related files and folders from the untouched home directory +if [ "$(id -un)" == "root" ]; then + if [ ! -d /root/.oh-my-zsh ]; then + cp -R /home/*/.oh-my-zsh /root; + fi + if [ ! -f /root/.zshrc ]; then + cp /home/*/.zshrc /root; + fi +else + if [ ! -d "$HOME/.oh-my-zsh" ]; then + sudo cp -R /root/.oh-my-zsh "$HOME"; + sudo chown -R "$(id -u)":"$(id -g)" "$HOME/.oh-my-zsh"; + fi + if [ ! -f "$HOME/.zshrc" ]; then + sudo cp /root/.zshrc "$HOME"; + sudo chown "$(id -u)":"$(id -g)" "$HOME/.zshrc"; + fi +fi + +# If existent, prepend the user's private bin to PATH +if ! grep -q "user's private bin" "$HOME/.bashrc"; then + cat "/var/tmp/snippets/rc.sh" >> "$HOME/.bashrc" +fi +if ! grep -q "user's private bin" "$HOME/.zshrc"; then + cat "/var/tmp/snippets/rc.sh" >> "$HOME/.zshrc" +fi + +# Enable Oh My Zsh plugins +sed -i "s/plugins=(git)/plugins=(git git-lfs pip screen tmux vscode)/g" \ + "$HOME/.zshrc" + +# Remove old .zcompdump files +rm -f "$HOME"/.zcompdump*