Although rare, there are scenarios where we may want to deploy a new virtual machine with a static, manually-configured IP address. Anaconda/Dracut support this via the `ip=` kernel command-line argument. To simplify populating that argument, the `newvm` script now takes additional command-line arguments for IP address (in CIDR prefix), default gateway, and name server address(es) and creates the appropriate string from these discrete values.
275 lines
5.7 KiB
Bash
Executable File
275 lines
5.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# vim: set sw=4 ts=4 sts=4 et :
|
|
|
|
METADATA_XMLNS='http://du5t1n.me/xmlns/libvirt/metadata/'
|
|
|
|
memory=2048
|
|
vcpus=2
|
|
disk_size=16
|
|
kickstart='http://pxe.pyrocufflink.blue/kickstart/master/fedora.ks'
|
|
fedora=$(rpm -E %fedora)
|
|
network=network=kube
|
|
dnsdomain=host.pyrocufflink.black
|
|
console=true
|
|
default_groups=true
|
|
graphics=false
|
|
|
|
gen_dracut_ipconfig() {
|
|
local hostname=$1
|
|
local ip_address=$2
|
|
local gateway=$3
|
|
local nameserver=$4
|
|
|
|
local netmask=$(ipcalc --no-decorate --netmask "${ip_address}")
|
|
if [ -z "${gateway}" ]; then
|
|
gateway=$(ipcalc --no-decorate --minaddr "${ip_address}")
|
|
fi
|
|
ip_address=$(ipcalc --no-decorate --address "${ip_address}")
|
|
|
|
printf 'ip=%s::%s:%s:%s::none:%s\n' \
|
|
"${ip_address}" \
|
|
"${gateway}" \
|
|
"${netmask}" \
|
|
"${hostname}" \
|
|
"${nameserver}"
|
|
}
|
|
|
|
|
|
usage() {
|
|
printf 'usage: %s [options] name\n' "${0##*/}"
|
|
}
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--kickstart)
|
|
shift
|
|
kickstart="$1"
|
|
;;
|
|
--kickstart=*)
|
|
kickstart="${1##*=}"
|
|
;;
|
|
--memory)
|
|
shift
|
|
memory="$1"
|
|
;;
|
|
--memory=*)
|
|
memory="${1#*=}"
|
|
;;
|
|
--vcpus)
|
|
shift
|
|
vcpus="$1"
|
|
;;
|
|
--vcpus=*)
|
|
vcpus="${1#*=}"
|
|
;;
|
|
--location)
|
|
shift
|
|
location="$1"
|
|
;;
|
|
--location=*)
|
|
location="${1#*=}"
|
|
;;
|
|
--disk-size)
|
|
shift
|
|
disk_size="$1"
|
|
;;
|
|
--disk=size=*)
|
|
disk_size="${1#*=}"
|
|
;;
|
|
--fedora)
|
|
shift
|
|
fedora="$1"
|
|
;;
|
|
--fedora=*)
|
|
shift
|
|
fedora="${1#*=}"
|
|
;;
|
|
--network)
|
|
shift
|
|
network="$1"
|
|
;;
|
|
--network=*)
|
|
network="${1#*=}"
|
|
;;
|
|
--ip-address)
|
|
shift
|
|
ip_address=$1
|
|
;;
|
|
--ip-address=*)
|
|
ip_address=${1#*=}
|
|
;;
|
|
--gateway)
|
|
shift
|
|
gateway=$1
|
|
;;
|
|
--gateway=*)
|
|
gateway=${1#*=}
|
|
;;
|
|
--nameserver)
|
|
shift
|
|
nameserver=$1
|
|
;;
|
|
--nameserver=*)
|
|
nameserver=${1#=*}
|
|
;;
|
|
--domain)
|
|
shift
|
|
dnsdomain=$1
|
|
;;
|
|
--domain=*)
|
|
dnsdomain=${1#=*}
|
|
;;
|
|
--with-graphics)
|
|
graphics=true
|
|
;;
|
|
--cfg-branch)
|
|
shift
|
|
cfg_branch=$1
|
|
;;
|
|
--cfg-branch=*)
|
|
cfg_branch=${1#*=}
|
|
;;
|
|
--group)
|
|
shift
|
|
groups_xml="${groups_xml}<group name=\"${1}\"/>"
|
|
;;
|
|
--group=*)
|
|
groups_xml="${groups_xml}<group name=\"${1#*=}\"/>"
|
|
;;
|
|
--no-default-groups)
|
|
default_groups=false;
|
|
;;
|
|
--no-console|--noconsole)
|
|
console=false
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
*)
|
|
if [ -z "${name}" ]; then
|
|
name="$1"
|
|
else
|
|
usage >&2
|
|
printf 'unknown option: %s\n' "${1}" >&2
|
|
exit 2
|
|
fi
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ -z "${name}" ]; then
|
|
usage >&2
|
|
exit 2
|
|
fi
|
|
|
|
case ${name} in
|
|
*.*)
|
|
hostname=${name}
|
|
name=${name%%.*}
|
|
;;
|
|
*)
|
|
hostname=${name}.${dnsdomain}
|
|
;;
|
|
esac
|
|
|
|
if [ -z "${LIBVIRT_DEFAULT_URI}" ]; then
|
|
printf 'LIBVIRT_DEFAULT_URI is not set.\n' >&2
|
|
printf 'If you want to create a new VM locally, explicitly set '
|
|
printf 'LIBVIRT_DEFAULT_URI=qemu:///session\n'
|
|
exit 1
|
|
fi
|
|
|
|
case ${ip_address} in
|
|
'')
|
|
ipconfig="ip=::::${hostname}::dhcp"
|
|
;;
|
|
*/*)
|
|
ipconfig=$(gen_dracut_ipconfig \
|
|
"${hostname}" \
|
|
"${ip_address}" \
|
|
"${gateway}" \
|
|
"${nameserver}"
|
|
)
|
|
;;
|
|
*)
|
|
printf 'Invalid IP configuration: missing prefix length\n' >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ ${fedora} -gt 40 ] && [ ${memory} -lt 4096 ]; then
|
|
printf 'WARNING Fedora 41+ requires at least 4 GB memory to install\n' >&2
|
|
memory=4096
|
|
fi
|
|
|
|
if ${default_groups}; then
|
|
groups_xml="<group name=\"chrony\"/>${groups_xml}"
|
|
groups_xml="<group name=\"collectd\"/>${groups_xml}"
|
|
fi
|
|
|
|
printf 'Creating %s on %s\n' "${name}" "${LIBVIRT_DEFAULT_URI}"
|
|
|
|
if [ -z "${location}" ]; then
|
|
location=http://dl.fedoraproject.org/pub/fedora/linux/releases/${fedora}/Everything/x86_64/os
|
|
fi
|
|
|
|
if [ -z ${http_proxy+on} ]; then
|
|
export http_proxy=http://proxy.pyrocufflink.blue:3128
|
|
printf 'Using default HTTP proxy: %s\n' "${http_proxy}" >&2
|
|
elif [ -z "${http_proxy}" ]; then
|
|
printf 'HTTP proxy disabled\n' "${http_proxy}" >&2
|
|
else
|
|
printf 'Using HTTP proxy: %s\n' "${http_proxy}" >&2
|
|
fi
|
|
|
|
extra_args="${ipconfig} inst.ks=${kickstart}"
|
|
if [ -n "${http_proxy}" ]; then
|
|
extra_args="${extra_args} inst.proxy=${http_proxy}"
|
|
if [ ${fedora} -lt 40 ]; then
|
|
extra_args="${extra_args} proxy=${http_proxy}"
|
|
fi
|
|
fi
|
|
extra_args="${extra_args} inst.notmux quiet systemd.show_status=1 console=ttyS0"
|
|
|
|
set -- \
|
|
--name ${name} \
|
|
--metadata title=${hostname} \
|
|
--memory ${memory} \
|
|
--vcpus ${vcpus} \
|
|
--cpu host-model \
|
|
--location ${location} \
|
|
--extra-args "${extra_args}" \
|
|
--disk pool=default,size=${disk_size},cache=none \
|
|
--network ${network} \
|
|
--os-variant fedora-rawhide \
|
|
--console pty,target.type=serial,log.file=/var/log/libvirt/console/${name}.log \
|
|
--sound none \
|
|
--redirdev none \
|
|
--rng /dev/random \
|
|
--boot uefi \
|
|
"$@"
|
|
|
|
if [ -n "${cfg_branch}" ]; then
|
|
set -- "$@" --qemu-commandline="-fw_cfg opt/dch/cfg-branch,string=${cfg_branch}"
|
|
fi
|
|
|
|
if ! $graphics; then
|
|
set -- "$@" --graphics=none
|
|
fi
|
|
|
|
if $console; then
|
|
set -- "$@" --autoconsole text
|
|
else
|
|
set -- "$@" --noautoconsole --wait -1
|
|
fi
|
|
|
|
(
|
|
virsh event --event lifecycle --loop | awk '/Started/{exit}'
|
|
virsh metadata ${name} --live --config ${METADATA_XMLNS} dch \
|
|
"<metadata><groups>${groups_xml}</groups></metadata>"
|
|
) &
|
|
|
|
virt-install "$@" || kill $!
|
|
wait
|