From 78630363d3bca708a4cf1fdcd398a8bb8fa98511 Mon Sep 17 00:00:00 2001 From: chidanandpujar Date: Tue, 10 Dec 2024 16:55:23 +0530 Subject: [PATCH 1/5] Dockerfile update --- Dockerfile | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index e78a4023..180c6263 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,36 @@ -FROM juniper/pyez:2.5.3 +FROM python:3.12-alpine LABEL net.juniper.image.maintainer="Juniper Networks " \ 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 /source -WORKDIR /tmp -COPY requirements.txt . -RUN pip3 install -r requirements.txt +## Copy project inside the containers +ADD setup.* ./ +ADD requirements.txt . +ADD entrypoint.sh /usr/local/bin/. -RUN apk del -r --purge gcc make g++ &&\ - rm -rf /source/* &&\ - rm -rf /var/cache/apk/* &&\ - rm -rf /tmp/* +## 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 \ + && pip install pipdeptree \ + && python3 -m pip install -r requirements.txt -WORKDIR /usr/bin -COPY entrypoint.sh . -RUN chmod +x entrypoint.sh +# Also install the collections junipernetworks.junos and juniper.device +# Install Ansible modules in one layer +RUN ansible-galaxy collection install junipernetworks.junos && \ + 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 /source/* \ + && chmod +x /usr/local/bin/entrypoint.sh WORKDIR /project VOLUME /project -ENTRYPOINT ["/usr/bin/entrypoint.sh"] +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] From b9302377e316409e951b7c27c97a43e34a1fdccd Mon Sep 17 00:00:00 2001 From: chidanandpujar Date: Wed, 18 Dec 2024 16:12:22 +0530 Subject: [PATCH 2/5] Dockerfile update --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 180c6263..0138a77d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,10 +3,9 @@ FROM python:3.12-alpine LABEL net.juniper.image.maintainer="Juniper Networks " \ net.juniper.image.description="Lightweight image with Ansible and the Junos roles" -WORKDIR /source +WORKDIR /tmp ## Copy project inside the containers -ADD setup.* ./ ADD requirements.txt . ADD entrypoint.sh /usr/local/bin/. From 91e50cceda87e84a25cb399ad5c7f3fab75ac3f4 Mon Sep 17 00:00:00 2001 From: chidanandpujar Date: Wed, 18 Dec 2024 16:14:17 +0530 Subject: [PATCH 3/5] Dockerfile update --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0138a77d..3decf34b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,6 @@ RUN ansible-galaxy collection install junipernetworks.junos && \ ## Clean up and start init RUN apk del -r --purge gcc make g++ \ - && rm -rf /source/* \ && chmod +x /usr/local/bin/entrypoint.sh WORKDIR /project From 66d516fef641175868a193f827db571962c8ecd0 Mon Sep 17 00:00:00 2001 From: chidanandpujar Date: Wed, 18 Dec 2024 17:05:18 +0530 Subject: [PATCH 4/5] Dockerfile update --- DOCKER-EXAMPLES.md | 78 ++++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 9 +++--- README.md | 53 +------------------------------ entrypoint.sh | 10 +++--- 4 files changed, 89 insertions(+), 61 deletions(-) create mode 100644 DOCKER-EXAMPLES.md diff --git a/DOCKER-EXAMPLES.md b/DOCKER-EXAMPLES.md new file mode 100644 index 00000000..ea927c87 --- /dev/null +++ b/DOCKER-EXAMPLES.md @@ -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 diff --git a/Dockerfile b/Dockerfile index 3decf34b..cce6b48d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,16 +15,17 @@ RUN apk add --no-cache build-base python3-dev py3-pip \ ca-certificates py3-pip bash openssh-client RUN pip install --upgrade pip \ - && pip install pipdeptree \ && python3 -m pip install -r requirements.txt -# Also install the collections junipernetworks.junos and juniper.device +# Also install the collections juniper.device # Install Ansible modules in one layer -RUN ansible-galaxy collection install junipernetworks.junos && \ - ansible-galaxy collection install juniper.device +RUN ansible-galaxy collection install juniper.device ## 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 diff --git a/README.md b/README.md index 88360e98..d5943f96 100644 --- a/README.md +++ b/README.md @@ -120,56 +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` @@ -186,11 +136,10 @@ As a bind mount. #### Ansible Packages -Environment Variable: `$ROLES` +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 -_NOTE:_ This works for collections as well as roles. Examples: diff --git a/entrypoint.sh b/entrypoint.sh index 1fc1d0c4..87be8428 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -18,7 +18,7 @@ function pip_install { } function galaxy_install { - echo "Install Ansible roles" + echo "Install Ansible Collections" ansible-galaxy install -r "$1" } @@ -38,9 +38,9 @@ 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 @@ -48,7 +48,7 @@ fi [[ -z "$REQ" ]] || pip_install "$REQ" -[[ -z "$ROLES" ]] || galaxy_install "$ROLES" +[[ -z "$COLLECTIONS" ]] || galaxy_install "$COLLECTIONS" if [ -z "$1" ] then From 0b1270e54f669a5e09f744fe9f16efe284771c18 Mon Sep 17 00:00:00 2001 From: chidanandpujar Date: Wed, 18 Dec 2024 17:09:26 +0530 Subject: [PATCH 5/5] Dockerfile update --- README.md | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/README.md b/README.md index d5943f96..55c1479f 100644 --- a/README.md +++ b/README.md @@ -120,35 +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 -#### 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 - ## Example Playbook This example outlines how to use Ansible to install or upgrade the software image on a device running Junos OS.