Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Dockerfile update #707

Merged
merged 5 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions DOCKER-EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Examples of using the Docker image

To run this as a Docker container, which includes JSNAPy and PyEZ, simply pull it from the Docker hub and run it. The following will pull the latest image and run it in an interactive ash shell.

docker run -it --rm juniper/pyez-ansible

Although, you'll probably want to bind mount a host directory (perhaps the directory containing your playbooks and associated files). The following will bind mount the current working directory and start the ash shell.

docker run -it --rm -v $PWD:/project juniper/pyez-ansible

You can also use the container as an executable to run your playbooks. Let's assume we have a typical playbook structure as below:

example
|playbook.yml
|hosts
|-vars
|-templates
|-scripts

We can move to the example directory and run the playbook with the following command:

cd example/
docker run -it --rm -v $PWD:/playbooks juniper/pyez-ansible ansible-playbook -i hosts playbook.yml

You can pass any valid command string after the container name and it will be passed to Bash for execution.

You may have noticed that the base command is almost always the same. We can also use an alias to save some keystrokes.

alias pb-ansible="docker run -it --rm -v $PWD:/project juniper/pyez-ansible ansible-playbook"
pb-ansible -i hosts playbook.yml

### Extending the container with additional packages

It's possible to install additional OS (Alpine) packages, Python packages (via pip), and Ansible collections at container instantiation. This can be done by passing in environment variables or binding mount files.

#### OS Packages

Environment Variable: `$APK`
Bind Mount: `/extras/apk.txt`
File Format: list of valid Alpine packages, one per line
Examples:

As an environment variable, where the file containing a list of packages is in the current directory.

docker run -it --rm -v $PWD:/project -e APK="apk.txt" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/apk.txt:/extras/apk.txt juniper/pyez-ansible

#### Python Packages

