Source Code

Visual Studio Code Remote Development is a new feature that allows for developing in a remote OS or a container. The reason I have stayed away from writing my code inside a Docker container was because I like to run things and debug them as I write them in VSCode.

devcontainer

The devcontainer.json file will reside in the project folder inside a folder called .devcontainer. This file tells VSCode the information it needs to run the container.

devcontainer.json


{
    "name": "Netops Docker",
    "dockerFile": "Dockerfile",
    "extensions": [
        "peterjausovec.vscode-docker",
        "ms-python.python",
        "redhat.vscode-yaml"

    ],
    "runArgs": ["-v","/var/run/docker.sock:/var/run/docker.sock"]
}

The file tells VScode to build the container using the Dockerfile in the .devcontainer directory. The extensions key installs VSCode extensions on the container that cannot run locally. Finally the ‘RunArgs’ key is for Docker in Docker communication.

Dockerfile

The Dockerfile has all of the applications and settings to duplicate my local dev environment. The full file is below, I will step through a few import parts as it relates to VScode.

Dockerfile

# Image currently locked to debian buster. 
FROM debian:buster

# Copy settings file so Docker extension is installed inside the container
COPY settings.vscode.json /root/.vscode-remote/data/Machine/settings.json

# Configure apt
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
  apt-get -y install --no-install-recommends apt-utils 2>&1

# Install Update Apt and install apps
RUN  apt-get update && \
  apt-get install -y zsh \ 
  fonts-powerline \ 
  wget \
  git \
  vim \
  locales \
  sudo \
  procps \
  apt-transport-https \
  ca-certificates \
  curl gnupg-agent \
  software-properties-common \
  lsb-release \
  curl \
  python3-pip && \
  wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true && \
  git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting && \
  git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions && \
  echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
  locale-gen && \
  # Install Docker CE CLI
  curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT) && \
  add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" && \
  apt-get update && \
  apt-get install -y docker-ce-cli

# Workaround for VSCODE https://bit.ly/2Ya0ExA
RUN echo "if [ -t 1 ]; then" >> /root/.bashrc
RUN echo "exec zsh" >> /root/.bashrc
RUN echo "fi" >> /root/.bashrc

# Install Python Libraries
RUN pip3 install ansible \
  napalm \
  netmiko \
  nornir \
  ipython \
  pylint \
  flake8

# Configure oh-my-zsh
COPY .zshrc /root/.zshrc

# Copy RSA key and set private key permissions
COPY id_rsa /root/.ssh/id_rsa
COPY id_rsa.pub /root/.ssh/id_rsa.pub
RUN chmod 400 /root/.ssh/id_rsa

# terminal colors with xterm
ENV TERM xterm

# run zsh
CMD ["zsh"]

# Clean up
RUN apt-get autoremove -y && \
  apt-get clean -y && \
  rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=dialog

# Image currently locked to debian buster. 
FROM debian:buster

# Copy settings file so Docker extension is installed inside the container
COPY settings.vscode.json /root/.vscode-remote/data/Machine/settings.json

The image will work with both Debian Buster and Ubuntu Bionic. I am using debian out of personal preference. The settings.vscode.json contents are for Docker in Docker.

# Install Python Libraries
RUN pip3 install ansible \
  napalm \
  netmiko \
  nornir \
  ipython \
  pylint \
  flake8

# Configure oh-my-zsh
COPY .zshrc /root/.zshrc

# Copy RSA key and set private key permissions
COPY id_rsa /root/.ssh/id_rsa
COPY id_rsa.pub /root/.ssh/id_rsa.pub
RUN chmod 400 /root/.ssh/id_rsa

Python3 is installed early in the file. The Libraries I use most often are installed via pip. I have a custom oh-my-zsh configuration file in the .devcontainer folder that will replace the default one during the build process. Finally, I copy over my RSA key and set permissions.

Bringing up the container

The project folder looks like this.

projectfolder

The script is the folder is a Napalm script and I don’t have Naplam installed that is why the python file is highlighted in red. The container will fix this. Now we just have to hit F1 then type Remote-Containers: Reopen Folder in Container. I know it has never been open in the container before, but that is the way the instructions say to do it, I am assuming this is because this is a preview feature and its not fully polished.

The project folder now looks like this.

projectfolder

Running the script

Let’s look at the napalm_test.py script.

#!/usr/bin/env python3

# Script to test vscode remote containers
from napalm import get_network_driver
driver = get_network_driver('eos')
with driver('192.168.128.201', 'admin', 'admin') as device:
    print(device.get_facts())

I have a vEOS switch running and we are going to connect to and it print out the return of the get facts function.

postrun

It works. It ran my local file just as if I was running in my own terminal. Now I can have the same environment no matter which machine or OS i am using. Here is the Source Code used in this post.