From 3dbe8192eaac5942c7a28491b5af1bbb31a4b4a8 Mon Sep 17 00:00:00 2001 From: Roman Dodin Date: Sun, 1 Dec 2024 01:39:12 +0100 Subject: [PATCH] Added "docker outside of docker" devcontainer (#2316) * added dood devcontainer * use file paths * mandatorize clab version during the build and add runargs * added tag munching step * fucking actions * bring back config * run devcontainer build on beta tags as well * try lowercase * output tag * move outputs * a day when you hate gh actions * change name * remove test * added needs deps * trying slim dockerfile for devcontainer * use slim zshrc * use explicit suffixes * change devcontainer base name * bring back moby for version matching * try 26.1.4 * try 25.0.5 * try 24 * switch to 26.1.5 and wait for better times https://github.com/moby/moby/issues/48987 * try moby 27.3.1 * try 26.1.3 * try 23.0.7 * try 26.1.4 docker * do not install docker-compose plugin * installDockerComposeSwitch false * bring back 23.0.7 fucking containers man * remove utm docs and finish dind/dood docs * added a video * test fira code embedded and zsh term settings * remove font download and set multiple fonts * added devcontainer requirements * do not require icons in the fonts * added windows install doc * fix bg color in animation * note about the reboot --- .devcontainer/Dockerfile | 3 +- .../{ => docker-in-docker}/devcontainer.json | 20 ++- .../docker-in-docker_slim/devcontainer.json | 48 +++++++ .../devcontainer.json | 68 +++++++++ .../devcontainer.json | 58 ++++++++ .devcontainer/slim.Dockerfile | 57 ++++++++ .devcontainer/zsh/.p10k.zsh | 33 +++-- .devcontainer/zsh/.zshrc-slim | 129 ++++++++++++++++++ .../zsh/install-tools-completions.sh | 6 + .devcontainer/zsh/install-zsh-plugins.sh | 6 - .github/workflows/build-devcontainer.yml | 28 +++- .github/workflows/cicd.yml | 56 ++++++-- docs/index.md | 2 +- docs/install.md | 41 ++---- docs/macos.md | 111 ++++++++++----- docs/windows.md | 125 +++++++++++++++++ 16 files changed, 686 insertions(+), 105 deletions(-) rename .devcontainer/{ => docker-in-docker}/devcontainer.json (63%) create mode 100644 .devcontainer/docker-in-docker_slim/devcontainer.json create mode 100644 .devcontainer/docker-outside-of-docker/devcontainer.json create mode 100644 .devcontainer/docker-outside-of-docker_slim/devcontainer.json create mode 100644 .devcontainer/slim.Dockerfile create mode 100644 .devcontainer/zsh/.zshrc-slim create mode 100755 .devcontainer/zsh/install-tools-completions.sh create mode 100644 docs/windows.md diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a75c539ce..47195c426 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -61,7 +61,8 @@ RUN mkdir -p /home/vscode/.docker && echo "{}" > /home/vscode/.docker/config.jso COPY ./.devcontainer/zsh/.zshrc /home/vscode/.zshrc COPY ./.devcontainer/zsh/.p10k.zsh /home/vscode/.p10k.zsh COPY ./.devcontainer/zsh/install-zsh-plugins.sh /tmp/install-zsh-plugins.sh -RUN bash -c "/tmp/install-zsh-plugins.sh" +COPY ./.devcontainer/zsh/install-tools-completions.sh /tmp/install-tools-completions.sh +RUN bash -c "/tmp/install-zsh-plugins.sh && /tmp/install-tools-completions.sh" # Setup pyenv virtual environment for clab tests COPY tests/requirements.txt /tmp/requirements.txt diff --git a/.devcontainer/devcontainer.json b/.devcontainer/docker-in-docker/devcontainer.json similarity index 63% rename from .devcontainer/devcontainer.json rename to .devcontainer/docker-in-docker/devcontainer.json index b9b11f929..ebb234b10 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/docker-in-docker/devcontainer.json @@ -1,17 +1,20 @@ // For format details, see https://aka.ms/devcontainer.json. { "build": { - "dockerfile": "./Dockerfile", - "context": "..", + "dockerfile": "../Dockerfile", + "context": "../..", "args": { "CLAB_VERSION": "${localEnv:CLAB_VERSION}" } }, "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { - "version": "26.1.4", + // docker/moby version is that old because newer ones failed to install under emulation + // see https://github.com/moby/moby/issues/48987#issuecomment-2507267417 + // and https://github.com/moby/moby/issues/47895#issuecomment-2507528678 + "version": "23.0.7", "dockerDashComposeVersion": "none", - "moby": "false" + "installDockerComposeSwitch": "false" }, // Add sshd to support gh cli codespace cp. "ghcr.io/devcontainers/features/sshd:1": { @@ -24,6 +27,15 @@ "remoteUser": "vscode", "customizations": { "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + }, + "terminal.integrated.fontFamily": "FiraCode Nerd Font, Menlo, Monaco, Cascadia Code, Consolas, Courier New, monospace" + }, "extensions": [ // go "golang.go", diff --git a/.devcontainer/docker-in-docker_slim/devcontainer.json b/.devcontainer/docker-in-docker_slim/devcontainer.json new file mode 100644 index 000000000..e2d9608e0 --- /dev/null +++ b/.devcontainer/docker-in-docker_slim/devcontainer.json @@ -0,0 +1,48 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "build": { + "dockerfile": "../slim.Dockerfile", + "context": "../..", + "args": { + "CLAB_VERSION": "${localEnv:CLAB_VERSION}" + } + }, + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "version": "23.0.7", + "dockerDashComposeVersion": "none", + "installDockerComposeSwitch": "false" + }, + // Add sshd to support gh cli codespace cp. + "ghcr.io/devcontainers/features/sshd:1": { + "version": "latest" + } + }, + "remoteUser": "vscode", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + }, + "terminal.integrated.fontFamily": "FiraCode Nerd Font, Menlo, Monaco, Cascadia Code, Consolas, Courier New, monospace" + }, + "extensions": [ + "ms-azuretools.vscode-docker", + // Python. + "ms-python.python", + // Errors and highlighters. + "mechatroner.rainbow-csv", + "redhat.vscode-yaml", + // markdown + "yzhang.markdown-all-in-one", + "davidanson.vscode-markdownlint" + ] + } + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/${containerWorkspaceFolder},type=bind", + "workspaceFolder": "/clab" +} \ No newline at end of file diff --git a/.devcontainer/docker-outside-of-docker/devcontainer.json b/.devcontainer/docker-outside-of-docker/devcontainer.json new file mode 100644 index 000000000..331e254be --- /dev/null +++ b/.devcontainer/docker-outside-of-docker/devcontainer.json @@ -0,0 +1,68 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "build": { + "dockerfile": "../Dockerfile", + "context": "../..", + "args": { + "CLAB_VERSION": "${localEnv:CLAB_VERSION}" + } + }, + "runArgs": [ + "--network=host", + "--pid=host", + "--privileged" + ], + "mounts": [ + "type=bind,src=/run/docker/netns,dst=/run/docker/netns", + "type=bind,src=/var/lib/docker,dst=/var/lib/docker", + "type=bind,src=/lib/modules,dst=/lib/modules" + ], + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "version": "23.0.7", + "dockerDashComposeVersion": "none", + "installDockerComposeSwitch": "false" + }, + // Add sshd to support gh cli codespaces cp. + "ghcr.io/devcontainers/features/sshd:1": { + "version": "latest" + }, + "ghcr.io/devcontainers/features/go:1": { + "version": "1.22" + } + }, + "remoteUser": "vscode", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + }, + "terminal.integrated.fontFamily": "FiraCode Nerd Font, Menlo, Monaco, Cascadia Code, Consolas, Courier New, monospace" + }, + "extensions": [ + // go + "golang.go", + "mhutchie.git-graph", + "ms-azuretools.vscode-docker", + // Python. + "ms-python.python", + "ms-python.vscode-pylance", + // Errors and highlighters. + "mechatroner.rainbow-csv", + "redhat.vscode-yaml", + "jinliming2.vscode-go-template", + // markdown + "yzhang.markdown-all-in-one", + "davidanson.vscode-markdownlint", + // proto + "zxh404.vscode-proto3" + ] + } + }, + "workspaceFolder": "${localWorkspaceFolder}", + "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind" +} \ No newline at end of file diff --git a/.devcontainer/docker-outside-of-docker_slim/devcontainer.json b/.devcontainer/docker-outside-of-docker_slim/devcontainer.json new file mode 100644 index 000000000..da5c8ee04 --- /dev/null +++ b/.devcontainer/docker-outside-of-docker_slim/devcontainer.json @@ -0,0 +1,58 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "build": { + "dockerfile": "../slim.Dockerfile", + "context": "../..", + "args": { + "CLAB_VERSION": "${localEnv:CLAB_VERSION}" + } + }, + "runArgs": [ + "--network=host", + "--pid=host", + "--privileged" + ], + "mounts": [ + "type=bind,src=/run/docker/netns,dst=/run/docker/netns", + "type=bind,src=/var/lib/docker,dst=/var/lib/docker", + "type=bind,src=/lib/modules,dst=/lib/modules" + ], + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "version": "23.0.7", + "dockerDashComposeVersion": "none", + "installDockerComposeSwitch": "false" + }, + // Add sshd to support gh cli codespaces cp. + "ghcr.io/devcontainers/features/sshd:1": { + "version": "latest" + } + }, + "remoteUser": "vscode", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + }, + "terminal.integrated.fontFamily": "FiraCode Nerd Font, Menlo, Monaco, Cascadia Code, Consolas, Courier New, monospace" + }, + "extensions": [ + "ms-azuretools.vscode-docker", + // Python. + "ms-python.python", + // Errors and highlighters. + "mechatroner.rainbow-csv", + "redhat.vscode-yaml", + // markdown + "yzhang.markdown-all-in-one", + "davidanson.vscode-markdownlint" + ] + } + }, + "workspaceFolder": "${localWorkspaceFolder}", + "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind" +} \ No newline at end of file diff --git a/.devcontainer/slim.Dockerfile b/.devcontainer/slim.Dockerfile new file mode 100644 index 000000000..f3ce088f9 --- /dev/null +++ b/.devcontainer/slim.Dockerfile @@ -0,0 +1,57 @@ +FROM mcr.microsoft.com/devcontainers/python:3.11-bookworm + +ARG CLAB_VERSION + +# Add the netdevops repository +RUN echo "deb [trusted=yes] https://netdevops.fury.site/apt/ /" | \ + tee -a /etc/apt/sources.list.d/netdevops.list + +# Install necessary packages, including curl +RUN apt-get update && apt-get install -y --no-install-recommends \ + direnv \ + btop \ + iputils-ping \ + tcpdump \ + iproute2 \ + qemu-kvm \ + dnsutils \ + telnet \ + curl + +# Install Containerlab +RUN bash -c "$(curl -sL https://get.containerlab.dev)" -- -v ${CLAB_VERSION} + +# Install GitHub CLI directly from the latest release +RUN bash -c 'ARCH=$(uname -m | sed "s/x86_64/amd64/" | sed "s/aarch64/arm64/") && \ + VERSION=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | \ + grep -oP "\"tag_name\": \"\K[^\"]+") && \ + CLEAN_VERSION=${VERSION#v} && \ + DOWNLOAD_URL="https://github.com/cli/cli/releases/download/${VERSION}/gh_${CLEAN_VERSION}_linux_${ARCH}.tar.gz" && \ + curl -L "$DOWNLOAD_URL" | tar xz -C /tmp && \ + mv /tmp/gh_${CLEAN_VERSION}_linux_${ARCH}/bin/gh /usr/local/bin/ && \ + chmod +x /usr/local/bin/gh && \ + rm -rf /tmp/gh_${CLEAN_VERSION}_linux_${ARCH}' + +# Add empty docker config files to avoid clab warnings for root user +RUN mkdir -p /root/.docker && echo "{}" > /root/.docker/config.json + +# Maintain SSH_AUTH_SOCK env var when using sudo +RUN mkdir -p /etc/sudoers.d && echo 'Defaults env_keep += "SSH_AUTH_SOCK"' > /etc/sudoers.d/ssh_auth_sock + +# Switch to the vscode user provided by the base image +USER vscode + +# Copy dclab script used to run the local containerlab build after `make build` +COPY ./.devcontainer/dclab /usr/local/bin/dclab + +# Create SSH key for vscode user to enable passwordless SSH to devices +RUN ssh-keygen -t ecdsa -b 256 -N "" -f ~/.ssh/id_ecdsa + +# Add empty docker config files to avoid clab warnings for vscode user +RUN mkdir -p /home/vscode/.docker && echo "{}" > /home/vscode/.docker/config.json + +# Setup Zsh and plugins +COPY ./.devcontainer/zsh/.zshrc-slim /home/vscode/.zshrc +COPY ./.devcontainer/zsh/.p10k.zsh /home/vscode/.p10k.zsh +COPY ./.devcontainer/zsh/install-zsh-plugins.sh /tmp/install-zsh-plugins.sh +RUN bash -c "/tmp/install-zsh-plugins.sh" diff --git a/.devcontainer/zsh/.p10k.zsh b/.devcontainer/zsh/.p10k.zsh index bbcace7b1..0a33ce889 100644 --- a/.devcontainer/zsh/.p10k.zsh +++ b/.devcontainer/zsh/.p10k.zsh @@ -1,7 +1,7 @@ -# Generated by Powerlevel10k configuration wizard on 2024-04-03 at 12:04 EEST. -# Based on romkatv/powerlevel10k/config/p10k-pure.zsh, checksum 35142. -# Wizard options: nerdfont-complete + powerline, small icons, pure, 2 lines, sparse, -# instant_prompt=verbose. +# Generated by Powerlevel10k configuration wizard on 2024-10-17 at 19:28 CEST. +# Based on romkatv/powerlevel10k/config/p10k-pure.zsh, checksum 07533. +# Wizard options: nerdfont-v3 + powerline, large icons, pure, snazzy, 24h time, 2 lines, +# sparse, instant_prompt=verbose. # Type `p10k configure` to generate another config. # # Config file for Powerlevel10k with the style of Pure (https://github.com/sindresorhus/pure). @@ -39,12 +39,19 @@ # Prompt colors. local grey='242' + # local red='#FF5C57' + # local yellow='#F3F99D' + # local blue='#57C7FF' + # local magenta='#FF6AC1' + # local cyan='#9AEDFE' + # local white='#F1F1F0' local red='1' local yellow='3' local blue='4' local magenta='5' local cyan='6' local white='7' + local darkgreen='#386641' # Left prompt segments. typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( @@ -52,9 +59,8 @@ context # user@host dir # current directory vcs # git status - command_execution_time # previous command duration virtualenv # python virtual environment - time # current time + command_execution_time # previous command duration # =========================[ Line #2 ]========================= newline # \n prompt_char # prompt symbol @@ -66,7 +72,7 @@ # command_execution_time # previous command duration # virtualenv # python virtual environment # context # user@host - + time # current time # =========================[ Line #2 ]========================= newline # \n ) @@ -96,11 +102,10 @@ typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=false # Grey Python Virtual Environment. - typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=$grey + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=$darkgreen # Don't show Python version. typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= - typeset -g POWERLEVEL9K_VIRTUALENV_LEFT_DELIMITER='\ue73c·' # Blue current directory. typeset -g POWERLEVEL9K_DIR_FOREGROUND=$blue @@ -136,14 +141,14 @@ typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan # Don't show remote branch, current tag or stashes. typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind) - # The branch icon. - typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uf418·' + # Don't show the branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= # When in detached HEAD state, show @commit where branch normally goes. typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' # Don't show staged, unstaged, untracked indicators. typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON= # Show '*' when there are staged, unstaged or untracked files. - typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*' + # typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*' # Show '⇣' if local branch is behind remote. typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=':⇣' # Show '⇡' if local branch is ahead of remote. @@ -177,7 +182,7 @@ # it incompatible with your zsh configuration files. # - quiet: Enable instant prompt and don't print warnings when detecting console output # during zsh initialization. Choose this if you've read and understood - # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # https://github.com/romkatv/powerlevel10k#instant-prompt. # - verbose: Enable instant prompt and print a warning when detecting console output during # zsh initialization. Choose this if you've never tried instant prompt, haven't # seen the warning, or if you are unsure what this all means. @@ -198,4 +203,4 @@ typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} (( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} -'builtin' 'unset' 'p10k_config_opts' \ No newline at end of file +'builtin' 'unset' 'p10k_config_opts' diff --git a/.devcontainer/zsh/.zshrc-slim b/.devcontainer/zsh/.zshrc-slim new file mode 100644 index 000000000..73e29f331 --- /dev/null +++ b/.devcontainer/zsh/.zshrc-slim @@ -0,0 +1,129 @@ +# init direnv +# https://github.com/romkatv/powerlevel10k/blob/master/README.md#how-do-i-initialize-direnv-when-using-instant-prompt +(( ${+commands[direnv]} )) && emulate zsh -c "$(direnv export zsh)" + +# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. +# Initialization code that may require console input (password prompts, [y/n] +# confirmations, etc.) must go above this block; everything else may go below. +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi + +(( ${+commands[direnv]} )) && emulate zsh -c "$(direnv hook zsh)" + + +# Path to your oh-my-zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +ZSH_THEME="powerlevel10k/powerlevel10k" + +ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=40 +ZSH_AUTOSUGGEST_HISTORY_IGNORE="?(#c50,)" + +# history options +export SAVEHIST=1000000000 +export HISTFILESIZE=1000000000 +setopt inc_append_history +setopt extended_history +setopt hist_ignore_all_dups +setopt hist_ignore_space + +# auto complete configs -- menu-select+unambiguous to have tab menu auto complete setup +zstyle ':autocomplete:tab:*' insert-unambiguous no +zstyle ':autocomplete:*' widget-style menu-select +# dont auto show next completions -- its very annoying +zstyle ':autocomplete:*' min-input 1 + +# limit history backward search (up arrow) +zstyle ':autocomplete:history-search-backward:*' list-lines 20 + +# auto completion list "bright white" - https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit +zstyle ':completion:*' list-colors '=*=97' + + +# 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 one of the following lines to change the auto-update behavior +# zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# 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=(brew git pip python F-Sy-H zsh-autocomplete zsh-autosuggestions colored-man-pages kubectl) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='mvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch x86_64" + +# Set personal aliases, overriding those provided by oh-my-zsh libs, +# plugins, and themes. Aliases can be placed here, though oh-my-zsh +# users are encouraged to define aliases within the ZSH_CUSTOM folder. +# For a full list of active aliases, run `alias`. +# +# Example aliases +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" + +[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh +eval "$(atuin init zsh)" + +# go path +export PATH=$PATH:/usr/local/go/bin:~/go/bin \ No newline at end of file diff --git a/.devcontainer/zsh/install-tools-completions.sh b/.devcontainer/zsh/install-tools-completions.sh new file mode 100755 index 000000000..153c80e51 --- /dev/null +++ b/.devcontainer/zsh/install-tools-completions.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +gnmic completion zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gnmic" +# generate gnoic completions +gnoic completion zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gnoic" +# generate gh +gh completion -s zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gh" diff --git a/.devcontainer/zsh/install-zsh-plugins.sh b/.devcontainer/zsh/install-zsh-plugins.sh index 5181193a5..bde01a99f 100755 --- a/.devcontainer/zsh/install-zsh-plugins.sh +++ b/.devcontainer/zsh/install-zsh-plugins.sh @@ -20,9 +20,3 @@ git clone --depth 1 https://github.com/z-shell/F-Sy-H.git ${ZSH_CUSTOM:-$HOME/.o /usr/bin/containerlab completion zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_containerlab" # add clab alias to the completions sed -i 's/compdef _containerlab containerlab/compdef _containerlab containerlab clab/g' /home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_containerlab -# generate gnmic completions -gnmic completion zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gnmic" -# generate gnoic completions -gnoic completion zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gnoic" -# generate gh -gh completion -s zsh > "/home/vscode/.oh-my-zsh/custom/plugins/zsh-autocomplete/Completions/_gh" diff --git a/.github/workflows/build-devcontainer.yml b/.github/workflows/build-devcontainer.yml index 2b0f43bc6..c22bf4756 100644 --- a/.github/workflows/build-devcontainer.yml +++ b/.github/workflows/build-devcontainer.yml @@ -1,6 +1,11 @@ name: build-devcontainer on: workflow_call: + inputs: + CLAB_VERSION: + description: "Containerlab version" + required: true + type: string workflow_dispatch: inputs: CLAB_VERSION: @@ -25,6 +30,26 @@ env: jobs: devcontainer: runs-on: ubuntu-22.04 + strategy: + matrix: + variant: + - "dind" + - "dind-slim" + - "dood" + - "dood-slim" + include: + - variant: dind + devContFile: .devcontainer/docker-in-docker/devcontainer.json + image-suffix: "-dind" + - variant: dind-slim + devContFile: .devcontainer/docker-in-docker_slim/devcontainer.json + image-suffix: "-dind-slim" + - variant: dood + devContFile: .devcontainer/docker-outside-of-docker/devcontainer.json + image-suffix: "-dood" + - variant: dood-slim + devContFile: .devcontainer/docker-outside-of-docker_slim/devcontainer.json + image-suffix: "-dood-slim" steps: - name: Checkout repository uses: actions/checkout@v4 @@ -80,7 +105,8 @@ jobs: env: CLAB_VERSION: ${{ inputs.clab_version }} with: - imageName: ghcr.io/${{ github.repository }}/clab-devcontainer + imageName: ghcr.io/${{ github.repository }}/devcontainer${{ matrix.image-suffix }} imageTag: ${{ steps.extract-tags.outputs.tags }} push: always platform: linux/amd64,linux/arm64 + configFile: ${{ matrix.devContFile }} diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 06040e2be..09c6b43eb 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -18,14 +18,30 @@ env: PY_VER: "3.10" jobs: - file-changes: + process-gitref: runs-on: ubuntu-22.04 outputs: - code: ${{ steps.filter.outputs.code }} - docs: ${{ steps.filter.outputs.docs }} + source_name: ${{ steps.set-outputs.outputs.SOURCE_NAME }} + source_branch: ${{ steps.set-outputs.outputs.SOURCE_BRANCH }} + source_tag: ${{ steps.set-outputs.outputs.SOURCE_TAG }} + source_tag_no_prefix: ${{ steps.set-outputs.outputs.SOURCE_TAG_NO_PREFIX }} # exporting env vars to be used in invoked workflows py_ver: ${{ env.PY_VER }} go_ver: ${{ env.GO_VER }} + steps: + - id: set-outputs + run: | + echo "SOURCE_NAME=${GITHUB_REF#refs/*/}" >> "$GITHUB_OUTPUT" + echo "SOURCE_BRANCH=${GITHUB_REF#refs/heads/}" >> "$GITHUB_OUTPUT" + echo "SOURCE_TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "SOURCE_TAG_NO_PREFIX=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT" + + file-changes: + runs-on: ubuntu-22.04 + needs: process-gitref + outputs: + code: ${{ steps.filter.outputs.code }} + docs: ${{ steps.filter.outputs.docs }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 @@ -60,11 +76,13 @@ jobs: - '.github/workflows/cicd.yml' build-containerlab: - needs: file-changes + needs: + - file-changes + - process-gitref if: needs.file-changes.outputs.code == 'true' || startsWith(github.ref, 'refs/tags/v') uses: ./.github/workflows/build-containerlab.yml with: - go_ver: ${{ needs.file-changes.outputs.go_ver }} + go_ver: ${{ needs.process-gitref.outputs.go_ver }} staticcheck: runs-on: ubuntu-22.04 @@ -132,9 +150,10 @@ jobs: smoke-tests: uses: ./.github/workflows/smoke-tests.yml with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} needs: - file-changes + - process-gitref - build-containerlab ext-container-tests: @@ -247,9 +266,10 @@ jobs: srlinux-basic-tests: uses: ./.github/workflows/srlinux-tests.yml with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} needs: - file-changes + - process-gitref - build-containerlab ixiac-one-basic-tests: @@ -303,16 +323,18 @@ jobs: needs: - file-changes - build-containerlab + - process-gitref with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} kind-tests: uses: ./.github/workflows/kind-tests.yml needs: - file-changes - build-containerlab + - process-gitref with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} # sros-tests: # uses: ./.github/workflows/sros-tests.yml @@ -320,23 +342,25 @@ jobs: # - file-changes # - build-containerlab # with: - # py_ver: ${{ needs.file-changes.outputs.py_ver }} + # py_ver: ${{ needs.process-gitref.outputs.py_ver }} fortigate-tests: uses: ./.github/workflows/fortigate-tests.yml needs: - file-changes - build-containerlab + - process-gitref with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} cisco_iol-tests: uses: ./.github/workflows/cisco_iol-tests.yml needs: - file-changes - build-containerlab + - process-gitref with: - py_ver: ${{ needs.file-changes.outputs.py_ver }} + py_ver: ${{ needs.process-gitref.outputs.py_ver }} # a job that downloads coverage artifact and uses codecov to upload it coverage: @@ -488,9 +512,13 @@ jobs: - run: docker run -v $(pwd):/docs --user $(id -u):$(id -g) --entrypoint mkdocs ghcr.io/srl-labs/mkdocs-material-insiders:$MKDOCS_INS_VER gh-deploy --force --strict build-devcontainer: - if: startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-') != true - needs: build-and-release + if: startsWith(github.ref, 'refs/tags/v') + needs: + - build-and-release + - process-gitref uses: ./.github/workflows/build-devcontainer.yml + with: + CLAB_VERSION: ${{ needs.process-gitref.outputs.source_tag_no_prefix }} # update docs allows to make the docs changes outside of the release cycle # it skips the code build/release and proceeds with docs publishing diff --git a/docs/index.md b/docs/index.md index 58441da12..d28208a14 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,7 +2,7 @@ hide: - navigation --- -

+

[![github release](https://img.shields.io/github/release/srl-labs/containerlab.svg?style=flat-square&color=00c9ff&labelColor=bec8d2)](https://github.com/srl-labs/containerlab/releases/) [![Github all releases](https://img.shields.io/github/downloads/srl-labs/containerlab/total.svg?style=flat-square&color=00c9ff&labelColor=bec8d2)](https://github.com/srl-labs/containerlab/releases/) diff --git a/docs/install.md b/docs/install.md index caee1c9a1..bd27abf5b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -38,7 +38,7 @@ To install all components at once, run the following command on any of the suppo curl -sL https://containerlab.dev/setup | sudo -E bash -s "all" ``` -Complete installation and enable sudo-less `docker` command execution please run `newgrp docker` or logout and log back in. +To complete installation and enable sudo-less `docker` command execution, please run `newgrp docker` or logout and log back in. @@ -181,6 +181,16 @@ yum install https://github.com/srl-labs/containerlab/releases/download/v0.7.0/co /// The package installer will put the `containerlab` binary in the `/usr/bin` directory as well as create the `/usr/bin/clab -> /usr/bin/containerlab` symlink. The symlink allows the users to save on typing when they use containerlab: `clab `. +## Windows + +Containerlab runs on Windows powered by Windows Subsystem Linux (aka WSL), where you can run Containerlab directly or in a Devcontainer. Open up [Containerlab on Windows](windows.md) documentation for more details. + +## Apple macOS + +Running containerlab on macOS is possible both on ARM (M1/M2/M3/etc) and Intel chipsets. For a long time, we had many caveats around M-chipsets on Macs, but with the introduction of ARM64-native NOSes like Nokia SR Linux and Arista cEOS, powered by Rosetta emulation for x86_64-based NOSes, it is now possible to run containerlab on ARM-based Macs. + +Since we wanted to share our experience with running containerlab on macOS in details, we have created a separate - [Containerlab on macOS](macos.md) - guide. + ## Container Containerlab is also available in a container packaging. The latest containerlab release can be pulled with: @@ -244,31 +254,9 @@ tar -zxvf /tmp/clab.tar.gz -C /etc/containerlab mv /etc/containerlab/containerlab /usr/bin && chmod a+x /usr/bin/containerlab ``` -## Windows Subsystem Linux (WSL) - -Containerlab [runs](https://twitter.com/ntdvps/status/1380915270328401922) on WSL, but you need to [install docker-ce](https://docs.docker.com/engine/install/) inside the WSL2 linux system instead of using Docker Desktop[^2]. - -If you are running Ubuntu/Debian as your WSL2 machine, you can use the [quick setup this script](https://github.com/srl-labs/containerlab/blob/main/utils/quick-setup.sh) to install docker-ce. - -```bash -curl -L https://containerlab.dev/setup | sudo bash -s "install-docker" | \ -``` - -Once installed, issue `sudo service docker start` to start the docker service inside WSL2 machine. - -/// details | Running VM-based routers inside WSL -In Windows 11 with WSL2 it is now possible to [enable KVM support](https://serverfault.com/a/1115773/351978). Let us know if that worked for you in our [Discord](community.md). -/// - -## Apple macOS - -Running containerlab on macOS is possible both on ARM (M1/M2/M3/etc) and Intel chipsets. For a long time, we had many caveats around M-chipsets on Macs, but with the introduction of ARM64-native NOSes like Nokia SR Linux and Arista cEOS, powered by Rosetta emulation for x86_64-based NOSes, it is now possible to run containerlab on ARM-based Macs. - -Since we wanted to share our experience with running containerlab on macOS in details, we have created a separate - [Containerlab on macOS](macos.md) - guide. - ## Upgrade -To upgrade `containerlab` to the latest available version issue the following command[^3]: +To upgrade `containerlab` to the latest available version issue the following command[^2]: ``` sudo -E containerlab version upgrade @@ -337,6 +325,5 @@ or more globally: sudo setsebool -P selinuxuser_execmod 1 ``` -[^1]: Most containerized NOS will require >1 vCPU. RAM size depends on the lab size. Architecture: AMD64. IPv6 should not be disabled in the kernel. -[^2]: No need to uninstall Docker Desktop, just make sure that it is not integrated with WSL2 machine that you intend to use with containerlab. Moreover, you can make it even work with Docker Desktop with a [few additional steps](https://twitter.com/networkop1/status/1380976461641834500/photo/1), but installing docker-ce into the WSL maybe more intuitive. -[^3]: only available if installed from packages \ No newline at end of file +[^1]: Most containerized NOS will require >1 vCPU. RAM size depends on the lab size. IPv6 should not be disabled in the kernel. +[^2]: only available if installed from packages diff --git a/docs/macos.md b/docs/macos.md index ea8eb9ae8..10cf8a098 100644 --- a/docs/macos.md +++ b/docs/macos.md @@ -10,14 +10,16 @@ hide: type: subtle-note 1. Install [OrbStack](https://orbstack.dev)[^1] on your macOS -2. Create an **arm64** Linux VM using OrbStack or alternatives +2. Create an **arm64** Linux VM using OrbStack 3. Install containerlab in the VM using the usual [installation instructions](install.md) 4. Check what images can/should work on ARM64 5. Deploy your lab. You can see the demo of this workflow in [this YT video][yt-demo]. +Or use the [Devcontainer](#devcontainer) if running another VM is not your thing. + [yt-demo]: https://www.youtube.com/watch?v=_BTa-CiTpvI&t=1573s -If you run an Intel mac, you can still use OrbStack to deploy a VM, but you will not need to worry about ARM64 images, as your processor runs x86_64 natively. +If you run an Intel mac, you still use OrbStack to deploy a VM, but you will not need to worry about the hard-to-find ARM64 images, as your processor runs x86_64 natively. /// For quite some time, we have been saying that containerlab and macOS is a challenging mix. This statement has been echoed through multiple workshops/demos and was based on the following reasons: @@ -122,6 +124,7 @@ There are many software solutions that deliver Docker on macOS, both for Intel a - :star: [OrbStack](https://orbstack.dev/) - a great UX and performance. A choice of many and is recommended by Containerlab maintainer. Free for personal use. - [Docker Desktop](https://www.docker.com/products/docker-desktop/) - the original and the most popular Docker on macOS. - [Rancher Desktop](https://rancherdesktop.io/) - another popular software. +- [Container Desktop](https://container-desktop.com/) - a cross-platform solution. - [CoLima](https://github.com/abiosoft/colima) - a lightweight, CLI-based VM solution. The way most users use Containerlab on macOS, though, not directly leveraging Docker that is provided by one of the above solutions. Instead, it might be easier to spin up a VM, powered by the above-mentioned software products, and install Containerlab natively inside this arm64/Linux VM. @@ -129,29 +132,66 @@ You can see this workflow demonstration in this [YT video][yt-demo]. ## Devcontainer -Another option to run containerlab on ARM or Intel Macs is to use the Docker in Docker approach which is enabled by our Devcontainer. +Another convenient option to run containerlab on ARM/Intel Macs (and [Windows](windows.md#devcontainer)) is to use the [Devcontainer](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers) feature that works great with VS Code and many other IDE's. + +A development container (or devcontainer) allows you to use a container as a full-featured development environment. By creating the `devcontainer.json`[^4] file, you define the development environment for your project. Containerlab project maintains a set of pre-built multi-arch devcontainer images that you can use to run containerlabs. +It was initially created to power [containerlab in codespaces](manual/codespaces.md), but it is a perfect fit for running containerlab on a **wide range of OSes** such as macOS and Windows. -Containerlab's devcontiner was created to power [containerlab in codespaces](manual/codespaces.md), but it is a perfect fit for running containerlab on **any macOS** as it uses the docker-in-docker method where an isolated instance of a docker daemon is created inside a container. +/// note | Requirements -/// note -Starting with **Containerlab v0.60.0**, you can use the devcontainer with ARM64 macOS to run containerlab. +1. Starting with **Containerlab v0.60.0**, you can use the devcontainer with ARM64 macOS to run containerlabs. +2. VS Code [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) needs to be installed to use this feature with VS Code. /// -To start using the devcontainer, you have to create a `devcontainer.json` file in your project directory where you have your containerlab topology. If you're using Containerlab the right way, your labs are neatly stored in a git repo, the `devcontainer.json` file will be in the root of the repo by the `.devcontainer/devcontainer.json` path. +To start using the devcontainer, you have to create a `devcontainer.json` file in your project directory where you have your containerlab topology. If you're using Containerlab the right way, your labs are neatly stored in a git repo; in this case the `devcontainer.json` file will be part of the repo. + +If you prefer a video tutorial, we've got you covered, else continue reading. + +-{{youtube(url='https://www.youtube.com/embed/Xue1pLiO0qQ')}}- + +### Devcontainer flavors + +Containerlab provides two types of devcontainer images: + +

Docker In Docker (dind)

+defined in the [.devcontainer directory](https://github.com/srl-labs/containerlab/tree/main/.devcontainer) and tagged with + +- [regular image](https://github.com/srl-labs/containerlab/pkgs/container/containerlab%2Fdevcontainer-dind): `ghcr.io/srl-labs/containerlab/devcontainer-dind:` +- [slim image](https://github.com/srl-labs/containerlab/pkgs/container/containerlab%2Fdevcontainer-dind-slim): `ghcr.io/srl-labs/containerlab/devcontainer-dind-slim:` + +where `` is the containerlab version without the `v` prefix. + +Docker In Docker variant provides an **isolated** docker environment inside the devcontainer. This means, that the docker daemon inside the devcontainer is not connected to the docker daemon on your host, you will not see the containers/images that you have on your host. + +This version is best to be used with [Codespaces](manual/codespaces.md). + +

Docker Outside Of Docker (dood)

+defined in the [.devcontainer directory](https://github.com/srl-labs/containerlab/tree/main/.devcontainer) and tagged with + +- [regular image](https://github.com/srl-labs/containerlab/pkgs/container/containerlab%2Fdevcontainer-dood): `ghcr.io/srl-labs/containerlab/devcontainer-dood:` +- [slim image](https://github.com/srl-labs/containerlab/pkgs/container/containerlab%2Fdevcontainer-dood-slim): `ghcr.io/srl-labs/containerlab/devcontainer-dood-slim:` + +where `` is the containerlab version without the `v` prefix. -Note, the labs that we publish with Codespaces support already have the `devcontainer.json` file, in that case you don't even need to create it manually. +Docker Outside Of Docker variant uses the docker daemon on your host, so inside your devcontainer image you will see the images and containers that you have on your host. This variant is likely best to be on your local machine running macOS or Windows. -If you create the `devcontainer.json` file manually, you won't need to be smart about the content of the file, all you have to specify is the containerlab version you want to run. Here is an example of the `devcontainer.json` file: +When running in this mode, VS Code will ask you to provide a path to the workspace first time you open the devcontainer. You should select the path to the repository on your host in the dialog. -```json title="./devcontainer/devcontainer.json" +The labs that we publish with Codespaces support often already have the `devcontainer.json` files, in that case you don't even need to create them manually. + +### Docker In Docker (dind) + +If you intend to run a docker-in-docker version of the devcontainer, create the `.devcontainer/docker-in-docker/devcontainer.json` file at the root of your repo with the following content: + +```json title="./devcontainer/docker-in-docker/devcontainer.json" { - "image": "ghcr.io/srl-labs/containerlab/clab-devcontainer:0.60.0" //(1)! + "image": "ghcr.io/srl-labs/containerlab/devcontainer-dind-slim:0.60.0" //(1)! } ``` 1. devcontainer versions match containerlab versions -With the devcontainer file in place, when you open a repo in VS Code, you will be prompted to reopen the workspace in the devcontainer. +With the devcontainer file in place, when you open a repo in VS Code, you will be prompted to reopen the workspace in the devcontainer. Or you can press F1 and select `Dev Containers: Rebuild and Reopen in Container`. ![img1](https://gitlab.com/rdodin/pics/-/wikis/uploads/ee918d1d5d85d83f45ced031c5fa999d/image.png) @@ -159,40 +199,37 @@ Clicking on this button will open the workspace in the devcontainer; you will se Open a terminal in the VS Code and run the topology by typing the familiar `sudo clab dep` command to deploy the lab. That's it! -## Alternative options - -### UTM +### Docker Outside Of Docker (dood) -If OrbStack for some reason can not be used in your environment, you can use [UTM](https://mac.getutm.app/) - a free[^4] and open-source graphical virtual machine manager that provides a simple interface for creating, managing, and running virtual machines with qemu. +The docker-in-docker method of running a devcontainer is great for Codespaces, but when running on your local machine you might want to use the images that your have already pulled in your host's docker or see the containers that might be running on your host. In these cases, the isolation that docker-in-docker provides stands in the way, and it also have some performance implications. -When you have UTM installed, you can download a pre-built Debian 12 UTM image built by the Containerlab team using the following command[^5]: +That's why we also have the docker-outside-of-docker (dood) variant of the devcontainer. To use this variant create the `.devcontainer/docker-outside-of-docker/devcontainer.json` file will have more meat in it, since we need to mount some host directories for containerlab to be able to do its magic: -```bash -sudo docker run --rm -v $(pwd):/workspace ghcr.io/oras-project/oras:v1.1.0 pull \ - ghcr.io/srl-labs/containerlab/clab-utm-box:0.1.0 +```json title="./devcontainer/docker-outside-of-docker/devcontainer.json" +{ + "image": "ghcr.io/srl-labs/containerlab/devcontainer-dood-slim:0.60.0", //(1)! + "runArgs": [ + "--network=host", + "--pid=host", + "--privileged" + ], + "mounts": [ + "type=bind,src=/run/docker/netns,dst=/run/docker/netns", + "type=bind,src=/var/lib/docker,dst=/var/lib/docker", + "type=bind,src=/lib/modules,dst=/lib/modules" + ], + "workspaceFolder": "${localWorkspaceFolder}", + "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind" +} ``` -By running this command you will download the `clab_debian12.utm` file which is a UTM image with `containerlab`, `docker-ce` and `gh` tools pre-installed[^6]. - -Open the downloaded image with UTM **File -> Open -> select .utm file** and start the VM. - -Once the VM is started, you can log in using `debian:debian` credentials. Run `ip -4 addr` in the terminal to find out which IP got assigned to this VM. -Now you can use this IP for your Mac terminal to connect to the VM via SSH[^7]. - -When logged in, you can upgrade the containerlab to the latest version with: - -```bash -sudo clab version upgrade -``` +1. The devcontainer version matches the containerlab version. The rest of the file does not change and can be copy pasted. -and start downloading the labs you want to run. +You can have both docker-in-docker and docker-outside-of-docker variants of the devcontainer file in your repo, and your IDE will be able to switch between them. [^1]: Or any other application that enables Docker on macOS. OrbStack is just a great choice that is used by many. [^2]: With Microsoft Surface laptop released with ARM64 architecture [^3]: The same principles apply to Docker Desktop on Windows -[^4]: There are two options to install UTM: via [downloadable dmg](https://github.com/utmapp/UTM/releases/latest/download/UTM.dmg) file (free) or App Store (paid). The App Store version is exactly the same, it is just a way to support the project. -[^5]: This command requires docker to be installed on your macOS. You can use Docker Desktop, Rancher or [colima](https://github.com/abiosoft/colima) to run docker on your macOS. -[^6]: If you want to install these tools on an existing Debian machine, you can run `wget -qO- containerlab.dev/setup-debian | bash -s -- all` command. -[^7]: The UTM image has a pre-installed ssh key for the `debian` user. You can download the shared private key from [here](https://github.com/srl-labs/clabernetes/blob/main/launcher/assets/default_id_rsa). +[^4]: Follows the devcontainer [specification](https://containers.dev/) diff --git a/docs/windows.md b/docs/windows.md new file mode 100644 index 000000000..4c1030b2f --- /dev/null +++ b/docs/windows.md @@ -0,0 +1,125 @@ +--- +comments: true +hide: +- navigation +--- + +# Containerlab on Windows + +By leveraging the [Windows Subsystem Linux (aka WSL)](https://learn.microsoft.com/en-us/windows/wsl/) you can run Containerlabs on Windows almost like on Linux. WSL allows Windows users to run a lightweight Linux VM inside Windows, and we can leverage this to run containerlab. + +There are two primary ways of running containerlab on Windows: + +1. Running containerlab directly in the WSL VM. +2. Running containerlab inside a [Devcontainer](https://code.visualstudio.com/docs/devcontainers/containers) inside WSL. + +We will cover both of these ways in this document, but first let's quickly go over the WSL setup. + +/// admonition | Windows and WSL version +The following instructions were tested on Windows 11 and WSL2. On Windows 10 some commands may be different, but the general idea should be the same. +/// + +## Setting up WSL + +WSL takes the central role in running containerlabs on Windows. Luckily, setting up WSL is very easy, and there are plenty of resources online from blogs to YT videos explaining the bits and pieces. Here we will provide some CLI-centric[^1] instructions that were executed on Windows 11. + +First things first, open up a terminal and list the running WSL virtual machines and their versions: + +```bash +wsl -l -v +``` + +
+```{.text .no-select .no-copy} + NAME STATE VERSION +* Ubuntu Running 2 +``` +
+ +On this system we already have a WSL VM with Ubuntu OS running, which was created when we installed WSL on Windows. If instead of a list of WSL VMs you get an error, you need to install WSL first: + +```bash title="Installing WSL on Windows 11" +wsl --install +``` + +Installing WSL on Windows 11 will by default install the Ubuntu distribution. While it is perfectly fine to use it, we prefer Debian, so let's remove Ubuntu and install Debian instead: + +```bash title="Removing Ubuntu and installing Debian" +wsl --unregister Ubuntu #(1)! +wsl --install -d Debian #(1)! +``` + +1. Unregistering a WSL VM will remove the VM. You should reference a WSL instance by the name you saw in the `wsl -l -v` command. +2. Installing a new WSL system will prompt you to choose a username and password. + +Once the installation is complete, you will enter the WSL shell, which is a regular Linux shell[^2]. + +It is recommended to reboot your Windows system after installing the WSL. When the reboot is done you have a working WSL system that can run containerlab, congratulations! + +## Installing docker and containerlab on WSL + +Now that we have a working WSL system, we can install docker and containerlab on it like we would on any Linux system. + +/// danger | WSL2 and Docker Desktop +If you have Docker Desktop[^3] installed on your Windows system, you need to ensure that it is not enabled for the WSL VM that we intend to use for containerlabs. +To check that your WSL system is "free" from Docker Desktop integration, run `sudo docker version` command and ensure that you have an error message saying that `docker` command is not found. + +Check Docker Desktop settings to see how to disable Docker Desktop integration with WSL2 if the above command **does not** return an expected error. +/// + +We are going to use the [quick setup script](install.md#quick-setup) to install docker and containerlab, but since this script uses `curl`, we need to install it first: + +```bash +sudo apt update && sudo apt -y install curl +``` + +and then run the quick setup script: + +--8<-- "docs/install.md:quick-setup-script-cmd" + +Now you should be able to run the `docker version` command and see the version of docker installed. That was easy, wasn't it? + +The installation script also installs containerlab, so you can run `clab version` to see the version of containerlab installed. This means that containerlab is installed in the WSL VM and you can run containerlabs in a normal way, like you would on Linux. + +/// details | Running VM-based routers inside WSL? + type: subtle-question +In Windows 11 with WSL2 it is now possible to [enable KVM support](https://serverfault.com/a/1115773/351978). Let us know if that worked for you in our [Discord](community.md). +/// + +## Devcontainer + +Another convenient option to run containerlab on Windows (and [macOS](macos.md#devcontainer)) is to use the [Devcontainer](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers) feature that works great with VS Code and many other IDE's. + +A development container (or devcontainer) allows you to use a container as a full-featured development environment. By creating the `devcontainer.json`[^4] file, you define the development environment for your project. Containerlab project maintains a set of pre-built multi-arch devcontainer images that you can use to run containerlabs. +It was initially created to power [containerlab in codespaces](manual/codespaces.md), but it is a perfect fit for running containerlab on a **wide range of OSes** such as macOS and Windows. + +Since the devcontainer works exactly the same way on Windows and macOS, [please refer to the macOS](macos.md#devcontainer) section for the detailed documentation and a video walkthrough. + +A few things to keep in mind when using devcontainers on windows: + +1. If using VS Code, you will need to install the server component in your WSL instance, this will require you to install `wget`, as VS Code installer requires it. + + ```bash + sudo apt -y install wget + ``` + + Then you will be able to type `code .` in the cloned repository to open the project in VS Code. +2. As with macOS, you will likely wish to use a Docker-outside-of-Docker method, where the devcontainer will have access to the images and containers from the WSL VM. + +[^1]: If you don't have a decent terminal emulator on Windows, install "Windows Terminal" from the Microsoft Store. +[^2]: The kernel and distribution parameters can be checked as follows: + + ```bash + roman@Win11:~$ uname -a + Linux LAPTOP-H6R3238F 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 GNU/Linux + ``` + + ```bash + roman@Win11:~$ cat /etc/os-release + PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" + NAME="Debian GNU/Linux" + VERSION_ID="12" + ``` + +[^3]: Or any other desktop docker solution like Rancher Desktop, Podman Desktop, etc. +[^4]: Follows the devcontainer [specification](https://containers.dev/)