Environment Variable: `$REQ`
Bind Mount: `/extras/requirements.txt`
File Format: pip [requirements](https://pip.pypa.io/en/stable/reference/requirements-file-format/) file

Examples:

docker run -it --rm -v $PWD:/project -e REQ="requirements.txt" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/requirements.txt:/extras/requirements.txt juniper/pyez-ansible

#### Ansible Packages

Environment Variable: `$COLLECTIONS`
Bind Mount: `/extras/requirements.yml`
File Format: Ansible [requirements](https://docs.ansible.com/ansible/devel/user_guide/collections_using.html#install-multiple-collections-with-a-requirements-file) file


Examples:

docker run -it --rm -v $PWD:/project -e REQ="requirements.yml" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/requirements.txt:/extras/requirements.yml juniper/pyez-ansible
39 changes: 21 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
FROM juniper/pyez:2.5.3
FROM python:3.12-alpine

LABEL net.juniper.image.maintainer="Juniper Networks <[email protected]>" \
net.juniper.image.description="Lightweight image with Ansible and the Junos roles"

RUN apk add --no-cache build-base python3-dev py3-pip \
openssl-dev curl ca-certificates bash openssh-client

WORKDIR /tmp
COPY requirements.txt .
RUN pip3 install -r requirements.txt

RUN apk del -r --purge gcc make g++ &&\
rm -rf /source/* &&\
rm -rf /var/cache/apk/* &&\
rm -rf /tmp/*
## Copy project inside the containers
ADD requirements.txt .
ADD entrypoint.sh /usr/local/bin/.

## Install dependencies and PyEZ
RUN apk add --no-cache build-base python3-dev py3-pip \
libxslt-dev libxml2-dev libffi-dev openssl-dev curl \
ca-certificates py3-pip bash openssh-client

WORKDIR /usr/share/ansible/collections/ansible_collections/
COPY ansible_collections/ .
RUN pip install --upgrade pip \
&& python3 -m pip install -r requirements.txt

WORKDIR /usr/bin
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
# Also install the collections juniper.device
# Install Ansible modules in one layer
RUN ansible-galaxy collection install juniper.device

# Also install the roles, until collections is ready for prime-time
RUN ansible-galaxy role install Juniper.junos,2.4.3
## Clean up and start init
RUN apk del -r --purge gcc make g++ \
&& rm -rf /var/cache/apk/* \
&& rm -rf /tmp/* \
&& rm -rf /root/.cache \
&& chmod +x /usr/local/bin/entrypoint.sh

WORKDIR /project

VOLUME /project

ENTRYPOINT ["/usr/bin/entrypoint.sh"]
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
80 changes: 0 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,86 +120,6 @@ This will set your `$ANSIBLE_LIBRARY` variable to the repo location and the inst
$ echo $ANSIBLE_LIBRARY
/home/jeremy/Ansible/ansible-junos-stdlib/library:/usr/share/ansible

### Docker

To run this as a Docker container, which includes JSNAPy and PyEZ, simply pull it from the Docker hub and run it. The following will pull the latest image and run it in an interactive ash shell.

docker run -it --rm juniper/pyez-ansible

Although, you'll probably want to bind mount a host directory (perhaps the directory containing your playbooks and associated files). The following will bind mount the current working directory and start the ash shell.

docker run -it --rm -v $PWD:/project juniper/pyez-ansible

You can also use the container as an executable to run your playbooks. Let's assume we have a typical playbook structure as below:

example
|playbook.yml
|hosts
|-vars
|-templates
|-scripts

We can move to the example directory and run the playbook with the following command:

cd example/
docker run -it --rm -v $PWD:/playbooks juniper/pyez-ansible ansible-playbook -i hosts playbook.yml

You can pass any valid command string after the container name and it will be passed to Bash for execution.

You may have noticed that the base command is almost always the same. We can also use an alias to save some keystrokes.

alias pb-ansible="docker run -it --rm -v $PWD:/project juniper/pyez-ansible ansible-playbook"
pb-ansible -i hosts playbook.yml

### Extending the container with additional packages

It's possible to install additional OS (Alpine) packages, Python packages (via pip), and Ansible collections at container instantiation. This can be done by passing in environment variables or binding mount files.

#### OS Packages

Environment Variable: `$APK`
Bind Mount: `/extras/apk.txt`
File Format: list of valid Alpine packages, one per line
Examples:

As an environment variable, where the file containing a list of packages is in the current directory.

docker run -it --rm -v $PWD:/project -e APK="apk.txt" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/apk.txt:/extras/apk.txt juniper/pyez-ansible

#### Python Packages

Environment Variable: `$REQ`
Bind Mount: `/extras/requirements.txt`
File Format: pip [requirements](https://pip.pypa.io/en/stable/reference/requirements-file-format/) file

Examples:

docker run -it --rm -v $PWD:/project -e REQ="requirements.txt" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/requirements.txt:/extras/requirements.txt juniper/pyez-ansible

#### Ansible Packages

Environment Variable: `$ROLES`
Bind Mount: `/extras/requirements.yml`
File Format: Ansible [requirements](https://docs.ansible.com/ansible/devel/user_guide/collections_using.html#install-multiple-collections-with-a-requirements-file) file

_NOTE:_ This works for collections as well as roles.

Examples:

docker run -it --rm -v $PWD:/project -e REQ="requirements.yml" juniper/pyez-ansible

As a bind mount.

docker run -it --rm -v $PWD/requirements.txt:/extras/requirements.yml juniper/pyez-ansible

## Example Playbook

This example outlines how to use Ansible to install or upgrade the software image on a device running Junos OS.
Expand Down
10 changes: 5 additions & 5 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function pip_install {
}

function galaxy_install {
echo "Install Ansible roles"
echo "Install Ansible Collections"
ansible-galaxy install -r "$1"
}

Expand All @@ -38,17 +38,17 @@ elif [ -f "/extras/requirements.txt" ];then REQ="/extras/requirements.txt"
else REQ=''
fi

if [ "$ROLES" ]; then ROLES=$ROLES
elif [ -f "/extras/requirements.yml" ]; then ROLES="/extras/requirements.yml"
else ROLES=''
if [ "$COLLECTIONS" ]; then COLLECTIONS=$COLLECTIONS
elif [ -f "/extras/requirements.yml" ]; then COLLECTIONS="/extras/requirements.yml"
else COLLECTIONS=''
fi


[[ -z "$APK" ]] || apk_add "$APK"

[[ -z "$REQ" ]] || pip_install "$REQ"

[[ -z "$ROLES" ]] || galaxy_install "$ROLES"
[[ -z "$COLLECTIONS" ]] || galaxy_install "$COLLECTIONS"

if [ -z "$1" ]
then
Expand Down