diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0fce7be --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "docker" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..40826a3 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,34 @@ +name: "Build docker image and push to DockerHub when a tag is pushed" + +on: + workflow_dispatch: + push: + tags: + - "*" + +jobs: + build: + name: "Build images" + runs-on: "ubuntu-latest" + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Docker metadata from Git + id: meta + uses: docker/metadata-action@v5 + with: + images: evilfreelancer/docker-routeros + - name: Login to DockerHub + if: ${{ !env.ACT }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build with Docker + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ !env.ACT }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8d069bb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: "Continuous Integration Tests" + +on: + push: + pull_request: + workflow_dispatch: + workflow_call: + +jobs: + test: + name: "Build & Test images" + runs-on: "ubuntu-latest" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download docker-compose when using act + if: env.ACT + run: | + sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + + - name: Test with Docker + run: | + # start the container + docker-compose -f docker-compose.dist.yml up --build -d routeros-local + # wait for the container to start + sleep 5 + DOCKERID=$(docker ps --format '{{.ID}}.{{.Names}}.{{.Image}}'|grep evilfreelancer/docker-routeros|cut -f 1 -d '.') + echo "Watching $DOCKERID for Mikrotik login..." + while true + do + if docker logs "$DOCKERID" 2>&1|grep 'MikroTik' + then + break + fi + echo "Not found yet, sleeping..." + sleep 5 + done + # display logs + echo "Container logs:" + docker logs "$DOCKERID" + # download resource and check platform is Mikrotik + curl --retry 12 --retry-all-errors -k -u admin: http://127.0.0.1:7777/rest/system/resource | jq .platform |grep -i mikrotik + + - name: Stop container + run: docker-compose -f docker-compose.dist.yml down diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..dbb13a9 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,14 @@ +name: Lint github-action + +on: [ 'pull_request' ] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Lint + uses: docker://rhysd/actionlint:1.6.26 + with: + args: -color diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..60bd332 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,47 @@ +name: "Check for update on Mikrotik website and generate a PR if necessary" + +on: + workflow_dispatch: + schedule: + - cron: "0 4 * * *" + +jobs: + routeros: + name: "Build & Test images" + runs-on: "ubuntu-latest" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: '1' + + - name: Check new release + id: check_release + run: | + LAST_MIKROTIK_RELEASE=$(curl https://mikrotik.com/download/archive -o - 2>/dev/null | grep -o ' "$GITHUB_OUTPUT" + echo "new=true" >> "$GITHUB_OUTPUT" + else + echo "No new version found" + echo "new=false" >> "$GITHUB_OUTPUT" + fi + + - name: Edit Dockerfile + if: ${{ steps.check_release.outputs.new == 'true' }} + run: | + sed -r "s/(ROUTEROS_VERSION=\")(.*)(\")/\1${{ steps.check_release.outputs.release }}\3/g" -i Dockerfile + git diff + + - name: Create Pull Request + if: ${{ steps.check_release.outputs.new == 'true' && !env.ACT }} + uses: peter-evans/create-pull-request@v6 + with: + commit-message: "Update RouterOS version to ${{ steps.check_release.outputs.release }}" + committer: "GitHub Actions" + body: 'Created by Github action' + title: 'Update RouterOS version to ${{ steps.check_release.outputs.release }}' + branch: update-routeros diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 0000000..86650d0 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,36 @@ +name: "Tag master with new version of RouterOS when CI pass" + +on: + push: + branches: + - "master" + +permissions: + contents: write + pull-requests: read + +jobs: + call_test: + uses: EvilFreelancer/docker-routeros/.github/workflows/ci.yml@master + + tag: + name: "Add a tag to git" + runs-on: "ubuntu-latest" + needs: call_test + if: always() && needs.call_test.result == 'success' + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: '0' + + - name: Add new tag on git + run: | + NEW_TAG=$(grep 'ROUTEROS_VERSION="' Dockerfile |cut -d '"' -f 2) + git config user.name 'GitHub Actions' + git config user.email 'github-actions@users.noreply.github.com' + git tag "$NEW_TAG" + + - name: Push new tag to git + if: ${{ !env.ACT }} + run: git push origin "$NEW_TAG" diff --git a/.gitignore b/.gitignore index 42efebe..1043c31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /.idea/ /*.vdi -/docker-compose.yml +/docker-compose.dist.yml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 5f650a2..d7319fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.11 +FROM alpine:3.19.1 # For access via VNC EXPOSE 5900 @@ -11,18 +11,20 @@ WORKDIR /routeros # Install dependencies RUN set -xe \ - && apk add --no-cache --update \ + && apk add --no-cache --update \ netcat-openbsd qemu-x86_64 qemu-system-x86_64 \ busybox-extras iproute2 iputils \ bridge-utils iptables jq bash python3 # Environments which may be change -ENV ROUTEROS_VERSON="7.1beta6" -ENV ROUTEROS_IMAGE="chr-$ROUTEROS_VERSON.vdi" -ENV ROUTEROS_PATH="https://download.mikrotik.com/routeros/$ROUTEROS_VERSON/$ROUTEROS_IMAGE" +ENV ROUTEROS_VERSION="7.13.2" +ENV ROUTEROS_IMAGE="chr-${ROUTEROS_VERSION}.vdi" +ENV ROUTEROS_PATH="https://download.mikrotik.com/routeros/${ROUTEROS_VERSION}/${ROUTEROS_IMAGE}.zip" # Download VDI image from remote site -RUN wget "$ROUTEROS_PATH" -O "/routeros/$ROUTEROS_IMAGE" +RUN wget "$ROUTEROS_PATH" -O "/routeros/${ROUTEROS_IMAGE}.zip" && \ + unzip "/routeros/${ROUTEROS_IMAGE}.zip" -d "/routeros" && \ + rm -f "/routeros/${ROUTEROS_IMAGE}.zip" # Copy script to routeros folder ADD ["./scripts", "/routeros"] diff --git a/cron.sh b/cron.sh index 0864392..ab4d883 100755 --- a/cron.sh +++ b/cron.sh @@ -36,11 +36,10 @@ getTarballs | while read line; do if [ "x$(checkTag "$tag")" == "x" ] then - url="https://download.mikrotik.com/routeros/$tag/chr-$tag.vdi" if curl --output /dev/null --silent --head --fail "$url"; then echo ">>> URL exists: $url" - sed -r "s/(ROUTEROS_VERSON=\")(.*)(\")/\1$tag\3/g" -i Dockerfile + sed -r "s/(ROUTEROS_VERSION=\")(.*)(\")/\1$tag\3/g" -i Dockerfile git commit -m "Release of RouterOS changed to $tag" -a git push git tag "$tag" diff --git a/docker-compose.dist.yml b/docker-compose.dist.yml index 2f20fb6..83031c6 100644 --- a/docker-compose.dist.yml +++ b/docker-compose.dist.yml @@ -1,27 +1,48 @@ version: "3" services: - - routeros-6-42: - image: evilfreelancer/docker-routeros:6.42.12 + routeros-6-48: + image: evilfreelancer/docker-routeros:6.48.4 restart: unless-stopped cap_add: - NET_ADMIN devices: - /dev/net/tun + - /dev/kvm ports: - "12222:22" - "12223:23" - "18728:8728" - "18729:8729" - routeros-6-47: + routeros-latest: + image: evilfreelancer/docker-routeros:latest + restart: unless-stopped + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun + - /dev/kvm + ports: + - "22222:22" + - "22223:23" + - "7777:80" + - "8728:8728" + - "8729:8729" + - "28728:8728" + - "28729:8729" + + routeros-local: image: evilfreelancer/docker-routeros:latest + build: + context: . + dockerfile: Dockerfile restart: unless-stopped cap_add: - NET_ADMIN devices: - /dev/net/tun + - /dev/kvm ports: - "22222:22" - "22223:23" @@ -30,3 +51,4 @@ services: - "8729:8729" - "28728:8728" - "28729:8729" + - "5900:5900" diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index c8e6afa..7240d84 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -36,6 +36,20 @@ prepare_intf $default_dev1 $QEMU_BRIDGE_ETH1 # Finally, start our DHCPD server udhcpd -I $DUMMY_DHCPD_IP -f $DHCPD_CONF_FILE & +CPU_FEATURES="" +KVM_OPTS="" +if [ -e /dev/kvm ]; then + if grep -q -e vmx -e svm /proc/cpuinfo; then + echo "Enabling KVM" + CPU_FEATURES=",kvm=on" + KVM_OPTS="-machine accel=kvm -enable-kvm" + fi +fi + +if [ "$CPU_FEATURES" = "" ]; then + echo "KVM not available, running in emulation mode. This will be slow." +fi + # And run the VM! A brief explanation of the options here: # -enable-kvm: Use KVM for this VM (much faster for our case). # -nographic: disable SDL graphics. @@ -44,10 +58,12 @@ udhcpd -I $DUMMY_DHCPD_IP -f $DHCPD_CONF_FILE & # -drive: The VM image we're booting. # mac: Set up your own interfaces mac addresses here, cause from winbox you can not change these later. exec qemu-system-x86_64 \ - -nographic -serial mon:stdio \ - -vnc 0.0.0.0:0 \ + -serial mon:stdio \ + -nographic \ -m 512 \ -smp 4,sockets=1,cores=4,threads=1 \ + -cpu host$CPU_FEATURES \ + $KVM_OPTS \ -nic tap,id=qemu1,mac=54:05:AB:CD:12:31,script=$QEMU_IFUP,downscript=$QEMU_IFDOWN \ "$@" \ -hda $ROUTEROS_IMAGE