Compare commits
1 commit
master
...
fnuxfedora
Author | SHA1 | Date | |
---|---|---|---|
|
366c9c65b2 |
62 changed files with 26 additions and 4336 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,10 +0,0 @@
|
||||||
opennebula-vm-etcd/config-and-secrets.conf
|
|
||||||
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
|
|
||||||
ipxe/
|
|
||||||
|
|
||||||
openwrt-*-*.bin
|
|
|
@ -3,8 +3,8 @@
|
||||||
set -e
|
set -e
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
MAJOR_VERSION=3.11
|
MAJOR_VERSION=3.10
|
||||||
MINOR_VERSION=2
|
MINOR_VERSION=3
|
||||||
IMAGE=alpine-minirootfs-$MAJOR_VERSION.$MINOR_VERSION-x86_64.tar.gz
|
IMAGE=alpine-minirootfs-$MAJOR_VERSION.$MINOR_VERSION-x86_64.tar.gz
|
||||||
SSH_KEYS=$(cat ~/.ssh/id_rsa.pub)
|
SSH_KEYS=$(cat ~/.ssh/id_rsa.pub)
|
||||||
RESOLVCONF=/etc/resolv.conf
|
RESOLVCONF=/etc/resolv.conf
|
||||||
|
|
0
build-alpine-chroot.sh
Executable file → Normal file
0
build-alpine-chroot.sh
Executable file → Normal file
|
@ -1,107 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# 17:19, 2018-02-09
|
|
||||||
# Nico Schottelius
|
|
||||||
|
|
||||||
# Based on ceph-disk -v prepare --bluestore /dev/sdc --osd-id ${ID} --osd-uuid $(uuidgen) --crush-device-class "ssd"
|
|
||||||
|
|
||||||
# Create:
|
|
||||||
# - block -> link to partuuid
|
|
||||||
# - block_uuid -e> uuid if the block
|
|
||||||
# - ceph_fsid -> get from ceph-conf
|
|
||||||
# crush_device_class -> ssd, hdd
|
|
||||||
# fsid -> uuidgen!
|
|
||||||
# magic -> string "ceph osd volume v026"
|
|
||||||
# type -> bluestore
|
|
||||||
|
|
||||||
fsid=$(ceph-conf --cluster=ceph --name=osd. --lookup fsid)
|
|
||||||
fs_uuid=$(uuidgen)
|
|
||||||
magic="ceph osd volume v026"
|
|
||||||
|
|
||||||
set -x
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
|
||||||
echo "$0 disk class [osdweight]"
|
|
||||||
echo "class = hdd or ssd"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
export DEV=$1;shift
|
|
||||||
export CLASS=$1; shift
|
|
||||||
|
|
||||||
|
|
||||||
uuid_metadata=$(uuidgen)
|
|
||||||
uuid_block=$(uuidgen)
|
|
||||||
|
|
||||||
osd_id=$(ceph osd create)
|
|
||||||
|
|
||||||
dev_metadata="/dev/disk/by-partuuid/$uuid_metadata"
|
|
||||||
dev_block="/dev/disk/by-partuuid/$uuid_block"
|
|
||||||
|
|
||||||
/usr/bin/sgdisk --new=0:0:+100M --change-name="0:ceph data" \
|
|
||||||
--partition-guid="0:$uuid_metadata" \
|
|
||||||
--typecode=0:4fbd7e29-9d25-41b8-afd0-062c0ceff05d \
|
|
||||||
--mbrtogpt -- $DEV
|
|
||||||
/sbin/udevadm settle --timeout=600
|
|
||||||
|
|
||||||
# Using gdisk --largest-new does not change the name or set guid;
|
|
||||||
# So use 2 steps instead
|
|
||||||
/usr/bin/sgdisk --largest-new=0 --mbrtogpt -- $DEV
|
|
||||||
/sbin/udevadm settle --timeout=600
|
|
||||||
|
|
||||||
|
|
||||||
lastpart=$(gdisk -l $DEV | tail -n1 | awk '{ print $1 }')
|
|
||||||
/usr/bin/sgdisk --change-name="${lastpart}:ceph block" \
|
|
||||||
--partition-guid="${lastpart}:$uuid_block" \
|
|
||||||
--typecode="${lastpart}:cafecafe-9b03-4f30-b4c6-b4b80ceff106" \
|
|
||||||
--mbrtogpt -- $DEV
|
|
||||||
/sbin/udevadm settle --timeout=600
|
|
||||||
|
|
||||||
#echo $1
|
|
||||||
#echo $(blkid | grep $1"2")
|
|
||||||
|
|
||||||
#cblock=$(blkid | grep $1"2" | cut -d'"' -f4)
|
|
||||||
#echo $cblock
|
|
||||||
|
|
||||||
/sbin/mkfs -t xfs -f -i size=2048 -- "$dev_metadata"
|
|
||||||
|
|
||||||
mountpath=/var/lib/ceph/osd/ceph-${osd_id}
|
|
||||||
|
|
||||||
mkdir -p "$mountpath"
|
|
||||||
mount "$dev_metadata" "$mountpath"
|
|
||||||
|
|
||||||
ln -s $dev_block "$mountpath/block"
|
|
||||||
|
|
||||||
echo "$uuid_block" > "$mountpath/block_uuid"
|
|
||||||
echo "$fsid" > "$mountpath/ceph_fsid"
|
|
||||||
echo "$magic" > "$mountpath/magic"
|
|
||||||
echo "$CLASS" > "$mountpath/crush_device_class"
|
|
||||||
echo $(echo $dev_block | cut -c23-) > "$mountpath/fsid"
|
|
||||||
|
|
||||||
|
|
||||||
# Important, otherwise --mkfs later will try to create filestore
|
|
||||||
echo bluestore > "$mountpath/type"
|
|
||||||
|
|
||||||
ceph auth get-or-create "osd.${osd_id}" osd \
|
|
||||||
'allow *' mon 'allow profile osd' > $mountpath/keyring
|
|
||||||
|
|
||||||
echo ${osd_id} > "$mountpath/whoami"
|
|
||||||
touch "$mountpath/openrc"
|
|
||||||
|
|
||||||
ceph-osd --cluster ceph -i "${osd_id}" --mkfs
|
|
||||||
chown -R ceph:ceph "$mountpath"
|
|
||||||
|
|
||||||
if [ $# -eq 1 ]; then
|
|
||||||
WEIGHT=$1; shift
|
|
||||||
else
|
|
||||||
devname=$(readlink -f $dev_block)
|
|
||||||
nodev=$(echo $devname | sed 's,/dev/,,')
|
|
||||||
WEIGHT=$(lsblk -l -b | awk "/^$nodev/ { print \$4/(1024^4) }")
|
|
||||||
fi
|
|
||||||
|
|
||||||
ceph osd crush add osd.${osd_id} ${WEIGHT} host=$(hostname)
|
|
||||||
|
|
||||||
echo "$metadata_dev /var/lib/ceph/osd/ceph-${osd_id} xfs noatime 0 0" >> /etc/fstab
|
|
||||||
|
|
||||||
# Starting with monit, if available
|
|
||||||
ceph-osd -i ${osd_id}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
rm -f /etc/apt/sources.list.d/ceph.list
|
|
||||||
|
|
||||||
cat > /etc/apt/sources.list <<EOF
|
|
||||||
|
|
||||||
deb http://pkgmaster.devuan.org/merged beowulf main contrib non-free
|
|
||||||
deb http://pkgmaster.devuan.org/merged beowulf-updates main contrib non-free
|
|
||||||
deb http://pkgmaster.devuan.org/merged beowulf-security main contrib non-free
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo deb http://ftp.debian.org/debian buster-backports main > /etc/apt/sources.list.d/backports.list
|
|
||||||
apt update
|
|
||||||
apt dist-upgrade -y
|
|
||||||
apt install -t buster-backports -y ceph
|
|
|
@ -1,41 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#option $1 is vm_list file name
|
|
||||||
#option $2 id DB location
|
|
||||||
#option $3 is DB user
|
|
||||||
#option $4 is DB name
|
|
||||||
|
|
||||||
#host='localhost'
|
|
||||||
|
|
||||||
user_arr=( $(cat $1 | awk '{print $1}' ))
|
|
||||||
vmid_arr=( $(cat $1 | awk '{print $2}' ))
|
|
||||||
port_arr=( $(cat $1 | awk '{print $3}' ))
|
|
||||||
place_arr=( $(cat $1 | awk '{print $4}' ))
|
|
||||||
|
|
||||||
for ((i=0; i<${#user_arr[@]}; i++)) do
|
|
||||||
#create user
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_entity (name, type) VALUES ('${user_arr[i]}','USER');"
|
|
||||||
en_id=$(psql -h $2 -U $3 -d $4 -tAc "SELECT entity_id FROM guacamole_entity WHERE name = '${user_arr[i]}';")
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('$en_id', '\x74657374', now());"
|
|
||||||
|
|
||||||
#create connection
|
|
||||||
cn=${user_arr[i]}${vmid_arr[i]}
|
|
||||||
echo $cn
|
|
||||||
if [ 0 -eq $(psql -h $2 -U $3 -d $4 -tAc "SELECT connection_id FROM guacamole_connection WHERE connection_name = '$cn';" | wc -l) ]; then
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('$cn', 'vnc');"
|
|
||||||
cn_id=$(psql -h $2 -U $3 -d $4 -tAc "SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '$cn' AND parent_id IS NULL;")
|
|
||||||
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_connection_parameter VALUES ('$cn_id','hostname','${place_arr[i]}');"
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_connection_parameter VALUES ('$cn_id','port','${port_arr[i]}');"
|
|
||||||
|
|
||||||
#connection permission
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_connection_permission(entity_id, connection_id, permission) VALUES ('$en_id', '$cn_id', 'READ');"
|
|
||||||
#clipboard-encoding
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "INSERT INTO guacamole_connection_parameter VALUES ('$cn_id','clipboard-encoding','UTF-8');"
|
|
||||||
|
|
||||||
else
|
|
||||||
cn_id=$(psql -h $2 -U $3 -d $4 -tAc "SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '$cn' AND parent_id IS NULL;")
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "UPDATE guacamole_connection_parameter SET parameter_value='${place_arr[i]}' where connection_id='$cn_id' and parameter_name='hostname';"
|
|
||||||
psql -h $2 -U $3 -d $4 -tAc "UPDATE guacamole_connection_parameter SET parameter_value='${port_arr[i]}' where connection_id='$cn_id' and parameter_name='port';"
|
|
||||||
fi
|
|
||||||
|
|
||||||
done
|
|
|
@ -1,38 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#option $1 is vm_list file name
|
|
||||||
#option $2 is DB name
|
|
||||||
#this script should be run on guacamole server
|
|
||||||
|
|
||||||
|
|
||||||
host='localhost'
|
|
||||||
user_arr=( $(cat $1 | awk '{print $1}' ))
|
|
||||||
vmid_arr=( $(cat $1 | awk '{print $2}' ))
|
|
||||||
port_arr=( $(cat $1 | awk '{print $3}' ))
|
|
||||||
place_arr=( $(cat $1 | awk '{print $4}' ))
|
|
||||||
|
|
||||||
for ((i=0; i<${#user_arr[@]}; i++)) do
|
|
||||||
#create user
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_entity (name, type) VALUES ('${user_arr[i]}','USER');\""
|
|
||||||
en_id=$(su - postgres -c "psql postgres -d $2 -tAc \"SELECT entity_id FROM guacamole_entity WHERE name = '${user_arr[i]}';\"")
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('$en_id', '\x74657374', now());\""
|
|
||||||
|
|
||||||
#create connection
|
|
||||||
cn=${user_arr[i]}${vmid_arr[i]}
|
|
||||||
|
|
||||||
if [ 0 -eq $(su - postgres -c "psql postgres -d $2 -tAc \"SELECT connection_id FROM guacamole_connection WHERE connection_name = '$cn';\"" | wc -l) ]; then
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('$cn', 'vnc');\""
|
|
||||||
cn_id=$(su - postgres -c "psql postgres -d $2 -tAc \"SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '$cn' AND parent_id IS NULL;\"")
|
|
||||||
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_connection_parameter VALUES ('$cn_id','hostname','$host');\""
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_connection_parameter VALUES ('$cn_id','port','${port_arr[i]}');\""
|
|
||||||
|
|
||||||
#connection permission
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"INSERT INTO guacamole_connection_permission(entity_id, connection_id, permission) VALUES ('$en_id', '$cn_id', 'READ');\""
|
|
||||||
|
|
||||||
else
|
|
||||||
cn_id=$(su - postgres -c "psql postgres -d $2 -tAc \"SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '$cn' AND parent_id IS NULL;\"")
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"UPDATE guacamole_connection_parameter SET parameter_value='$host' where connection_id='$cn_id' and parameter_name='hostname';\""
|
|
||||||
su - postgres -c "psql postgres -d $2 -tAc \"UPDATE guacamole_connection_parameter SET parameter_value='${port_arr[i]}' where connection_id='$cn_id' and parameter_name='port';\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
done
|
|
|
@ -1,113 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Nico Schottelius, 2019-12-09
|
|
||||||
# the ugly code is llnu
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo $0 suite out-directory
|
|
||||||
echo out-directory: into which directory to place resulting files
|
|
||||||
echo suite is for instance ascii, beowulf, etc
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
suite=$1; shift
|
|
||||||
outdir=$1; shift
|
|
||||||
|
|
||||||
date=$(date +%F)
|
|
||||||
mkdir -p ${outdir}
|
|
||||||
|
|
||||||
basename=${suite}-${date}
|
|
||||||
abs_outdir=$(cd ${outdir} && pwd -P)
|
|
||||||
|
|
||||||
chroot_dir=${abs_outdir}/${basename}
|
|
||||||
kernel=${abs_outdir}/kernel-${basename}
|
|
||||||
initramfs=${abs_outdir}/initramfs-${basename}
|
|
||||||
|
|
||||||
keyurl=https://code.ungleich.ch/ungleich-public/__ungleich_staff_ssh_access/raw/master/files
|
|
||||||
|
|
||||||
debootstrap "${suite}" "${chroot_dir}"
|
|
||||||
|
|
||||||
# need non-free for firmware-bnx2
|
|
||||||
echo "deb http://pkgmaster.devuan.org/merged ${suite} main contrib non-free" > ${chroot_dir}/etc/apt/sources.list
|
|
||||||
|
|
||||||
chroot ${chroot_dir} apt update
|
|
||||||
chroot ${chroot_dir} apt install -y openssh-server rdnssd linux-image-amd64 firmware-bnx2 ifenslave vlan
|
|
||||||
|
|
||||||
echo "unconfigured-host" > ${chroot_dir}/etc/hostname
|
|
||||||
|
|
||||||
cp ${chroot_dir}/boot/vmlinuz-* ${kernel}
|
|
||||||
|
|
||||||
echo '* * * * * root ip -o -6 addr show | grep -E -v " lo |one" > /etc/issue' > ${chroot_dir}/etc/cron.d/ipv6addr
|
|
||||||
|
|
||||||
mkdir -p ${chroot_dir}/root/.ssh
|
|
||||||
|
|
||||||
for key in fnux balazs dominique jinguk nico; do
|
|
||||||
curl -s ${keyurl}/${key}.pub >> ${chroot_dir}/root/.ssh/authorized_keys
|
|
||||||
done
|
|
||||||
|
|
||||||
# Fix possible permission issue from above
|
|
||||||
chown -R root:root ${chroot_dir}/root/
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# networking
|
|
||||||
|
|
||||||
# echo bonding
|
|
||||||
|
|
||||||
cat > ${chroot_dir}/etc/network/interfaces << EOF
|
|
||||||
auto lo
|
|
||||||
iface lo inet loopback
|
|
||||||
|
|
||||||
auto bond0
|
|
||||||
iface bond0 inet manual
|
|
||||||
bond-miimon 500
|
|
||||||
bond-mode 4
|
|
||||||
post-up /sbin/ip link set \$IFACE mtu 9000
|
|
||||||
bond-slaves none
|
|
||||||
|
|
||||||
auto eth0
|
|
||||||
iface eth0 inet manual
|
|
||||||
bond-master bond0
|
|
||||||
post-up /sbin/ip link set \$IFACE mtu 9000
|
|
||||||
|
|
||||||
auto eth1
|
|
||||||
iface eth1 inet manual
|
|
||||||
bond-master bond0
|
|
||||||
post-up /sbin/ip link set \$IFACE mtu 9000
|
|
||||||
|
|
||||||
# server network
|
|
||||||
auto bond0.11
|
|
||||||
iface bond0.11 inet6 auto
|
|
||||||
post-up /sbin/ip link set \$IFACE mtu 9000
|
|
||||||
vlan-raw-device bond0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# find the boot interfaces at boot - not needed, always eth0/eth1
|
|
||||||
# cat > ${chroot_dir}/etc/rc.local <<EOF
|
|
||||||
# mac=\$(cat /proc/cmdline | tr ' ' '\n' | awk -F= '/bootdev/ { print \$2 }')
|
|
||||||
# dev=\$(ip -o link | awk -F: "/\$mac/ { print \\\$2 }" | sed 's/ *//g')
|
|
||||||
|
|
||||||
# cat > /etc/network/interfaces.d/bootinterface << eof
|
|
||||||
# auto \$dev
|
|
||||||
# iface \$dev inet6 auto
|
|
||||||
# eof
|
|
||||||
|
|
||||||
# ifup "\${dev}"
|
|
||||||
|
|
||||||
# exit 0
|
|
||||||
# EOF
|
|
||||||
|
|
||||||
# chmod a+rx "${chroot_dir}/etc/rc.local"
|
|
||||||
|
|
||||||
# ensure there is /init in the initramfs -> otherwise there is a kernel panic
|
|
||||||
# reason: initramfs is designed to be PRE regular os, so /init usually hands over to /sbin/init
|
|
||||||
# in our case, they are just the same
|
|
||||||
ln -fs /sbin/init ${chroot_dir}/init
|
|
||||||
|
|
||||||
# Finally building the initramfs
|
|
||||||
( cd ${chroot_dir} ; find . | cpio -H newc -o | gzip -9 > ${initramfs} )
|
|
||||||
|
|
||||||
# Fix paranoid permissions
|
|
||||||
chmod a+rx ${abs_outdir}
|
|
||||||
chmod a+r ${kernel} ${initramfs}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# reverting for a running system that still needs access to old style
|
|
||||||
# rules
|
|
||||||
|
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
|
||||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
|
||||||
update-alternatives --set arptables /usr/sbin/arptables-legacy
|
|
||||||
update-alternatives --set ebtables /usr/sbin/ebtables-legacy
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# Nico Schottelius, 2020-01-07
|
|
||||||
# Detect the DNS64 prefix
|
|
||||||
# Based on https://tools.ietf.org/html/draft-ietf-behave-nat64-discovery-heuristic-05
|
|
||||||
#
|
|
||||||
# How it works:
|
|
||||||
# - ipv4only.arpa only has A records.
|
|
||||||
# - a DNS64 server will add AAAA records
|
|
||||||
# - we take this response (if any) and derive the IPv6 prefix from it
|
|
||||||
#
|
|
||||||
|
|
||||||
import dns.resolver
|
|
||||||
import ipaddress
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
dns64_prefix = None
|
|
||||||
answers = dns.resolver.query('ipv4only.arpa', 'AAAA')
|
|
||||||
|
|
||||||
for rdata in answers:
|
|
||||||
address = str(rdata)
|
|
||||||
network = ipaddress.IPv6Network("{}/96".format(address),
|
|
||||||
strict=False)
|
|
||||||
# print("{}: {}".format(rdata, network))
|
|
||||||
print("{}".format(network))
|
|
8
devuan-netboot.sh
Normal file
8
devuan-netboot.sh
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
date=$(date +%F)
|
||||||
|
suite=ascii
|
||||||
|
|
||||||
|
dir=${suit}-${date}
|
||||||
|
|
||||||
|
debootstrap ${suite}
|
|
@ -1,28 +0,0 @@
|
||||||
import json
|
|
||||||
import pprint
|
|
||||||
#import etcd3
|
|
||||||
|
|
||||||
with open("nico-vm-one.json", "r") as fd:
|
|
||||||
vmcontent = fd.read()
|
|
||||||
|
|
||||||
#vm = json.loads(vmcontent.decode('utf-8'))
|
|
||||||
vm = json.loads(vmcontent)
|
|
||||||
pprint.pprint(vm['TEMPLATE']['DISK'])
|
|
||||||
|
|
||||||
# storing info
|
|
||||||
|
|
||||||
for_etcd={}
|
|
||||||
for_etcd['data_version'] = "1"
|
|
||||||
for_etcd['vm_id'] = vm['ID']
|
|
||||||
for_etcd['owner'] = vm['UNAME']
|
|
||||||
|
|
||||||
for_etcd['disks'] = []
|
|
||||||
for disk in vm['TEMPLATE']['DISK']:
|
|
||||||
disk_etcd = {}
|
|
||||||
disk_etcd['image_name'] = disk['IMAGE']
|
|
||||||
disk_etcd['image_id'] = disk['IMAGE_ID']
|
|
||||||
disk_etcd['datastore_name'] = disk['DATASTORE']
|
|
||||||
disk_etcd['datastore_id'] = disk['DATASTORE_ID']
|
|
||||||
for_etcd['disks'].append(disk_etcd)
|
|
||||||
|
|
||||||
pprint.pprint(for_etcd)
|
|
|
@ -9,7 +9,7 @@
|
||||||
# definitely opinionated.
|
# definitely opinionated.
|
||||||
|
|
||||||
# Depends on the following packages (as of Fedora 31):
|
# Depends on the following packages (as of Fedora 31):
|
||||||
# qemu-img util-linux coreutils dnf curl e2fsprogs
|
# qemu-img util-linux coreutils dnf curl
|
||||||
|
|
||||||
# Run locally (without network) with:
|
# Run locally (without network) with:
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
||||||
|
@ -18,9 +18,9 @@ set -e
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
# XXX: Handle command-line arguments?
|
||||||
RELEASE=32
|
RELEASE=31
|
||||||
ARCH=x86_64
|
ARCH=x86_64
|
||||||
IMAGE_PATH=fedora-$RELEASE-$(date +%+F).img.qcow2
|
IMAGE_PATH=fedora-$RELEASE-$(date --iso-8601).img.qcow2
|
||||||
IMAGE_SIZE=10G
|
IMAGE_SIZE=10G
|
||||||
NBD_DEVICE=/dev/nbd1
|
NBD_DEVICE=/dev/nbd1
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ trap cleanup EXIT
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
# Create partition table, format partitions.
|
||||||
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
||||||
1M,500M,L,*
|
1M,100M,L,*
|
||||||
,,L
|
,,L
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ mount "${NBD_DEVICE}p2" /mnt
|
||||||
mkdir /mnt/boot
|
mkdir /mnt/boot
|
||||||
mount "${NBD_DEVICE}p1" /mnt/boot
|
mount "${NBD_DEVICE}p1" /mnt/boot
|
||||||
|
|
||||||
|
# XXX: dnf has a lot a weird (libX11?) dependencies, use microdnf instead?
|
||||||
|
|
||||||
dnf -y \
|
dnf -y \
|
||||||
--releasever=$RELEASE \
|
--releasever=$RELEASE \
|
||||||
--installroot=/mnt \
|
--installroot=/mnt \
|
||||||
|
@ -105,14 +107,8 @@ mount --bind /sys /mnt/sys
|
||||||
# systemd-networkd.
|
# systemd-networkd.
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
# Required to resolve package mirror in chroot.
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
# TODO: use non-$BIGCORP DNS service.
|
||||||
|
echo 'nameserver 1.1.1.1' >> /mnt/etc/resolv.conf
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux/issues/121 for details.
|
# See https://github.com/OpenNebula/addon-context-linux/issues/121 for details.
|
||||||
# network-scripts.x86_64 : Legacy scripts for manipulating of network devices
|
# network-scripts.x86_64 : Legacy scripts for manipulating of network devices
|
||||||
|
@ -123,32 +119,15 @@ curl -L "$ONE_CONTEXT_RPM_URL" > "/mnt$ONE_CONTEXT_RPM_PATH"
|
||||||
run_root dnf -y install "$ONE_CONTEXT_RPM_PATH"
|
run_root dnf -y install "$ONE_CONTEXT_RPM_PATH"
|
||||||
run_root rm "$ONE_CONTEXT_RPM_PATH"
|
run_root rm "$ONE_CONTEXT_RPM_PATH"
|
||||||
|
|
||||||
# Install resize2fs, which is required to resize the root file-system.
|
|
||||||
run_root dnf -y install e2fsprogs
|
|
||||||
|
|
||||||
# Initalize base services.
|
# Initalize base services.
|
||||||
run_root systemd-machine-id-setup
|
run_root systemd-machine-id-setup
|
||||||
|
run_root systemctl enable systemd-networkd.service
|
||||||
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
||||||
run_root systemctl enable systemd-timesyncd.service
|
run_root systemctl enable systemd-timesyncd.service
|
||||||
|
|
||||||
# Install haveged due to lack of entropy in ONE environment.
|
|
||||||
run_root dnf -y install haveged
|
|
||||||
run_root systemctl enable haveged.service
|
|
||||||
|
|
||||||
# Install kernel and bootloader.
|
# Install kernel and bootloader.
|
||||||
# Note: linux-firmware is not required our environment and takes almost 200M
|
|
||||||
# uncompressed but is a direct dependency of kernel-core...
|
|
||||||
run_root dnf -y install kernel grub2
|
run_root dnf -y install kernel grub2
|
||||||
|
|
||||||
# Add support for virtio block devices at boot time.
|
|
||||||
cat > /mnt/etc/dracut.conf.d/virtio-blk.conf <<EOF
|
|
||||||
add_drivers="virtio-blk"
|
|
||||||
EOF
|
|
||||||
kernel_version=$(ls /mnt/boot | grep "vmlinuz.*.$ARCH" | cut -d- -f2-)
|
|
||||||
run_root dracut --force --kver $kernel_version
|
|
||||||
|
|
||||||
# Configure grub2.
|
|
||||||
run_root grub2-install --target=i386-pc "${NBD_DEVICE}"
|
run_root grub2-install --target=i386-pc "${NBD_DEVICE}"
|
||||||
run_root grub2-mkconfig -o /boot/grub2/grub.cfg
|
run_root grub2-mkconfig -o /boot/grub2/grub.cfg
|
||||||
|
|
||||||
|
@ -164,14 +143,5 @@ UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Remove temporary files and reclaim freed disk space.
|
|
||||||
# Note: build logs could be removed as well.
|
|
||||||
run_root dnf clean all
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
# Make sure everything is written to disk before exiting.
|
||||||
sync
|
sync
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
rm -rf ~/rc_test_result
|
|
||||||
|
|
||||||
osd_list=( $(ceph tell 'osd.*' config get osd_recovery_sleep_hdd | awk '{print $1}') )
|
|
||||||
osd_recovery_sleep_hdd=( $(ceph tell 'osd.*' config get osd_recovery_sleep_hdd | awk '{print $2}') )
|
|
||||||
osd_recovery_op_priority=( $(ceph tell 'osd.*' config get osd_recovery_op_priority | awk '{print $2}') )
|
|
||||||
osd_recovery_max_single_start=( $(ceph tell 'osd.*' config get osd_recovery_max_single_start | awk '{print $2}') )
|
|
||||||
osd_recovery_sleep_hybrid=( $(ceph tell 'osd.*' config get osd_recovery_sleep_hybrid | awk '{print $2}') )
|
|
||||||
osd_max_backfills=( $(ceph tell 'osd.*' config get osd_max_backfills | awk '{print $2}') )
|
|
||||||
osd_recovery_max_active=( $(ceph tell 'osd.*' config get osd_recovery_max_active | awk '{print $2}') )
|
|
||||||
osd_recovery_priority=( $(ceph tell 'osd.*' config get osd_recovery_priority |awk '{print $2}') )
|
|
||||||
osd_client_op_priority=( $(ceph tell 'osd.*' config get osd_client_op_priority | awk '{print $2}') )
|
|
||||||
|
|
||||||
echo "|osd|osd_recovery_sleep_hdd|osd_recovery_op_priority|osd_recovery_max_single_start|osd_recovery_sleep_hybrid|osd_max_backfills|osd_recovery_max_active|osd_recovery_priority|osd_client_op_priority|" >> ~/rc_test_result
|
|
||||||
for ((i=0; i<${#osd_max_backfills[@]}; i++)) do
|
|
||||||
echo "| "${osd_list[$i]}" |"${osd_recovery_sleep_hdd[$i]}" | "${osd_recovery_op_priority[$i]}" | "${osd_recovery_max_single_start}" | "${osd_recovery_sleep_hybrid[$i]}" | "${osd_max_backfills[$i]}" | "${osd_recovery_max_active[$i]}" | "${osd_recovery_priority[$i]}" | "${osd_client_op_priority[$i]}" |" >> ~/rc_test_result
|
|
||||||
done
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# List mail addresses found under base DN $1 (defaults to dc=ungleich,dc=ch)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Hardcoded parameters.
|
|
||||||
LDAP_SERVER="ldaps://ldap1.ungleich.ch"
|
|
||||||
LDAP_BIND_DN="cn=manager,dc=ungleich,dc=ch"
|
|
||||||
|
|
||||||
if [ "$1" != "" ]; then
|
|
||||||
LDAP_SEARCH_BASE="$1"
|
|
||||||
else
|
|
||||||
LDAP_SEARCH_BASE="dc=ungleich,dc=ch"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read secrets from environment.
|
|
||||||
if [ "$LDAP_BIND_PASSWD" = "" ]; then
|
|
||||||
echo "You have to define LDAP_BIND_PASSWD before launching this script." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract mail addresses from LDAP directory.
|
|
||||||
ldap_search_result="$(
|
|
||||||
ldapsearch -x -H "$LDAP_SERVER" \
|
|
||||||
-D "$LDAP_BIND_DN" \
|
|
||||||
-w "$LDAP_BIND_PASSWD" \
|
|
||||||
-b "$LDAP_SEARCH_BASE" mail
|
|
||||||
)"
|
|
||||||
|
|
||||||
echo "$ldap_search_result" | grep 'mail:' | cut -d ' ' -f 2 -
|
|
|
@ -1,2 +0,0 @@
|
||||||
This directory contains old scripts that are not used anymore but might still
|
|
||||||
be useful.
|
|
|
@ -1,243 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright 2020 -- Evilham <contact@evilham.com>
|
|
||||||
# This is BSD licensed as it's based on BSD-licensed code
|
|
||||||
#
|
|
||||||
# We could have used e.g. something like:
|
|
||||||
# - https://git.sr.ht/~sircmpwn/builds.sr.ht/tree/master/images/freebsd/genimg
|
|
||||||
#
|
|
||||||
# But we actually do want to compile the kernel, so that the IPv6-only images
|
|
||||||
# are different and don't support INET.
|
|
||||||
|
|
||||||
# Explode if something goes wrong
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# What are we building?
|
|
||||||
# These are the only configuration options.
|
|
||||||
# They default to current environment.
|
|
||||||
# RELEASE: should be 'CURRENT' for current or 'X.Y' Defaults to 'CURRENT'.
|
|
||||||
# ARCH: probably amd64 for DCL
|
|
||||||
# VMFORMATS: defaults to qcow2, can also be raw. See man mkimg.
|
|
||||||
# OPENNEBULA_CONTEXT_VERSION: For DCL's OpenNebula that'd be 5.10.0 (default)
|
|
||||||
# OPENNEBULA_CONTEXT_REVISION: Defaults to 1.
|
|
||||||
RELEASE=${RELEASE:-CURRENT}
|
|
||||||
if [ "${RELEASE}" == "CURRENT" ]; then
|
|
||||||
SRCBRANCH="master"
|
|
||||||
else
|
|
||||||
SRCBRANCH="releng/${RELEASE}"
|
|
||||||
fi
|
|
||||||
ARCH=${ARCH:-amd64}
|
|
||||||
VMFORMATS=${VMFORMATS:-qcow2}
|
|
||||||
OPENNEBULA_CONTEXT_VERSION=${OPENNEBULA_CONTEXT_VERSION:-5.10.0}
|
|
||||||
OPENNEBULA_CONTEXT_REVISION=${OPENNEBULA_CONTEXT_REVISION:-1}
|
|
||||||
|
|
||||||
# Didn't see a need to make these configurable.
|
|
||||||
CHROOTDIR="/scratch"
|
|
||||||
SRCDIR="${CHROOTDIR}/usr/src"
|
|
||||||
OUR_DIR="$(realpath $(dirname "${0}"))"
|
|
||||||
OUR_SRCCONF="${SRCDIR}/release/src.conf"
|
|
||||||
OUR_RELEASE_CONF="${SRCDIR}/release/release.conf"
|
|
||||||
# Shorthand for the package file name.
|
|
||||||
OPENNEBULA_CONTEXT="one-context-${OPENNEBULA_CONTEXT_VERSION}_${OPENNEBULA_CONTEXT_REVISION}.txz"
|
|
||||||
|
|
||||||
setup_sources() {
|
|
||||||
# Let's use git, we might need to install it
|
|
||||||
if ! which git 2>&1 > /dev/null; then
|
|
||||||
pkg install -y git
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$(dirname ${SRCDIR})" ]; then
|
|
||||||
mkdir -p "$(dirname ${SRCDIR})"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Checkout needed branch
|
|
||||||
if [ ! -d "${SRCDIR}" ]; then
|
|
||||||
git clone "https://github.com/freebsd/freebsd" \
|
|
||||||
--branch "${SRCBRANCH}" "${SRCDIR}"
|
|
||||||
else
|
|
||||||
GIT_CMD="git -C ${SRCDIR}"
|
|
||||||
${GIT_CMD} clean -df
|
|
||||||
${GIT_CMD} reset --hard
|
|
||||||
${GIT_CMD} fetch
|
|
||||||
${GIT_CMD} checkout "${SRCBRANCH}"
|
|
||||||
${GIT_CMD} pull
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add settings for IPv6-only kernel
|
|
||||||
cat > "${SRCDIR}/sys/${ARCH}/conf/GENERIC-IPV6ONLY" << EOF
|
|
||||||
include GENERIC
|
|
||||||
ident GENERIC-IPV6ONLY
|
|
||||||
makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="
|
|
||||||
nooptions INET
|
|
||||||
nodevice gre
|
|
||||||
EOF
|
|
||||||
# Fix vmimage.subr to install custom package and fix other things
|
|
||||||
cat >> "${SRCDIR}/release/tools/vmimage.subr" << EOF
|
|
||||||
vm_extra_install_ports() {
|
|
||||||
# Make sure we install the opennbula context package
|
|
||||||
cp "/${OPENNEBULA_CONTEXT}" "\${DESTDIR}/tmp/${OPENNEBULA_CONTEXT}"
|
|
||||||
chroot \${DESTDIR} \${EMULATOR} env ASSUME_ALWAYS_YES=yes \\
|
|
||||||
/usr/sbin/pkg add '/tmp/${OPENNEBULA_CONTEXT}'
|
|
||||||
|
|
||||||
# Now make sure the system has better defaults
|
|
||||||
cat >> "\${DESTDIR}/etc/rc.conf" << eof
|
|
||||||
# Update to latest patch on first boot
|
|
||||||
firstboot_freebsd_update_enable="YES"
|
|
||||||
# Enable OpenNebula's service.
|
|
||||||
one_context_enable="YES"
|
|
||||||
# Enable SSH for customers
|
|
||||||
sshd_enable="YES"
|
|
||||||
# Clear tmp on boot
|
|
||||||
clear_tmp_enable="YES"
|
|
||||||
# Disable sendmail by default
|
|
||||||
sendmail_enable="NONE"
|
|
||||||
# Disable crash dumps
|
|
||||||
dumpdev="NO"
|
|
||||||
eof
|
|
||||||
# Enable root access with SSH key.
|
|
||||||
# It is user's responsibility to further secure their system.
|
|
||||||
sed -i '' -E \
|
|
||||||
's/(^#[ ]*|^)PermitRootLogin .*/PermitRootLogin without-password/' \
|
|
||||||
"\${DESTDIR}/etc/ssh/sshd_config"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
# Skip building iso images
|
|
||||||
rm "${SRCDIR}/release/${ARCH}/mkisoimages.sh"
|
|
||||||
# This is a hack to not build the memstick
|
|
||||||
cat > "${SRCDIR}/release/${ARCH}/make-memstick.sh" <<EOF
|
|
||||||
# Create an empty file, else checksums fail
|
|
||||||
touch "\${2}" || true
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_our_env() {
|
|
||||||
# Required by META_MODE to build faster next time
|
|
||||||
# This saves a lot of time when e.g. compiling GENERIC and GENERIC-IPV6ONLY
|
|
||||||
if ! kldstat | grep -q filemon; then
|
|
||||||
kldload filemon
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_releaseconf() {
|
|
||||||
cat << EOF
|
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Based off FreeBSD's release/release.conf.sample
|
|
||||||
#
|
|
||||||
|
|
||||||
# This redefines the prototype defined in release.sh.
|
|
||||||
# At this stage, the build chroot exists.
|
|
||||||
buildenv_setup() {
|
|
||||||
# Ensure META_MODE is on
|
|
||||||
echo "WITH_META_MODE=yes" > \${CHROOTDIR}/etc/src-env.conf
|
|
||||||
}
|
|
||||||
|
|
||||||
## Set the directory within which the release will be built.
|
|
||||||
CHROOTDIR="${CHROOTDIR}"
|
|
||||||
|
|
||||||
## Set to override the default target architecture and kernel
|
|
||||||
TARGET="${ARCH}"
|
|
||||||
TARGET_ARCH="${ARCH}"
|
|
||||||
KERNEL="${KERNEL_CONFIG}"
|
|
||||||
|
|
||||||
## Set to specify a custom make.conf and/or src.conf
|
|
||||||
SRC_CONF="${OUR_SRCCONF}"
|
|
||||||
|
|
||||||
# Since these are VMs, users should add other components if they want to.
|
|
||||||
NODOC=YES
|
|
||||||
NOPORTS=YES
|
|
||||||
NOSRC=YES
|
|
||||||
|
|
||||||
# We manage sources manually
|
|
||||||
SRC_UPDATE_SKIP=YES
|
|
||||||
|
|
||||||
## Set to pass additional flags to make(1) for the build chroot setup, such
|
|
||||||
## as TARGET/TARGET_ARCH.
|
|
||||||
# This was necessary for "cross-compiling"
|
|
||||||
CHROOT_MAKEENV="MK_LLVM_TARGET_X86=yes"
|
|
||||||
|
|
||||||
WITH_VMIMAGES=YES
|
|
||||||
|
|
||||||
# VM image size, see man 1 truncate
|
|
||||||
VMSIZE="10G"
|
|
||||||
|
|
||||||
# List of disk image formats, see man mkgimg.
|
|
||||||
VMFORMATS="${VMFORMATS}"
|
|
||||||
|
|
||||||
# These variables have to be exported because they are needed in subprocesses.
|
|
||||||
export NOSWAP=YES
|
|
||||||
# Custom ports
|
|
||||||
# - firstboot-freebsd-update helps us not have to create an image for each
|
|
||||||
# patch level. We still will have to do it for each minor version update.
|
|
||||||
# - bash is apparently needed for one-context
|
|
||||||
export VM_EXTRA_PACKAGES="firstboot-freebsd-update bash"
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
_do_run_release() {
|
|
||||||
. "${SRCDIR}/release/release.sh"
|
|
||||||
}
|
|
||||||
run_release() {
|
|
||||||
_do_run_release -c "${OUR_RELEASE_CONF}"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
build_image() {
|
|
||||||
# Generate configuration
|
|
||||||
echo "${2}" > "${OUR_SRCCONF}"
|
|
||||||
KERNEL_CONFIG="${1}"
|
|
||||||
gen_releaseconf > "${OUR_RELEASE_CONF}"
|
|
||||||
# Be paranoid about files and stuff
|
|
||||||
sync
|
|
||||||
# Continue with the release script
|
|
||||||
run_release
|
|
||||||
# Be paranoid about files and stuff
|
|
||||||
sync
|
|
||||||
|
|
||||||
mv "${CHROOTDIR}/R/vmimages" "${OUR_DIR}/FreeBSD-${RELEASE}-${1}"
|
|
||||||
|
|
||||||
# Be paranoid about files and stuff
|
|
||||||
sync
|
|
||||||
}
|
|
||||||
|
|
||||||
our_main() {
|
|
||||||
case "$1" in
|
|
||||||
--dualstack)
|
|
||||||
BUILD_DUALSTACK=yes
|
|
||||||
;;
|
|
||||||
--ipv6only)
|
|
||||||
BUILD_IPV6ONLY=yes
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
cat << EOF
|
|
||||||
Run with --dualstack or --ipv6only depending on the image you want.
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
setup_sources
|
|
||||||
setup_our_env
|
|
||||||
# Fetch OpenNebula's context package
|
|
||||||
fetch "https://github.com/OpenNebula/addon-context-linux/releases/download/v${OPENNEBULA_CONTEXT_VERSION}/${OPENNEBULA_CONTEXT}" \
|
|
||||||
-o "${CHROOTDIR}/${OPENNEBULA_CONTEXT}"
|
|
||||||
# Do run
|
|
||||||
if [ -n "${BUILD_DUALSTACK}" ]; then
|
|
||||||
build_image "GENERIC"
|
|
||||||
fi
|
|
||||||
if [ -n "${BUILD_IPV6ONLY}" ]; then
|
|
||||||
build_image "GENERIC-IPV6ONLY" "$(cat << EOF
|
|
||||||
WITHOUT_INET=yes
|
|
||||||
WITHOUT_INET_SUPPORT=yes
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
|
|
||||||
*************** DONE ***************
|
|
||||||
You will find the images under "${OUR_DIR}".
|
|
||||||
************************************
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
our_main "${@}"
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright 2020 -- Evilham <contact@evilham.com>
|
|
||||||
# This is BSD licensed as it's based on BSD-licensed code
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# This builds all needed FreeBSD images for ungleich's Data Center Light
|
|
||||||
# When there are new releases, they should be updated here and the script
|
|
||||||
# should run.
|
|
||||||
# 11.4 is scheduled end of June 2020
|
|
||||||
# 12.2 is scheduled end of October 2020
|
|
||||||
#
|
|
||||||
|
|
||||||
SUPPORTED_RELEASES="11.3 12.1"
|
|
||||||
|
|
||||||
# This should run in a DCL VM with an OK amount of cores (4/8 minimum),
|
|
||||||
# 4G RAM, and storage of roughly 20G + 5G * #resulting_images.
|
|
||||||
#
|
|
||||||
# This is because there is the base system, a 'pristine chroot', and during the
|
|
||||||
# build there can be 2 copies of the resulting system written to the system.
|
|
||||||
# Since there are 4 combinations of images:
|
|
||||||
# {STABLE,RELEASE} x {dualstack, IPv6ONLY}
|
|
||||||
#
|
|
||||||
# That means we'll need to assign about 40G storage to be on the safe side.
|
|
||||||
|
|
||||||
date=$(date -I)
|
|
||||||
for release in ${SUPPORTED_RELEASES}; do
|
|
||||||
for build in dualstack ipv6only; do
|
|
||||||
env RELEASE=${release} sh freebsd-build-opennebula-image-generic.sh --${build} \
|
|
||||||
| tee "freebsd-${release}-${build}-${date}.log"
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,2 +0,0 @@
|
||||||
* * * * * root ip -o -6 addr show | grep -E -v "lo |one" | awk '{print $1" " $2": "$4}' >> /dev/tty1
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script will find the locally active osd-s and display their information with the help of Megacli tools.
|
|
||||||
# Assumes that you run it on a host which has at least 1 osd that matches hdd or ssd disk device class in ceph osd df tree output.
|
|
||||||
#
|
|
||||||
# An example for usage:
|
|
||||||
# for NUM in 14 2 3 4 6 ; do printf "server$NUM\n" >> /tmp/osd_infos; ssh root@server"$NUM".place6.ungleich.ch "/opt/ungleich-tools/map-osd-to-disktype" >> /tmp/osd_infos ; printf "\n \n" >> /tmp/osd_infos; done
|
|
||||||
#
|
|
||||||
# llnu's most hacky/advanced script at the time of writing (2020-05-27)
|
|
||||||
|
|
||||||
|
|
||||||
# Future functionality (arguments, and filtering):
|
|
||||||
#OSDTYPE=ssd
|
|
||||||
|
|
||||||
|
|
||||||
# Tempfile
|
|
||||||
/opt/ungleich-tools/megaclisas-status > /tmp/megaclisas-status.out
|
|
||||||
|
|
||||||
# Gets osd numbers of a particular device class, and gets their mountpoints on the host, and puts them into a tempfile
|
|
||||||
#for osd in $(ceph osd tree | grep $OSDTYPE | grep -v down | cut -b 1-3); do findmnt -t xfs -n -o TARGET,SOURCE | grep "ceph-$osd " | cut -c 24- >> /tmp/list_osd_mountpoint.out; done
|
|
||||||
for osd in $(ceph osd tree | grep 'ssd\|hdd' | grep -v down | cut -b 1-3); do lsblk -p -o NAME,MOUNTPOINT | grep -w "/var/lib/ceph/osd/ceph-$osd" | cut -c 3- >> /tmp/list_osd_mountpoint.out ; done
|
|
||||||
|
|
||||||
# Gets the Megacli mappings for the mountpoints
|
|
||||||
for MOUNT in $(cat /tmp/list_osd_mountpoint.out | awk '{print $1}' | sed 's/[0-9]*//g') ; do cat /tmp/megaclisas-status.out | grep $MOUNT | awk '{print $1}' >> /tmp/megacli-mappings.out; done
|
|
||||||
|
|
||||||
# Gets the hardware types for the Megacli mappings
|
|
||||||
for megacli_mappings in $(cat /tmp/megacli-mappings.out); do awk '/Disk info/,0' /tmp/megaclisas-status.out | grep -w "$megacli_mappings"p0 | cut -d '|' -f 2-6,8 >> /tmp/disk_types.out; done
|
|
||||||
|
|
||||||
# Formatting, to get the local $OSDTYPE osd-s
|
|
||||||
for osd_num in $(cat /tmp/list_osd_mountpoint.out | awk '{print $2}' | cut -c 24- ); do printf "%-7s%s\n" "osd-$osd_num" >> /tmp/local_osds.out; done
|
|
||||||
|
|
||||||
# Combine and display the outputs
|
|
||||||
paste /tmp/local_osds.out /tmp/disk_types.out -d '|'
|
|
||||||
|
|
||||||
# Cleanup *.out files in the temp dir
|
|
||||||
rm /tmp/*.out
|
|
|
@ -1,875 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# $Id: megaclisas-status,v 1.68 2016/10/21 14:38:56 root Exp root $
|
|
||||||
#
|
|
||||||
# Written by Adam Cecile <gandalf@NOSPAM.le-vert.net>
|
|
||||||
# Modified by Vincent S. Cojot <vincent@NOSPAM.cojot.name>
|
|
||||||
#
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import pdb
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
import ctypes
|
|
||||||
|
|
||||||
def_megaclipath = "/opt/MegaRAID/MegaCli/MegaCli64"
|
|
||||||
|
|
||||||
# Non-Nagios Mode defaults
|
|
||||||
nagiosmode = False
|
|
||||||
nagiosoutput=''
|
|
||||||
nagiosgoodarray = 0
|
|
||||||
nagiosbadarray = 0
|
|
||||||
nagiosgooddisk = 0
|
|
||||||
nagiosbaddisk = 0
|
|
||||||
|
|
||||||
# Sane defaults
|
|
||||||
printarray = True
|
|
||||||
printcontroller = True
|
|
||||||
debugmode = False
|
|
||||||
notempmode = False
|
|
||||||
totaldrivenumber = 0
|
|
||||||
|
|
||||||
# Hardcode a max of 16 HBA and 128 LDs for now. LDTable must be initialized to accept populating list of LD's into each ctlr's list.
|
|
||||||
MaxNumHBA = 16
|
|
||||||
MaxNumLD = 128
|
|
||||||
LDTable = [ [] * MaxNumHBA for i in range(MaxNumLD) ]
|
|
||||||
NestedLDTable = [[False for i in range(MaxNumHBA)] for j in range(MaxNumLD)]
|
|
||||||
|
|
||||||
# Outputs is a 'dict' of all MegaCLI outputs so we can re-use them during loops..
|
|
||||||
Outputs = {}
|
|
||||||
|
|
||||||
# Startup
|
|
||||||
def print_usage():
|
|
||||||
print 'Usage: megaraid-status [--nagios|--debug|--notemp]'
|
|
||||||
|
|
||||||
# We need root access to query
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
root_or_admin = os.geteuid() == 0
|
|
||||||
except AttributeError:
|
|
||||||
root_or_admin = ctypes.windll.shell32.IsUserAnAdmin() !=0
|
|
||||||
if not root_or_admin:
|
|
||||||
print '# This script requires Administrator privileges'
|
|
||||||
sys.exit(5)
|
|
||||||
|
|
||||||
# Check command line arguments to enable nagios or not
|
|
||||||
if len(sys.argv) > 2:
|
|
||||||
print_usage()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
if sys.argv[1] == '--nagios':
|
|
||||||
nagiosmode = True
|
|
||||||
elif sys.argv[1] == '--debug':
|
|
||||||
debugmode = True
|
|
||||||
elif sys.argv[1] == '--notemp':
|
|
||||||
notempmode = True
|
|
||||||
else:
|
|
||||||
print_usage()
|
|
||||||
sys.exit(1)
|
|
||||||
# Functions
|
|
||||||
def dbgprint(msg):
|
|
||||||
if (debugmode):
|
|
||||||
sys.stderr.write ( str('# DEBUG : '+msg+'\n'))
|
|
||||||
|
|
||||||
def is_exe(fpath):
|
|
||||||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
|
||||||
|
|
||||||
def which(program):
|
|
||||||
import os
|
|
||||||
fpath, fname = os.path.split(program)
|
|
||||||
if fpath:
|
|
||||||
if is_exe(program):
|
|
||||||
return program
|
|
||||||
else:
|
|
||||||
# Add some defaults
|
|
||||||
os.environ["PATH"] += os.pathsep + '/opt/MegaRAID/MegaCli'
|
|
||||||
os.environ["PATH"] += os.pathsep + '/ms/dist/hwmgmt/bin'
|
|
||||||
os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.realpath(sys.argv[0]))
|
|
||||||
for path in os.environ["PATH"].split(os.pathsep):
|
|
||||||
dbgprint ('Looking in PATH '+str(path))
|
|
||||||
path = path.strip('"')
|
|
||||||
exe_file = os.path.join(path, program)
|
|
||||||
if is_exe(exe_file):
|
|
||||||
dbgprint ('Found "'+program+'" at '+exe_file)
|
|
||||||
return exe_file
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Find MegaCli
|
|
||||||
for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe":
|
|
||||||
dbgprint ('Looking for '+str(megabin)+' in PATH next..')
|
|
||||||
megaclipath = which(megabin)
|
|
||||||
if (megaclipath != None):
|
|
||||||
dbgprint ('Will use MegaCLI from here: '+str(megaclipath))
|
|
||||||
break
|
|
||||||
|
|
||||||
# Check binary exists (and +x), if not print an error message
|
|
||||||
if (megaclipath != None):
|
|
||||||
if os.path.exists(megaclipath) and os.access(megaclipath, os.X_OK):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if nagiosmode:
|
|
||||||
print 'UNKNOWN - Cannot find '+megaclipath
|
|
||||||
else:
|
|
||||||
print 'Cannot find ' + megaclipath + 'in your PATH. Please install it.'
|
|
||||||
sys.exit(3)
|
|
||||||
else:
|
|
||||||
print 'Cannot find "MegaCli64","MegaCli" or "megacli" or "MegaCli.exe" in your PATH. Please install it.'
|
|
||||||
sys.exit(3)
|
|
||||||
|
|
||||||
|
|
||||||
#### pdb.set_trace()
|
|
||||||
|
|
||||||
def returnWdthFromArrayCol(glarray,idx):
|
|
||||||
maxwdth = 0
|
|
||||||
for glrow in glarray:
|
|
||||||
if ( len(glrow[idx]) > maxwdth):
|
|
||||||
maxwdth = len(glrow[idx])
|
|
||||||
return maxwdth
|
|
||||||
|
|
||||||
# Get command output
|
|
||||||
def getOutput(cmd):
|
|
||||||
lines = []
|
|
||||||
if ( Outputs.has_key(cmd) ):
|
|
||||||
dbgprint ("Got Cached value: "+str(cmd))
|
|
||||||
lines = Outputs[cmd]
|
|
||||||
else:
|
|
||||||
dbgprint ("Not a Cached value: "+str(cmd))
|
|
||||||
output = os.popen(cmd)
|
|
||||||
for line in output:
|
|
||||||
if not re.match(r'^$',line.strip()):
|
|
||||||
lines.append(line.strip())
|
|
||||||
Outputs[cmd] = lines
|
|
||||||
return lines
|
|
||||||
|
|
||||||
def returnControllerNumber(output):
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Controller Count.*$',line.strip()):
|
|
||||||
return int(line.split(':')[1].strip().strip('.'))
|
|
||||||
|
|
||||||
def returnTotalDriveNumber(output):
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'Number of Physical Drives on Adapter.*$',line.strip()):
|
|
||||||
return int(line.split(':')[1].strip())
|
|
||||||
|
|
||||||
def returnRebuildProgress(output):
|
|
||||||
percent = 0
|
|
||||||
tmpstr = ''
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Rebuild Progress on Device at Enclosure.*, Slot .* Completed ',line.strip()):
|
|
||||||
tmpstr = line.split('Completed')[1].strip()
|
|
||||||
percent = int(tmpstr.split('%')[0].strip())
|
|
||||||
return percent
|
|
||||||
|
|
||||||
def returnConfDriveNumber(output):
|
|
||||||
# Count the configured drives
|
|
||||||
confdrives = 0
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'.*Number of PDs:.*$',line.strip()):
|
|
||||||
confdrives += int(line.split(':')[2].strip())
|
|
||||||
return int(confdrives)
|
|
||||||
|
|
||||||
def returnUnConfDriveNumber(output):
|
|
||||||
# Count the configured drives
|
|
||||||
confdrives = 0
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Firmware state: Unconfigured.*$',line.strip()):
|
|
||||||
confdrives += 1
|
|
||||||
return int(confdrives)
|
|
||||||
|
|
||||||
def returnControllerModel(output):
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Product Name.*$',line.strip()):
|
|
||||||
return line.split(':')[1].strip()
|
|
||||||
|
|
||||||
def returnMemorySize(output):
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Memory Size.*$',line.strip()):
|
|
||||||
return line.split(':')[1].strip()
|
|
||||||
|
|
||||||
def returnFirmwareVersion(output):
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^FW Package Build.*$',line.strip()):
|
|
||||||
return line.split(':')[1].strip()
|
|
||||||
|
|
||||||
def returnROCTemp(output):
|
|
||||||
ROCtemp = ''
|
|
||||||
tmpstr = ''
|
|
||||||
if (notempmode):
|
|
||||||
return str('N/A')
|
|
||||||
else:
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^ROC temperature :.*$',line.strip()):
|
|
||||||
tmpstr = line.split(':')[1].strip()
|
|
||||||
ROCtemp = re.sub(' +.*$', '', tmpstr)
|
|
||||||
if ( ROCtemp != '' ):
|
|
||||||
return str(str(ROCtemp)+'C')
|
|
||||||
else:
|
|
||||||
return str('N/A')
|
|
||||||
|
|
||||||
def returnBBUPresence(output):
|
|
||||||
BBU = ''
|
|
||||||
tmpstr = ''
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^BBU +:.*$',line.strip()):
|
|
||||||
tmpstr = line.split(':')[1].strip()
|
|
||||||
BBU = re.sub(' +.*$', '', tmpstr)
|
|
||||||
break
|
|
||||||
if ( BBU != '' ):
|
|
||||||
return str(BBU)
|
|
||||||
else:
|
|
||||||
return str('N/A')
|
|
||||||
|
|
||||||
def returnBBUStatus(output):
|
|
||||||
BBUStatus = ''
|
|
||||||
tmpstr = ''
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^ *Battery Replacement required +:.*$',line.strip()):
|
|
||||||
tmpstr = line.split(':')[1].strip()
|
|
||||||
BBUStatus = re.sub(' +.*$', '', tmpstr)
|
|
||||||
break
|
|
||||||
if ( BBUStatus == 'Yes' ):
|
|
||||||
return str('REPL')
|
|
||||||
else:
|
|
||||||
return str('Good')
|
|
||||||
|
|
||||||
def returnArrayNumber(output):
|
|
||||||
i = 0
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^(CacheCade )?Virtual Drive:.*$',line.strip()):
|
|
||||||
i += 1
|
|
||||||
return i
|
|
||||||
|
|
||||||
def returnHBAPCIInfo(output):
|
|
||||||
busprefix = '0000'
|
|
||||||
busid = ''
|
|
||||||
devid = ''
|
|
||||||
functionid = ''
|
|
||||||
pcipath = ''
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Bus Number.*:.*$',line.strip()):
|
|
||||||
busid = str(line.strip().split(':')[1].strip()).zfill(2)
|
|
||||||
if re.match(r'^Device Number.*:.*$',line.strip()):
|
|
||||||
devid = str(line.strip().split(':')[1].strip()).zfill(2)
|
|
||||||
if re.match(r'^Function Number.*:.*$',line.strip()):
|
|
||||||
functionid = str(line.strip().split(':')[1].strip()).zfill(1)
|
|
||||||
if busid:
|
|
||||||
pcipath = str(busprefix + ':' + busid + ':' + devid + '.' + functionid)
|
|
||||||
dbgprint("Array PCI path : "+pcipath)
|
|
||||||
return str(pcipath)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def returnHBAInfo(table,output,controllerid):
|
|
||||||
controllermodel = 'Unknown'
|
|
||||||
controllerram = 'Unknown'
|
|
||||||
controllerrev = 'Unknown'
|
|
||||||
controllertemp = ''
|
|
||||||
controllermodel = returnControllerModel(output)
|
|
||||||
controllerram = returnMemorySize(output)
|
|
||||||
controllerrev = returnFirmwareVersion(output)
|
|
||||||
controllertemp = returnROCTemp(output)
|
|
||||||
controllerbbu = returnBBUPresence(output)
|
|
||||||
if controllerbbu == 'Present':
|
|
||||||
cmd = '%s -AdpBbuCmd -GetBbuStatus -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
controllerbbu = returnBBUStatus(output)
|
|
||||||
|
|
||||||
if controllermodel != 'Unknown':
|
|
||||||
table.append([ 'c'+str(controllerid), controllermodel, controllerram, str(controllertemp), str(controllerbbu), str('FW: '+controllerrev) ])
|
|
||||||
|
|
||||||
def returnArrayInfo(output,controllerid,arrayid,arrayindex):
|
|
||||||
id = 'c'+str(controllerid)+'u'+str(arrayid)
|
|
||||||
operationlinennumber = False
|
|
||||||
linenumber = 0
|
|
||||||
targetid = ''
|
|
||||||
raidtype = ''
|
|
||||||
raidlvl = ''
|
|
||||||
size = ''
|
|
||||||
state = 'N/A'
|
|
||||||
strpsz = ''
|
|
||||||
dskcache = 'N/A'
|
|
||||||
properties = ''
|
|
||||||
spandepth = 0
|
|
||||||
diskperspan = 0
|
|
||||||
cachecade_info = 'None'
|
|
||||||
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^(CacheCade )?Virtual Drive:.*(Target Id: [0-9]+).*$',line.strip()):
|
|
||||||
# Extract the SCSI Target ID
|
|
||||||
targetid = line.strip().split(':')[2].split(')')[0].strip()
|
|
||||||
elif re.match(r'^RAID Level.*?:.*$',line.strip()):
|
|
||||||
# Extract the primary raid type, decide on X0 RAID level later when we hit Span Depth
|
|
||||||
raidlvl = int(line.strip().split(':')[1].split(',')[0].split('-')[1].strip())
|
|
||||||
elif re.match(r'^Size.*?:.*$',line.strip()):
|
|
||||||
# Size reported in MB
|
|
||||||
if re.match(r'^.*MB$',line.strip().split(':')[1]):
|
|
||||||
size = line.strip().split(':')[1].strip('MB').strip()
|
|
||||||
if ( float(size) > 1000):
|
|
||||||
size = str(int(round((float(size) / 1000))))+'G'
|
|
||||||
else:
|
|
||||||
size = str(int(round(float(size))))+'M'
|
|
||||||
# Size reported in TB
|
|
||||||
elif re.match(r'^.*TB$',line.strip().split(':')[1]):
|
|
||||||
size = line.strip().split(':')[1].strip('TB').strip()
|
|
||||||
size = str(int(round((float(size) * 1000))))+'G'
|
|
||||||
# Size reported in GB (default)
|
|
||||||
else:
|
|
||||||
size = line.strip().split(':')[1].strip('GB').strip()
|
|
||||||
size = str(int(round((float(size)))))+'G'
|
|
||||||
elif re.match(r'^Span Depth.*?:.*$',line.strip()):
|
|
||||||
# If Span Depth is greater than 1 chances are we have a RAID 10, 50 or 60
|
|
||||||
spandepth = line.strip().split(':')[1].strip()
|
|
||||||
elif re.match(r'^State.*?:.*$',line.strip()):
|
|
||||||
state = line.strip().split(':')[1].strip()
|
|
||||||
elif re.match(r'^Strip Size.*?:.*$',line.strip()):
|
|
||||||
strpsz = line.strip().split(':')[1].strip()
|
|
||||||
elif re.match(r'^Number Of Drives per span.*:.*$',line.strip()):
|
|
||||||
diskperspan = int(line.strip().split(':')[1].strip())
|
|
||||||
elif re.match(r'^Current Cache Policy.*?:.*$',line.strip()):
|
|
||||||
props = line.strip().split(':')[1].strip()
|
|
||||||
if re.search('ReadAdaptive', props):
|
|
||||||
properties += 'ADRA'
|
|
||||||
if re.search('ReadAhead', props):
|
|
||||||
properties += 'RA'
|
|
||||||
if re.match('ReadAheadNone', props):
|
|
||||||
properties += 'NORA'
|
|
||||||
if re.search('WriteBack', props):
|
|
||||||
properties += ',WB'
|
|
||||||
if re.match('WriteThrough', props):
|
|
||||||
properties += ',WT'
|
|
||||||
elif re.match(r'^Disk Cache Policy.*?:.*$',line.strip()):
|
|
||||||
props = line.strip().split(':')[1].strip()
|
|
||||||
if re.search('Disabled', props):
|
|
||||||
dskcache = 'Disabled'
|
|
||||||
if re.search('Disk.s Default', props):
|
|
||||||
dskcache = 'Default'
|
|
||||||
if re.search('Enabled', props):
|
|
||||||
dskcache = 'Enabled'
|
|
||||||
elif re.match(r'^Ongoing Progresses.*?:.*$',line.strip()):
|
|
||||||
operationlinennumber = linenumber
|
|
||||||
elif re.match(r'Cache Cade Type\s*:.*$', line):
|
|
||||||
cachecade_info = "Type : " + line.strip().split(':')[1].strip()
|
|
||||||
elif re.match(r'^Target Id of the Associated LDs\s*:.*$', line):
|
|
||||||
associated=[]
|
|
||||||
for array in line.split(':')[1].strip().split(','):
|
|
||||||
if array.isdigit():
|
|
||||||
associated.append('c%du%d' % (controllerid, int(array)))
|
|
||||||
if len(associated) >= 1:
|
|
||||||
cachecade_info = "Associated : %s" %(', '.join(associated))
|
|
||||||
linenumber += 1
|
|
||||||
|
|
||||||
# If there was an ongoing operation, find the relevant line in the previous output
|
|
||||||
if operationlinennumber:
|
|
||||||
inprogress = output[operationlinennumber + 1]
|
|
||||||
else:
|
|
||||||
inprogress = 'None'
|
|
||||||
|
|
||||||
# Compute the RAID level
|
|
||||||
NestedLDTable[int(controllerid)][int(arrayindex)] = False
|
|
||||||
if raidlvl == '':
|
|
||||||
raidtype = str('N/A')
|
|
||||||
else:
|
|
||||||
if (int(spandepth) >= 2):
|
|
||||||
raidtype = str('RAID-' + str(raidlvl) + '0')
|
|
||||||
NestedLDTable[controllerid][int(arrayindex)] = True
|
|
||||||
else:
|
|
||||||
if(raidlvl == 1):
|
|
||||||
if(diskperspan > 2):
|
|
||||||
raidtype = str('RAID-10')
|
|
||||||
NestedLDTable[controllerid][int(arrayindex)] = True
|
|
||||||
else:
|
|
||||||
raidtype = str('RAID-' + str(raidlvl))
|
|
||||||
else:
|
|
||||||
raidtype = str('RAID-' + str(raidlvl))
|
|
||||||
|
|
||||||
dbgprint('RAID Level: ' + str(raidlvl)
|
|
||||||
+ ' Span Depth: ' + str(spandepth)
|
|
||||||
+ ' Disk Per Span: ' + str(diskperspan)
|
|
||||||
+ ' Raid Type: ' + str(raidtype))
|
|
||||||
return [id,raidtype,size,strpsz,properties,dskcache,state,targetid,cachecade_info,inprogress]
|
|
||||||
|
|
||||||
def returnDiskInfo(output,controllerid):
|
|
||||||
arrayid = False
|
|
||||||
arrayindex = -1
|
|
||||||
sarrayid = 'Unknown'
|
|
||||||
diskid = False
|
|
||||||
oldenclid = False
|
|
||||||
enclid = False
|
|
||||||
spanid = False
|
|
||||||
slotid = False
|
|
||||||
lsidid = 'Unknown'
|
|
||||||
table = []
|
|
||||||
fstate = 'Offline'
|
|
||||||
substate = 'Unknown'
|
|
||||||
model = 'Unknown'
|
|
||||||
speed = 'Unknown'
|
|
||||||
dsize = 'Unknown'
|
|
||||||
temp = 'Unk0C'
|
|
||||||
percent = 0
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Span: [0-9]+ - Number of PDs:',line.strip()):
|
|
||||||
spanid = line.split(':')[1].strip()
|
|
||||||
spanid = re.sub(' - Number of PDs.*', '', spanid)
|
|
||||||
elif re.match(r'Enclosure Device ID: .*$',line.strip()):
|
|
||||||
# We match here early in the analysis so reset the vars if this is a new disk we're reading..
|
|
||||||
oldenclid = enclid
|
|
||||||
enclid = line.split(':')[1].strip()
|
|
||||||
if oldenclid != False:
|
|
||||||
fstate = 'Offline'
|
|
||||||
model = 'Unknown'
|
|
||||||
speed = 'Unknown'
|
|
||||||
temp = 'Unk0C'
|
|
||||||
slotid = False
|
|
||||||
lsidid = 'Unknown'
|
|
||||||
elif re.match(r'^Coerced Size: ',line.strip()):
|
|
||||||
dsize = line.split(':')[1].strip()
|
|
||||||
dsize = re.sub(' \[.*\.*$', '', dsize)
|
|
||||||
dsize = re.sub('[0-9][0-9] GB', ' Gb', dsize)
|
|
||||||
elif re.match(r'^(CacheCade )?Virtual (Disk|Drive): [0-9]+.*$',line.strip()):
|
|
||||||
arrayindex += 1
|
|
||||||
arrayid = line.split('(')[0].split(':')[1].strip()
|
|
||||||
elif re.match(r'PD: [0-9]+ Information.*$',line.strip()):
|
|
||||||
diskid = line.split()[1].strip()
|
|
||||||
elif re.match(r'^Device Id: .*$',line.strip()):
|
|
||||||
lsidid = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Slot Number: .*$',line.strip()):
|
|
||||||
slotid = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Firmware state: .*$',line.strip()):
|
|
||||||
fstate = line.split(':')[1].strip()
|
|
||||||
subfstate = re.sub('\(.*', '', fstate)
|
|
||||||
dbgprint('Firmware State: '+str(fstate)+' '+str(subfstate))
|
|
||||||
elif re.match(r'Inquiry Data: .*$',line.strip()):
|
|
||||||
model = line.split(':')[1].strip()
|
|
||||||
model = re.sub(' +', ' ', model)
|
|
||||||
# Sub code
|
|
||||||
manuf = re.sub(' .*', '', model)
|
|
||||||
dtype = re.sub(manuf+' ', '', model)
|
|
||||||
dtype = re.sub(' .*', '', dtype)
|
|
||||||
hwserial = re.sub('.*'+dtype+' *', '', model)
|
|
||||||
elif re.match(r'^Media Type: .*$',line.strip()):
|
|
||||||
mtype = line.split(':')[1].strip()
|
|
||||||
if mtype == 'Hard Disk Device':
|
|
||||||
mtype = 'HDD'
|
|
||||||
else:
|
|
||||||
if mtype == 'Solid State Device':
|
|
||||||
mtype = 'SSD'
|
|
||||||
else:
|
|
||||||
mtype = 'N/A'
|
|
||||||
elif re.match(r'Device Speed: .*$',line.strip()):
|
|
||||||
speed = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Drive Temperature :.*$',line.strip()):
|
|
||||||
if (notempmode):
|
|
||||||
temp = 'N/A'
|
|
||||||
else:
|
|
||||||
# Drive temp is amongst the last few lines matched, decide here if we add information to the table..
|
|
||||||
temp = line.split(':')[1].strip()
|
|
||||||
temp = re.sub(' \(.*\)', '', temp)
|
|
||||||
if model != 'Unknown':
|
|
||||||
dbgprint('Disk Info: '+str(arrayid)+' '+str(diskid)+' '+str(oldenclid))
|
|
||||||
if subfstate == 'Rebuild':
|
|
||||||
cmd = '%s pdrbld -showprog -physdrv\[%s:%s\] -a%d -NoLog' % (megaclipath, enclid, slotid, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
percent = returnRebuildProgress(output)
|
|
||||||
fstate = str('Rebuilding (%d%%)' % (percent))
|
|
||||||
|
|
||||||
if (( NestedLDTable[controllerid][int(arrayindex)] == True) and (spanid != False)):
|
|
||||||
sarrayid = str(arrayid)+"s"+spanid
|
|
||||||
else:
|
|
||||||
sarrayid = str(arrayid)
|
|
||||||
table.append([sarrayid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid])
|
|
||||||
return table
|
|
||||||
|
|
||||||
|
|
||||||
def returnUnconfDiskInfo(output,controllerid):
|
|
||||||
arrayid = False
|
|
||||||
diskid = False
|
|
||||||
olddiskid = False
|
|
||||||
enclid = False
|
|
||||||
slotid = False
|
|
||||||
lsidid = 'Unknown'
|
|
||||||
table = []
|
|
||||||
fstate = 'Offline'
|
|
||||||
substate = 'Unknown'
|
|
||||||
model = 'Unknown'
|
|
||||||
speed = 'Unknown'
|
|
||||||
mtype = 'Unknown'
|
|
||||||
dsize = 'Unknown'
|
|
||||||
temp = 'Unk0C'
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'Enclosure Device ID: .*$',line.strip()):
|
|
||||||
# We match here early in the analysis so reset the vars if this is a new disk we're reading..
|
|
||||||
oldenclid = enclid
|
|
||||||
enclid = line.split(':')[1].strip()
|
|
||||||
if oldenclid != False:
|
|
||||||
arrayid = False
|
|
||||||
fstate = 'Offline'
|
|
||||||
model = 'Unknown'
|
|
||||||
speed = 'Unknown'
|
|
||||||
temp = 'Unk0C'
|
|
||||||
slotid = False
|
|
||||||
lsidid = 'Unknown'
|
|
||||||
|
|
||||||
elif re.match(r'^Coerced Size: ',line.strip()):
|
|
||||||
dsize = line.split(':')[1].strip()
|
|
||||||
dsize = re.sub(' \[.*\.*$', '', dsize)
|
|
||||||
dsize = re.sub('[0-9][0-9] GB', ' Gb', dsize)
|
|
||||||
elif re.match(r'^Drive.s position: DiskGroup: [0-9]+,.*$',line.strip()):
|
|
||||||
arrayid = line.split(',')[1].split(':')[1].strip()
|
|
||||||
elif re.match(r'^Device Id: [0-9]+.*$',line.strip()):
|
|
||||||
diskid = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'^Device Id: .*$',line.strip()):
|
|
||||||
lsidid = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Slot Number: .*$',line.strip()):
|
|
||||||
slotid = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Firmware state: .*$',line.strip()):
|
|
||||||
fstate = line.split(':')[1].strip()
|
|
||||||
subfstate = re.sub('\(.*', '', fstate)
|
|
||||||
dbgprint('Firmware State: '+str(fstate)+' '+str(subfstate))
|
|
||||||
elif re.match(r'Inquiry Data: .*$',line.strip()):
|
|
||||||
model = line.split(':')[1].strip()
|
|
||||||
model = re.sub(' +', ' ', model)
|
|
||||||
manuf = re.sub(' .*', '', model)
|
|
||||||
dtype = re.sub(manuf+' ', '', model)
|
|
||||||
dtype = re.sub(' .*', '', dtype)
|
|
||||||
hwserial = re.sub('.*'+dtype+' *', '', model)
|
|
||||||
elif re.match(r'^Media Type: .*$',line.strip()):
|
|
||||||
mtype = line.split(':')[1].strip()
|
|
||||||
if mtype == 'Hard Disk Device':
|
|
||||||
mtype = 'HDD'
|
|
||||||
else:
|
|
||||||
if mtype == 'Solid State Device':
|
|
||||||
mtype = 'SSD'
|
|
||||||
else:
|
|
||||||
mtype = 'N/A'
|
|
||||||
elif re.match(r'Device Speed: .*$',line.strip()):
|
|
||||||
speed = line.split(':')[1].strip()
|
|
||||||
elif re.match(r'Drive Temperature :.*$',line.strip()):
|
|
||||||
temp = line.split(':')[1].strip()
|
|
||||||
temp = re.sub('\(.*\)', '', temp)
|
|
||||||
# Drive temp is amongst the last few lines matched, decide here if we add information to the table..
|
|
||||||
if arrayid == False:
|
|
||||||
if subfstate == 'Unconfigured':
|
|
||||||
dbgprint('Unconfigured Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate))
|
|
||||||
elif subfstate == 'Online, Spun Up':
|
|
||||||
dbgprint('Online Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate))
|
|
||||||
table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, lsidid])
|
|
||||||
return table
|
|
||||||
|
|
||||||
cmd = '%s -adpCount -NoLog' % (megaclipath)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
controllernumber = returnControllerNumber(output)
|
|
||||||
|
|
||||||
bad = False
|
|
||||||
|
|
||||||
# List available controller
|
|
||||||
if printcontroller:
|
|
||||||
if controllernumber:
|
|
||||||
if not nagiosmode:
|
|
||||||
print '-- Controller information --'
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
controllerid = 0
|
|
||||||
mlen = 0
|
|
||||||
hbainfo = []
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
cmd = '%s -AdpAllInfo -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
returnHBAInfo(hbainfo, output,controllerid)
|
|
||||||
controllerid += 1
|
|
||||||
mlen = returnWdthFromArrayCol(hbainfo,1)
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
for hba in hbainfo:
|
|
||||||
hbafmt = str('%-5s | %-'+str(mlen)+'s | %-6s | %-4s | %-6s | %-12s ')
|
|
||||||
# Header
|
|
||||||
if ( i == 0 ):
|
|
||||||
if not nagiosmode:
|
|
||||||
print hbafmt % ("-- ID","H/W Model","RAM","Temp","BBU", "Firmware")
|
|
||||||
if not nagiosmode:
|
|
||||||
print hbafmt % (
|
|
||||||
hba[0],
|
|
||||||
hba[1],
|
|
||||||
hba[2],
|
|
||||||
hba[3],
|
|
||||||
hba[4],
|
|
||||||
hba[5])
|
|
||||||
i += 1
|
|
||||||
if not nagiosmode:
|
|
||||||
print ''
|
|
||||||
else:
|
|
||||||
print "No MegaRAID or PERC adapter detected on your system!"
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
if printarray:
|
|
||||||
if not nagiosmode:
|
|
||||||
print '-- Array information --'
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
pcipath = ''
|
|
||||||
diskpath = ''
|
|
||||||
i = 0 ; j = 0
|
|
||||||
mlen = 0 ; rlen = 0 ; clen = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
arrayindex = 0
|
|
||||||
|
|
||||||
cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraynumber = returnArrayNumber(output)
|
|
||||||
# We need to explore each HBA to look for gaps in LD's
|
|
||||||
ldid = 0 ; ldcount = 0
|
|
||||||
while ldcount < arraynumber:
|
|
||||||
cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
for line in output:
|
|
||||||
if re.match(r'^Adapter.*Virtual Drive .* Does not Exist',line.strip()):
|
|
||||||
ldid += 1
|
|
||||||
elif re.match(r'^(CacheCade )?Virtual Drive:',line.strip()):
|
|
||||||
LDTable[controllerid].append ( ldid )
|
|
||||||
#NestedLDTable[controllerid][int(arrayindex)] = False
|
|
||||||
ldcount += 1
|
|
||||||
ldid += 1
|
|
||||||
|
|
||||||
while arrayindex < arraynumber:
|
|
||||||
ldid = LDTable[controllerid][arrayindex]
|
|
||||||
cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arrayinfo = returnArrayInfo(output, controllerid, ldid, arrayindex)
|
|
||||||
if ( len(arrayinfo[1]) > rlen):
|
|
||||||
rlen = len(arrayinfo[1])
|
|
||||||
if ( len(arrayinfo[4]) > mlen):
|
|
||||||
mlen = len(arrayinfo[4])
|
|
||||||
if ( len(arrayinfo[8]) > clen):
|
|
||||||
clen = len(arrayinfo[8])
|
|
||||||
arrayindex += 1
|
|
||||||
controllerid += 1
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
arrayindex = 0
|
|
||||||
|
|
||||||
cmd = '%s -AdpGetPciInfo -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
pcipath = returnHBAPCIInfo(output)
|
|
||||||
|
|
||||||
cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraynumber = returnArrayNumber(output)
|
|
||||||
while arrayindex < arraynumber:
|
|
||||||
ldid = LDTable[controllerid][arrayindex]
|
|
||||||
cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arrayinfo = returnArrayInfo(output,controllerid, ldid, arrayindex)
|
|
||||||
|
|
||||||
if pcipath:
|
|
||||||
diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:')
|
|
||||||
for j in range (8):
|
|
||||||
diskpath = diskprefix + str(j) + ':' + str(arrayinfo[7]) + ':0'
|
|
||||||
if os.path.exists(diskpath):
|
|
||||||
arrayinfo[7] = os.path.realpath(diskpath)
|
|
||||||
else:
|
|
||||||
arrayinfo[7] = 'N/A'
|
|
||||||
|
|
||||||
# Pad the string length, just to make sure it's aligned with the headers...
|
|
||||||
if (rlen < len("Type")):
|
|
||||||
rlen = len("Type")
|
|
||||||
if (mlen < len("Flags")):
|
|
||||||
mlen = len("Flags")
|
|
||||||
if (clen < len("CacheCade")):
|
|
||||||
clen = len("CacheCade")
|
|
||||||
|
|
||||||
ldfmt = str('%-5s | %-'+str(rlen)+'s | %7s | %7s | %'+str(mlen)+'s | %8s | %8s | %8s | %-'+str(clen)+'s |%-12s ')
|
|
||||||
# Header
|
|
||||||
if ( i == 0 ):
|
|
||||||
if not nagiosmode:
|
|
||||||
print ldfmt % ("-- ID", "Type", "Size", "Strpsz", "Flags", "DskCache", "Status", "OS Path", "CacheCade", "InProgress" )
|
|
||||||
if not nagiosmode:
|
|
||||||
print ldfmt % (
|
|
||||||
arrayinfo[0],
|
|
||||||
arrayinfo[1],
|
|
||||||
arrayinfo[2],
|
|
||||||
arrayinfo[3],
|
|
||||||
arrayinfo[4],
|
|
||||||
arrayinfo[5],
|
|
||||||
arrayinfo[6],
|
|
||||||
arrayinfo[7],
|
|
||||||
arrayinfo[8],
|
|
||||||
arrayinfo[9])
|
|
||||||
dbgprint("Array state : "+arrayinfo[6])
|
|
||||||
if arrayinfo[6] not in [ 'Optimal', 'N/A' ]:
|
|
||||||
bad = True
|
|
||||||
nagiosbadarray=nagiosbadarray+1
|
|
||||||
else:
|
|
||||||
nagiosgoodarray=nagiosgoodarray+1
|
|
||||||
arrayindex += 1
|
|
||||||
i += 1
|
|
||||||
controllerid += 1
|
|
||||||
if not nagiosmode:
|
|
||||||
print ''
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
cmd = '%s -PDGetNum -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
totaldrivenumber += returnTotalDriveNumber(output)
|
|
||||||
controllerid += 1
|
|
||||||
|
|
||||||
if totaldrivenumber:
|
|
||||||
if not nagiosmode:
|
|
||||||
print '-- Disk information --'
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
dlen = 0 ; mlen = 0 ; flen = 0
|
|
||||||
controllerid = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
arrayid = 0
|
|
||||||
cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraynumber = returnArrayNumber(output)
|
|
||||||
#### BUG: -LdPdInfo shows all PD on the adapter, not just for said LD..
|
|
||||||
#### while arrayid <= arraynumber:
|
|
||||||
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraydisk = returnDiskInfo(output,controllerid)
|
|
||||||
for array in arraydisk:
|
|
||||||
dbgprint('Disk c'+str(controllerid)+'u'+array[0]+'p'+array[1] + ' status : ' + array[5])
|
|
||||||
if array[5] not in [ 'Online', 'Online, Spun Up' ]:
|
|
||||||
bad = True
|
|
||||||
nagiosbaddisk=nagiosbaddisk+1
|
|
||||||
else:
|
|
||||||
nagiosgooddisk=nagiosgooddisk+1
|
|
||||||
|
|
||||||
if ( returnWdthFromArrayCol(arraydisk,0) > dlen):
|
|
||||||
dlen = returnWdthFromArrayCol(arraydisk,0)
|
|
||||||
if ( returnWdthFromArrayCol(arraydisk,3) > mlen):
|
|
||||||
mlen = returnWdthFromArrayCol(arraydisk,3)
|
|
||||||
if ( returnWdthFromArrayCol(arraydisk,5) > flen):
|
|
||||||
flen = returnWdthFromArrayCol(arraydisk,5)
|
|
||||||
controllerid += 1
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
arrayid = 0
|
|
||||||
|
|
||||||
cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraynumber = returnArrayNumber(output)
|
|
||||||
#### BUG: -LdPdInfo shows all PD on the adapter, not just for said LD..
|
|
||||||
#### while arrayid <= arraynumber:
|
|
||||||
|
|
||||||
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraydisk = returnDiskInfo(output,controllerid)
|
|
||||||
|
|
||||||
# Adjust print format with width computed above
|
|
||||||
drvfmt = "%-"+str(dlen+5)+"s | %-4s | %-"+str(mlen)+"s | %-8s | %-"+str(flen)+"s | %-8s | %-4s | %-8s | %-8s"
|
|
||||||
for array in arraydisk:
|
|
||||||
# Header
|
|
||||||
if ( i == 0 ):
|
|
||||||
if not nagiosmode:
|
|
||||||
print drvfmt % (
|
|
||||||
"-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI Device ID")
|
|
||||||
# Drive information
|
|
||||||
if not nagiosmode:
|
|
||||||
print drvfmt % (
|
|
||||||
str('c'+str(controllerid)+'u'+array[0]+'p'+array[1]), # c0p0
|
|
||||||
array[2], # HDD/SDD
|
|
||||||
array[3], # Model Information (Variable len)
|
|
||||||
array[4], # Size
|
|
||||||
array[5], # Status (Variable len)
|
|
||||||
array[6], # Speed
|
|
||||||
array[7], # Temp
|
|
||||||
str('['+array[8]+':'+array[9]+']'), # Slot ID
|
|
||||||
array[10]) # LSI ID
|
|
||||||
i = i + 1
|
|
||||||
controllerid += 1
|
|
||||||
if not nagiosmode:
|
|
||||||
print ''
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
totalconfdrivenumber = 0
|
|
||||||
totalunconfdrivenumber = 0
|
|
||||||
totaldrivenumber = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
totalconfdrivenumber += returnConfDriveNumber(output)
|
|
||||||
|
|
||||||
cmd = '%s -PDGetNum -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
totaldrivenumber += returnTotalDriveNumber(output)
|
|
||||||
|
|
||||||
cmd = '%s -PDList -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
totalunconfdrivenumber += returnUnConfDriveNumber(output)
|
|
||||||
|
|
||||||
controllerid += 1
|
|
||||||
|
|
||||||
dbgprint('Total Drives in system : ' + str(totaldrivenumber))
|
|
||||||
dbgprint('Total Configured Drives : ' + str(totalconfdrivenumber))
|
|
||||||
dbgprint('Total Unconfigured Drives : ' + str(totalunconfdrivenumber))
|
|
||||||
|
|
||||||
if totalunconfdrivenumber:
|
|
||||||
if not nagiosmode:
|
|
||||||
print '-- Unconfigured Disk information --'
|
|
||||||
|
|
||||||
controllerid = 0
|
|
||||||
while controllerid < controllernumber:
|
|
||||||
arrayid = 0
|
|
||||||
|
|
||||||
cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraynumber = returnArrayNumber(output)
|
|
||||||
#### BUG: -LdPdInfo shows all PD on the adapter, not just for given LD..
|
|
||||||
#### while arrayid <= arraynumber:
|
|
||||||
|
|
||||||
cmd = '%s -PDList -a%d -NoLog' % (megaclipath, controllerid)
|
|
||||||
output = getOutput(cmd)
|
|
||||||
arraydisk = returnUnconfDiskInfo(output,controllerid)
|
|
||||||
for array in arraydisk:
|
|
||||||
dbgprint('Disk c'+str(controllerid)+'uXpY status : ' + array[3])
|
|
||||||
if array[3] not in [ 'Online', 'Unconfigured(good), Spun Up', 'Unconfigured(good), Spun down', 'JBOD','Hotspare, Spun Up','Hotspare, Spun down' ]:
|
|
||||||
bad = True
|
|
||||||
nagiosbaddisk=nagiosbaddisk+1
|
|
||||||
else:
|
|
||||||
nagiosgooddisk=nagiosgooddisk+1
|
|
||||||
|
|
||||||
mlen = returnWdthFromArrayCol(arraydisk,1)
|
|
||||||
flen = returnWdthFromArrayCol(arraydisk,3)
|
|
||||||
|
|
||||||
# Adjust print format with widths computed above
|
|
||||||
drvfmt = "%-7s | %-4s | %-"+str(mlen)+"s | %-8s | %-"+str(flen+2)+"s | %-8s | %-4s | %-8s | %-8s"
|
|
||||||
i = 0
|
|
||||||
for array in arraydisk:
|
|
||||||
# Header
|
|
||||||
if ( i == 0 ):
|
|
||||||
if not nagiosmode:
|
|
||||||
print drvfmt % (
|
|
||||||
"-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI Device ID")
|
|
||||||
# Drive information
|
|
||||||
if not nagiosmode:
|
|
||||||
print drvfmt % (
|
|
||||||
str('c'+str(controllerid)+'uXpY'), # cXpY
|
|
||||||
array[0], # HDD/SDD
|
|
||||||
array[1], # Model Information (Variable len)
|
|
||||||
array[2], # Size
|
|
||||||
array[3], # Status (Variable len)
|
|
||||||
array[4], # Speed
|
|
||||||
array[5], # Temp
|
|
||||||
str('['+array[6]+':'+array[7]+']'), # Slot ID
|
|
||||||
array[8]) # LSI ID
|
|
||||||
i = i + 1
|
|
||||||
controllerid += 1
|
|
||||||
if not nagiosmode:
|
|
||||||
print ''
|
|
||||||
|
|
||||||
if nagiosmode:
|
|
||||||
if bad:
|
|
||||||
print 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk)
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
print 'RAID OK - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk)
|
|
||||||
else:
|
|
||||||
if bad:
|
|
||||||
print '\nThere is at least one disk/array in a NOT OPTIMAL state.'
|
|
||||||
sys.exit(1)
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Nico Schottelius, 2020-08-03
|
|
||||||
# Setup a standard crs326
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if [ $# -ne 4 ]; then
|
|
||||||
echo "$0 <current-ip> <new-ipv6-network> <hostname-to-be-setup> <password>"
|
|
||||||
echo "Example:"
|
|
||||||
echo "$0 fe80::764d:28ff:fe09:9355%eth1 2a0a:e5c0:2::/64 mikrotik-crs326-8 \$(pass ...)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ip=$1; shift
|
|
||||||
newip=$1; shift
|
|
||||||
hostname=$1; shift
|
|
||||||
password=$1; shift
|
|
||||||
|
|
||||||
target=$ip
|
|
||||||
bridge=bridge
|
|
||||||
|
|
||||||
conf() {
|
|
||||||
echo $@
|
|
||||||
ssh admin@${target} "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
commastring() {
|
|
||||||
echo $@ | sed 's/ /,/g'
|
|
||||||
}
|
|
||||||
|
|
||||||
conf "/system identity set name=$hostname"
|
|
||||||
conf "/interface bridge add name=$bridge"
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# MTU
|
|
||||||
|
|
||||||
for i in $(seq 1 24); do
|
|
||||||
conf "/interface ethernet set ether$i mtu=9200 l2mtu=9204"
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
for i in $(seq 1 2); do
|
|
||||||
conf "/interface ethernet set sfp-sfpplus$i mtu=9200 l2mtu=9204"
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=sfp-sfpplus$i hw=yes"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# IPv6 address, password
|
|
||||||
|
|
||||||
conf "/ipv6 address add eui-64=yes advertise=no address=$newip interface=$bridge"
|
|
||||||
conf "/ipv6 address print"
|
|
||||||
conf "/password old-password=\"\" new-password=$password confirm-new-password=$password"
|
|
||||||
|
|
||||||
# Show neigh
|
|
||||||
conf "/interface bridge host print where !local"
|
|
||||||
|
|
||||||
echo "do not forget to set a password"
|
|
|
@ -1,103 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Nico Schottelius, 2020-08-03
|
|
||||||
# Setup a standard crs326
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo "$0 <ip> <hostname-to-be-setup>"
|
|
||||||
echo "Example:"
|
|
||||||
echo "$0 fe80::764d:28ff:fe09:9355%eth1 mikrotik-crs326-8"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ip=$1; shift
|
|
||||||
hostname=$1; shift
|
|
||||||
password=$1; shift
|
|
||||||
|
|
||||||
target=$ip
|
|
||||||
bridge=bridgevlans
|
|
||||||
|
|
||||||
internal=10
|
|
||||||
coworking=15
|
|
||||||
server=11
|
|
||||||
other="8 16 18 33 34"
|
|
||||||
|
|
||||||
tagged="ether23 ether24 sfp-sfpplus1"
|
|
||||||
|
|
||||||
net_internal=2a0a:e5c0:2::/64
|
|
||||||
|
|
||||||
conf() {
|
|
||||||
echo $@
|
|
||||||
ssh admin@${target} "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
commastring() {
|
|
||||||
echo $@ | sed 's/ /,/g'
|
|
||||||
}
|
|
||||||
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
|
|
||||||
# do this out of band -- see mikrotik-setup.sh
|
|
||||||
#conf "/password new-password=$password confirm-new-password=$password old-password=\"\""
|
|
||||||
|
|
||||||
conf "/system identity set name=$hostname"
|
|
||||||
conf "/interface bridge add name=$bridge"
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# MTU
|
|
||||||
|
|
||||||
for i in $(seq 1 24); do
|
|
||||||
conf "/interface ethernet set ether$i mtu=9200 l2mtu=9204"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
for i in $(seq 1 2); do
|
|
||||||
conf "/interface ethernet set sfp-sfpplus$i mtu=9200 l2mtu=9204"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# VLANs
|
|
||||||
|
|
||||||
# Internal ports 1-16
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 1 16); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$internal"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
|
|
||||||
# also tag the bridge for the vlan interface we need later
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged),$bridge untagged=$(commastring $ifaces) vlan-ids=$internal"
|
|
||||||
|
|
||||||
# Coworking 17-18
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 17 18); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$coworking"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) untagged=$(commastring $ifaces) vlan-ids=$coworking"
|
|
||||||
|
|
||||||
# Server 19-20
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 19 20); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$server"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) untagged=$(commastring $ifaces) vlan-ids=$server"
|
|
||||||
|
|
||||||
# Not modified 21-22
|
|
||||||
|
|
||||||
# Tagged 23-24, sfp-sfpplus1
|
|
||||||
for iface in $tagged; do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=$iface hw=yes"
|
|
||||||
done
|
|
||||||
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) vlan-ids=$(commastring $other)"
|
|
||||||
conf "/interface vlan add interface=$bridge vlan-id=$internal mtu=9200 name=internal"
|
|
||||||
conf "/ipv6 address add eui-64=yes advertise=no address=$net_internal interface=internal"
|
|
||||||
conf "/interface bridge set $bridge vlan-filtering=yes"
|
|
||||||
|
|
||||||
# Show neigh
|
|
||||||
conf "/interface bridge host print where !local"
|
|
|
@ -1,103 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Nico Schottelius, 2020-08-03
|
|
||||||
# Setup a standard crs326
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if [ $# -ne 3 ]; then
|
|
||||||
echo "$0 <ip> <hostname-to-be-setup>"
|
|
||||||
echo "Example:"
|
|
||||||
echo "$0 fe80::764d:28ff:fe09:9355%eth1 mikrotik-crs326-8 $(pass place6-linthal/mikrotik)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ip=$1; shift
|
|
||||||
hostname=$1; shift
|
|
||||||
password=$1; shift
|
|
||||||
|
|
||||||
target=$ip
|
|
||||||
bridge=bridgevlans
|
|
||||||
|
|
||||||
internal=10
|
|
||||||
coworking=15
|
|
||||||
server=11
|
|
||||||
other="8 16 18 33 34"
|
|
||||||
|
|
||||||
tagged="ether23 ether24 sfp-sfpplus1"
|
|
||||||
|
|
||||||
net_internal=2a0a:e5c0:2::/64
|
|
||||||
|
|
||||||
conf() {
|
|
||||||
echo $@
|
|
||||||
ssh admin@${target} "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
commastring() {
|
|
||||||
echo $@ | sed 's/ /,/g'
|
|
||||||
}
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
|
|
||||||
# do this out of band -- see mikrotik-setup.sh
|
|
||||||
#conf "/password new-password=$password confirm-new-password=$password old-password=\"\""
|
|
||||||
|
|
||||||
conf "/system identity set name=$hostname"
|
|
||||||
conf "/interface bridge add name=$bridge"
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# MTU
|
|
||||||
|
|
||||||
for i in $(seq 1 24); do
|
|
||||||
conf "/interface ethernet set ether$i mtu=9200 l2mtu=9204"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
for i in $(seq 1 2); do
|
|
||||||
conf "/interface ethernet set sfp-sfpplus$i mtu=9200 l2mtu=9204"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# VLANs
|
|
||||||
|
|
||||||
# Internal ports 1-16
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 1 16); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$internal"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
|
|
||||||
# also tag the bridge for the vlan interface we need later
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged),$bridge untagged=$(commastring $ifaces) vlan-ids=$internal"
|
|
||||||
|
|
||||||
# Coworking 17-18
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 17 18); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$coworking"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) untagged=$(commastring $ifaces) vlan-ids=$coworking"
|
|
||||||
|
|
||||||
# Server 19-20
|
|
||||||
ifaces=""
|
|
||||||
for i in $(seq 19 20); do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=ether$i hw=yes pvid=$server"
|
|
||||||
ifaces="ether$i ${ifaces}"
|
|
||||||
done
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) untagged=$(commastring $ifaces) vlan-ids=$server"
|
|
||||||
|
|
||||||
# Not modified 21-22
|
|
||||||
|
|
||||||
# Tagged 23-24, sfp-sfpplus1
|
|
||||||
for iface in ; do
|
|
||||||
conf "/interface bridge port add bridge=$bridge interface=$iface hw=yes"
|
|
||||||
done
|
|
||||||
|
|
||||||
conf "/interface bridge vlan add bridge=$bridge tagged=$(commastring $tagged) lan-ids=$(commastring $other)"
|
|
||||||
conf "/interface vlan add interface=$bridge vlan-id=$internal name=MGMT"
|
|
||||||
conf "/ipv6 address add eui-64=yes advertise=no address=$net_internal interface=MGMT"
|
|
||||||
conf "/interface bridge set $bridge vlan-filtering=yes"
|
|
||||||
|
|
||||||
# Show neigh
|
|
||||||
conf "/interface bridge host print where !local"
|
|
7
mikrotik-setup.sh
Executable file → Normal file
7
mikrotik-setup.sh
Executable file → Normal file
|
@ -16,12 +16,7 @@ conf() {
|
||||||
ssh admin@${target} "$@"
|
ssh admin@${target} "$@"
|
||||||
}
|
}
|
||||||
copy() {
|
copy() {
|
||||||
if echo ${target} | grep -q :; then
|
scp "$1" admin@${target}:
|
||||||
ltarget="[$target]"
|
|
||||||
else
|
|
||||||
ltarget="$target"
|
|
||||||
fi
|
|
||||||
scp "$1" admin@${ltarget}:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# store ssh key in the admin user!
|
# store ssh key in the admin user!
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin
|
||||||
# Nico Schottelius, 2019-12-02
|
# Nico Schottelius, 2019-12-02
|
||||||
# Update mikrotik routers to the latest package
|
# Update mikrotik routers to the latest package
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
if [ $# -lt 2 ]; then
|
||||||
echo "$0 <version> <arch> router [router...]"
|
echo "$0 <version> <arch> router [router...]"
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Version:
|
|
||||||
- the package version as found on https://mikrotik.com/download
|
|
||||||
Arch:
|
Arch:
|
||||||
- rb4011: arm
|
- rb4011: arm
|
||||||
- crs326: arm
|
|
||||||
- hapac: mipsbe
|
- hapac: mipsbe
|
||||||
|
|
||||||
router:
|
|
||||||
- The hostname(s) or IP(v6) addresses of the routers you want to update
|
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -29,7 +23,7 @@ cd "$tmp"
|
||||||
wget "${url}"
|
wget "${url}"
|
||||||
unzip "${file}"
|
unzip "${file}"
|
||||||
|
|
||||||
pkg_list="dhcp ipv6 lcd lte multicast ppp routing security system user-manager wireless"
|
pkg_list="dhcp ipv6 lcd lte multicast ppp routing security system user-manager wireless"!
|
||||||
|
|
||||||
while [ $# -ge 1 ]; do
|
while [ $# -ge 1 ]; do
|
||||||
target=$1; shift
|
target=$1; shift
|
||||||
|
|
|
@ -20,28 +20,15 @@ if echo $to_monitor | grep ^osd; then
|
||||||
depends="${depends}, ${to_monitor}-whoami"
|
depends="${depends}, ${to_monitor}-whoami"
|
||||||
osd="yes"
|
osd="yes"
|
||||||
osdid=$(echo $to_monitor | cut -d. -f2)
|
osdid=$(echo $to_monitor | cut -d. -f2)
|
||||||
cat > "$conf" <<EOF
|
fi
|
||||||
# Generated by $0
|
|
||||||
check process ${to_monitor} with pidfile /var/run/ceph/${to_monitor}.pid
|
|
||||||
start program = "/usr/bin/ceph-osd -i ${osdid} --pid-file /var/run/ceph/osd.${osdid}.pid -c /etc/ceph/ceph.conf --cluster ceph --setuser ceph --setgroup ceph" with timeout 3600 seconds
|
|
||||||
stop program = "/usr/bin/pkill -f '/usr/bin/ceph-osd -i ${osdid}'"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
else
|
|
||||||
# monitor, mgr
|
cat > "$conf" <<EOF
|
||||||
cat > "$conf" <<EOF
|
|
||||||
# Generated by $0
|
# Generated by $0
|
||||||
check process ${to_monitor} with pidfile /var/run/ceph/${to_monitor}.pid
|
check process ${to_monitor} with pidfile /var/run/ceph/${to_monitor}.pid
|
||||||
start program = "/etc/init.d/ceph start ${to_monitor}" with timeout 60 seconds
|
start program = "/etc/init.d/ceph start ${to_monitor}" with timeout 60 seconds
|
||||||
stop program = "/etc/init.d/ceph stop ${to_monitor}"
|
stop program = "/etc/init.d/ceph stop ${to_monitor}"
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# final clause same for both
|
|
||||||
cat >> "$conf" <<EOF
|
|
||||||
|
|
||||||
group ceph
|
group ceph
|
||||||
depends on $depends
|
depends on $depends
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# This script extract VM IDs and filter them if a pattern is provided as first
|
|
||||||
# argument.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Extract instances from ONE.
|
|
||||||
instances=$(onevm list --csv | tail -n +2)
|
|
||||||
|
|
||||||
# Filter them is a pattern has been provided.
|
|
||||||
if [ "$1" != "" ]; then
|
|
||||||
filtered_instances="$(echo "$instances" | grep -E "$1")"
|
|
||||||
instances="$filtered_instances"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Outputs instance IDs.
|
|
||||||
echo "$instances" | cut -d ',' -f 1 -
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# This script is expected to run on the ONE server (i.e.
|
|
||||||
# opennebula.ungleich.ch).
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Fetch instance list from STDIN.
|
|
||||||
instances=$(cat -)
|
|
||||||
|
|
||||||
# For every instance, extract relevant information:
|
|
||||||
for id in $instances; do
|
|
||||||
nics_raw="$(onevm show --xml $id | xml_grep 'NIC')"
|
|
||||||
networks="$(echo $nics_raw | xml_grep --text_only 'NETWORK' | tr '\n' ',' | sed 's/,$//')"
|
|
||||||
ip="$(echo $nics_raw | xml_grep --text_only 'IP' | tr '\n' ',' | sed 's/,$//')"
|
|
||||||
ip6="$(echo $nics_raw | xml_grep --text_only 'IP6_GLOBAL' | tr '\n' ',' | sed 's/,$//')"
|
|
||||||
echo "$id,$networks,$ip,$ip6"
|
|
||||||
done
|
|
|
@ -1,179 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates Alpine images for OpenNebula.
|
|
||||||
#
|
|
||||||
# Test image locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
RELEASE=v3.12
|
|
||||||
ARCH=x86_64
|
|
||||||
IMAGE_PATH=alpine-$RELEASE-$(date -I).img.qcow2
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
NBD_DEVICE=/dev/nbd0
|
|
||||||
APK_MIRROR=http://dl-2.alpinelinux.org/alpine/ # Mind the trailing /
|
|
||||||
|
|
||||||
ONE_CONTEXT_APK_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context-5.10.0-r1.apk"
|
|
||||||
ONE_CONTEXT_APK_PATH=/root/one-context.apk
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
qemu-nbd --disconnect "$NBD_DEVICE" || true
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$(lsb_release --short --id)" != "Alpine" ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on an Alpine system." >&2
|
|
||||||
echo "WARNING: Not running Alpine. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create base QCOW2 image.
|
|
||||||
qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
modprobe nbd max_part=16
|
|
||||||
qemu-nbd --connect="$NBD_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Wait for qemu-nbd to settle.
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
|
||||||
1M,500M,L,*
|
|
||||||
,,L
|
|
||||||
EOF
|
|
||||||
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p1"
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p2"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
|
|
||||||
mount "${NBD_DEVICE}p2" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${NBD_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Remove bash
|
|
||||||
apk add -U -X $APK_MIRROR$RELEASE/main/ \
|
|
||||||
--allow-untrusted \
|
|
||||||
--arch="$ARCH" \
|
|
||||||
--root=/mnt \
|
|
||||||
--initdb \
|
|
||||||
alpine-base alpine-conf openssh sudo tzdata gnupg haveged bash eudev
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize networking.
|
|
||||||
run_root setup-interfaces -i << EOF
|
|
||||||
auto lo
|
|
||||||
iface lo inet loopback
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Configure package sources and update package index.
|
|
||||||
run_root setup-timezone -z UTC
|
|
||||||
if [ "$RELEASE" = "edge" ]
|
|
||||||
then
|
|
||||||
cat >/mnt/etc/apk/repositories <<EOF
|
|
||||||
$APK_MIRROR$RELEASE/main
|
|
||||||
$APK_MIRROR$RELEASE/community
|
|
||||||
$APK_MIRROR$RELEASE/testing
|
|
||||||
EOF
|
|
||||||
else
|
|
||||||
cat >/mnt/etc/apk/repositories <<EOF
|
|
||||||
$APK_MIRROR$RELEASE/main
|
|
||||||
$APK_MIRROR$RELEASE/community
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update package index.
|
|
||||||
run_root apk update
|
|
||||||
|
|
||||||
# Initialize base services.
|
|
||||||
for i in devfs dmesg hwdrivers mdev; do
|
|
||||||
run_root rc-update add $i sysinit
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in bootmisc hostname hwclock modules sysctl syslog acpid networking urandom haveged; do
|
|
||||||
run_root rc-update add $i boot
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in ntpd sshd crond; do
|
|
||||||
run_root rc-update add $i default
|
|
||||||
done
|
|
||||||
|
|
||||||
for i in mount-ro killprocs savecache; do
|
|
||||||
run_root rc-update add $i shutdown
|
|
||||||
done
|
|
||||||
|
|
||||||
# Set hostname.
|
|
||||||
run_root setup-hostname -n alpine
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p1")
|
|
||||||
root_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p2")
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Install kernel and bootloader.
|
|
||||||
run_root apk add linux-virt syslinux
|
|
||||||
|
|
||||||
dd if=/usr/share/syslinux/mbr.bin of="$NBD_DEVICE" bs=1 count=440
|
|
||||||
extlinux -i /mnt/boot
|
|
||||||
|
|
||||||
cat >/mnt/boot/extlinux.conf <<EOF
|
|
||||||
DEFAULT linux
|
|
||||||
LABEL linux
|
|
||||||
LINUX vmlinuz-virt
|
|
||||||
INITRD initramfs-virt
|
|
||||||
APPEND root=UUID=$root_uuid rw modules=sd-mod,usb-storage,ext4 quiet rootfstype=ext4
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Install one-context APK and hope things works as expected.
|
|
||||||
curl -L "$ONE_CONTEXT_APK_URL" > "/mnt$ONE_CONTEXT_APK_PATH"
|
|
||||||
run_root apk add --allow-untrusted "$ONE_CONTEXT_APK_PATH"
|
|
||||||
run_root rm "$ONE_CONTEXT_APK_PATH"
|
|
||||||
|
|
||||||
# Remove resolvconf: handled by uncloud-init.
|
|
||||||
run_root rm /etc/resolv.conf
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
|
@ -1,154 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates Debian images for OpenNebula.
|
|
||||||
#
|
|
||||||
# Test image locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
ARCH=amd64
|
|
||||||
IMAGE_PATH=arch-$(date --iso-8601).img.qcow2
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
NBD_DEVICE=/dev/nbd0
|
|
||||||
|
|
||||||
# TODO: find the package definition and built ourself, publish in some RPM repository.
|
|
||||||
ONE_CONTEXT_DEB_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context_5.10.0-1.deb"
|
|
||||||
ONE_CONTEXT_DEB_PATH=/root/one-context.deb
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
qemu-nbd --disconnect "$NBD_DEVICE" || true
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $(lsb_release --short --id) != "Arch" ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on an Ubuntu system." >&2
|
|
||||||
echo "WARNING: Not running Ubuntu. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create base QCOW2 image.
|
|
||||||
qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
modprobe nbd max_part=16
|
|
||||||
qemu-nbd --connect="$NBD_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Wait for qemu-nbd to settle.
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
|
||||||
1M,500M,L,*
|
|
||||||
,,L
|
|
||||||
EOF
|
|
||||||
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p1"
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p2"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
|
|
||||||
mount "${NBD_DEVICE}p2" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${NBD_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
# Install base system.
|
|
||||||
pacstrap /mnt nbase base-devel openssh
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Guest networking is to be handled by the one-context package.
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux for details.
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Configure package sources and update package index.
|
|
||||||
cat > /mnt/etc/pacman.d/mirrorlist << EOF
|
|
||||||
##
|
|
||||||
## Arch Linux repository mirrorlist
|
|
||||||
## Generated on 2020-05-12
|
|
||||||
##
|
|
||||||
|
|
||||||
## Switzerland
|
|
||||||
Server = http://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch
|
|
||||||
Server = https://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch
|
|
||||||
Server = http://mirror.init7.net/archlinux/$repo/os/$arch
|
|
||||||
Server = https://mirror.init7.net/archlinux/$repo/os/$arch
|
|
||||||
Server = http://mirror.puzzle.ch/archlinux/$repo/os/$arch
|
|
||||||
Server = https://mirror.puzzle.ch/archlinux/$repo/os/$arch
|
|
||||||
Server = https://mirror.ungleich.ch/mirror/packages/archlinux/$repo/os/$arch
|
|
||||||
EOF
|
|
||||||
run_root pacman --sync --refresh --upgrade
|
|
||||||
|
|
||||||
# Initalize base services.
|
|
||||||
run_root systemd-machine-id-setup
|
|
||||||
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
||||||
run_root systemctl enable systemd-timesyncd.service
|
|
||||||
|
|
||||||
# Install kernel and generate initramfs.
|
|
||||||
run_root pacman --sync linux mkinitcpio
|
|
||||||
run_rot mkinitcpio -P
|
|
||||||
|
|
||||||
# Install and configure bootloader.
|
|
||||||
run_root pacman --sync grub
|
|
||||||
run_root grub-install --target=i386-pc "${NBD_DEVICE}"
|
|
||||||
run_root grub-mkconfig -o /boot/grub/grub.cfg
|
|
||||||
|
|
||||||
# Install en configure SSH daemon.
|
|
||||||
run_root pacman --sync openssh-server
|
|
||||||
|
|
||||||
# Install haveged due to lack of entropy in ONE environment.
|
|
||||||
run_root pacman --sync haveged
|
|
||||||
run_root systemctl enable haveged.service
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p1")
|
|
||||||
root_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p2")
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
|
@ -1,170 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates CentOS images for OpenNebula.
|
|
||||||
|
|
||||||
# Depends on the following packages (as of CentOS 8):
|
|
||||||
# qemu-img util-linux coreutils dnf curl e2fsprogs
|
|
||||||
|
|
||||||
# Run locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
RELEASE=8
|
|
||||||
ARCH=x86_64
|
|
||||||
IMAGE_PATH=centos-$RELEASE-$(date --iso-8601).img
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
LOOPBACK_DEVICE=/dev/loop0
|
|
||||||
|
|
||||||
# TODO: find the package definition and built ourself, publish in some RPM repository.
|
|
||||||
ONE_CONTEXT_RPM_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context-5.10.0-1.el8.noarch.rpm"
|
|
||||||
ONE_CONTEXT_RPM_PATH=/root/one-context.rpm
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
losetup -d "$LOOPBACK_DEVICE"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f '/etc/centos-release' ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on a CentOS system." >&2
|
|
||||||
echo "WARNING: Not running CentOS. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create base RAW image (no LOOPBACK support in RHEL/CentOS).
|
|
||||||
qemu-img create -f raw "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
losetup "$LOOPBACK_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
{
|
|
||||||
sfdisk --no-reread "$LOOPBACK_DEVICE" <<EOF
|
|
||||||
1M,500M,L,*
|
|
||||||
,,L
|
|
||||||
EOF
|
|
||||||
} || true
|
|
||||||
|
|
||||||
partprobe "$LOOPBACK_DEVICE"
|
|
||||||
|
|
||||||
mkfs.ext4 "${LOOPBACK_DEVICE}p1"
|
|
||||||
mkfs.ext4 "${LOOPBACK_DEVICE}p2"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
mount "${LOOPBACK_DEVICE}p2" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${LOOPBACK_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
dnf -y \
|
|
||||||
--releasever=$RELEASE \
|
|
||||||
--installroot=/mnt \
|
|
||||||
--disablerepo='*' \
|
|
||||||
--enablerepo=BaseOS \
|
|
||||||
--enablerepo=AppStream \
|
|
||||||
--enablerepo=extras \
|
|
||||||
--setopt=install_weak_deps=False install \
|
|
||||||
bash basesystem systemd systemd-udev dnf centos-release
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Guest networking is to be handled by the one-context package.
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux for details.
|
|
||||||
# Note: as of writing, one-context does not support NetworkManager or
|
|
||||||
# systemd-networkd.
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux/issues/121 for details.
|
|
||||||
# network-scripts.x86_64 : Legacy scripts for manipulating of network devices
|
|
||||||
run_root dnf -y install network-scripts
|
|
||||||
|
|
||||||
# Install (magic?) one-context RPM and hope things works as expected.
|
|
||||||
curl -L "$ONE_CONTEXT_RPM_URL" > "/mnt$ONE_CONTEXT_RPM_PATH"
|
|
||||||
run_root dnf -y install "$ONE_CONTEXT_RPM_PATH"
|
|
||||||
run_root rm "$ONE_CONTEXT_RPM_PATH"
|
|
||||||
|
|
||||||
# Install resize2fs, which is required to resize the root file-system.
|
|
||||||
run_root dnf -y install e2fsprogs
|
|
||||||
|
|
||||||
# Initalize base services.
|
|
||||||
run_root systemd-machine-id-setup
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
||||||
|
|
||||||
# Install and configure NTP client.
|
|
||||||
run_root dnf install -y chrony
|
|
||||||
run_root systemctl enable chronyd.service
|
|
||||||
|
|
||||||
# Install kernel and bootloader.
|
|
||||||
# Note: linux-firmware is not required our environment and takes almost 200M
|
|
||||||
# uncompressed but is a direct dependency of kernel-core...
|
|
||||||
run_root dnf -y install kernel grub2
|
|
||||||
|
|
||||||
# Add support for virtio block devices at boot time.
|
|
||||||
cat > /mnt/etc/dracut.conf.d/virtio-blk.conf <<EOF
|
|
||||||
add_drivers="virtio-blk"
|
|
||||||
EOF
|
|
||||||
kernel_version=$(ls /mnt/boot | grep "vmlinuz.*.$ARCH" | cut -d- -f2-)
|
|
||||||
run_root dracut --force --kver $kernel_version
|
|
||||||
|
|
||||||
# Configure grub2.
|
|
||||||
run_root grub2-install --target=i386-pc "${LOOPBACK_DEVICE}"
|
|
||||||
run_root grub2-mkconfig -o /boot/grub2/grub.cfg
|
|
||||||
|
|
||||||
# Install en configure SSH daemon.
|
|
||||||
run_root dnf -y install openssh-server
|
|
||||||
run_root systemctl enable sshd
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid --match-tag UUID --output value "${LOOPBACK_DEVICE}p1")
|
|
||||||
root_uuid=$(blkid --match-tag UUID --output value "${LOOPBACK_DEVICE}p2")
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Remove temporary files and reclaim freed disk space.
|
|
||||||
# Note: build logs could be removed as well.
|
|
||||||
run_root dnf clean all
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
|
@ -1,186 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates CentOS images for OpenNebula. Expected to run on CentOS 7.
|
|
||||||
|
|
||||||
# Depends on the following packages:
|
|
||||||
# qemu-img util-linux coreutils dnf curl e2fsprogs cryptsetup parted
|
|
||||||
|
|
||||||
# Run locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=raw
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
RELEASE=7
|
|
||||||
ARCH=x86_64
|
|
||||||
IMAGE_PATH=centos-luks-$RELEASE-$(date --iso-8601).img
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
LOOPBACK_DEVICE=/dev/loop0
|
|
||||||
LUKS_DEVICE_NAME=cryptroot
|
|
||||||
LUKS_DEVICE="/dev/mapper/$LUKS_DEVICE_NAME"
|
|
||||||
DISABLED_ONE_SCRIPTS="loc-20-set-username-password loc-22-ssh_public_key"
|
|
||||||
|
|
||||||
ONE_CONTEXT_RPM_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context-5.10.0-1.el$RELEASE.noarch.rpm"
|
|
||||||
ONE_CONTEXT_RPM_PATH=/root/one-context.rpm
|
|
||||||
|
|
||||||
# Get LUKS passphrase.
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "Usage: centos7-build-luks-opennebula-image.sh LUKS_PASSPHRASE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
LUKS_PASSPHRASE="$1"
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
losetup -d "$LOOPBACK_DEVICE"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f '/etc/centos-release' ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on a CentOS system." >&2
|
|
||||||
echo "WARNING: Not running CentOS. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install requirements
|
|
||||||
yum install -y qemu cryptsetup dnf
|
|
||||||
|
|
||||||
# Create base RAW image (no LOOPBACK support in RHEL/CentOS).
|
|
||||||
qemu-img create -f raw "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
losetup "$LOOPBACK_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
parted --script "$LOOPBACK_DEVICE" \
|
|
||||||
mklabel msdos \
|
|
||||||
mkpart primary ext4 1M 500M \
|
|
||||||
mkpart primary ext4 500M 100%
|
|
||||||
|
|
||||||
partprobe "$LOOPBACK_DEVICE"
|
|
||||||
|
|
||||||
mkfs.ext4 "${LOOPBACK_DEVICE}p1"
|
|
||||||
echo -n "$LUKS_PASSPHRASE" | cryptsetup luksFormat -v -d - "${LOOPBACK_DEVICE}p2"
|
|
||||||
echo -n "$LUKS_PASSPHRASE" | cryptsetup open -v -d - "${LOOPBACK_DEVICE}p2" "$LUKS_DEVICE_NAME"
|
|
||||||
mkfs.ext4 "$LUKS_DEVICE"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
mount "${LUKS_DEVICE}" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${LOOPBACK_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
# Add --setopt=reposdir=rpm-repositories if you do not run on CentOS 7.
|
|
||||||
dnf -y \
|
|
||||||
--releasever=$RELEASE \
|
|
||||||
--installroot=/mnt \
|
|
||||||
--disablerepo='*' \
|
|
||||||
--enablerepo=base \
|
|
||||||
--enablerepo=extras \
|
|
||||||
--setopt=install_weak_deps=False install \
|
|
||||||
bash basesystem systemd dnf centos-release cryptsetup dnf passwd
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Guest networking is to be handled by the one-context package.
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux for details.
|
|
||||||
# Note: as of writing, one-context does not support NetworkManager or
|
|
||||||
# systemd-networkd.
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Setup root password
|
|
||||||
run_root passwd
|
|
||||||
|
|
||||||
# Install one-context RPM and hope things works as expected.
|
|
||||||
curl -L "$ONE_CONTEXT_RPM_URL" > "/mnt$ONE_CONTEXT_RPM_PATH"
|
|
||||||
run_root dnf -y install "$ONE_CONTEXT_RPM_PATH"
|
|
||||||
run_root rm "$ONE_CONTEXT_RPM_PATH"
|
|
||||||
for script in $DISABLED_ONE_SCRIPTS; do
|
|
||||||
run_root rm "/etc/one-context.d/$script"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Install resize2fs, which is required to resize the root file-system.
|
|
||||||
run_root dnf -y install e2fsprogs
|
|
||||||
|
|
||||||
# Initalize base services.
|
|
||||||
run_root systemd-machine-id-setup
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
||||||
|
|
||||||
# Install and configure NTP client.
|
|
||||||
run_root dnf install -y chrony
|
|
||||||
run_root systemctl enable chronyd.service
|
|
||||||
|
|
||||||
# Install kernel and bootloader.
|
|
||||||
# Note: linux-firmware is not required our environment and takes almost 200M
|
|
||||||
# uncompressed but is a direct dependency of kernel-core...
|
|
||||||
run_root dnf -y install kernel grub2
|
|
||||||
|
|
||||||
# Add support for virtio block devices at boot time, configure bootloader.
|
|
||||||
cat > /mnt/etc/dracut.conf.d/virtio-blk.conf <<EOF
|
|
||||||
add_drivers="virtio-blk"
|
|
||||||
EOF
|
|
||||||
kernel_version=$(ls /mnt/boot | grep "vmlinuz.*.$ARCH" | cut -d- -f2-)
|
|
||||||
luks_uuid=$(blkid -o value "${LOOPBACK_DEVICE}p2" | head -n 1)
|
|
||||||
echo "cryptroot UUID=$luks_uuid luks,timeout=30" >> /mnt/etc/crypttab
|
|
||||||
|
|
||||||
run_root dracut -v --force --kver $kernel_version
|
|
||||||
run_root grub2-install --target=i386-pc "${LOOPBACK_DEVICE}"
|
|
||||||
run_root grub2-mkconfig -o /boot/grub2/grub.cfg
|
|
||||||
|
|
||||||
# Install en configure SSH daemon.
|
|
||||||
run_root dnf -y install openssh-server
|
|
||||||
run_root systemctl enable sshd
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid -o value "${LOOPBACK_DEVICE}p1" | head -n 1)
|
|
||||||
root_uuid=$(blkid -o value "$LUKS_DEVICE" | head -n 1)
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Remove temporary files and reclaim freed disk space.
|
|
||||||
# Note: build logs could be removed as well.
|
|
||||||
run_root dnf clean all
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
||||||
|
|
||||||
# Cleanup!
|
|
||||||
cleanup
|
|
|
@ -1,171 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates Debian images for OpenNebula.
|
|
||||||
#
|
|
||||||
# Test image locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
RELEASE=buster # 10.X
|
|
||||||
ARCH=amd64
|
|
||||||
IMAGE_PATH=debian-$RELEASE-$(date --iso-8601).img.qcow2
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
NBD_DEVICE=/dev/nbd0
|
|
||||||
HOSTNAME=debian
|
|
||||||
|
|
||||||
# TODO: find the package definition and built ourself, publish in some RPM repository.
|
|
||||||
ONE_CONTEXT_DEB_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context_5.10.0-1.deb"
|
|
||||||
ONE_CONTEXT_DEB_PATH=/root/one-context.deb
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
qemu-nbd --disconnect "$NBD_DEVICE" || true
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $(lsb_release --short --id) != "Debian" ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on an Debian system." >&2
|
|
||||||
echo "WARNING: Not running Debian. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create base QCOW2 image.
|
|
||||||
qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
modprobe nbd max_part=16
|
|
||||||
qemu-nbd --connect="$NBD_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Wait for qemu-nbd to settle.
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
|
||||||
1M,500M,L,*
|
|
||||||
,,L
|
|
||||||
EOF
|
|
||||||
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p1"
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p2"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
|
|
||||||
mount "${NBD_DEVICE}p2" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${NBD_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
debootstrap \
|
|
||||||
--arch=$ARCH $RELEASE \
|
|
||||||
/mnt http://ftp.ch.debian.org/debian
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Guest networking is to be handled by the one-context package.
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux for details.
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 $HOSTNAME localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 $HOSTNAME localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
run_root hostnamectl set-hostname $HOSTNAME
|
|
||||||
|
|
||||||
# Configure package sources and update package index.
|
|
||||||
cat >/mnt/etc/apt/sources.list <<EOF
|
|
||||||
# Stable
|
|
||||||
deb http://ftp.ch.debian.org/debian $RELEASE main contrib non-free
|
|
||||||
deb-src http://ftp.ch.debian.org/debian $RELEASE main contrib non-free
|
|
||||||
|
|
||||||
# Security updates
|
|
||||||
deb http://ftp.ch.debian.org/debian $RELEASE-updates main contrib non-free
|
|
||||||
deb-src http://ftp.ch.debian.org/debian $RELEASE-updates main contrib non-free
|
|
||||||
|
|
||||||
# Backports
|
|
||||||
#deb http://ftp.ch.debian.org/debian $RELEASE-backports main
|
|
||||||
#deb-src http://ftp.ch.debian.org/debian $RELEASE-backports main
|
|
||||||
EOF
|
|
||||||
run_root apt-get update
|
|
||||||
|
|
||||||
# Install (magic?) one-context DEB and hope things works as expected.
|
|
||||||
curl -L "$ONE_CONTEXT_DEB_URL" > "/mnt$ONE_CONTEXT_DEB_PATH"
|
|
||||||
run_root apt-get -y install "$ONE_CONTEXT_DEB_PATH"
|
|
||||||
run_root rm "$ONE_CONTEXT_DEB_PATH"
|
|
||||||
|
|
||||||
# Manually install legacy network scripts used by one-context.
|
|
||||||
run_root apt-get -y install ifupdown
|
|
||||||
|
|
||||||
# Initalize base services.
|
|
||||||
run_root systemd-machine-id-setup
|
|
||||||
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
||||||
run_root systemctl enable systemd-timesyncd.service
|
|
||||||
|
|
||||||
# Install kernel and bootloader. Do not autoconfigure grub.
|
|
||||||
run_root 'echo "grub-pc grub-pc/install_devices_empty boolean true" | debconf-set-selections'
|
|
||||||
run_root DEBIAN_FRONTEND=noninteractive apt-get -y install locales linux-image-amd64 grub-pc
|
|
||||||
|
|
||||||
# Configure grub.
|
|
||||||
run_root grub-install --target=i386-pc "${NBD_DEVICE}"
|
|
||||||
run_root grub-mkconfig -o /boot/grub/grub.cfg
|
|
||||||
|
|
||||||
# Install en configure SSH daemon.
|
|
||||||
run_root apt-get -y install openssh-server
|
|
||||||
|
|
||||||
# Install haveged due to lack of entropy in ONE environment.
|
|
||||||
run_root apt-get -y install haveged
|
|
||||||
run_root systemctl enable haveged.service
|
|
||||||
|
|
||||||
# Generate locales.
|
|
||||||
run_root 'sed -i "s/^# *\(en_GB.UTF-8\)/\1/" etc/locale.gen'
|
|
||||||
run_root locale-gen
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p1")
|
|
||||||
root_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p2")
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Remove temporary files and reclaim freed disk space.
|
|
||||||
run_root apt-get clean
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
|
@ -1,116 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates FreeBSD images for OpenNebula, being heavily inspired
|
|
||||||
# from srht's FreeBSD build image definition. It assumes running on a FreeBSD host.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
RELEASE=12.1-RELEASE
|
|
||||||
ARCH=amd64
|
|
||||||
IMAGE_PATH=freebsd-$RELEASE-$(date -I).img.qcow2
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
|
|
||||||
DIST_BASE="https://download.freebsd.org/ftp/releases/$ARCH/$RELEASE"
|
|
||||||
PORTS_BASE="https://download.freebsd.org/ftp/snapshots/$ARCH/12.1-STABLE"
|
|
||||||
|
|
||||||
ONE_CONTEXT_PKG_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.12.0/one-context-5.12.0_1.txz"
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
sync || true
|
|
||||||
umount /mnt/dev || true
|
|
||||||
umount /mnt || true
|
|
||||||
mdconfig -du md0 || true
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Allocate and partition/format disk image.
|
|
||||||
disk=$(mktemp)
|
|
||||||
truncate -s 6G $disk
|
|
||||||
mdconfig -a -t vnode -f $disk -u md0
|
|
||||||
gpart create -s gpt /dev/md0
|
|
||||||
gpart add -t freebsd-boot -l bootfs -b 40 -s 512K md0
|
|
||||||
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 md0
|
|
||||||
gpart add -t freebsd-ufs -l rootfs -b 1M -s 5G md0
|
|
||||||
newfs -U /dev/md0p2
|
|
||||||
|
|
||||||
# Mount allocated image.
|
|
||||||
mount /dev/md0p2 /mnt
|
|
||||||
mkdir -p /mnt/dev
|
|
||||||
mount -t devfs devfs /mnt/dev
|
|
||||||
|
|
||||||
# Download and extract base system.
|
|
||||||
dist_files="kernel.txz base.txz"
|
|
||||||
dist_dir="/usr/freebsd-dist/$ARCH/$RELEASE"
|
|
||||||
|
|
||||||
mkdir -p "$dist_dir"
|
|
||||||
for f in $dist_files
|
|
||||||
do
|
|
||||||
fetch -m -o "$dist_dir/$f" "$DIST_BASE/$f"
|
|
||||||
tar -C /mnt -xJf "$dist_dir/$f"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Configure new system.
|
|
||||||
echo "/dev/gpt/rootfs / ufs rw,noatime 1 1" >/mnt/etc/fstab
|
|
||||||
touch /mnt/firstboot
|
|
||||||
echo 'autoboot_delay="-1"' >>/mnt/boot/loader.conf
|
|
||||||
|
|
||||||
cat >>/mnt/etc/rc.conf <<EOF
|
|
||||||
ntpd_enable=YES
|
|
||||||
sshd_enable=YES
|
|
||||||
growfs_enable=YES
|
|
||||||
hostname="freebsd"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
tzsetup -s -C /mnt UTC
|
|
||||||
|
|
||||||
cat >>/mnt/etc/ssh/sshd_config <<EOF
|
|
||||||
PermitRootLogin yes
|
|
||||||
PasswordAuthentication no
|
|
||||||
PermitEmptyPasswords no
|
|
||||||
EOF
|
|
||||||
|
|
||||||
mkdir -p /mnt/usr/local/etc/pkg/repos/
|
|
||||||
cat >/mnt/usr/local/etc/pkg/repos/FreeBSD.conf <<EOF
|
|
||||||
FreeBSD: {
|
|
||||||
url: pkg+http://pkg.FreeBSD.org/\$\{ABI\}/latest
|
|
||||||
enabled: yes
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# freebsd-update is only supported for RELEASE
|
|
||||||
if [ "${release%-RELEASE}" != "$RELEASE" ]
|
|
||||||
then
|
|
||||||
env PAGER=true /usr/sbin/freebsd-update \
|
|
||||||
-b /mnt \
|
|
||||||
--currently-running "$RELEASE" \
|
|
||||||
--not-running-from-cron -F \
|
|
||||||
fetch install
|
|
||||||
fi
|
|
||||||
|
|
||||||
env ASSUME_ALWAYS_YES=YES pkg -c /mnt bootstrap -f
|
|
||||||
env ASSUME_ALWAYS_YES=YES pkg -c /mnt install bash curl
|
|
||||||
|
|
||||||
curl -L "$ONE_CONTEXT_PKG_URL" -o /mnt/one-context.txz
|
|
||||||
env ASSUME_ALWAYS_YES=YES pkg -c /mnt add one-context.txz
|
|
||||||
rm /mnt/one-context.txz
|
|
||||||
|
|
||||||
fetch -m -o "$dist_dir/ports.txz" "$PORTS_BASE/ports.txz"
|
|
||||||
tar -C /mnt -xJf "$dist_dir/ports.txz"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
trap : EXIT
|
|
||||||
|
|
||||||
mkdir -p "$ARCH"
|
|
||||||
qemu-img convert -f raw -O qcow2 "$disk" "$IMAGE_PATH"
|
|
||||||
rm "$disk"
|
|
||||||
|
|
||||||
# Filesystem will be enlarged by growfs(7) on next startup
|
|
||||||
qemu-img resize "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
|
@ -1,16 +0,0 @@
|
||||||
[base]
|
|
||||||
name=CentOS-$releasever - Base
|
|
||||||
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
|
|
||||||
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
|
|
||||||
gpgcheck=0
|
|
||||||
enabled=0
|
|
||||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
|
|
||||||
|
|
||||||
#released updates
|
|
||||||
[updates]
|
|
||||||
name=CentOS-$releasever - Updates
|
|
||||||
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
|
|
||||||
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
|
|
||||||
gpgcheck=0
|
|
||||||
enabled=0
|
|
||||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
|
|
|
@ -1,7 +0,0 @@
|
||||||
[extras]
|
|
||||||
name=CentOS-$releasever - Extras
|
|
||||||
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
|
|
||||||
#baseurl=http://mirror.centos.org/$contentdir/$releasever/extras/$basearch/os/
|
|
||||||
gpgcheck=0
|
|
||||||
enabled=0
|
|
||||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
|
|
|
@ -1,153 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script generates Ubuntu images for OpenNebula.
|
|
||||||
#
|
|
||||||
# Test image locally (without network) with:
|
|
||||||
# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=qcow2
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# XXX: Handle command-line arguments?
|
|
||||||
RELEASE=eoan # 19.10
|
|
||||||
ARCH=amd64
|
|
||||||
IMAGE_PATH=ubuntu-$RELEASE-$(date --iso-8601).img.qcow2
|
|
||||||
IMAGE_SIZE=10G
|
|
||||||
NBD_DEVICE=/dev/nbd0
|
|
||||||
|
|
||||||
# TODO: find the package definition and built ourself, publish in some RPM repository.
|
|
||||||
ONE_CONTEXT_DEB_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context_5.10.0-1.deb"
|
|
||||||
ONE_CONTEXT_DEB_PATH=/root/one-context.deb
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
# The order here is important.
|
|
||||||
umount /mnt/dev/pts 2>/dev/null || true
|
|
||||||
umount /mnt/dev/shm 2>/dev/null || true
|
|
||||||
umount /mnt/dev 2>/dev/null || true
|
|
||||||
umount /mnt/proc 2>/dev/null || true
|
|
||||||
umount /mnt/run 2>/dev/null || true
|
|
||||||
umount /mnt/sys 2>/dev/null || true
|
|
||||||
umount /mnt/boot 2>/dev/null || true
|
|
||||||
umount /mnt 2>/dev/null || true
|
|
||||||
qemu-nbd --disconnect "$NBD_DEVICE" || true
|
|
||||||
}
|
|
||||||
|
|
||||||
run_root() {
|
|
||||||
chroot /mnt /usr/bin/env \
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin \
|
|
||||||
sh -c "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(whoami)" != 'root' ]; then
|
|
||||||
echo "This script must be run as root." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $(lsb_release --short --id) != "Ubuntu" ]; then
|
|
||||||
echo "WARNING: this script has been designed to run on an Ubuntu system." >&2
|
|
||||||
echo "WARNING: Not running Ubuntu. Giving you 5 seconds to abort." >&2
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create base QCOW2 image.
|
|
||||||
qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE"
|
|
||||||
modprobe nbd max_part=16
|
|
||||||
qemu-nbd --connect="$NBD_DEVICE" "$IMAGE_PATH"
|
|
||||||
|
|
||||||
# Wait for qemu-nbd to settle.
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Don't forget to cleanup, even if the script crash.
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create partition table, format partitions.
|
|
||||||
sfdisk --no-reread "$NBD_DEVICE" <<EOF
|
|
||||||
1M,500M,L,*
|
|
||||||
,,L
|
|
||||||
EOF
|
|
||||||
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p1"
|
|
||||||
mkfs.ext4 "${NBD_DEVICE}p2"
|
|
||||||
|
|
||||||
# Mount partitions, install base OS.
|
|
||||||
|
|
||||||
mount "${NBD_DEVICE}p2" /mnt
|
|
||||||
mkdir /mnt/boot
|
|
||||||
mount "${NBD_DEVICE}p1" /mnt/boot
|
|
||||||
|
|
||||||
debootstrap \
|
|
||||||
--arch=$ARCH $RELEASE \
|
|
||||||
/mnt http://archive.ubuntu.com/ubuntu/
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/dev
|
|
||||||
mount --bind /dev/pts /mnt/dev/pts
|
|
||||||
mount --bind /dev/shm /mnt/dev/shm
|
|
||||||
mount --bind /proc /mnt/proc
|
|
||||||
mount --bind /run /mnt/run
|
|
||||||
mount --bind /sys /mnt/sys
|
|
||||||
|
|
||||||
# Guest networking is to be handled by the one-context package.
|
|
||||||
# See https://github.com/OpenNebula/addon-context-linux for details.
|
|
||||||
|
|
||||||
# Required to resolve package mirror in chroot.
|
|
||||||
cp /etc/resolv.conf /mnt/etc/resolv.conf
|
|
||||||
|
|
||||||
# Initialize /etc/hosts.
|
|
||||||
cat > /mnt/etc/hosts << EOF
|
|
||||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
||||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Configure package sources and update package index.
|
|
||||||
cat >/mnt/etc/apt/sources.list <<EOF
|
|
||||||
deb http://archive.ubuntu.com/ubuntu/ $RELEASE main restricted universe multiverse
|
|
||||||
deb http://archive.ubuntu.com/ubuntu/ $RELEASE-security main restricted universe multiverse
|
|
||||||
deb http://archive.ubuntu.com/ubuntu/ $RELEASE-updates main restricted universe multiverse
|
|
||||||
deb http://archive.ubuntu.com/ubuntu/ $RELEASE-backports main restricted universe multiverse
|
|
||||||
EOF
|
|
||||||
run_root apt-get update
|
|
||||||
|
|
||||||
# Install (magic?) one-context DEB and hope things works as expected.
|
|
||||||
curl -L "$ONE_CONTEXT_DEB_URL" > "/mnt$ONE_CONTEXT_DEB_PATH"
|
|
||||||
run_root apt-get -y install "$ONE_CONTEXT_DEB_PATH"
|
|
||||||
run_root rm "$ONE_CONTEXT_DEB_PATH"
|
|
||||||
|
|
||||||
# Manually install legacy network scripts used by one-context.
|
|
||||||
run_root apt-get -y install ifupdown
|
|
||||||
|
|
||||||
# Initalize base services.
|
|
||||||
run_root systemd-machine-id-setup
|
|
||||||
|
|
||||||
run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
||||||
run_root systemctl enable systemd-timesyncd.service
|
|
||||||
|
|
||||||
# Install kernel and bootloader. Do not autoconfigure grub.
|
|
||||||
run_root echo "grub-pc grub-pc/install_devices_empty boolean true" | debconf-set-selections
|
|
||||||
run_root DEBIAN_FRONTEND=noninteractive apt-get -y install locales linux-base linux-image-generic grub-pc
|
|
||||||
|
|
||||||
# Configure grub.
|
|
||||||
run_root grub-install --target=i386-pc "${NBD_DEVICE}"
|
|
||||||
run_root grub-mkconfig -o /boot/grub/grub.cfg
|
|
||||||
|
|
||||||
# Install en configure SSH daemon.
|
|
||||||
run_root apt-get -y install openssh-server
|
|
||||||
|
|
||||||
# Generate fstab file.
|
|
||||||
boot_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p1")
|
|
||||||
root_uuid=$(blkid --match-tag UUID --output value "${NBD_DEVICE}p2")
|
|
||||||
cat >>/mnt/etc/fstab <<EOF
|
|
||||||
UUID=$boot_uuid /boot ext4 rw,relatime,data=ordered 0 2
|
|
||||||
UUID=$root_uuid / ext4 rw,relatime,data=ordered 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Reset systemd's environment.
|
|
||||||
run_root rm -f /etc/machine-id
|
|
||||||
run_root touch /etc/machine-id
|
|
||||||
rm -f /var/lib/systemd/random-seed
|
|
||||||
|
|
||||||
# Remove temporary files and reclaim freed disk space.
|
|
||||||
run_root apt-get clean
|
|
||||||
|
|
||||||
# Make sure everything is written to disk before exiting.
|
|
||||||
sync
|
|
|
@ -1,12 +0,0 @@
|
||||||
import configparser
|
|
||||||
|
|
||||||
from etcd_wrapper import EtcdWrapper
|
|
||||||
|
|
||||||
config = configparser.ConfigParser(allow_no_value=True)
|
|
||||||
config.read('config-and-secrets.conf')
|
|
||||||
|
|
||||||
etcd_client = EtcdWrapper(
|
|
||||||
host=config['etcd']['url'], port=config['etcd']['port'],
|
|
||||||
ca_cert=config['etcd']['ca_cert'], cert_key=config['etcd']['cert_key'],
|
|
||||||
cert_cert=config['etcd']['cert_cert']
|
|
||||||
)
|
|
|
@ -1,73 +0,0 @@
|
||||||
import etcd3
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
|
|
||||||
class EtcdEntry:
|
|
||||||
def __init__(self, meta_or_key, value, value_in_json=True):
|
|
||||||
if hasattr(meta_or_key, 'key'):
|
|
||||||
# if meta has attr 'key' then get it
|
|
||||||
self.key = meta_or_key.key.decode('utf-8')
|
|
||||||
else:
|
|
||||||
# otherwise meta is the 'key'
|
|
||||||
self.key = meta_or_key
|
|
||||||
self.value = value.decode('utf-8')
|
|
||||||
|
|
||||||
if value_in_json:
|
|
||||||
self.value = json.loads(self.value)
|
|
||||||
|
|
||||||
|
|
||||||
def readable_errors(func):
|
|
||||||
@wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
try:
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
except etcd3.exceptions.ConnectionFailedError:
|
|
||||||
raise etcd3.exceptions.ConnectionFailedError('Cannot connect to etcd: is etcd running as configured?')
|
|
||||||
except etcd3.exceptions.ConnectionTimeoutError as err:
|
|
||||||
raise etcd3.exceptions.ConnectionTimeoutError('etcd connection timeout.') from err
|
|
||||||
except Exception as err:
|
|
||||||
logging.exception('Some etcd error occured. See syslog for details.', err)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class EtcdWrapper:
|
|
||||||
@readable_errors
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.client = etcd3.client(*args, **kwargs)
|
|
||||||
|
|
||||||
@readable_errors
|
|
||||||
def get(self, *args, value_in_json=True, **kwargs):
|
|
||||||
_value, _key = self.client.get(*args, **kwargs)
|
|
||||||
if _key is None or _value is None:
|
|
||||||
return None
|
|
||||||
return EtcdEntry(_key, _value, value_in_json=value_in_json)
|
|
||||||
|
|
||||||
@readable_errors
|
|
||||||
def put(self, *args, value_in_json=True, **kwargs):
|
|
||||||
_key, _value = args
|
|
||||||
if value_in_json:
|
|
||||||
_value = json.dumps(_value)
|
|
||||||
|
|
||||||
if not isinstance(_key, str):
|
|
||||||
_key = _key.decode('utf-8')
|
|
||||||
|
|
||||||
return self.client.put(_key, _value, **kwargs)
|
|
||||||
|
|
||||||
@readable_errors
|
|
||||||
def get_prefix(self, *args, value_in_json=True, **kwargs):
|
|
||||||
event_iterator = self.client.get_prefix(*args, **kwargs)
|
|
||||||
for e in event_iterator:
|
|
||||||
yield EtcdEntry(*e[::-1], value_in_json=value_in_json)
|
|
||||||
|
|
||||||
@readable_errors
|
|
||||||
def watch_prefix(self, key, value_in_json=True):
|
|
||||||
event_iterator, cancel = self.client.watch_prefix(key)
|
|
||||||
for e in event_iterator:
|
|
||||||
if hasattr(e, '_event'):
|
|
||||||
e = getattr('e', '_event')
|
|
||||||
if e.type == e.PUT:
|
|
||||||
yield EtcdEntry(e.kv.key, e.kv.value, value_in_json=value_in_json)
|
|
|
@ -1,98 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from enum import IntEnum
|
|
||||||
from xmlrpc.client import ServerProxy as RPCClient
|
|
||||||
|
|
||||||
from xmltodict import parse
|
|
||||||
|
|
||||||
from config import config, etcd_client
|
|
||||||
|
|
||||||
|
|
||||||
# Constants
|
|
||||||
ALL_VM_STATES = -1
|
|
||||||
START_ID = -1 # First id whatever it is
|
|
||||||
END_ID = -1 # Last id whatever it is
|
|
||||||
|
|
||||||
|
|
||||||
def put_under_list(obj):
|
|
||||||
if not isinstance(obj, list):
|
|
||||||
return [obj]
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
class VMState(IntEnum):
|
|
||||||
INIT = 0
|
|
||||||
PENDING = 1
|
|
||||||
HOLD = 2
|
|
||||||
ACTIVE = 3
|
|
||||||
STOPPED = 4
|
|
||||||
SUSPENDED = 5
|
|
||||||
DONE = 6
|
|
||||||
FAILED = 7
|
|
||||||
POWEROFF = 8
|
|
||||||
UNDEPLOYED = 9
|
|
||||||
CLONING = 10
|
|
||||||
CLONING_FAILURE = 11
|
|
||||||
|
|
||||||
|
|
||||||
class VmFilterFlag(IntEnum):
|
|
||||||
UIDUserResources = 0 # UID User’s Resources
|
|
||||||
UserAndItsGroupsResources = -1 # Resources belonging to the user and any of his groups
|
|
||||||
AllResources = -2 # All resources
|
|
||||||
UserResources = -3 # Resources belonging to the user
|
|
||||||
UserPrimaryGroupResources = -4 # Resources belonging to the user’s primary group
|
|
||||||
|
|
||||||
|
|
||||||
class VM:
|
|
||||||
def __init__(self, vm: dict):
|
|
||||||
self.id = vm.get('ID', None)
|
|
||||||
self.owner = {
|
|
||||||
'id': vm.get('UID', None),
|
|
||||||
'name': vm.get('UNAME', None),
|
|
||||||
'gname': vm.get('GNAME', None)
|
|
||||||
}
|
|
||||||
self.name = vm.get('NAME', None)
|
|
||||||
self.status = vm.get('STATE', None)
|
|
||||||
if self.status:
|
|
||||||
self.status = VMState(int(self.status)).name.lower()
|
|
||||||
|
|
||||||
template = vm['TEMPLATE']
|
|
||||||
|
|
||||||
self.disk = put_under_list(template.get('DISK', []))
|
|
||||||
self.graphics = template.get('GRAPHICS', {})
|
|
||||||
self.memory = template.get('MEMORY', None)
|
|
||||||
self.nic = put_under_list(template.get('NIC', []))
|
|
||||||
self.vcpu = template.get('VCPU', None)
|
|
||||||
self.host = {
|
|
||||||
'name': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HOSTNAME', None),
|
|
||||||
'id': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HID', None),
|
|
||||||
}
|
|
||||||
self.snapshots = put_under_list(vm.get('SNAPSHOTS', []))
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
return {
|
|
||||||
attr: getattr(self, attr)
|
|
||||||
for attr in dir(self)
|
|
||||||
if not attr.startswith('__') and not callable(getattr(self, attr))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
with RPCClient('https://opennebula.ungleich.ch:2634/RPC2') as rpc_client:
|
|
||||||
success, response, *_ = rpc_client.one.vmpool.infoextended(
|
|
||||||
config['oca']['client_secrets'], VmFilterFlag.AllResources.value, START_ID, END_ID, ALL_VM_STATES
|
|
||||||
)
|
|
||||||
if success:
|
|
||||||
vms = json.loads(json.dumps(parse(response)))['VM_POOL']['VM']
|
|
||||||
for i, vm in enumerate(vms):
|
|
||||||
vm_id = vm['ID']
|
|
||||||
etcd_client.put(f'/opennebula/vm/{vm_id}', vm)
|
|
||||||
|
|
||||||
parsed_vm = VM(vm)
|
|
||||||
etcd_client.put(f'/opennebula/parsed_vm/{parsed_vm.id}', parsed_vm.get_data())
|
|
||||||
else:
|
|
||||||
print(response)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,56 +0,0 @@
|
||||||
from pprint import pprint
|
|
||||||
|
|
||||||
from config import etcd_client
|
|
||||||
|
|
||||||
|
|
||||||
def get_vm_by_ip(vms, ip, status='active'):
|
|
||||||
vms_by_status = {
|
|
||||||
vm_id: vm
|
|
||||||
for vm_id, vm in vms.items()
|
|
||||||
if vm['status'] == status
|
|
||||||
}
|
|
||||||
for vm_id, vm in vms_by_status.items():
|
|
||||||
vm_ips = []
|
|
||||||
for nic in vm.get('nic', []):
|
|
||||||
global_ipv6 = nic.get('IP6_GLOBAL', None)
|
|
||||||
local_ipv6 = nic.get('IP6_LINK', None)
|
|
||||||
ipv4 = nic.get('IP', None)
|
|
||||||
vm_ips += [global_ipv6, local_ipv6, ipv4]
|
|
||||||
|
|
||||||
if ip in vm_ips:
|
|
||||||
return {vm_id: vm}
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
vm_prefix = '/opennebula/parsed_vm/'
|
|
||||||
|
|
||||||
vms = {
|
|
||||||
int(vm.key.split('/')[-1]): vm.value
|
|
||||||
for vm in etcd_client.get_prefix(vm_prefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
VM_ID = 10761 # One of nico's VM
|
|
||||||
|
|
||||||
# Get all data related to a VM
|
|
||||||
pprint(vms.get(VM_ID))
|
|
||||||
|
|
||||||
# Get host of a VM
|
|
||||||
print(vms.get(VM_ID).get('host').get('name'))
|
|
||||||
|
|
||||||
# Get VNC Port of a VM
|
|
||||||
print(vms.get(VM_ID).get('graphics').get('PORT'))
|
|
||||||
|
|
||||||
# Get all disks attached with VM
|
|
||||||
pprint(vms.get(VM_ID).get('disk'))
|
|
||||||
|
|
||||||
# Who is owner of a VM?
|
|
||||||
print(vms.get(VM_ID).get('owner').get('name'))
|
|
||||||
|
|
||||||
# Get VM who has 2a0a:e5c0:0:5:0:78ff:fe11:d75f
|
|
||||||
search_ungleich_ch = get_vm_by_ip(vms, '2a0a:e5c0:0:5:0:78ff:fe11:d75f')
|
|
||||||
pprint(search_ungleich_ch)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
opkg install luci-ssl-openssl acme luci-app-acme
|
|
||||||
|
|
||||||
uci set uhttpd.main.redirect_https=1
|
|
||||||
uci commit
|
|
||||||
/etc/init.d/uhttpd restart
|
|
|
@ -1,43 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Based on work of Samuel Hailu, 2020-09-10
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo "$0 ip-address interface"
|
|
||||||
echo " ip-address: where to find the OpenWRT device"
|
|
||||||
echo " interface: which interface (eth3 for instance) is the LTE device"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
my_ip=$1; shift
|
|
||||||
interface=$1; shift
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${my_ip}"
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# update the sources & allow https handling
|
|
||||||
opkg update
|
|
||||||
opkg install libustream-openssl ca-bundle ca-certificates
|
|
||||||
|
|
||||||
# Install needed kernel module
|
|
||||||
opkg install kmod-usb-net-cdc-ether usb-modeswitch
|
|
||||||
|
|
||||||
# Create interface
|
|
||||||
uci set network.LTE=interface
|
|
||||||
uci set network.LTE.ifname='${interface}'
|
|
||||||
uci set network.LTE.proto='dhcp'
|
|
||||||
|
|
||||||
# add to correct firewall zone
|
|
||||||
current_networks=\$(uci get firewall.@zone[1].network)
|
|
||||||
|
|
||||||
if ! echo \$current_networks | grep -q LTE; then
|
|
||||||
uci set firewall.@zone[1].network='\${current_networks} LTE'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# commit
|
|
||||||
uci commit
|
|
||||||
|
|
||||||
# reboot
|
|
||||||
|
|
||||||
reboot
|
|
||||||
|
|
||||||
EOF
|
|
|
@ -1,60 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
|
|
||||||
if [ $# -ne 1 ]; then
|
|
||||||
echo "$0 ip-address interface"
|
|
||||||
echo " ip-address: where to find the OpenWRT device"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
my_ip=$1; shift
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${my_ip}"
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# update the sources & allow https handling
|
|
||||||
opkg update
|
|
||||||
opkg install motion kmod-video-uvc
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
motion sample:
|
|
||||||
|
|
||||||
daemon off
|
|
||||||
setup_mode off
|
|
||||||
log_level 2
|
|
||||||
|
|
||||||
ipv6_enabled on
|
|
||||||
|
|
||||||
videodevice /dev/video0
|
|
||||||
width 1280
|
|
||||||
height 720
|
|
||||||
input -1
|
|
||||||
framerate 15
|
|
||||||
|
|
||||||
text_left place10, Diesbach
|
|
||||||
text_right %Y-%m-%d\n%T-%q
|
|
||||||
|
|
||||||
emulate_motion off
|
|
||||||
|
|
||||||
# Threshold for number of changed pixels that triggers motion.
|
|
||||||
threshold 1500
|
|
||||||
|
|
||||||
# Despeckle the image using (E/e)rode or (D/d)ilate or (l)abel.
|
|
||||||
despeckle_filter EedDl
|
|
||||||
|
|
||||||
# Enable this if you have storage attached
|
|
||||||
picture_output off
|
|
||||||
movie_output off
|
|
||||||
|
|
||||||
webcontrol_port 8080
|
|
||||||
webcontrol_localhost on
|
|
||||||
webcontrol_parms 0
|
|
||||||
|
|
||||||
stream_port 8081
|
|
||||||
stream_localhost off
|
|
||||||
|
|
||||||
# use native mjpeg
|
|
||||||
v4l2_palette 8
|
|
14
pg_repair
14
pg_repair
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
pglist_arr=( $(ceph health detail | grep pg | grep active | awk '{print $2}' ))
|
|
||||||
|
|
||||||
echo ${pglist_arr[*]}
|
|
||||||
|
|
||||||
for ((i=0; i<${#pglist_arr[@]}; i++)) do
|
|
||||||
if [ 1 -eq $(ceph pg repair ${pglist_arr[$i]} | grep repair | grep instructing | wc -l) ]; then
|
|
||||||
echo repair script error
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo ${pglist_arr[$i]} repair script done
|
|
||||||
sleep 10
|
|
||||||
done
|
|
181
pib-setup.sh
181
pib-setup.sh
|
@ -1,181 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Assumptions:
|
|
||||||
# - pib (APU) is factory reset OpenWRT
|
|
||||||
# - WAN port is connected with an active upstream (pib has internet connectivity via WAN port)
|
|
||||||
# - You are connected via LAN and you can ssh into it
|
|
||||||
|
|
||||||
# How it works
|
|
||||||
#
|
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
|
||||||
echo "$0 ip-address vpn-network [wireguard-private-key]"
|
|
||||||
echo " ip-address: where to find the PIB"
|
|
||||||
echo " network: 2a0a:e5c0:123::/48"
|
|
||||||
echo " private-key: specify if you already have a private key"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
my_ip=$1; shift
|
|
||||||
my_network=$1; shift
|
|
||||||
|
|
||||||
if [ $# -eq 1 ]; then
|
|
||||||
private_key=$1; shift
|
|
||||||
else
|
|
||||||
private_key=$(wg genkey)
|
|
||||||
fi
|
|
||||||
|
|
||||||
my_prefix=$(echo $my_network | sed 's,::/.*,,')
|
|
||||||
my_hostname=pib-$(echo ${my_prefix} | sed 's/:/-/g')
|
|
||||||
|
|
||||||
my_wireguard_ip=${my_prefix}::42
|
|
||||||
my_lan_ip=${my_prefix}:cafe::42
|
|
||||||
|
|
||||||
public_key=$(echo $private_key | wg pubkey)
|
|
||||||
|
|
||||||
vpn_endpoint_host=vpn-2a0ae5c1.ungleich.ch
|
|
||||||
vpn_endpoint_pubkey=hi60lGP+xEUQ+kVnqA7PlJAO1SVqTS1W36g0LhFP0xQ=
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${my_ip}" || exit 1
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# Check if we can reach upstream - otherwise abort
|
|
||||||
ping6 -c5 ungleich.ch || ping -c5 ungleich.ch || exit 1
|
|
||||||
|
|
||||||
# update the sources & allow https handling
|
|
||||||
opkg update
|
|
||||||
opkg install libustream-openssl ca-bundle ca-certificates
|
|
||||||
|
|
||||||
# install wireguard + gui
|
|
||||||
opkg install wireguard luci-app-wireguard
|
|
||||||
|
|
||||||
# We are never authoritative for IPv4
|
|
||||||
uci delete dhcp.@dnsmasq[0].authoritative
|
|
||||||
|
|
||||||
# Do not announce ULA - we have GUA
|
|
||||||
uci delete network.globals.ula_prefix
|
|
||||||
|
|
||||||
# Setup hostname
|
|
||||||
uci set system.@system[0].hostname="${my_hostname}"
|
|
||||||
|
|
||||||
# Do not set/get? Was necessary, don't recall why
|
|
||||||
uci set dhcp.@dnsmasq[0].noresolv='1'
|
|
||||||
|
|
||||||
# Fix DNS: make the OS use the locally provided DNS servers
|
|
||||||
# otherwise the VPN tunnel cannot be established
|
|
||||||
uci set dhcp.@dnsmasq[0].localuse='0'
|
|
||||||
|
|
||||||
# Remove static IPv4 on LAN
|
|
||||||
uci delete network.lan.ipaddr
|
|
||||||
uci delete network.lan.netmask
|
|
||||||
|
|
||||||
# Setup IPv6 on LAN
|
|
||||||
uci add_list network.lan.ip6addr='${my_lan_ip}/64'
|
|
||||||
|
|
||||||
# IPv6 announcements
|
|
||||||
uci set dhcp.lan.ra='server'
|
|
||||||
uci set dhcp.lan.ra_management='1'
|
|
||||||
|
|
||||||
# No DHCP server on the LAN
|
|
||||||
uci set dhcp.lan.ignore='1'
|
|
||||||
|
|
||||||
# Cleanup dhcp options
|
|
||||||
|
|
||||||
# Disable any dynamic leases
|
|
||||||
uci set dhcp.lan.dynamicdhcp='0'
|
|
||||||
|
|
||||||
# Remove dhcpv6 server
|
|
||||||
uci delete dhcp.lan.dhcpv6
|
|
||||||
|
|
||||||
# Remove leftover from the dhcpv4 server items
|
|
||||||
uci delete dhcp.lan.start
|
|
||||||
uci delete dhcp.lan.limit
|
|
||||||
uci delete dhcp.lan.leasetime
|
|
||||||
|
|
||||||
# VPN / Wireguard
|
|
||||||
uci set network.wg0=interface
|
|
||||||
uci set network.wg0.proto='wireguard'
|
|
||||||
uci set network.wg0.private_key='${private_key}'
|
|
||||||
uci set network.wg0.listen_port='51820'
|
|
||||||
uci set network.wg0.addresses='${my_wireguard_ip}/64'
|
|
||||||
|
|
||||||
if ! uci get network.@wireguard_wg0[0]; then
|
|
||||||
uci add network wireguard_wg0
|
|
||||||
fi
|
|
||||||
|
|
||||||
uci set network.@wireguard_wg0[0]=wireguard_wg0
|
|
||||||
uci set network.@wireguard_wg0[0].persistent_keepalive='25'
|
|
||||||
uci set network.@wireguard_wg0[0].public_key='${vpn_endpoint_pubkey}'
|
|
||||||
uci set network.@wireguard_wg0[0].description='IPv6VPN.ch by ungleich'
|
|
||||||
uci set network.@wireguard_wg0[0].allowed_ips='::/0'
|
|
||||||
uci set network.@wireguard_wg0[0].endpoint_host='${vpn_endpoint_host}'
|
|
||||||
uci set network.@wireguard_wg0[0].endpoint_port='51820'
|
|
||||||
uci set network.@wireguard_wg0[0].route_allowed_ips='1'
|
|
||||||
|
|
||||||
# Firewall configuration
|
|
||||||
if ! uci show firewall | grep "name='Allow-SSH'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-SSH'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='22'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! uci show firewall | grep "name='Allow-HTTPS'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-HTTPS'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='443'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! uci show firewall | grep "name='Allow-HTTP'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-HTTP'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='80'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add interfaces to the right network zone
|
|
||||||
uci set firewall.@zone[0].network='lan lanv6'
|
|
||||||
uci set firewall.@zone[1].network='wan wg0'
|
|
||||||
|
|
||||||
# DNS upstream over VPN gives DNS64
|
|
||||||
uci delete dhcp.@dnsmasq[0].server
|
|
||||||
uci add_list dhcp.@dnsmasq[0].server='2a0a:e5c0:0:a::a'
|
|
||||||
uci add_list dhcp.@dnsmasq[0].server='2a0a:e5c0:2:a::a'
|
|
||||||
|
|
||||||
# This is the save & apply button in LUCI (or just save button)
|
|
||||||
uci commit
|
|
||||||
|
|
||||||
reboot
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
my_ip=$my_lan_ip
|
|
||||||
|
|
||||||
echo "Waiting for it to come back..."
|
|
||||||
while ! ping -c1 ${my_ip}; do
|
|
||||||
echo "Cannot ping $my_ip yet - waiting"
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Wireguard public key and id: ${id} ${public_key}"
|
|
||||||
echo ${public_key} > ${my_hostname}.public_key
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
Open steps:
|
|
||||||
|
|
||||||
- Remove your ssh key(s) from the device (if any are present)
|
|
||||||
- Setup a secure root password and forward it to the customer
|
|
||||||
- Ensure that the VPN works
|
|
||||||
- Connect to the LAN port and surf in the Internet IPv6 only!
|
|
||||||
|
|
||||||
EOF
|
|
|
@ -1,8 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Nico Schottelius, 2019-09-20, Seoul, Coffebean, 23:56
|
# Nico Schottelius, 2019-09-20, Seoul, Coffebean, 23:56
|
||||||
# Copying: GPLv3
|
# Copying: GPLv3
|
||||||
echo "If you are running alpine, these packages are needed:"
|
|
||||||
echo "apk add alpine-sdk xz-dev"
|
|
||||||
set -x
|
set -x
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# 2020-06-13, Nico Schottelius
|
|
||||||
# See https://ungleich.ch/u/products/viirb-ipv6-box/
|
|
||||||
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
echo "$0 interface [address]"
|
|
||||||
echo " interface to add the config ip address to"
|
|
||||||
echo " address: connect to this address, ignore the interface"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -x
|
|
||||||
dev=$1; shift
|
|
||||||
|
|
||||||
if [ $# -ge 1 ]; then
|
|
||||||
viirb_ip=$1; shift
|
|
||||||
dev=""
|
|
||||||
else
|
|
||||||
viirb_ip=192.168.61.1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# openwrt
|
|
||||||
version=19.07.3
|
|
||||||
filename=openwrt-${version}-ramips-mt76x8-vocore2-squashfs-sysupgrade.bin
|
|
||||||
|
|
||||||
# IP address for setting it up initially
|
|
||||||
|
|
||||||
if [ "$dev" ]; then
|
|
||||||
sudo ip addr del 192.168.61.2/24 dev "$dev" 2>/dev/null || true
|
|
||||||
sudo ip addr add 192.168.61.2/24 dev "$dev"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# don't care about other/old known_host entries
|
|
||||||
ssh-keygen -R ${viirb_ip}
|
|
||||||
|
|
||||||
while ! ping -c1 ${viirb_ip}; do
|
|
||||||
echo "Cannot ping $viirb_ip yet - waiting"
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
cat ~/.ssh/id_rsa.pub | ssh root@${viirb_ip} "cat > /etc/dropbear/authorized_keys"
|
|
||||||
|
|
||||||
# Don't re-download if we already have it
|
|
||||||
wget -c http://downloads.openwrt.org/releases/${version}/targets/ramips/mt76x8/${filename}
|
|
||||||
scp ${filename} root@${viirb_ip}:/tmp
|
|
||||||
ssh root@${viirb_ip} "sysupgrade /tmp/*.bin"
|
|
||||||
|
|
||||||
# It still pings for some time - wait for the reboot to happen
|
|
||||||
echo "Waiting for VIIRB to really disappear"
|
|
||||||
sleep 15
|
|
||||||
|
|
||||||
wait=0
|
|
||||||
found=""
|
|
||||||
|
|
||||||
while [ $wait -lt 180 ]; do
|
|
||||||
ping -c1 ${viirb_ip} >/dev/null
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
found=yes
|
|
||||||
# wait for ssh to come up
|
|
||||||
sleep 10
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
wait=$((wait+1))
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ! "$found" ]; then
|
|
||||||
echo "Did not find updated viirb - debug / restart it"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "VIIRB successfully updated to ${version}"
|
|
|
@ -1,220 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# 2020-06-13, Nico Schottelius
|
|
||||||
# See https://ungleich.ch/u/products/viirb-ipv6-box/
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo "$0 viirb-ip-address viirb-id"
|
|
||||||
echo " viirb-ip-address: where to find the viirb"
|
|
||||||
echo " viirb-id: number in decimal format"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
set -x
|
|
||||||
viirb_ip=$1; shift
|
|
||||||
id=$1; shift
|
|
||||||
hex_id=$(printf "%0.2x\n" "$id")
|
|
||||||
viirb_hostname=viirb${id}
|
|
||||||
|
|
||||||
prefix_base=2a0a:e5c1:3
|
|
||||||
my_prefix=${prefix_base}${hex_id}
|
|
||||||
my_network=${my_prefix}::/48
|
|
||||||
|
|
||||||
my_wireguard_ip=${my_prefix}::42
|
|
||||||
my_lan_ip=${my_prefix}:cafe::42
|
|
||||||
my_wifi_ip=${my_prefix}:7ea::42
|
|
||||||
|
|
||||||
# wireguard
|
|
||||||
private_key=$(wg genkey)
|
|
||||||
public_key=$(echo $private_key | wg pubkey)
|
|
||||||
|
|
||||||
vpn_endpoint_host=vpn-2a0ae5c1300.ungleich.ch
|
|
||||||
vpn_endpoint_pubkey=ft68G2RID7gZ6PXjFCSCOdJ9yspRg+tUw0YrNK9cTxE=
|
|
||||||
|
|
||||||
ping -c3 ${viirb_ip}
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Cannot reach ${viirb_ip}, aborting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${viirb_ip}"
|
|
||||||
set -x
|
|
||||||
# Setup lan to also retrieve an ip address via dhcp
|
|
||||||
|
|
||||||
# This stays in the final setup
|
|
||||||
uci set network.lan.proto='dhcp'
|
|
||||||
uci delete network.lan.ipaddr
|
|
||||||
uci delete network.lan.netmask
|
|
||||||
|
|
||||||
# The IPv6 lan configuration
|
|
||||||
uci set network.lanv6=interface
|
|
||||||
uci set network.lanv6.proto='static'
|
|
||||||
uci set network.lanv6.ip6addr='${my_lan_ip}/64'
|
|
||||||
uci set network.lanv6.ifname='br-lan'
|
|
||||||
|
|
||||||
# LAN / Router advertisements / DHCP
|
|
||||||
# DHCP: we are not authoratative
|
|
||||||
uci delete dhcp.@dnsmasq[0].authoritative
|
|
||||||
uci delete dhcp.lan.dhcpv6
|
|
||||||
uci delete dhcp.lan.start
|
|
||||||
uci delete dhcp.lan.limit
|
|
||||||
uci delete dhcp.lan.leasetime
|
|
||||||
|
|
||||||
# Do not announce ULA - we have GUA
|
|
||||||
uci delete network.globals.ula_prefix
|
|
||||||
|
|
||||||
# This is configuring the dhcp IPv4 client
|
|
||||||
uci set dhcp.lan=dhcp
|
|
||||||
|
|
||||||
# Setup Router Advertisements
|
|
||||||
uci set dhcp.lan.interface='lanv6'
|
|
||||||
uci set dhcp.lan.ra='server'
|
|
||||||
uci set dhcp.lan.dynamicdhcp='0'
|
|
||||||
|
|
||||||
# Fix DNS: make dnsmasq NOT use a resolv.conf
|
|
||||||
# so that it only reads from our servers with DNS64 enabled
|
|
||||||
uci set dhcp.@dnsmasq[0].noresolv='1'
|
|
||||||
|
|
||||||
# Fix DNS: make the OS use the locally provided DNS servers
|
|
||||||
# otherwise the VPN tunnel cannot be established
|
|
||||||
dhcp.@dnsmasq[0].localuse='0'
|
|
||||||
|
|
||||||
# DNS upstream over VPN gives DNS64
|
|
||||||
uci delete dhcp.@dnsmasq[0].server
|
|
||||||
uci add_list dhcp.@dnsmasq[0].server='2a0a:e5c0:0:a::a'
|
|
||||||
uci add_list dhcp.@dnsmasq[0].server='2a0a:e5c0:2:a::a'
|
|
||||||
|
|
||||||
# wifi ip address
|
|
||||||
uci set network.wifi=interface
|
|
||||||
uci set network.wifi.proto='static'
|
|
||||||
uci set network.wifi.ip6addr='${my_wifi_ip}/64'
|
|
||||||
|
|
||||||
# Wifi configuration
|
|
||||||
uci set wireless.radio0=wifi-device
|
|
||||||
uci set wireless.radio0.type='mac80211'
|
|
||||||
uci set wireless.radio0.hwmode='11g'
|
|
||||||
uci set wireless.radio0.path='platform/10300000.wmac'
|
|
||||||
uci set wireless.radio0.htmode='HT40'
|
|
||||||
uci set wireless.radio0.country='CH'
|
|
||||||
uci set wireless.radio0.channel='6'
|
|
||||||
|
|
||||||
uci set wireless.default_radio0=wifi-iface
|
|
||||||
uci set wireless.default_radio0.device='radio0'
|
|
||||||
uci set wireless.default_radio0.mode='ap'
|
|
||||||
uci set wireless.default_radio0.encryption='psk2'
|
|
||||||
uci set wireless.default_radio0.key='iloveipv6'
|
|
||||||
uci set wireless.default_radio0.ssid='IPv6 everywhere ${viirb_hostname}'
|
|
||||||
uci set wireless.default_radio0.network='wifi'
|
|
||||||
|
|
||||||
# Wifi / Router advertisements
|
|
||||||
uci set dhcp.wifi=dhcp
|
|
||||||
uci set dhcp.wifi.interface='wifi'
|
|
||||||
uci set dhcp.wifi.ra='server'
|
|
||||||
uci set dhcp.wifi.dynamicdhcp='0'
|
|
||||||
|
|
||||||
# Ensure it is not disabled
|
|
||||||
uci delete wireless.radio0.disabled
|
|
||||||
|
|
||||||
# This is temporary - keeping it until the config process is through
|
|
||||||
# Probably not needet - we can connect to the final IPv6 address!
|
|
||||||
# This code commented out == The address vanishes due to above reconfiguration
|
|
||||||
# uci set network.lanv4temp=interface
|
|
||||||
# uci set network.lanv4temp.proto='static'
|
|
||||||
# uci set network.lanv4temp.ifname='br-lan'
|
|
||||||
# uci set network.lanv4temp.ipaddr='192.168.61.1'
|
|
||||||
# uci set network.lanv4temp.netmask='255.255.255.0'
|
|
||||||
|
|
||||||
uci commit
|
|
||||||
|
|
||||||
# Need to reboot to restore /etc/resolv.conf
|
|
||||||
reboot
|
|
||||||
|
|
||||||
#/etc/init.d/network restart
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# ensure viirb is back
|
|
||||||
# ensure viirb network is up and running - bridge takes a bit of time
|
|
||||||
# ensure viirb gives out ipv6 address
|
|
||||||
# Found: 30s is not enough for full reconfiguration
|
|
||||||
echo "Public VPN key: ${id} ${public_key}"
|
|
||||||
sleep 60
|
|
||||||
|
|
||||||
# change to ipv6
|
|
||||||
viirb_ip=${my_lan_ip}
|
|
||||||
|
|
||||||
ping -c5 ${viirb_ip}
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${viirb_ip}"
|
|
||||||
ping -c5 ungleich.ch || exit 1
|
|
||||||
|
|
||||||
# update the sources
|
|
||||||
opkg update
|
|
||||||
|
|
||||||
# install wireguard + gui
|
|
||||||
opkg install wireguard
|
|
||||||
opkg install luci-app-wireguard
|
|
||||||
|
|
||||||
# VPN / Wireguard
|
|
||||||
uci set network.wg0=interface
|
|
||||||
uci set network.wg0.proto='wireguard'
|
|
||||||
uci set network.wg0.private_key='${private_key}'
|
|
||||||
uci set network.wg0.listen_port='51820'
|
|
||||||
uci set network.wg0.addresses='${my_wireguard_ip}/64'
|
|
||||||
|
|
||||||
if ! uci get network.@wireguard_wg0[0]; then
|
|
||||||
uci add network wireguard_wg0
|
|
||||||
fi
|
|
||||||
|
|
||||||
uci set network.@wireguard_wg0[0]=wireguard_wg0
|
|
||||||
uci set network.@wireguard_wg0[0].persistent_keepalive='25'
|
|
||||||
uci set network.@wireguard_wg0[0].public_key='${vpn_endpoint_pubkey}'
|
|
||||||
uci set network.@wireguard_wg0[0].description='IPv6VPN.ch by ungleich'
|
|
||||||
uci set network.@wireguard_wg0[0].allowed_ips='::/0'
|
|
||||||
uci set network.@wireguard_wg0[0].endpoint_host='${vpn_endpoint_host}'
|
|
||||||
uci set network.@wireguard_wg0[0].endpoint_port='51820'
|
|
||||||
uci set network.@wireguard_wg0[0].route_allowed_ips='1'
|
|
||||||
|
|
||||||
uci set system.@system[0].hostname="${viirb_hostname}"
|
|
||||||
|
|
||||||
# Firewall configuration
|
|
||||||
if ! uci show firewall | grep "name='Allow-SSH'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-SSH'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='22'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! uci show firewall | grep "name='Allow-HTTPS'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-HTTPS'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='443'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! uci show firewall | grep "name='Allow-HTTP'"; then
|
|
||||||
uci add firewall rule
|
|
||||||
uci set firewall.@rule[-1].name='Allow-HTTP'
|
|
||||||
uci set firewall.@rule[-1].src='wan'
|
|
||||||
uci set firewall.@rule[-1].dest='lan'
|
|
||||||
uci set firewall.@rule[-1].proto='tcp'
|
|
||||||
uci set firewall.@rule[-1].dest_port='80'
|
|
||||||
uci set firewall.@rule[-1].target='ACCEPT'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add interfaces to the right network zone
|
|
||||||
uci set firewall.@zone[0].network='lan lanv6 wifi'
|
|
||||||
uci set firewall.@zone[1].network='wg0'
|
|
||||||
|
|
||||||
uci commit
|
|
||||||
|
|
||||||
reboot
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Wireguard public key and id: ${id} ${public_key}"
|
|
||||||
echo ${public_key} > ${viirb_hostname}.public_key
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# 2020-06-13, Nico Schottelius
|
|
||||||
# See https://ungleich.ch/u/products/viirb-ipv6-box/
|
|
||||||
|
|
||||||
if [ $# -ne 3 ]; then
|
|
||||||
echo "$0 your-dot-cdist viirb-id public-key"
|
|
||||||
echo " your-dot-cdist: path to YOUR ungleich-dot-cdist repo"
|
|
||||||
echo " viirb-id: number in decimal format"
|
|
||||||
echo " wireguard public key"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -x
|
|
||||||
dot_cdist=$1; shift
|
|
||||||
id=$1; shift
|
|
||||||
public_key=$1; shift
|
|
||||||
|
|
||||||
hex_id=$(printf "%0.2x\n" "$id")
|
|
||||||
viirb_hostname=viirb${id}
|
|
||||||
|
|
||||||
prefix_base=2a0a:e5c1:3
|
|
||||||
my_prefix=${prefix_base}${hex_id}
|
|
||||||
my_network=${my_prefix}::/48
|
|
||||||
my_wireguard_ip=${my_prefix}::42
|
|
||||||
my_lan_ip=${my_prefix}:cafe::42
|
|
||||||
my_wifi_ip=${my_prefix}:7ea::42
|
|
||||||
|
|
||||||
vpn_endpoint_host=vpn-2a0ae5c1300.ungleich.ch
|
|
||||||
|
|
||||||
# cdist
|
|
||||||
dot_cdist_files=${dot_cdist}/type/__ungleich_wireguard/files
|
|
||||||
peerfilename=${vpn_endpoint_host}.peer${hex_id}
|
|
||||||
peerfile=${dot_cdist_files}/${peerfilename}
|
|
||||||
vpnconfig=${dot_cdist_files}/${vpn_endpoint_host}
|
|
||||||
|
|
||||||
|
|
||||||
# Configure VPN server / update cdist
|
|
||||||
echo Updating VPNserver
|
|
||||||
cat <<EOF > ${peerfile}
|
|
||||||
# ${viirb_hostname}, $(date +%F)
|
|
||||||
[Peer]
|
|
||||||
PublicKey = ${public_key}
|
|
||||||
AllowedIPs = ${my_network}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Generate real config
|
|
||||||
cat ${dot_cdist_files}/${vpn_endpoint_host}.* > ${vpnconfig}
|
|
||||||
cd ${dot_cdist_files}
|
|
||||||
git add ${vpn_endpoint_host} ${peerfilename}
|
|
||||||
git commit -m "[vpn] Updated config for peer ${viirb_hostname} ${my_network}"
|
|
||||||
git pull
|
|
||||||
git push
|
|
||||||
|
|
||||||
cdist config -vv -j8 ${vpn_endpoint_host} -c ${dot_cdist}
|
|
||||||
|
|
||||||
# Test that the VPN connection is established
|
|
||||||
# Might take longer due to reboot
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
ping -c10 ${my_wireguard_ip}
|
|
||||||
ping -c10 ${my_lan_ip}
|
|
||||||
ping -c90 ${my_wifi_ip}
|
|
|
@ -1,41 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Nico Schottelius
|
|
||||||
# 2020-06-14
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo "$0 viirb-ip-address viirb-id"
|
|
||||||
echo " viirb-ip-address: where to find the viirb"
|
|
||||||
echo " viirb-id: number in decimal format"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
viirb_ip=$1; shift
|
|
||||||
|
|
||||||
id=$1; shift
|
|
||||||
viirb_hostname=viirb${id}
|
|
||||||
|
|
||||||
root_password=$(pwgen -1 32)
|
|
||||||
|
|
||||||
# Save for sending to user
|
|
||||||
# FIXME: future make this more easy / better to transfer
|
|
||||||
echo $root_password > ${viirb_hostname}.rootpw
|
|
||||||
|
|
||||||
cat <<EOF | ssh -t "root@${viirb_ip}"
|
|
||||||
# Remove temporary IP
|
|
||||||
uci delete network.lanv4temp
|
|
||||||
|
|
||||||
# Correct test SSID to final one
|
|
||||||
uci set wireless.default_radio0.ssid='IPv6 everywhere'
|
|
||||||
uci commit
|
|
||||||
|
|
||||||
# Remove our ssh keys
|
|
||||||
rm -f /etc/dropbear/authorized_keys
|
|
||||||
|
|
||||||
# Setup root password
|
|
||||||
printf "${root_password}\n${root_password}\n" | passwd
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Submit to user the root password = ${root_password}"
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ $# -ne 1 ]; then
|
|
||||||
echo "$0 viirb-id"
|
|
||||||
echo " viirb-id: number in decimal format"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
id=$1; shift
|
|
||||||
|
|
||||||
./viirb-1-connect-flash-latest-openwrt.sh eth0 192.168.61.1
|
|
||||||
# reboot may take longer / rewriting the flash
|
|
||||||
sleep 120
|
|
||||||
./viirb-2-configure-fully-after-upgrade.sh 192.168.61.1 "$id"
|
|
19
vm_list
19
vm_list
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
#option $1 is ldap password
|
|
||||||
#option $2 is ou
|
|
||||||
|
|
||||||
|
|
||||||
uid_list=( $(ldapsearch -x -H ldaps://ldap1.ungleich.ch:636 -D cn=manager,dc=ungleich,dc=ch -w $1 -b "ou=$2,dc=ungleich,dc=ch" | grep uid: | awk '{print $2}') )
|
|
||||||
|
|
||||||
for ((i=0; i<${#uid_list[@]}; i++)) do
|
|
||||||
list_email[$i]=$(ldapsearch -x -H ldaps://ldap1.ungleich.ch:636 -D cn=manager,dc=ungleich,dc=ch -w $1 -b "uid=${uid_list[$i]},ou=$2,dc=ungleich,dc=ch" | grep mail: | awk '{print $2}' )
|
|
||||||
list_vmid=()
|
|
||||||
list_vmid=( $(onevm list | grep ${list_email[$i]} | grep runn | awk '{print $1}' ) )
|
|
||||||
for ((j=0; j<${#list_vmid[@]}; j++)) do
|
|
||||||
temp=$(onevm show ${list_vmid[$j]} | grep PORT)
|
|
||||||
temp1="${temp#*\"}"
|
|
||||||
port="${temp1%%\"*}"
|
|
||||||
host=$(onevm show ${list_vmid[$j]} | grep HOST | grep ungleich | awk '{print $3}')
|
|
||||||
echo ${uid_list[$i]} ${list_vmid[$j]} $port $host >> ~/vm_vnc_list
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
#option $1 is ldap password
|
|
||||||
#option $2 is ou
|
|
||||||
|
|
||||||
|
|
||||||
uid_list=( $(ldapsearch -x -H ldaps://ldap1.ungleich.ch:636 -D cn=manager,dc=ungleich,dc=ch -w $1 -b "ou=$2,dc=ungleich,dc=ch" | grep uid: | awk '{print $2}') )
|
|
||||||
|
|
||||||
for ((i=0; i<${#uid_list[@]}; i++)) do
|
|
||||||
uid_temp=$(echo ${uid_list[i]} | sed "s/b'//g" | sed "s/'//g")
|
|
||||||
list_email[$i]=$(ldapsearch -x -H ldaps://ldap1.ungleich.ch:636 -D cn=manager,dc=ungleich,dc=ch -w $1 -b "uid=${uid_list[$i]},ou=$2,dc=ungleich,dc=ch" | grep mail: | awk '{print $2}' )
|
|
||||||
list_vmid=()
|
|
||||||
list_vmid=( $(onevm list | grep ${list_email[$i]} | grep runn | awk '{print $1}' ) )
|
|
||||||
for ((j=0; j<${#list_vmid[@]}; j++)) do
|
|
||||||
temp=$(onevm show ${list_vmid[$j]} | grep PORT)
|
|
||||||
temp1="${temp#*\"}"
|
|
||||||
port="${temp1%%\"*}"
|
|
||||||
host=$(onevm show ${list_vmid[$j]} | grep HOST | grep ungleich | awk '{print $3}')
|
|
||||||
echo $uid_temp ${list_vmid[$j]} $port $host >> ~/vm_vnc_list
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,5 +0,0 @@
|
||||||
vm_list=( $(virsh list | awk '{print $2}') )
|
|
||||||
|
|
||||||
for ((i=0; i<${#vm_list[@]}; i++)) do
|
|
||||||
ceph osd map hdd ${vm_list[i]}
|
|
||||||
done
|
|
|
@ -1,5 +0,0 @@
|
||||||
import configparser
|
|
||||||
|
|
||||||
config = configparser.ConfigParser(allow_no_value=True)
|
|
||||||
config.read('/opt/ungleich-tools/vnc_console_connection/config-and-secrets.conf')
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
import psycopg2 as pg2
|
|
||||||
from config import config
|
|
||||||
|
|
||||||
db_name = config['db']['db_name']
|
|
||||||
db_user = config['db']['db_user']
|
|
||||||
db_password = config['db']['db_password']
|
|
||||||
db_port = config['db']['db_port']
|
|
||||||
|
|
||||||
|
|
||||||
def setconn(u_id, vm_num, vm_port,vm_host):
|
|
||||||
conn = pg2.connect("host = localhost dbname={} user={} password={} port={}".format(db_name,db_user,db_password,db_port))
|
|
||||||
conn.autocommit = True
|
|
||||||
cur = conn.cursor()
|
|
||||||
cur.execute("SELECT entity_id FROM guacamole_entity WHERE name = '{}'".format(u_id))
|
|
||||||
row = cur.fetchone()
|
|
||||||
if row == None:
|
|
||||||
cur.execute("INSERT INTO guacamole_entity (name, type) VALUES ('{}','USER')".format(u_id))
|
|
||||||
cur.execute("SELECT entity_id FROM guacamole_entity WHERE name = '{}'".format(u_id))
|
|
||||||
row = cur.fetchone()
|
|
||||||
en_id = row[0]
|
|
||||||
cur.execute("INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('{}', '\x74657374', now())".format(en_id))
|
|
||||||
print("create user : " , u_id)
|
|
||||||
else:
|
|
||||||
en_id = row[0]
|
|
||||||
cur.execute("SELECT password_hash FROM guacamole_user WHERE entity_id = '{}'".format(en_id))
|
|
||||||
row = cur.fetchone()
|
|
||||||
if row == None:
|
|
||||||
cur.execute("INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('{}', '\x74657374', now())".format(en_id))
|
|
||||||
print("user exsit")
|
|
||||||
cn = "{}{}".format(u_id,vm_num)
|
|
||||||
cur.execute("SELECT connection_id FROM guacamole_connection WHERE connection_name = '{}'".format(cn))
|
|
||||||
row = cur.fetchone()
|
|
||||||
if row == None:
|
|
||||||
#create connection
|
|
||||||
cur.execute("INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('{}', 'vnc')".format(cn))
|
|
||||||
cur.execute("SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '{}' AND parent_id IS NULL".format(cn))
|
|
||||||
temp_cn_id = cur.fetchone()
|
|
||||||
cn_id = temp_cn_id[0]
|
|
||||||
cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','hostname','{}')".format(cn_id, vm_host))
|
|
||||||
cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','port','{}')".format(cn_id,vm_port))
|
|
||||||
#connection permission
|
|
||||||
cur.execute("INSERT INTO guacamole_connection_permission(entity_id, connection_id, permission) VALUES ('{}', '{}', 'READ')".format(en_id,cn_id))
|
|
||||||
#clipboard-encoding
|
|
||||||
cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','clipboard-encoding','UTF-8')".format(cn_id))
|
|
||||||
print("create connection")
|
|
||||||
else:
|
|
||||||
cur.execute("SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '{}' AND parent_id IS NULL".format(cn))
|
|
||||||
temp_cn_id = cur.fetchone()
|
|
||||||
cn_id = temp_cn_id[0]
|
|
||||||
cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='{}' where connection_id='{}' and parameter_name='hostname'".format(vm_host,cn_id))
|
|
||||||
cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='{}' where connection_id='{}' and parameter_name='port'".format(vm_port,cn_id))
|
|
||||||
#cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='UTF-8' where connection_id='{}' and parameter_name='clipboard-encoding'".format(cn_id))
|
|
||||||
print("no connection")
|
|
||||||
conn.close()
|
|
||||||
return None
|
|
|
@ -1,88 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from enum import IntEnum
|
|
||||||
from xmlrpc.client import ServerProxy as RPCClient
|
|
||||||
from xmltodict import parse
|
|
||||||
from config import config
|
|
||||||
from ldap_list import vm_list
|
|
||||||
from db_export import setconn
|
|
||||||
|
|
||||||
# Constants
|
|
||||||
ALL_VM_STATES = -1
|
|
||||||
START_ID = -1 # First id whatever it is
|
|
||||||
END_ID = -1 # Last id whatever it is
|
|
||||||
session_string = config['oca']['client_secrets']
|
|
||||||
opnserver = config['oca']['opn_server']
|
|
||||||
|
|
||||||
class VMState(IntEnum):
|
|
||||||
INIT = 0
|
|
||||||
PENDING = 1
|
|
||||||
HOLD = 2
|
|
||||||
ACTIVE = 3
|
|
||||||
STOPPED = 4
|
|
||||||
SUSPENDED = 5
|
|
||||||
DONE = 6
|
|
||||||
FAILED = 7
|
|
||||||
POWEROFF = 8
|
|
||||||
UNDEPLOYED = 9
|
|
||||||
CLONING = 10
|
|
||||||
CLONING_FAILURE = 11
|
|
||||||
|
|
||||||
|
|
||||||
class VmFilterFlag(IntEnum):
|
|
||||||
UIDUserResources = 0 # UID User’s Resources
|
|
||||||
UserAndItsGroupsResources = -1 # Resources belonging to the user and any of his groups
|
|
||||||
AllResources = -2 # All resources
|
|
||||||
UserResources = -3 # Resources belonging to the user
|
|
||||||
UserPrimaryGroupResources = -4 # Resources belonging to the user’s primary group
|
|
||||||
|
|
||||||
|
|
||||||
class VM:
|
|
||||||
def __init__(self, vm: dict):
|
|
||||||
self.id = vm.get('ID', None)
|
|
||||||
self.owner = {
|
|
||||||
'id': vm.get('UID', None),
|
|
||||||
'name': vm.get('UNAME', None),
|
|
||||||
'gname': vm.get('GNAME', None)
|
|
||||||
}
|
|
||||||
self.name = vm.get('NAME', None)
|
|
||||||
self.status = vm.get('STATE', None)
|
|
||||||
if self.status:
|
|
||||||
self.status = VMState(int(self.status)).name.lower()
|
|
||||||
|
|
||||||
template = vm['TEMPLATE']
|
|
||||||
|
|
||||||
self.graphics = template.get('GRAPHICS', {})
|
|
||||||
self.memory = template.get('MEMORY', None)
|
|
||||||
self.vcpu = template.get('VCPU', None)
|
|
||||||
self.host = {
|
|
||||||
'name': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HOSTNAME', None),
|
|
||||||
'id': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HID', None),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
with RPCClient(opnserver) as rpc_client:
|
|
||||||
success, response, *_ = rpc_client.one.vmpool.infoextended(
|
|
||||||
session_string , VmFilterFlag.AllResources.value, START_ID, END_ID, VMState.ACTIVE.value
|
|
||||||
)
|
|
||||||
if success:
|
|
||||||
vms = json.loads(json.dumps(parse(response)))['VM_POOL']['VM']
|
|
||||||
for entry in vm_list.entries:
|
|
||||||
temp_uname = entry.uid
|
|
||||||
for i, vm in enumerate(vms):
|
|
||||||
vm_user = vm['UNAME']
|
|
||||||
vm_id = vm['ID']
|
|
||||||
vm_port = vm['TEMPLATE']['GRAPHICS'].get('PORT')
|
|
||||||
vm_host = vm['HISTORY_RECORDS']['HISTORY']['HOSTNAME']
|
|
||||||
if vm['UNAME'] == temp_uname:
|
|
||||||
#print(entry.uid, vm_id, vm_port, vm_host)
|
|
||||||
setconn(entry.uid, vm_id, vm_port, vm_host)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print(response)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import ldap3
|
|
||||||
import sys
|
|
||||||
from config import config
|
|
||||||
from ldap3 import Server, Connection, ObjectDef, Reader, ALL, SUBTREE, ALL_ATTRIBUTES
|
|
||||||
from ldap3.core import exceptions
|
|
||||||
|
|
||||||
|
|
||||||
LDAP_SERVER = config['ldap']['server']
|
|
||||||
LDAP_PASSWORD = config['ldap']['admin_password']
|
|
||||||
LDAP_USER = config['ldap']['admin_dn']
|
|
||||||
LDAP_PORT = int(config['ldap']['ldap_port'])
|
|
||||||
|
|
||||||
# Create the Server object with the given address.
|
|
||||||
server = Server(LDAP_SERVER, LDAP_PORT, get_info=ALL)
|
|
||||||
#Create a connection object, and bind with the given DN and password.
|
|
||||||
try:
|
|
||||||
conn = Connection(server, LDAP_USER, LDAP_PASSWORD, auto_bind=True)
|
|
||||||
print('LDAP Bind Successful.')
|
|
||||||
# Perform a search for a pre-defined criteria.
|
|
||||||
# Mention the search filter / filter type and attributes.
|
|
||||||
conn.search('ou=customer,dc=ungleich,dc=ch', '(&(!({}={})))'.format('mail','*@ungleich.ch') , attributes=['uid','mail'])
|
|
||||||
#conn.search('ou=customer,dc=ungleich,dc=ch', '(objectClass=*)' , attributes=['uid','mail'])
|
|
||||||
# Print the resulting entriesn.
|
|
||||||
#for entry in conn.entries:
|
|
||||||
#print(entry.uid, entry.mail)
|
|
||||||
vm_list = conn
|
|
||||||
except exceptions.LDAPException as err:
|
|
||||||
sys.exit(f'LDAP Error: {err}')
|
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,3 @@ done
|
||||||
|
|
||||||
# countries with counter
|
# countries with counter
|
||||||
( for ip in $(wg | grep endpoint | sed -e 's/endpoint: //' -e 's/\(.*\):[0-9]*/\1/' -e 's/\[//' -e 's/\]//'); do curl -s ipinfo.io/$ip | grep -e country ; done ) | sort | uniq -c | sort -g
|
( for ip in $(wg | grep endpoint | sed -e 's/endpoint: //' -e 's/\(.*\):[0-9]*/\1/' -e 's/\[//' -e 's/\]//'); do curl -s ipinfo.io/$ip | grep -e country ; done ) | sort | uniq -c | sort -g
|
||||||
|
|
||||||
# Get number of configured VPNs
|
|
||||||
configured_vpns=$(wg show | grep ^peer | wc -l)
|
|
||||||
active_vpns=$(wg show | grep endpoint | wc -l)
|
|
||||||
|
|
||||||
echo "Configured VPNs: ${configured_vpns}"
|
|
||||||
echo "Active VPNs: ${active_vpns}"
|
|
||||||
|
|
Loading…
Reference in a new issue