Files
ProxmoxVE/vm/mikrotik-routeros.sh
T
CanbiZ (MickLesk) 712656a330 Refactor: MikroTik RouterOS (#17748)
* Refactor: MikroTik RouterOS

* Update COMMUNITY_SCRIPTS_URL to ProxmoxVE repository
2026-10-07 21:36:18 +02:00

223 lines
6.4 KiB
Bash

#!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster)
# License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
load_functions
GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
APP="MikroTik RouterOS"
APP_TYPE="vm"
NSAPP="mikrotik-routeros"
var_os="mikrotik"
var_version=" "
DISK_SIZE="1G"
THIN="discard=on,ssd=1,"
header_info
echo -e "Loading..."
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap cleanup EXIT
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
vm_require_arch amd64
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
function default_settings() {
vm_apply_machine_type "i440fx"
VMID=$(get_valid_nextid)
DISK_SIZE="8G"
DISK_CACHE=""
HN="mikrotik-routeros-chr"
CPU_TYPE=""
CORE_COUNT="2"
RAM_SIZE="512"
BRG="vmbr0"
MAC="$GEN_MAC"
VLAN=""
MTU=""
START_VM="yes"
CLOUD_INIT="no"
METHOD="default"
vm_echo_default_settings
}
function get_mikrotik_version() {
local mode="$1"
local rss_url
local tree_name
case "$mode" in
s) rss_url="https://cdn.mikrotik.com/routeros/latest-stable.rss" ;;
d) rss_url="https://cdn.mikrotik.com/routeros/latest-development.rss" ;;
l) rss_url="https://cdn.mikrotik.com/routeros/latest-long-term.rss" ;;
t) rss_url="https://cdn.mikrotik.com/routeros/latest-testing.rss" ;;
*) return 0 ;;
esac
local rss_content
rss_content=$(curl -fsSL $rss_url 2>/dev/null)
if [ -n "$rss_content" ]; then
local version
version=$(echo "$rss_content" | grep -oP '<title>RouterOS \K[0-9.]+(?= \[)' 2>/dev/null || echo "$rss_content" | sed -n 's/.*<title>RouterOS \([0-9.]\+\) \[.*/\1/p' 2>/dev/null)
if [[ "$version" =~ ^[0-9]+\.[0-9]+ ]]; then
echo "$version"
return 0
fi
fi
case "$mode" in
s) tree_name="Stable release tree" ;;
d) tree_name="Development release tree" ;;
l) tree_name="Long-term release tree" ;;
t) tree_name="Testing release tree" ;;
esac
local html
html=$(curl -fsSL "https://mikrotik.com/download/changelogs" 2>/dev/null)
if [ -n "$html" ]; then
local start_line
start_line=$(echo "$html" | grep -n "$tree_name" | cut -d: -f1 | head -n1)
if [[ "$start_line" =~ ^[0-9]+$ ]]; then
local line
line=$(echo "$html" | tail -n +"$start_line" | grep -m 1 -E "c-(stable|longTerm|testing|development)-v|RouterOS [0-9]+\.[0-9]+" 2>/dev/null)
local version
version=$(echo "$line" | sed -n 's/.*c-[^"]*-v\([0-9_.a-zA-Z-]\+\).*/\1/p' | tr '_' '.' 2>/dev/null)
[ -z "$version" ] && version=$(echo "$line" | grep -oP 'RouterOS \K[0-9]+\.[0-9]+(\.[0-9]+)?' 2>/dev/null)
if [[ "$version" =~ ^[0-9]+\.[0-9]+ ]]; then
echo "$version"
return 0
fi
fi
fi
for minor in $(seq 50 -1 15); do
local test_version="7.${minor}"
if curl -fsSL -I "https://download.mikrotik.com/routeros/${test_version}/chr-${test_version}.img.zip" 2>/dev/null | grep -q "200 OK"; then
echo "$test_version"
return 0
fi
done
return 0
}
function advanced_settings() {
METHOD="advanced"
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
vm_prompt_machine_type "i440fx"
vm_prompt_disk_size "8G"
vm_prompt_disk_cache "none"
vm_prompt_hostname "mikrotik-routeros-chr"
vm_prompt_cpu_model "kvm64"
vm_prompt_cpu_cores "2"
vm_prompt_ram "512"
vm_prompt_bridge "vmbr0"
vm_prompt_mac "$GEN_MAC"
vm_prompt_vlan
vm_prompt_mtu
vm_prompt_verbose "no"
vm_prompt_start_vm "yes"
if vm_confirm_advanced_settings "Ready to create a MikroTik RouterOS VM?"; then
echo -e "${CREATING}${BOLD}${DGN}Creating a MikroTik RouterOS VM using the above advanced settings${CL}"
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
advanced_settings
fi
}
vm_preflight
vm_start_script "Use Default Settings?\n\nDefaults:\n• 2 CPU Cores\n• 512 MB RAM\n• 8 GB Disk" 13 58
post_to_api_vm
vm_select_storage "$HN"
msg_info "Getting URL for Latest Mikrotik RouterOS CHR Disk Image"
MIK_VER=$(get_mikrotik_version s)
if [ -n "$MIK_VER" ]; then
msg_ok "Latest stable version: ${CL}${BL}$MIK_VER${CL}."
else
msg_error "Could not get latest version"
msg_ok "Defaulting to version 7.20"
MIK_VER="7.20"
fi
URL=https://download.mikrotik.com/routeros/$MIK_VER/chr-$MIK_VER.img.zip
sleep 2
msg_ok "Downloading from URL: ${CL}${BL}${URL}${CL}"
# A mirror serving an error page returns 200, so size decides whether this
# is an image. Anything real here is far above 5 MB.
CACHE_FILE="$(vm_image_cache_path "$URL")"
vm_fetch_image "$URL" "$CACHE_FILE" --cache --min-bytes $((5 * 1024 * 1024)) || exit 115
msg_info "Extracting Mikrotik RouterOS CHR Disk Image"
# Decompress out of the cache rather than over it, gunzip eats its input.
FILE="$(basename "${CACHE_FILE%.zip}")"
gunzip -c -S .zip "$CACHE_FILE" >"$FILE"
STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')
case $STORAGE_TYPE in
nfs | dir)
DISK_EXT=".qcow2"
DISK_REF="$VMID/"
DISK_IMPORT="-format qcow2"
;;
btrfs)
DISK_EXT=".raw"
DISK_REF="$VMID/"
DISK_IMPORT="-format raw"
;;
zfspool)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}"
DISK_REF="${STORAGE}:${DISK_REF:-}${DISK_VAR:-}"
msg_ok "Extracted Mikrotik RouterOS CHR Disk Image"
msg_info "Creating Mikrotik RouterOS CHR VM"
qm create $VMID -tablet 0 -localtime 1 -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \
-tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \
-onboot 1 -ostype l26 -scsihw virtio-scsi-pci
qm importdisk $VMID "$FILE" $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
qm set $VMID \
-scsi0 "$DISK_REF" \
-boot order=scsi0 >/dev/null
set_description
vm_resize_disk
msg_ok "Mikrotik RouterOS CHR VM ${CL}${BL}(${HN})"
if [ "$START_VM" == "yes" ]; then
msg_info "Starting Mikrotik RouterOS CHR VM"
$STD qm start $VMID
msg_ok "Started Mikrotik RouterOS CHR VM"
fi
post_update_to_api "done" "none"
msg_ok "Completed successfully!\n"