129 lines
4.8 KiB
Bash
Executable File
129 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# incus-macvlan.sh — pasang NIC macvlan + aktifkan DHCP di guest incus,
|
|
# supaya instance langsung dapat IP di LAN (mis. 192.168.200.x).
|
|
#
|
|
# Pakai:
|
|
# ./incus-macvlan.sh <instance> [device] [network]
|
|
# ./incus-macvlan.sh web1
|
|
# ./incus-macvlan.sh web1 eth1 eth200
|
|
#
|
|
# Opsi:
|
|
# --parent <iface> interface fisik host (default: dari default route host)
|
|
# --network <name> nama network macvlan (default: eth200)
|
|
# --device <name> nama NIC di guest (default: eth1)
|
|
# --create buat network macvlan kalau belum ada
|
|
# -h, --help bantuan
|
|
#
|
|
# Idempotent: aman dijalankan berulang. Kalau instance sudah punya NIC
|
|
# di network macvlan (termasuk dari profile), NIC tidak ditambahkan lagi.
|
|
set -euo pipefail
|
|
|
|
INSTANCE=""; DEVICE="eth1"; NETWORK="eth200"; PARENT=""; CREATE=0
|
|
POS=()
|
|
|
|
say(){ printf '%s\n' "$*"; }
|
|
die(){ printf 'error: %s\n' "$*" >&2; exit 1; }
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--parent) PARENT="${2:?--parent butuh nilai}"; shift 2 ;;
|
|
--network) NETWORK="${2:?--network butuh nilai}"; shift 2 ;;
|
|
--device) DEVICE="${2:?--device butuh nilai}"; shift 2 ;;
|
|
--create) CREATE=1; shift ;;
|
|
-h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
-*) die "opsi tak dikenal: $1" ;;
|
|
*) POS+=("$1"); shift ;;
|
|
esac
|
|
done
|
|
|
|
INSTANCE="${POS[0]:-}"
|
|
[ -n "${POS[1]:-}" ] && DEVICE="${POS[1]}"
|
|
[ -n "${POS[2]:-}" ] && NETWORK="${POS[2]}"
|
|
[ -n "$INSTANCE" ] || die "pakai: $(basename "$0") <instance> [device] [network]"
|
|
|
|
[[ "$DEVICE" =~ ^[A-Za-z0-9_.-]+$ ]] || die "nama device tidak valid: $DEVICE"
|
|
[[ "$NETWORK" =~ ^[A-Za-z0-9_.-]+$ ]] || die "nama network tidak valid: $NETWORK"
|
|
command -v incus >/dev/null 2>&1 || die "perintah 'incus' tidak ditemukan"
|
|
incus info "$INSTANCE" </dev/null >/dev/null 2>&1 || die "instance '$INSTANCE' tidak ditemukan"
|
|
|
|
if [ -z "$PARENT" ]; then
|
|
PARENT="$(ip route show default 2>/dev/null | awk '{print $5; exit}')"
|
|
PARENT="${PARENT:-enp2s0}"
|
|
fi
|
|
|
|
# ---- network macvlan ----
|
|
if incus network list -c n -f csv </dev/null 2>/dev/null | grep -qx "$NETWORK"; then
|
|
say "network '$NETWORK' sudah ada"
|
|
else
|
|
[ "$CREATE" = 1 ] || die "network '$NETWORK' belum ada (pakai --create, parent $PARENT)"
|
|
say "membuat network macvlan '$NETWORK' (parent $PARENT)"
|
|
incus network create "$NETWORK" --type=macvlan parent="$PARENT" </dev/null
|
|
fi
|
|
|
|
# ---- pastikan running ----
|
|
STATE="$(incus info "$INSTANCE" </dev/null | awk -F': ' '/^Status:/{print $2}')"
|
|
if [ "$STATE" != "RUNNING" ]; then
|
|
say "menyalakan instance '$INSTANCE'"
|
|
incus start "$INSTANCE" </dev/null
|
|
sleep 3
|
|
fi
|
|
|
|
# ---- pasang NIC (kalau belum ada NIC di network ini, termasuk dari profile) ----
|
|
if incus config show --expanded "$INSTANCE" </dev/null 2>/dev/null | grep -q "network: $NETWORK"; then
|
|
say "instance sudah punya NIC di network '$NETWORK' (dilewati)"
|
|
elif incus config device list "$INSTANCE" </dev/null | grep -qx "$DEVICE"; then
|
|
say "device '$DEVICE' sudah ada (dilewati)"
|
|
else
|
|
if incus config device add "$INSTANCE" "$DEVICE" nic network="$NETWORK" name="$DEVICE" </dev/null; then
|
|
say "NIC '$DEVICE' (network $NETWORK) ditambahkan"
|
|
else
|
|
say "peringatan: gagal menambah NIC '$DEVICE' (lanjut cek DHCP)"
|
|
fi
|
|
fi
|
|
|
|
# ---- aktifkan DHCP di guest untuk semua NIC tanpa IPv4 ----
|
|
say "mengaktifkan DHCP di guest"
|
|
incus exec "$INSTANCE" -- sh -c '
|
|
configure_one() {
|
|
dev="$1"
|
|
if systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
|
nmcli device connect "$dev" >/dev/null 2>&1 || true
|
|
elif systemctl is-active --quiet systemd-networkd 2>/dev/null || [ -d /etc/systemd/network ]; then
|
|
printf "[Match]\nName=%s\n[Network]\nDHCP=yes\n" "$dev" > "/etc/systemd/network/20-$dev.network"
|
|
elif command -v dhcpcd >/dev/null 2>&1; then dhcpcd "$dev" >/dev/null 2>&1 || true
|
|
elif command -v dhclient >/dev/null 2>&1; then dhclient "$dev" >/dev/null 2>&1 || true
|
|
elif command -v udhcpc >/dev/null 2>&1; then udhcpc -i "$dev" >/dev/null 2>&1 || true
|
|
fi
|
|
}
|
|
for i in /sys/class/net/*; do
|
|
dev=$(basename "$i"); [ "$dev" = lo ] && continue
|
|
ip -4 addr show "$dev" 2>/dev/null | grep -q "inet " && continue
|
|
configure_one "$dev"
|
|
done
|
|
systemctl restart systemd-networkd >/dev/null 2>&1 || true
|
|
' </dev/null || say "peringatan: konfigurasi DHCP di guest gagal (lanjut)"
|
|
|
|
# ---- tunggu IP LAN ----
|
|
IP=""
|
|
for _ in $(seq 1 20); do
|
|
IP="$(incus list "$INSTANCE" -c 4 -f csv </dev/null 2>/dev/null \
|
|
| tr ',' '\n' | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' \
|
|
| grep -vE '^(10\.|127\.)' | head -1 || true)"
|
|
[ -n "$IP" ] && break
|
|
sleep 1
|
|
done
|
|
|
|
say ""
|
|
if [ -n "$IP" ]; then
|
|
say "instance : $INSTANCE"
|
|
say "network : $NETWORK (parent $PARENT)"
|
|
say "IP LAN : $IP"
|
|
say "SSH : ssh root@$IP"
|
|
else
|
|
say "instance : $INSTANCE"
|
|
say "IP LAN : belum terdeteksi"
|
|
say "cek : incus exec $INSTANCE -- ip -4 addr"
|
|
exit 1
|
|
fi
|