mirror of
https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git
synced 2025-12-14 10:52:44 +03:00
Add .editorconfig and replace spaces with tabs
This commit is contained in:
parent
7d9a280a67
commit
000f41a48b
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@ -0,0 +1,18 @@
|
||||
# https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[Makefile]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[*.{md,yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
192
bin/imds
192
bin/imds
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
|
||||
# Tiny Cloud - Instance MetaData Service client
|
||||
|
||||
@ -9,43 +9,43 @@
|
||||
. "$LIBDIR/tiny-cloud/common"
|
||||
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||
cat <<EOT
|
||||
Usage: imds [-h] { -e | +e | +n | +s | +t | @<alias> | <imds-path> } ...
|
||||
-h : help
|
||||
-e / +e : ignore / catch errors
|
||||
+n / +s / +t : insert newline / space / tab
|
||||
<alias> :-
|
||||
hostname : instance hostname
|
||||
local-hostname : instance local hostname
|
||||
ssh-keys : instance SSH keys
|
||||
userdata : instance user data
|
||||
nics : instance NICs
|
||||
nic:<iface>[,<nic-key> ...] : specific NIC interface
|
||||
<iface> : network interface (i.e. eth1)
|
||||
<nic-key> :- { -e | +e | +n | +s | +t | @<nic-alias> | <nic-path> }
|
||||
<nic-alias> :-
|
||||
mac : mac address
|
||||
ipv4 : ipv4 address(es)
|
||||
ipv6 : ipv6 address(es)
|
||||
ipv4-net : subnet ipv4 network(s)
|
||||
ipv6-net : subnet ipv6 network(s)
|
||||
ipv4-prefix : delegated ipv4 CIDR(s)
|
||||
ipv6-prefix : delegated ipv6 CIDR(s)
|
||||
EOT
|
||||
exit 0
|
||||
cat <<-EOT
|
||||
Usage: imds [-h] { -e | +e | +n | +s | +t | @<alias> | <imds-path> } ...
|
||||
-h : help
|
||||
-e / +e : ignore / catch errors
|
||||
+n / +s / +t : insert newline / space / tab
|
||||
<alias> :-
|
||||
hostname : instance hostname
|
||||
local-hostname : instance local hostname
|
||||
ssh-keys : instance SSH keys
|
||||
userdata : instance user data
|
||||
nics : instance NICs
|
||||
nic:<iface>[,<nic-key> ...] : specific NIC interface
|
||||
<iface> : network interface (i.e. eth1)
|
||||
<nic-key> :- { -e | +e | +n | +s | +t | @<nic-alias> | <nic-path> }
|
||||
<nic-alias> :-
|
||||
mac : mac address
|
||||
ipv4 : ipv4 address(es)
|
||||
ipv6 : ipv6 address(es)
|
||||
ipv4-net : subnet ipv4 network(s)
|
||||
ipv6-net : subnet ipv6 network(s)
|
||||
ipv4-prefix : delegated ipv4 CIDR(s)
|
||||
ipv6-prefix : delegated ipv6 CIDR(s)
|
||||
EOT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
### cloud-specific variables/functions
|
||||
|
||||
unset \
|
||||
IMDS_HEADER \
|
||||
IMDS_URI \
|
||||
IMDS_QUERY
|
||||
IMDS_HEADER \
|
||||
IMDS_URI \
|
||||
IMDS_QUERY
|
||||
unset -f \
|
||||
_imds_token \
|
||||
_imds_header \
|
||||
_imds_nic_index \
|
||||
2>/dev/null || true
|
||||
_imds_token \
|
||||
_imds_header \
|
||||
_imds_nic_index \
|
||||
2>/dev/null || true
|
||||
|
||||
### default variables/functions
|
||||
|
||||
@ -67,19 +67,19 @@ IMDS_IPV4_PREFIX="ipv4-prefix"
|
||||
IMDS_IPV6_PREFIX="ipv6-prefix"
|
||||
|
||||
_imds() {
|
||||
wget --quiet --timeout 1 --output-document - \
|
||||
--header "$(_imds_header)" \
|
||||
"http://$IMDS_ENDPOINT/$IMDS_URI/$1$IMDS_QUERY"
|
||||
wget --quiet --timeout 1 --output-document - \
|
||||
--header "$(_imds_header)" \
|
||||
"http://$IMDS_ENDPOINT/$IMDS_URI/$1$IMDS_QUERY"
|
||||
}
|
||||
|
||||
_imds_userdata() { _imds "$IMDS_USERDATA"; }
|
||||
|
||||
_imds_ssh_keys() {
|
||||
local key
|
||||
for key in $(_imds "$IMDS_SSH_KEYS"); do
|
||||
_imds "$IMDS_SSH_KEYS/${key%=*}/openssh-key"
|
||||
echo
|
||||
done | sort -u
|
||||
local key
|
||||
for key in $(_imds "$IMDS_SSH_KEYS"); do
|
||||
_imds "$IMDS_SSH_KEYS/${key%=*}/openssh-key"
|
||||
echo
|
||||
done | sort -u
|
||||
}
|
||||
|
||||
_imds_nic_index() { cat "/sys/class/net/$1/address"; }
|
||||
@ -87,71 +87,71 @@ _imds_nic_index() { cat "/sys/class/net/$1/address"; }
|
||||
### load cloud-specific variables and functions
|
||||
|
||||
if [ ! -d "$LIBDIR/tiny-cloud/cloud/$CLOUD" ]; then
|
||||
echo "ERROR: Unknown Cloud '$CLOUD'" >&2
|
||||
echo "ERROR: Unknown Cloud '$CLOUD'" >&2
|
||||
fi
|
||||
. "$LIBDIR/tiny-cloud/cloud/$CLOUD/imds"
|
||||
|
||||
### non-overrideable functions
|
||||
|
||||
imds() {
|
||||
local cmd args key rv err=1
|
||||
while [ -n "$1" ]; do
|
||||
cmd=_imds
|
||||
args=
|
||||
key="$1"; shift
|
||||
case $key in
|
||||
# error handling
|
||||
-e) err=0; continue ;; # ignore
|
||||
+e) err=1; continue ;; # return
|
||||
# TODO: retry/deadline
|
||||
# output control
|
||||
+n) printf "\n"; continue ;; # insert newline
|
||||
+s) printf " "; continue ;; # insert space
|
||||
+t) printf "\t"; continue ;; # insert tab
|
||||
# key aliasing
|
||||
@hostname) args="$IMDS_HOSTNAME" ;;
|
||||
@local-hostname) args="$IMDS_LOCAL_HOSTNAME" ;;
|
||||
@ssh-keys) cmd=_imds_ssh_keys ;;
|
||||
@userdata) cmd=_imds_userdata ;;
|
||||
@nics) args="$IMDS_NICS" ;;
|
||||
@nic:*)
|
||||
cmd=imds
|
||||
args=$(_imds_nic_args $(echo "${key#@nic:}" | tr , ' '))
|
||||
;;
|
||||
# use key verbatim
|
||||
*) args="$key" ;;
|
||||
esac
|
||||
# TODO: retry/deadline
|
||||
"$cmd" $args
|
||||
rv=$?
|
||||
[ $err -eq 0 ] && continue
|
||||
[ $rv = "0" ] || return $rv
|
||||
done
|
||||
local cmd args key rv err=1
|
||||
while [ -n "$1" ]; do
|
||||
cmd=_imds
|
||||
args=
|
||||
key="$1"; shift
|
||||
case $key in
|
||||
# error handling
|
||||
-e) err=0; continue ;; # ignore
|
||||
+e) err=1; continue ;; # return
|
||||
# TODO: retry/deadline
|
||||
# output control
|
||||
+n) printf "\n"; continue ;; # insert newline
|
||||
+s) printf " "; continue ;; # insert space
|
||||
+t) printf "\t"; continue ;; # insert tab
|
||||
# key aliasing
|
||||
@hostname) args="$IMDS_HOSTNAME" ;;
|
||||
@local-hostname) args="$IMDS_LOCAL_HOSTNAME" ;;
|
||||
@ssh-keys) cmd=_imds_ssh_keys ;;
|
||||
@userdata) cmd=_imds_userdata ;;
|
||||
@nics) args="$IMDS_NICS" ;;
|
||||
@nic:*)
|
||||
cmd=imds
|
||||
args=$(_imds_nic_args $(echo "${key#@nic:}" | tr , ' '))
|
||||
;;
|
||||
# use key verbatim
|
||||
*) args="$key" ;;
|
||||
esac
|
||||
# TODO: retry/deadline
|
||||
"$cmd" $args
|
||||
rv=$?
|
||||
[ $err -eq 0 ] && continue
|
||||
[ $rv = "0" ] || return $rv
|
||||
done
|
||||
}
|
||||
|
||||
_imds_nic_args() {
|
||||
local key nic
|
||||
nic=$(_imds_nic_index "$1") || return 1
|
||||
if [ -z "$2" ]; then
|
||||
echo "$IMDS_NICS/$nic"
|
||||
return
|
||||
fi
|
||||
while [ -n "$2" ]; do
|
||||
key="$2"
|
||||
shift
|
||||
case "$key" in
|
||||
@mac) key="$IMDS_MAC" ;;
|
||||
@ipv4) key="$IMDS_IPV4" ;;
|
||||
@ipv6) key="$IMDS_IPV6" ;;
|
||||
@ipv4-net) key="$IMDS_IPV4_NET" ;;
|
||||
@ipv6-net) key="$IMDS_IPV6_NET" ;;
|
||||
@ipv4-prefix) key="$IMDS_IPV4_PREFIX" ;;
|
||||
@ipv6-prefix) key="$IMDS_IPV6_PREFIX" ;;
|
||||
# error/output control passthrough
|
||||
-e|+[enst]) printf "$key\n"; continue ;;
|
||||
esac
|
||||
printf "$IMDS_NICS/$nic/$key\n"
|
||||
done
|
||||
local key nic
|
||||
nic=$(_imds_nic_index "$1") || return 1
|
||||
if [ -z "$2" ]; then
|
||||
echo "$IMDS_NICS/$nic"
|
||||
return
|
||||
fi
|
||||
while [ -n "$2" ]; do
|
||||
key="$2"
|
||||
shift
|
||||
case "$key" in
|
||||
@mac) key="$IMDS_MAC" ;;
|
||||
@ipv4) key="$IMDS_IPV4" ;;
|
||||
@ipv6) key="$IMDS_IPV6" ;;
|
||||
@ipv4-net) key="$IMDS_IPV4_NET" ;;
|
||||
@ipv6-net) key="$IMDS_IPV6_NET" ;;
|
||||
@ipv4-prefix) key="$IMDS_IPV4_PREFIX" ;;
|
||||
@ipv6-prefix) key="$IMDS_IPV6_PREFIX" ;;
|
||||
# error/output control passthrough
|
||||
-e|+[enst]) printf "$key\n"; continue ;;
|
||||
esac
|
||||
printf "$IMDS_NICS/$nic/$key\n"
|
||||
done
|
||||
}
|
||||
|
||||
imds "$@"
|
||||
|
||||
2
dist/openrc/tiny-cloud
vendored
2
dist/openrc/tiny-cloud
vendored
@ -1,5 +1,5 @@
|
||||
#!/sbin/openrc-run
|
||||
# vim:set ts=8 noet ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
description="Tiny Cloud Bootstrap - main phase"
|
||||
|
||||
2
dist/openrc/tiny-cloud-early
vendored
2
dist/openrc/tiny-cloud-early
vendored
@ -1,5 +1,5 @@
|
||||
#!/sbin/openrc-run
|
||||
# vim:set ts=8 noet ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
description="Tiny Cloud Bootstrap - early phase"
|
||||
|
||||
2
dist/openrc/tiny-cloud-final
vendored
2
dist/openrc/tiny-cloud-final
vendored
@ -1,5 +1,5 @@
|
||||
#!/sbin/openrc-run
|
||||
# vim:set ts=8 noet ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
description="Tiny Cloud Bootstrap - final phase"
|
||||
|
||||
2
dist/openrc/tiny-cloud-net
vendored
2
dist/openrc/tiny-cloud-net
vendored
@ -1,5 +1,5 @@
|
||||
#!/sbin/openrc-run
|
||||
# vim:set ts=8 noet ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
description="Tiny Cloud Bootstrap - net phase"
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=2 et:
|
||||
# vim:set ft=sh:
|
||||
|
||||
# NOTE: The mdev-conf APK handles this now, but only for xvd or sd links (not
|
||||
# both)
|
||||
# both)
|
||||
|
||||
: "${LIBDIR:=$PREFIX/lib}"
|
||||
. "$LIBDIR/tiny-cloud/common"
|
||||
@ -11,39 +11,39 @@
|
||||
[ -x /usr/sbin/nvme ] || log crit "nvme cli not installed"
|
||||
|
||||
raw_ebs_alias() {
|
||||
/usr/sbin/nvme id-ctrl "/dev/$BASE" -b 2>/dev/null |
|
||||
dd bs=32 skip=96 count=1 2>/dev/null
|
||||
/usr/sbin/nvme id-ctrl "/dev/$BASE" -b 2>/dev/null |
|
||||
dd bs=32 skip=96 count=1 2>/dev/null
|
||||
}
|
||||
|
||||
case $ACTION in
|
||||
add|"")
|
||||
BASE=$(echo "$MDEV" | sed -re 's/^(nvme[0-9]+n[0-9]+).*/\1/')
|
||||
PART=$(echo "$MDEV" | sed -re 's/nvme[0-9]+n[0-9]+p?//g')
|
||||
# TODO: deadline instead of max tries
|
||||
MAXTRY=30
|
||||
TRY=0
|
||||
until [ -n "$EBS" ]; do
|
||||
EBS=$(raw_ebs_alias | sed -nre '/^(\/dev\/)?(s|xv)d[a-z]{1,2} /p' | tr -d ' ')
|
||||
[ -n "$EBS" ] && break
|
||||
TRY=$((TRY + 1))
|
||||
if [ $TRY -eq $MAXTRY ]; then
|
||||
log err "Failed to get EBS volume alias for $MDEV after $MAXTRY attempts ($(raw_ebs_alias))"
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
# remove any leading '/dev/', 'sd', or 'xvd', and append partition
|
||||
EBS=${EBS#/dev/}
|
||||
EBS=${EBS#sd}
|
||||
EBS=${EBS#xvd}$PART
|
||||
ln -sf "$MDEV" "sd$EBS" && log notice "Added sd$EBS symlink for $MDEV"
|
||||
ln -sf "$MDEV" "xvd$EBS" && log notice "Added xvd$EBS symlink for $MDEV"
|
||||
;;
|
||||
remove)
|
||||
for TARGET in sd* xvd*
|
||||
do
|
||||
[ "$(readlink "$TARGET" 2>/dev/null)" = "$MDEV" ] && rm -f "$TARGET" && \
|
||||
log notice "Removed $TARGET symlink for $MDEV"
|
||||
done
|
||||
;;
|
||||
add|"")
|
||||
BASE=$(echo "$MDEV" | sed -re 's/^(nvme[0-9]+n[0-9]+).*/\1/')
|
||||
PART=$(echo "$MDEV" | sed -re 's/nvme[0-9]+n[0-9]+p?//g')
|
||||
# TODO: deadline instead of max tries
|
||||
MAXTRY=30
|
||||
TRY=0
|
||||
until [ -n "$EBS" ]; do
|
||||
EBS=$(raw_ebs_alias | sed -nre '/^(\/dev\/)?(s|xv)d[a-z]{1,2} /p' | tr -d ' ')
|
||||
[ -n "$EBS" ] && break
|
||||
TRY=$((TRY + 1))
|
||||
if [ $TRY -eq $MAXTRY ]; then
|
||||
log err "Failed to get EBS volume alias for $MDEV after $MAXTRY attempts ($(raw_ebs_alias))"
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
# remove any leading '/dev/', 'sd', or 'xvd', and append partition
|
||||
EBS=${EBS#/dev/}
|
||||
EBS=${EBS#sd}
|
||||
EBS=${EBS#xvd}$PART
|
||||
ln -sf "$MDEV" "sd$EBS" && log notice "Added sd$EBS symlink for $MDEV"
|
||||
ln -sf "$MDEV" "xvd$EBS" && log notice "Added xvd$EBS symlink for $MDEV"
|
||||
;;
|
||||
remove)
|
||||
for TARGET in sd* xvd*
|
||||
do
|
||||
[ "$(readlink "$TARGET" 2>/dev/null)" = "$MDEV" ] && rm -f "$TARGET" && \
|
||||
log notice "Removed $TARGET symlink for $MDEV"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=4 et:
|
||||
# vim:set ft=sh:
|
||||
|
||||
set -e
|
||||
|
||||
@ -7,52 +7,52 @@ set -e
|
||||
. "$LIBDIR/tiny-cloud/common"
|
||||
|
||||
if [ -z "$MDEV" ] || [ -z "$ACTION" ]; then
|
||||
log crit "MDEV or ACTION undefined, aborting"
|
||||
log crit "MDEV or ACTION undefined, aborting"
|
||||
fi
|
||||
|
||||
IFACE_CFG=/etc/network/interfaces
|
||||
|
||||
ip() {
|
||||
local v=-4 lev=info
|
||||
if [ "$1" = '-4' ] || [ "$1" = '-6' ]; then
|
||||
v="$1"
|
||||
shift
|
||||
fi
|
||||
local op="$2"
|
||||
local v=-4 lev=info
|
||||
if [ "$1" = '-4' ] || [ "$1" = '-6' ]; then
|
||||
v="$1"
|
||||
shift
|
||||
fi
|
||||
local op="$2"
|
||||
|
||||
[ "$op" = show ] && lev=debug
|
||||
if /sbin/ip "$v" "$@" || [ -n "$FAIL_OK" ]; then
|
||||
log "$lev" "OK: ip $v $*"
|
||||
else
|
||||
log err "FAIL: ip $v $*"
|
||||
fi
|
||||
[ "$op" = show ] && lev=debug
|
||||
if /sbin/ip "$v" "$@" || [ -n "$FAIL_OK" ]; then
|
||||
log "$lev" "OK: ip $v $*"
|
||||
else
|
||||
log err "FAIL: ip $v $*"
|
||||
fi
|
||||
}
|
||||
|
||||
interface_up() {
|
||||
log info "Bringing up $MDEV"
|
||||
# umask so udhcpc PID file isn't non-owner writeable
|
||||
(umask 0022 && ifup "$MDEV")
|
||||
log info "Bringing up $MDEV"
|
||||
# umask so udhcpc PID file isn't non-owner writeable
|
||||
(umask 0022 && ifup "$MDEV")
|
||||
}
|
||||
|
||||
cleanup_interface() {
|
||||
local v pref rtable="${MDEV#eth}"
|
||||
let rtable+=10000
|
||||
local v pref rtable="${MDEV#eth}"
|
||||
let rtable+=10000
|
||||
|
||||
log info "Cleaning up $MDEV"
|
||||
log info "Cleaning up $MDEV"
|
||||
|
||||
# kill related udhcpc, don't panic if it's not there
|
||||
kill "$(cat "/run/udhcpc.$MDEV.pid")" || true
|
||||
# kill related udhcpc, don't panic if it's not there
|
||||
kill "$(cat "/run/udhcpc.$MDEV.pid")" || true
|
||||
|
||||
# tidy up /run/ifstate, if it exists
|
||||
[ -f /run/ifstate ] && sed -i -e "/^$MDEV=/d" /run/ifstate
|
||||
rm -f /run/ifstate."$MDEV".lock
|
||||
# tidy up /run/ifstate, if it exists
|
||||
[ -f /run/ifstate ] && sed -i -e "/^$MDEV=/d" /run/ifstate
|
||||
rm -f /run/ifstate."$MDEV".lock
|
||||
|
||||
# remove related rules
|
||||
for v in 4 6; do
|
||||
for pref in $(ip -"$v" rule show table "$rtable" | cut -d: -f1); do
|
||||
ip -"$v" rule del pref "$pref"
|
||||
done
|
||||
done
|
||||
# remove related rules
|
||||
for v in 4 6; do
|
||||
for pref in $(ip -"$v" rule show table "$rtable" | cut -d: -f1); do
|
||||
ip -"$v" rule del pref "$pref"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
is_networking_started() { service networking status -q 2>/dev/null; }
|
||||
@ -60,28 +60,28 @@ is_networking_started() { service networking status -q 2>/dev/null; }
|
||||
log info "STARTING: $ACTION $MDEV"
|
||||
|
||||
if exec 200>>"$IFACE_CFG"; then
|
||||
if flock 200; then
|
||||
case $ACTION in
|
||||
add|"")
|
||||
assemble-interfaces
|
||||
is_networking_started && interface_up
|
||||
;;
|
||||
remove)
|
||||
assemble-interfaces
|
||||
is_networking_started && cleanup_interface
|
||||
;;
|
||||
*)
|
||||
log err "Unknown action '$ACTION'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
log err "Unable to flock $IFACE_CFG"
|
||||
exit 1
|
||||
fi
|
||||
if flock 200; then
|
||||
case $ACTION in
|
||||
add|"")
|
||||
assemble-interfaces
|
||||
is_networking_started && interface_up
|
||||
;;
|
||||
remove)
|
||||
assemble-interfaces
|
||||
is_networking_started && cleanup_interface
|
||||
;;
|
||||
*)
|
||||
log err "Unknown action '$ACTION'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
log err "Unable to flock $IFACE_CFG"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log err "Unable to assign fd 200 to flock $IFACE_CFG"
|
||||
exit 1
|
||||
log err "Unable to assign fd 200 to flock $IFACE_CFG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log info "FINISHED: $ACTION $MDEV"
|
||||
|
||||
@ -1,27 +1,27 @@
|
||||
# Tiny Cloud - Init Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
INIT_ACTIONS_EARLY="$(replace_word set_default_interfaces set_network_interfaces $INIT_ACTIONS_EARLY)"
|
||||
|
||||
set_resolv_conf() {
|
||||
# resolv.conf
|
||||
local nameservers="$(imds meta-data/resolv_conf/nameservers)"
|
||||
for i in $nameservers; do
|
||||
local server="$(imds meta-data/resolv_conf/nameservers/$i)"
|
||||
add_once "$ROOT"/etc/resolv.conf "nameserver $server"
|
||||
done
|
||||
# resolv.conf
|
||||
local nameservers="$(imds meta-data/resolv_conf/nameservers)"
|
||||
for i in $nameservers; do
|
||||
local server="$(imds meta-data/resolv_conf/nameservers/$i)"
|
||||
add_once "$ROOT"/etc/resolv.conf "nameserver $server"
|
||||
done
|
||||
}
|
||||
|
||||
init__set_network_interfaces() {
|
||||
local interfaces="$(imds meta-data/network-interfaces)"
|
||||
mkdir -p "$ROOT"/etc/network
|
||||
if [ -n "$interfaces" ]; then
|
||||
printf "%s\n" "$interfaces" > "$ROOT"/etc/network/interfaces
|
||||
elif ! [ -f "$ROOT"/etc/network/interfaces ]; then
|
||||
init__set_default_interfaces
|
||||
fi
|
||||
if ! grep -q dhcp "$ROOT"/etc/network/interfaces; then
|
||||
set_resolv_conf
|
||||
fi
|
||||
local interfaces="$(imds meta-data/network-interfaces)"
|
||||
mkdir -p "$ROOT"/etc/network
|
||||
if [ -n "$interfaces" ]; then
|
||||
printf "%s\n" "$interfaces" > "$ROOT"/etc/network/interfaces
|
||||
elif ! [ -f "$ROOT"/etc/network/interfaces ]; then
|
||||
init__set_default_interfaces
|
||||
fi
|
||||
if ! grep -q dhcp "$ROOT"/etc/network/interfaces; then
|
||||
set_resolv_conf
|
||||
fi
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# AWS Instance MetaData Service variables and functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
IMDS_HEADER="X-aws-ec2-metadata-token"
|
||||
@ -8,11 +8,11 @@ IMDS_TOKEN_TTL_HEADER="X-aws-ec2-metadata-token-ttl-seconds"
|
||||
IMDS_URI="latest"
|
||||
|
||||
_imds_token() {
|
||||
printf "PUT /latest/api/token HTTP/1.0\r\n%s: %s\r\n\r\n" \
|
||||
"$IMDS_TOKEN_TTL_HEADER" "$IMDS_TOKEN_TTL" \
|
||||
| nc -w 1 "$IMDS_ENDPOINT" 80 | tail -n 1
|
||||
printf "PUT /latest/api/token HTTP/1.0\r\n%s: %s\r\n\r\n" \
|
||||
"$IMDS_TOKEN_TTL_HEADER" "$IMDS_TOKEN_TTL" \
|
||||
| nc -w 1 "$IMDS_ENDPOINT" 80 | tail -n 1
|
||||
}
|
||||
|
||||
_imds_header() {
|
||||
echo "$IMDS_HEADER: $(_imds_token)"
|
||||
echo "$IMDS_HEADER: $(_imds_token)"
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
# AWS mdev Hotplug Modules
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# makes symlinks for NVMe devices that correlate to AWS EBS sd/xvd devices
|
||||
mod__nvme_ebs_links() {
|
||||
# nvme-cli not installed?
|
||||
[ -x /usr/sbin/nvme ] || return 1
|
||||
# nvme-cli not installed?
|
||||
[ -x /usr/sbin/nvme ] || return 1
|
||||
|
||||
install_before '^nvme\.\*' \
|
||||
'nvme[0-9]+n.* root:disk 0660 */lib/mdev/nvme-ebs-links'
|
||||
install_before '^nvme\.\*' \
|
||||
'nvme[0-9]+n.* root:disk 0660 */lib/mdev/nvme-ebs-links'
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Azure Instance MetaData Service variables and functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
IMDS_HEADER="Metadata"
|
||||
@ -14,28 +14,28 @@ IMDS_NICS="network/interface"
|
||||
|
||||
# TODO: flesh out networking
|
||||
unset \
|
||||
IMDS_MAC \
|
||||
IMDS_IPV4 \
|
||||
IMDS_IPV6 \
|
||||
IMDS_IPV4_NET \
|
||||
IMDS_IPV6_NET \
|
||||
IMDS_IPV4_PREFIX \
|
||||
IMDS_IPV6_PREFIX
|
||||
IMDS_MAC \
|
||||
IMDS_IPV4 \
|
||||
IMDS_IPV6 \
|
||||
IMDS_IPV4_NET \
|
||||
IMDS_IPV6_NET \
|
||||
IMDS_IPV4_PREFIX \
|
||||
IMDS_IPV6_PREFIX
|
||||
|
||||
_imds_header() {
|
||||
echo "$IMDS_HEADER: true"
|
||||
echo "$IMDS_HEADER: true"
|
||||
}
|
||||
|
||||
# dig deeper than default
|
||||
_imds_ssh_keys() {
|
||||
local key
|
||||
local key
|
||||
|
||||
for key in $(imds "$IMDS_SSH_KEYS"); do
|
||||
imds "$IMDS_SSH_KEYS/${key}/keyData"
|
||||
done | sort -u
|
||||
for key in $(imds "$IMDS_SSH_KEYS"); do
|
||||
imds "$IMDS_SSH_KEYS/${key}/keyData"
|
||||
done | sort -u
|
||||
}
|
||||
|
||||
# decode userdata value
|
||||
_imds_userdata() {
|
||||
imds "$IMDS_USERDATA" | base64 -d
|
||||
imds "$IMDS_USERDATA" | base64 -d
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Google Cloud Instance MetaData Service variables and functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
IMDS_HEADER="Metadata-Flavor"
|
||||
@ -8,21 +8,21 @@ IMDS_URI="computeMetadata/v1"
|
||||
IMDS_HOSTNAME="instance/hostname"
|
||||
IMDS_LOCAL_HOSTNAME="$IMDS_HOSTNAME"
|
||||
IMDS_SSH_KEYS="
|
||||
project/attributes/ssh-keys
|
||||
instance/attributes/ssh-keys
|
||||
project/attributes/ssh-keys
|
||||
instance/attributes/ssh-keys
|
||||
"
|
||||
IMDS_USERDATA="instance/attributes/user-data"
|
||||
|
||||
_imds_header() {
|
||||
echo "$IMDS_HEADER: Google"
|
||||
echo "$IMDS_HEADER: Google"
|
||||
}
|
||||
|
||||
# merge project and instance keys
|
||||
_imds_ssh_keys() {
|
||||
local ssh_keys
|
||||
local ssh_keys
|
||||
|
||||
for ssh_keys in $IMDS_SSH_KEYS; do
|
||||
# ignore errors and strip leading '<login>:'
|
||||
imds -e "$ssh_keys" | cut -d: -f2-
|
||||
done | sort -u
|
||||
for ssh_keys in $IMDS_SSH_KEYS; do
|
||||
# ignore errors and strip leading '<login>:'
|
||||
imds -e "$ssh_keys" | cut -d: -f2-
|
||||
done | sort -u
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# NoCloud Instance Metadata
|
||||
# vim: ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
NOCLOUD_FILES="meta-data user-data vendor-data network-config"
|
||||
@ -7,100 +7,100 @@ NOCLOUD_FILES="meta-data user-data vendor-data network-config"
|
||||
is_nocloud_loaded() { [ -f "$TINY_CLOUD_VAR/.nocloud_loaded" ]; }
|
||||
|
||||
_load_nocloud_cmdline() {
|
||||
local kopt kv k v data
|
||||
local kopt kv k v data
|
||||
|
||||
for kopt in $(cat "$ROOT/proc/cmdline" 2>/dev/null); do
|
||||
echo "$kopt" | grep -qE '(^|=)ds=nocloud(-net)?;' || continue
|
||||
for kv in $(echo "${kopt#*;}" | tr \; ' '); do
|
||||
k=$(echo "$kv" | cut -d= -f1)
|
||||
v=$(echo "$kv" | cut -d= -f2-)
|
||||
case "$k" in
|
||||
h|local-hostname)
|
||||
printf "\nlocal-hostname: %s" "$v" >> "$TINY_CLOUD_VAR/meta-data"
|
||||
;;
|
||||
i|instance-id)
|
||||
printf "\ninstance-id: %s" "$v" >> "$TINY_CLOUD_VAR/meta-data"
|
||||
;;
|
||||
s|seedfrom)
|
||||
for data in $NOCLOUD_FILES; do
|
||||
case "${v#file:/}" in
|
||||
/*)
|
||||
cat "$v/$data" >> "$TINY_CLOUD_VAR/$data" || continue
|
||||
echo >> "$TINY_CLOUD_VAR/$data"
|
||||
;;
|
||||
http://*|https://*)
|
||||
wget -qO - "$v/$data" >> "$TINY_CLOUD_VAR/$data" || continue
|
||||
echo >> "$TINY_CLOUD_VAR/$data"
|
||||
;;
|
||||
*) log -s warning "Unknown NoCloud seedfrom value '$v'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
*) log -s warning "Unknown NoCloud kernel cmdline key '$k'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return
|
||||
done
|
||||
return 1
|
||||
for kopt in $(cat "$ROOT/proc/cmdline" 2>/dev/null); do
|
||||
echo "$kopt" | grep -qE '(^|=)ds=nocloud(-net)?;' || continue
|
||||
for kv in $(echo "${kopt#*;}" | tr \; ' '); do
|
||||
k=$(echo "$kv" | cut -d= -f1)
|
||||
v=$(echo "$kv" | cut -d= -f2-)
|
||||
case "$k" in
|
||||
h|local-hostname)
|
||||
printf "\nlocal-hostname: %s" "$v" >> "$TINY_CLOUD_VAR/meta-data"
|
||||
;;
|
||||
i|instance-id)
|
||||
printf "\ninstance-id: %s" "$v" >> "$TINY_CLOUD_VAR/meta-data"
|
||||
;;
|
||||
s|seedfrom)
|
||||
for data in $NOCLOUD_FILES; do
|
||||
case "${v#file:/}" in
|
||||
/*)
|
||||
cat "$v/$data" >> "$TINY_CLOUD_VAR/$data" || continue
|
||||
echo >> "$TINY_CLOUD_VAR/$data"
|
||||
;;
|
||||
http://*|https://*)
|
||||
wget -qO - "$v/$data" >> "$TINY_CLOUD_VAR/$data" || continue
|
||||
echo >> "$TINY_CLOUD_VAR/$data"
|
||||
;;
|
||||
*) log -s warning "Unknown NoCloud seedfrom value '$v'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
*) log -s warning "Unknown NoCloud kernel cmdline key '$k'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_load_nocloud_volume() {
|
||||
mkdir -p "$ROOT"/run/tiny-cloud
|
||||
local mntdir=$(mktemp -d "$ROOT/run/tiny-cloud/cidata-XXXXXX")
|
||||
local data mounted
|
||||
mkdir -p "$ROOT"/run/tiny-cloud
|
||||
local mntdir=$(mktemp -d "$ROOT/run/tiny-cloud/cidata-XXXXXX")
|
||||
local data mounted
|
||||
|
||||
mkdir -p "$mntdir"
|
||||
for fstype in vfat iso9660; do
|
||||
[ "$mounted" ] && break
|
||||
for label in cidata CIDATA; do
|
||||
[ -n "$mounted" ] && break
|
||||
mount -o ro -t "$fstype" LABEL="$label" "$mntdir" && mounted=1
|
||||
done
|
||||
done
|
||||
if [ -n "$mounted" ]; then
|
||||
for data in $NOCLOUD_FILES; do
|
||||
# lack of source results in empty target
|
||||
cat "$mntdir/$data" > "$TINY_CLOUD_VAR/$data" 2>/dev/null
|
||||
done
|
||||
umount "$mntdir"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
rmdir "$mntdir"
|
||||
mkdir -p "$mntdir"
|
||||
for fstype in vfat iso9660; do
|
||||
[ "$mounted" ] && break
|
||||
for label in cidata CIDATA; do
|
||||
[ -n "$mounted" ] && break
|
||||
mount -o ro -t "$fstype" LABEL="$label" "$mntdir" && mounted=1
|
||||
done
|
||||
done
|
||||
if [ -n "$mounted" ]; then
|
||||
for data in $NOCLOUD_FILES; do
|
||||
# lack of source results in empty target
|
||||
cat "$mntdir/$data" > "$TINY_CLOUD_VAR/$data" 2>/dev/null
|
||||
done
|
||||
umount "$mntdir"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
rmdir "$mntdir"
|
||||
}
|
||||
|
||||
load_nocloud() {
|
||||
# start with a clean slate
|
||||
(cd "$TINY_CLOUD_VAR" && rm -f $NOCLOUD_FILES)
|
||||
# start with a clean slate
|
||||
(cd "$TINY_CLOUD_VAR" && rm -f $NOCLOUD_FILES)
|
||||
|
||||
if _load_nocloud_cmdline || _load_nocloud_volume; then
|
||||
touch "$TINY_CLOUD_VAR/.nocloud_loaded"
|
||||
else
|
||||
log -s err "Unable to load NoCloud datasource"
|
||||
return 1
|
||||
fi
|
||||
if _load_nocloud_cmdline || _load_nocloud_volume; then
|
||||
touch "$TINY_CLOUD_VAR/.nocloud_loaded"
|
||||
else
|
||||
log -s err "Unable to load NoCloud datasource"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# minimally, we expect some content in meta-data
|
||||
[ -s "$TINY_CLOUD_VAR/meta-data" ] ||
|
||||
log -s warning "NoCloud 'meta-data' is empty"
|
||||
# minimally, we expect some content in meta-data
|
||||
[ -s "$TINY_CLOUD_VAR/meta-data" ] ||
|
||||
log -s warning "NoCloud 'meta-data' is empty"
|
||||
}
|
||||
|
||||
_imds() {
|
||||
mkdir -p "$TINY_CLOUD_VAR"
|
||||
local file="$TINY_CLOUD_VAR/$(echo "$1" | cut -d/ -f1)"
|
||||
local keypath="$(echo "$1" | cut -d/ -f2- | tr / ' ')"
|
||||
mkdir -p "$TINY_CLOUD_VAR"
|
||||
local file="$TINY_CLOUD_VAR/$(echo "$1" | cut -d/ -f1)"
|
||||
local keypath="$(echo "$1" | cut -d/ -f2- | tr / ' ')"
|
||||
|
||||
is_nocloud_loaded || load_nocloud
|
||||
is_nocloud_loaded || load_nocloud
|
||||
|
||||
# does file exist?
|
||||
[ -f "$file" ] || return 1
|
||||
# does file exist?
|
||||
[ -f "$file" ] || return 1
|
||||
|
||||
# use 'file/' to get top-level keys
|
||||
if [ $(basename "$file") = "$keypath" ]; then
|
||||
cat "$file"
|
||||
else
|
||||
yx -f "$file" $keypath
|
||||
fi
|
||||
# use 'file/' to get top-level keys
|
||||
if [ $(basename "$file") = "$keypath" ]; then
|
||||
cat "$file"
|
||||
else
|
||||
yx -f "$file" $keypath
|
||||
fi
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# OCI Instance MetaData Service variables and functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
IMDS_HEADER="Authorization"
|
||||
@ -13,25 +13,25 @@ IMDS_NICS="nics"
|
||||
|
||||
# TODO: flesh out networking
|
||||
unset \
|
||||
IMDS_MAC \
|
||||
IMDS_IPV4 \
|
||||
IMDS_IPV6 \
|
||||
IMDS_IPV4_NET \
|
||||
IMDS_IPV6_NET \
|
||||
IMDS_IPV4_PREFIX \
|
||||
IMDS_IPV6_PREFIX
|
||||
IMDS_MAC \
|
||||
IMDS_IPV4 \
|
||||
IMDS_IPV6 \
|
||||
IMDS_IPV4_NET \
|
||||
IMDS_IPV6_NET \
|
||||
IMDS_IPV4_PREFIX \
|
||||
IMDS_IPV6_PREFIX
|
||||
|
||||
_imds_header() {
|
||||
echo "$IMDS_HEADER: Bearer Oracle"
|
||||
echo "$IMDS_HEADER: Bearer Oracle"
|
||||
}
|
||||
|
||||
_imds_ssh_keys() { _imds "$IMDS_SSH_KEYS"; }
|
||||
|
||||
_imds_nic_index() {
|
||||
local m n=0
|
||||
local mac=$(cat "/sys/class/net/$1/mac")
|
||||
while m=$(imds "$IMDS_NICS/$n/mac" | tr A-F a-f); do
|
||||
[ "$m" = "$mac" ] && echo $n; return 0
|
||||
done
|
||||
return 1
|
||||
local m n=0
|
||||
local mac=$(cat "/sys/class/net/$1/mac")
|
||||
while m=$(imds "$IMDS_NICS/$n/mac" | tr A-F a-f); do
|
||||
[ "$m" = "$mac" ] && echo $n; return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Tiny Cloud - common script functions
|
||||
# vim: ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# set defaults
|
||||
@ -10,62 +10,62 @@
|
||||
: "${TINY_CLOUD_VAR:=$ROOT/var/lib/cloud}"
|
||||
|
||||
log() {
|
||||
local facility="local7"
|
||||
local stderr init
|
||||
local tag=$(basename "$0")
|
||||
while [ "${1#-}" != "$1" ]; do
|
||||
case "$1" in
|
||||
-i) init=1 ;; # TODO: value = indent?
|
||||
-f) facility="$2"; shift ;;
|
||||
-s) stderr=-s ;;
|
||||
-t) tag="$tag/$2"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
local level="$1"
|
||||
[ -z "$DEBUG" ] && [ "$level" = debug ] && return
|
||||
shift
|
||||
local facility="local7"
|
||||
local stderr init
|
||||
local tag=$(basename "$0")
|
||||
while [ "${1#-}" != "$1" ]; do
|
||||
case "$1" in
|
||||
-i) init=1 ;; # TODO: value = indent?
|
||||
-f) facility="$2"; shift ;;
|
||||
-s) stderr=-s ;;
|
||||
-t) tag="$tag/$2"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
local level="$1"
|
||||
[ -z "$DEBUG" ] && [ "$level" = debug ] && return
|
||||
shift
|
||||
|
||||
[ -n "$init" ] && echo "$@" >&2
|
||||
logger $stderr -p "$facility.$level" -t "${tag}[$$]" "$@"
|
||||
case "$level" in
|
||||
crit|alert|emerg) exit 1 ;;
|
||||
esac
|
||||
[ -n "$init" ] && echo "$@" >&2
|
||||
logger $stderr -p "$facility.$level" -t "${tag}[$$]" "$@"
|
||||
case "$level" in
|
||||
crit|alert|emerg) exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# usage: replace_word <search> <replace> <list>...
|
||||
replace_word() {
|
||||
local search="$1" replace="$2"
|
||||
shift 2
|
||||
for word in "$@"; do
|
||||
if [ "$word" = "$search" ]; then
|
||||
echo "$replace"
|
||||
else
|
||||
echo "$word"
|
||||
fi
|
||||
done
|
||||
local search="$1" replace="$2"
|
||||
shift 2
|
||||
for word in "$@"; do
|
||||
if [ "$word" = "$search" ]; then
|
||||
echo "$replace"
|
||||
else
|
||||
echo "$word"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# usage: insert_after <where> <what> <list>...
|
||||
insert_after() {
|
||||
local search="$1" addition="$2"
|
||||
shift 2
|
||||
for i in "$@"; do
|
||||
echo "$i"
|
||||
if [ "$i" = "$search" ]; then
|
||||
echo "$addition"
|
||||
fi
|
||||
done
|
||||
local search="$1" addition="$2"
|
||||
shift 2
|
||||
for i in "$@"; do
|
||||
echo "$i"
|
||||
if [ "$i" = "$search" ]; then
|
||||
echo "$addition"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# usage: add_once <file> <line-to-add>...
|
||||
add_once() {
|
||||
local file="$1"
|
||||
shift
|
||||
for line; do
|
||||
if ! grep -x -F "$line" "$file" 2>/dev/null; then
|
||||
mkdir -p "${file%/*}"
|
||||
printf "%s\n" "$line" >> "$file"
|
||||
fi
|
||||
done
|
||||
local file="$1"
|
||||
shift
|
||||
for line; do
|
||||
if ! grep -x -F "$line" "$file" 2>/dev/null; then
|
||||
mkdir -p "${file%/*}"
|
||||
printf "%s\n" "$line" >> "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Tiny Cloud - Init Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# set defaults
|
||||
@ -12,18 +12,18 @@
|
||||
### default phase actions (without leading 'init__')
|
||||
|
||||
DEFAULT_ACTIONS_EARLY="
|
||||
expand_root
|
||||
install_hotplugs
|
||||
set_default_interfaces
|
||||
create_default_user
|
||||
enable_sshd
|
||||
expand_root
|
||||
install_hotplugs
|
||||
set_default_interfaces
|
||||
create_default_user
|
||||
enable_sshd
|
||||
"
|
||||
DEFAULT_ACTIONS_NET="
|
||||
save_userdata
|
||||
save_userdata
|
||||
"
|
||||
DEFAULT_ACTIONS_MAIN="
|
||||
set_hostname
|
||||
set_ssh_keys
|
||||
set_hostname
|
||||
set_ssh_keys
|
||||
"
|
||||
DEFAULT_ACTIONS_FINAL=""
|
||||
|
||||
@ -40,236 +40,236 @@ DEFAULT_ACTIONS_FINAL=""
|
||||
### standard init-early functions...
|
||||
|
||||
init__expand_root() {
|
||||
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts 2>/dev/null)
|
||||
local filesystem=$(awk '$2 == "/" {print $3}' "$ROOT"/proc/mounts 2>/dev/null)
|
||||
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
|
||||
local dev=$(awk '$2 == "/" {print $1}' "$ROOT"/proc/mounts 2>/dev/null)
|
||||
local filesystem=$(awk '$2 == "/" {print $3}' "$ROOT"/proc/mounts 2>/dev/null)
|
||||
local partition=$(cat "$ROOT/sys/class/block/${dev#/dev/}/partition" 2>/dev/null)
|
||||
|
||||
# only support ext2/ext3/ext4 for now
|
||||
case "$filesystem" in
|
||||
ext*) ;;
|
||||
*) return;;
|
||||
esac
|
||||
# only support ext2/ext3/ext4 for now
|
||||
case "$filesystem" in
|
||||
ext*) ;;
|
||||
*) return;;
|
||||
esac
|
||||
|
||||
if [ -n "$partition" ]; then
|
||||
# it's a partition, resize it
|
||||
local volume=$(readlink -f "$ROOT/sys/class/block/${dev#/dev/}/..")
|
||||
volume="/dev/${volume##*/}"
|
||||
echo ", +" | $MOCK sfdisk -q --no-reread -N "$partition" "$volume"
|
||||
$MOCK partx -u "$volume"
|
||||
fi
|
||||
# resize filesystem
|
||||
$MOCK resize2fs "$dev"
|
||||
if [ -n "$partition" ]; then
|
||||
# it's a partition, resize it
|
||||
local volume=$(readlink -f "$ROOT/sys/class/block/${dev#/dev/}/..")
|
||||
volume="/dev/${volume##*/}"
|
||||
echo ", +" | $MOCK sfdisk -q --no-reread -N "$partition" "$volume"
|
||||
$MOCK partx -u "$volume"
|
||||
fi
|
||||
# resize filesystem
|
||||
$MOCK resize2fs "$dev"
|
||||
}
|
||||
|
||||
init__install_hotplugs() {
|
||||
local level result rc=0
|
||||
local level result rc=0
|
||||
|
||||
[ ! -n "$HOTPLUG_MODULES" ] && return
|
||||
if [ -f "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE" ]; then
|
||||
. "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE"
|
||||
fi
|
||||
[ ! -n "$HOTPLUG_MODULES" ] && return
|
||||
if [ -f "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE" ]; then
|
||||
. "$LIBDIR/tiny-cloud/$HOTPLUG_TYPE"
|
||||
fi
|
||||
|
||||
for module in $HOTPLUG_MODULES; do
|
||||
result='unknown'
|
||||
level='err'
|
||||
printf " >> " >&2
|
||||
log -i -t "$phase/$ACTION" info "$module: installing"
|
||||
if type "mod__$module" | grep -q -w "function"; then
|
||||
if "mod__$module"; then
|
||||
result='installed'
|
||||
level='info'
|
||||
else
|
||||
result='failed'
|
||||
rc=1
|
||||
fi
|
||||
fi
|
||||
printf " >> " >&2
|
||||
log -i -t "$phase/$ACTION" info "$module: $result"
|
||||
done
|
||||
return $rc
|
||||
for module in $HOTPLUG_MODULES; do
|
||||
result='unknown'
|
||||
level='err'
|
||||
printf " >> " >&2
|
||||
log -i -t "$phase/$ACTION" info "$module: installing"
|
||||
if type "mod__$module" | grep -q -w "function"; then
|
||||
if "mod__$module"; then
|
||||
result='installed'
|
||||
level='info'
|
||||
else
|
||||
result='failed'
|
||||
rc=1
|
||||
fi
|
||||
fi
|
||||
printf " >> " >&2
|
||||
log -i -t "$phase/$ACTION" info "$module: $result"
|
||||
done
|
||||
return $rc
|
||||
}
|
||||
|
||||
# collect ethernet interfaces, sorted by index
|
||||
ethernets() {
|
||||
for i in "$ROOT/sys/class/net/"*; do
|
||||
local iface="${i##*/}"
|
||||
case "$iface" in
|
||||
eth*) echo "$(cat "$i/ifindex") $iface";;
|
||||
esac
|
||||
done | sort -n | awk '{print $2}'
|
||||
for i in "$ROOT/sys/class/net/"*; do
|
||||
local iface="${i##*/}"
|
||||
case "$iface" in
|
||||
eth*) echo "$(cat "$i/ifindex") $iface";;
|
||||
esac
|
||||
done | sort -n | awk '{print $2}'
|
||||
}
|
||||
|
||||
# find the interface that is has operstate up
|
||||
find_first_interface_up() {
|
||||
local n=0
|
||||
[ $# -eq 0 ] && return
|
||||
while [ $n -le ${TINY_CLOUD_LINK_WAIT_MAX:-10} ]; do
|
||||
for i in "$@"; do
|
||||
if [ "$(cat "$ROOT/sys/class/net/$i/operstate")" = "up" ]; then
|
||||
echo "$i"
|
||||
return
|
||||
fi
|
||||
done
|
||||
sleep 0.1
|
||||
n=$((n+1))
|
||||
done
|
||||
local n=0
|
||||
[ $# -eq 0 ] && return
|
||||
while [ $n -le ${TINY_CLOUD_LINK_WAIT_MAX:-10} ]; do
|
||||
for i in "$@"; do
|
||||
if [ "$(cat "$ROOT/sys/class/net/$i/operstate")" = "up" ]; then
|
||||
echo "$i"
|
||||
return
|
||||
fi
|
||||
done
|
||||
sleep 0.1
|
||||
n=$((n+1))
|
||||
done
|
||||
}
|
||||
|
||||
# auto detect which network interface to auto configure
|
||||
# check which is connected or fallback to first
|
||||
# This will set link to down to all eth* except the found
|
||||
auto_detect_ethernet_interface() {
|
||||
local ifaces="$(ethernets)"
|
||||
[ -z "$ifaces" ] && return
|
||||
local ifaces="$(ethernets)"
|
||||
[ -z "$ifaces" ] && return
|
||||
|
||||
# find first connected interface
|
||||
for i in $ifaces; do
|
||||
$MOCK ip link set dev $i up >/dev/null
|
||||
done
|
||||
local iface="$(find_first_interface_up $ifaces)"
|
||||
# find first connected interface
|
||||
for i in $ifaces; do
|
||||
$MOCK ip link set dev $i up >/dev/null
|
||||
done
|
||||
local iface="$(find_first_interface_up $ifaces)"
|
||||
|
||||
# use first if all are disconnected
|
||||
if [ -z "$iface" ]; then
|
||||
set -- $ifaces
|
||||
iface="$1"
|
||||
fi
|
||||
# use first if all are disconnected
|
||||
if [ -z "$iface" ]; then
|
||||
set -- $ifaces
|
||||
iface="$1"
|
||||
fi
|
||||
|
||||
# we will use the found interface later so lets keep it up
|
||||
for i in $ifaces; do
|
||||
if [ "$i" != "$iface" ]; then
|
||||
$MOCK ip link set dev $i down >/dev/null
|
||||
fi
|
||||
done
|
||||
echo "$iface"
|
||||
# we will use the found interface later so lets keep it up
|
||||
for i in $ifaces; do
|
||||
if [ "$i" != "$iface" ]; then
|
||||
$MOCK ip link set dev $i down >/dev/null
|
||||
fi
|
||||
done
|
||||
echo "$iface"
|
||||
}
|
||||
|
||||
init__set_default_interfaces() {
|
||||
if [ -f "$ROOT"/etc/network/interfaces ]; then
|
||||
log -i -t "$phase" info "$ACTION: already set up"
|
||||
return
|
||||
fi
|
||||
if [ -f "$ROOT"/etc/network/interfaces ]; then
|
||||
log -i -t "$phase" info "$ACTION: already set up"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "$ROOT/etc/network"
|
||||
printf "%s\n%s\n\n" \
|
||||
"auto lo" \
|
||||
"iface lo inet loopback" \
|
||||
> "$ROOT/etc/network/interfaces"
|
||||
mkdir -p "$ROOT/etc/network"
|
||||
printf "%s\n%s\n\n" \
|
||||
"auto lo" \
|
||||
"iface lo inet loopback" \
|
||||
> "$ROOT/etc/network/interfaces"
|
||||
|
||||
local iface="$(auto_detect_ethernet_interface)"
|
||||
if [ -z "$iface" ]; then
|
||||
# TODO: message/log?
|
||||
return
|
||||
fi
|
||||
printf "%s\n%s\n\t%s\n\n" \
|
||||
"auto $iface" \
|
||||
"iface $iface" \
|
||||
"use dhcp" >> "$ROOT/etc/network/interfaces"
|
||||
local iface="$(auto_detect_ethernet_interface)"
|
||||
if [ -z "$iface" ]; then
|
||||
# TODO: message/log?
|
||||
return
|
||||
fi
|
||||
printf "%s\n%s\n\t%s\n\n" \
|
||||
"auto $iface" \
|
||||
"iface $iface" \
|
||||
"use dhcp" >> "$ROOT/etc/network/interfaces"
|
||||
}
|
||||
|
||||
init__create_default_user() {
|
||||
local user="$CLOUD_USER"
|
||||
# don't do anything if it already exists
|
||||
if getent passwd "$user" >/dev/null; then
|
||||
log -i -t "$phase" info "$ACTION: already exists"
|
||||
return
|
||||
fi
|
||||
local user="$CLOUD_USER"
|
||||
# don't do anything if it already exists
|
||||
if getent passwd "$user" >/dev/null; then
|
||||
log -i -t "$phase" info "$ACTION: already exists"
|
||||
return
|
||||
fi
|
||||
|
||||
$MOCK addgroup "$user"
|
||||
$MOCK adduser -h "/home/$user" -s /bin/sh -G "$user" -D "$user"
|
||||
$MOCK addgroup "$user" wheel
|
||||
echo "$user:*" | $MOCK chpasswd -e
|
||||
$MOCK addgroup "$user"
|
||||
$MOCK adduser -h "/home/$user" -s /bin/sh -G "$user" -D "$user"
|
||||
$MOCK addgroup "$user" wheel
|
||||
echo "$user:*" | $MOCK chpasswd -e
|
||||
|
||||
# setup sudo and/or doas
|
||||
if [ -d "$ROOT/etc/sudoers.d" ]; then
|
||||
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > "$ROOT/etc/sudoers.d/wheel"
|
||||
fi
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
echo 'permit nopass :wheel' > "$TARGET/etc/doas.d/wheel.conf"
|
||||
fi
|
||||
# setup sudo and/or doas
|
||||
if [ -d "$ROOT/etc/sudoers.d" ]; then
|
||||
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > "$ROOT/etc/sudoers.d/wheel"
|
||||
fi
|
||||
if [ -d "$ROOT/etc/doas.d" ]; then
|
||||
echo 'permit nopass :wheel' > "$TARGET/etc/doas.d/wheel.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
init__enable_sshd() {
|
||||
$MOCK rc-update add sshd default
|
||||
# in case something else has enabled/disabled dservices
|
||||
$MOCK rc-update --update
|
||||
$MOCK rc-update add sshd default
|
||||
# in case something else has enabled/disabled dservices
|
||||
$MOCK rc-update --update
|
||||
}
|
||||
|
||||
|
||||
### standard init-main functions
|
||||
|
||||
init__set_hostname() {
|
||||
local fqdn=$(imds @hostname)
|
||||
if [ -z "$fqdn" ]; then
|
||||
log -i -t "$phase" info "$ACTION: no hostname set"
|
||||
return
|
||||
fi
|
||||
local fqdn=$(imds @hostname)
|
||||
if [ -z "$fqdn" ]; then
|
||||
log -i -t "$phase" info "$ACTION: no hostname set"
|
||||
return
|
||||
fi
|
||||
|
||||
local host="${fqdn%%\.*}"
|
||||
if [ -z "$host" ]; then
|
||||
log -i -t "$phase" warn "$ACTION: invalid hostname '$fqdn'"
|
||||
return 1
|
||||
fi
|
||||
local host="${fqdn%%\.*}"
|
||||
if [ -z "$host" ]; then
|
||||
log -i -t "$phase" warn "$ACTION: invalid hostname '$fqdn'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$ROOT"/etc
|
||||
echo "$host" > "$ROOT"/etc/hostname
|
||||
$MOCK hostname -F "$ROOT"/etc/hostname
|
||||
echo -e "127.0.1.1\t$fqdn $host" >> "$ROOT"/etc/hosts
|
||||
mkdir -p "$ROOT"/etc
|
||||
echo "$host" > "$ROOT"/etc/hostname
|
||||
$MOCK hostname -F "$ROOT"/etc/hostname
|
||||
echo -e "127.0.1.1\t$fqdn $host" >> "$ROOT"/etc/hosts
|
||||
}
|
||||
|
||||
init__set_ssh_keys() {
|
||||
local sshkeys="$(imds @ssh-keys)"
|
||||
if [ -z "$sshkeys" ]; then
|
||||
log -i -t "$phase" info "$ACTION: no ssh key found"
|
||||
return
|
||||
fi
|
||||
local user="$CLOUD_USER"
|
||||
local pwent="$(getent passwd "$user")"
|
||||
if [ -z "$pwent" ]; then
|
||||
log -i -t "$phase" err "$ACTION: failed to find user $user"
|
||||
return 1
|
||||
fi
|
||||
local group=$(echo "$pwent" | cut -d: -f4)
|
||||
local ssh_dir="${ROOT}$(echo "$pwent" | cut -d: -f6)/.ssh"
|
||||
local keys_file="$ssh_dir/authorized_keys"
|
||||
local sshkeys="$(imds @ssh-keys)"
|
||||
if [ -z "$sshkeys" ]; then
|
||||
log -i -t "$phase" info "$ACTION: no ssh key found"
|
||||
return
|
||||
fi
|
||||
local user="$CLOUD_USER"
|
||||
local pwent="$(getent passwd "$user")"
|
||||
if [ -z "$pwent" ]; then
|
||||
log -i -t "$phase" err "$ACTION: failed to find user $user"
|
||||
return 1
|
||||
fi
|
||||
local group=$(echo "$pwent" | cut -d: -f4)
|
||||
local ssh_dir="${ROOT}$(echo "$pwent" | cut -d: -f6)/.ssh"
|
||||
local keys_file="$ssh_dir/authorized_keys"
|
||||
|
||||
if [ ! -d "$ssh_dir" ]; then
|
||||
mkdir -p "$ssh_dir"
|
||||
chmod 700 "$ssh_dir"
|
||||
fi
|
||||
if [ ! -d "$ssh_dir" ]; then
|
||||
mkdir -p "$ssh_dir"
|
||||
chmod 700 "$ssh_dir"
|
||||
fi
|
||||
|
||||
touch "$keys_file"
|
||||
chmod 600 "$keys_file"
|
||||
$MOCK chown -R "$user:$group" "$ssh_dir"
|
||||
echo "$sshkeys" > "$keys_file"
|
||||
touch "$keys_file"
|
||||
chmod 600 "$keys_file"
|
||||
$MOCK chown -R "$user:$group" "$ssh_dir"
|
||||
echo "$sshkeys" > "$keys_file"
|
||||
}
|
||||
|
||||
init__save_userdata() {
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
if [ -f "$userdata" ]; then
|
||||
log -i -t "$phase" info "$ACTION: user-data already saved"
|
||||
return
|
||||
fi
|
||||
local tmpfile=$(mktemp "$userdata.XXXXXX")
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
if [ -f "$userdata" ]; then
|
||||
log -i -t "$phase" info "$ACTION: user-data already saved"
|
||||
return
|
||||
fi
|
||||
local tmpfile=$(mktemp "$userdata.XXXXXX")
|
||||
|
||||
imds -e @userdata > "$tmpfile"
|
||||
if printf '\037\213\010' | cmp -s -n 3 "$tmpfile"; then
|
||||
gzip -dc "$tmpfile" > "$userdata"
|
||||
elif printf 'BZh' | cmp -s -n 3 "$tmpfile"; then
|
||||
bzip2 -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\375\067\172\130\132\000' | cmp -s -n 6 "$tmpfile"; then
|
||||
unxz -c "$tmpfile" > "$userdata"
|
||||
elif printf '\135\000\000' | cmp -s -n 3 "$tmpfile"; then
|
||||
lzma -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\211\114\132' | cmp -s -n 3 "$tmpfile"; then
|
||||
lzop -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\004\042\115\030' | cmp -s -n 4 "$tmpfile"; then
|
||||
lz4 -dc "$tmpfile" > "$userdata"
|
||||
elif printf '(\265/\375' | cmp -s -n 4 "$tmpfile"; then
|
||||
zstd -dc "$tmpfile" > "$userdata"
|
||||
else
|
||||
cp "$tmpfile" "$userdata"
|
||||
fi
|
||||
rm "$tmpfile"
|
||||
imds -e @userdata > "$tmpfile"
|
||||
if printf '\037\213\010' | cmp -s -n 3 "$tmpfile"; then
|
||||
gzip -dc "$tmpfile" > "$userdata"
|
||||
elif printf 'BZh' | cmp -s -n 3 "$tmpfile"; then
|
||||
bzip2 -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\375\067\172\130\132\000' | cmp -s -n 6 "$tmpfile"; then
|
||||
unxz -c "$tmpfile" > "$userdata"
|
||||
elif printf '\135\000\000' | cmp -s -n 3 "$tmpfile"; then
|
||||
lzma -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\211\114\132' | cmp -s -n 3 "$tmpfile"; then
|
||||
lzop -dc "$tmpfile" > "$userdata"
|
||||
elif printf '\004\042\115\030' | cmp -s -n 4 "$tmpfile"; then
|
||||
lz4 -dc "$tmpfile" > "$userdata"
|
||||
elif printf '(\265/\375' | cmp -s -n 4 "$tmpfile"; then
|
||||
zstd -dc "$tmpfile" > "$userdata"
|
||||
else
|
||||
cp "$tmpfile" "$userdata"
|
||||
fi
|
||||
rm "$tmpfile"
|
||||
}
|
||||
|
||||
|
||||
@ -279,26 +279,26 @@ init__save_userdata() {
|
||||
### load cloud-specific init functions / vars (potentially overriding)
|
||||
|
||||
if [ -f "$LIBDIR/tiny-cloud/cloud/$CLOUD/init" ]; then
|
||||
. "$LIBDIR/tiny-cloud/cloud/$CLOUD/init"
|
||||
. "$LIBDIR/tiny-cloud/cloud/$CLOUD/init"
|
||||
fi
|
||||
|
||||
|
||||
### load user-data type-specific init functions / vars (potentially overriding)
|
||||
|
||||
userdata_type() {
|
||||
if [ ! -f "$TINY_CLOUD_VAR/user-data" ]; then
|
||||
echo missing
|
||||
return
|
||||
fi
|
||||
header=$(head -n1 "$TINY_CLOUD_VAR/user-data" | sed -e 's/[[:space:]].*//g')
|
||||
case "$header" in
|
||||
'#!'*) echo script;;
|
||||
'#'*) echo ${header#\#};;
|
||||
*) echo unknown;;
|
||||
esac
|
||||
if [ ! -f "$TINY_CLOUD_VAR/user-data" ]; then
|
||||
echo missing
|
||||
return
|
||||
fi
|
||||
header=$(head -n1 "$TINY_CLOUD_VAR/user-data" | sed -e 's/[[:space:]].*//g')
|
||||
case "$header" in
|
||||
'#!'*) echo script;;
|
||||
'#'*) echo ${header#\#};;
|
||||
*) echo unknown;;
|
||||
esac
|
||||
}
|
||||
|
||||
USERDATA_TYPE="$(userdata_type)"
|
||||
if [ -f "$LIBDIR/tiny-cloud/user-data/$USERDATA_TYPE" ]; then
|
||||
. "$LIBDIR/tiny-cloud/user-data/$USERDATA_TYPE"
|
||||
. "$LIBDIR/tiny-cloud/user-data/$USERDATA_TYPE"
|
||||
fi
|
||||
|
||||
@ -1,36 +1,36 @@
|
||||
# Tiny Cloud - mdev hotplug functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# generic helper function to install mdev rules
|
||||
install_before() {
|
||||
local before="$1"
|
||||
shift
|
||||
local line="$*"
|
||||
local before="$1"
|
||||
shift
|
||||
local line="$*"
|
||||
|
||||
# already installed
|
||||
fgrep -q "$line" /etc/mdev.conf && return 0
|
||||
# already installed
|
||||
fgrep -q "$line" /etc/mdev.conf && return 0
|
||||
|
||||
if grep -q "$before" /etc/mdev.conf; then
|
||||
# install before existing rule
|
||||
line="-$line"
|
||||
else
|
||||
# no rule exists, put it before the catch-all fallback
|
||||
before="^# fallback"
|
||||
line="$line\n"
|
||||
fi
|
||||
sed -i -Ee "s|($before.*)|$line\n\1|" /etc/mdev.conf
|
||||
if grep -q "$before" /etc/mdev.conf; then
|
||||
# install before existing rule
|
||||
line="-$line"
|
||||
else
|
||||
# no rule exists, put it before the catch-all fallback
|
||||
before="^# fallback"
|
||||
line="$line\n"
|
||||
fi
|
||||
sed -i -Ee "s|($before.*)|$line\n\1|" /etc/mdev.conf
|
||||
}
|
||||
|
||||
# hotpluggable VNICs (multi-cloud)
|
||||
mod__vnic_eth_hotplug() {
|
||||
[ -f /lib/mdev/vnic-eth-hotplug ] || return 1
|
||||
[ -f /lib/mdev/vnic-eth-hotplug ] || return 1
|
||||
|
||||
install_before "^eth" \
|
||||
"eth[0-9] root:root 0644 */lib/mdev/vnic-eth-hotplug"
|
||||
install_before "^eth" \
|
||||
"eth[0-9] root:root 0644 */lib/mdev/vnic-eth-hotplug"
|
||||
|
||||
# NICs attached at launch don't get added with mdev -s
|
||||
assemble-interfaces
|
||||
# NICs attached at launch don't get added with mdev -s
|
||||
assemble-interfaces
|
||||
}
|
||||
|
||||
# load cloud-specific functions
|
||||
|
||||
@ -1,117 +1,117 @@
|
||||
# Script UserData Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
INIT_ACTIONS_MAIN="$(insert_after set_hostname \
|
||||
"userdata_bootcmd userdata_write_files userdata_ntp userdata_apk_cache userdata_apk_repositories userdata_packages" \
|
||||
$INIT_ACTIONS_MAIN)"
|
||||
"userdata_bootcmd userdata_write_files userdata_ntp userdata_apk_cache userdata_apk_repositories userdata_packages" \
|
||||
$INIT_ACTIONS_MAIN)"
|
||||
INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_runcmd"
|
||||
|
||||
get_userdata() {
|
||||
IFS="/"
|
||||
yx -f "$TINY_CLOUD_VAR/user-data" $1 2>/dev/null
|
||||
unset IFS
|
||||
IFS="/"
|
||||
yx -f "$TINY_CLOUD_VAR/user-data" $1 2>/dev/null
|
||||
unset IFS
|
||||
}
|
||||
|
||||
init__userdata_bootcmd() {
|
||||
# run bootcmd
|
||||
local bootcmds="$(get_userdata bootcmd)"
|
||||
for i in $bootcmds; do
|
||||
local cmd="$(get_userdata bootcmd/"$i")"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
# run bootcmd
|
||||
local bootcmds="$(get_userdata bootcmd)"
|
||||
for i in $bootcmds; do
|
||||
local cmd="$(get_userdata bootcmd/"$i")"
|
||||
sh -c "$cmd"
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_ntp() {
|
||||
local ntp_enabled="$(get_userdata ntp/enabled)"
|
||||
if [ "$ntp_enabled" != "yes" ] && [ "$ntp_enabled" != "true" ]; then
|
||||
return
|
||||
fi
|
||||
local ntp_client="$(get_userdata ntp/ntp_client)"
|
||||
local svc= pkg=
|
||||
case "$ntp_client" in
|
||||
busybox)
|
||||
svc=ntpd
|
||||
;;
|
||||
chrony|"")
|
||||
pkg=chrony
|
||||
svc=chronyd
|
||||
;;
|
||||
openntpd)
|
||||
pkg=openntpd
|
||||
svc=openntpd
|
||||
;;
|
||||
esac
|
||||
if [ -n "$pkg" ]; then
|
||||
$MOCK apk add "$pkg"
|
||||
fi
|
||||
if [ -n "$svc" ]; then
|
||||
$MOCK rc-update add "$svc" default
|
||||
$MOCK rc-service "$svc" start
|
||||
fi
|
||||
local ntp_enabled="$(get_userdata ntp/enabled)"
|
||||
if [ "$ntp_enabled" != "yes" ] && [ "$ntp_enabled" != "true" ]; then
|
||||
return
|
||||
fi
|
||||
local ntp_client="$(get_userdata ntp/ntp_client)"
|
||||
local svc= pkg=
|
||||
case "$ntp_client" in
|
||||
busybox)
|
||||
svc=ntpd
|
||||
;;
|
||||
chrony|"")
|
||||
pkg=chrony
|
||||
svc=chronyd
|
||||
;;
|
||||
openntpd)
|
||||
pkg=openntpd
|
||||
svc=openntpd
|
||||
;;
|
||||
esac
|
||||
if [ -n "$pkg" ]; then
|
||||
$MOCK apk add "$pkg"
|
||||
fi
|
||||
if [ -n "$svc" ]; then
|
||||
$MOCK rc-update add "$svc" default
|
||||
$MOCK rc-service "$svc" start
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_apk_cache() {
|
||||
local cache="$(get_userdata apk/cache)"
|
||||
if [ -z "$cache" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "$ROOT/$cache"
|
||||
# make link relative
|
||||
case "$cache" in
|
||||
/*) cache="../..$cache";;
|
||||
esac
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
ln -sf "$cache" "$ROOT"/etc/apk/cache
|
||||
local cache="$(get_userdata apk/cache)"
|
||||
if [ -z "$cache" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "$ROOT/$cache"
|
||||
# make link relative
|
||||
case "$cache" in
|
||||
/*) cache="../..$cache";;
|
||||
esac
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
ln -sf "$cache" "$ROOT"/etc/apk/cache
|
||||
}
|
||||
|
||||
init__userdata_apk_cache() {
|
||||
local cache="$(get_userdata apk/cache)"
|
||||
if [ -z "$cache" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "$ROOT/$cache"
|
||||
# make link relative
|
||||
case "$cache" in
|
||||
/*) cache="../..$cache";;
|
||||
esac
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
ln -sf "$cache" "$ROOT"/etc/apk/cache
|
||||
local cache="$(get_userdata apk/cache)"
|
||||
if [ -z "$cache" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "$ROOT/$cache"
|
||||
# make link relative
|
||||
case "$cache" in
|
||||
/*) cache="../..$cache";;
|
||||
esac
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
ln -sf "$cache" "$ROOT"/etc/apk/cache
|
||||
}
|
||||
|
||||
init__userdata_apk_repositories() {
|
||||
local repositories="$(get_userdata apk/repositories)"
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
for r in $repositories; do
|
||||
local baseurl="$(get_userdata apk/repositories/$r/base_url)"
|
||||
local repos="$(get_userdata apk/repositories/$r/repos)"
|
||||
local version="$(get_userdata apk/repositories/$r/version)"
|
||||
if [ -z "$version" ]; then
|
||||
local version_id=$( . "$ROOT"/etc/os-release 2>/dev/null && echo "$VERSION_ID")
|
||||
case "$version_id" in
|
||||
edge*|*_alpha*) version="edge";;
|
||||
[0-9]*.[0-9]*.[0-9]*) version="v${version_id%.*}";;
|
||||
esac
|
||||
fi
|
||||
if [ -n "$version" ] && [ "$version" != "." ] && [ "$version" != "/" ]; then
|
||||
baseurl="${baseurl%/}/$version"
|
||||
fi
|
||||
for repo in $repos; do
|
||||
local uri="${baseurl%/}/$(get_userdata apk/repositories/$r/repos/$repo)"
|
||||
add_once "$ROOT"/etc/apk/repositories "$uri"
|
||||
done
|
||||
done
|
||||
local repositories="$(get_userdata apk/repositories)"
|
||||
mkdir -p "$ROOT"/etc/apk
|
||||
for r in $repositories; do
|
||||
local baseurl="$(get_userdata apk/repositories/$r/base_url)"
|
||||
local repos="$(get_userdata apk/repositories/$r/repos)"
|
||||
local version="$(get_userdata apk/repositories/$r/version)"
|
||||
if [ -z "$version" ]; then
|
||||
local version_id=$( . "$ROOT"/etc/os-release 2>/dev/null && echo "$VERSION_ID")
|
||||
case "$version_id" in
|
||||
edge*|*_alpha*) version="edge";;
|
||||
[0-9]*.[0-9]*.[0-9]*) version="v${version_id%.*}";;
|
||||
esac
|
||||
fi
|
||||
if [ -n "$version" ] && [ "$version" != "." ] && [ "$version" != "/" ]; then
|
||||
baseurl="${baseurl%/}/$version"
|
||||
fi
|
||||
for repo in $repos; do
|
||||
local uri="${baseurl%/}/$(get_userdata apk/repositories/$r/repos/$repo)"
|
||||
add_once "$ROOT"/etc/apk/repositories "$uri"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
init__userdata_packages() {
|
||||
local packages="$(get_userdata packages)"
|
||||
local pkgs=
|
||||
for i in $packages; do
|
||||
pkgs="$pkgs $(get_userdata packages/$i)"
|
||||
done
|
||||
if [ -n "$pkgs" ]; then
|
||||
$MOCK apk add $pkgs
|
||||
fi
|
||||
local packages="$(get_userdata packages)"
|
||||
local pkgs=
|
||||
for i in $packages; do
|
||||
pkgs="$pkgs $(get_userdata packages/$i)"
|
||||
done
|
||||
if [ -n "$pkgs" ]; then
|
||||
$MOCK apk add $pkgs
|
||||
fi
|
||||
}
|
||||
|
||||
init__userdata_runcmd() {
|
||||
@ -124,60 +124,60 @@ init__userdata_runcmd() {
|
||||
|
||||
# write_file <path> <mode> <owner> <encoding> <append>
|
||||
write_file() {
|
||||
# Defaults used are the same as for full cloud-init "spec":
|
||||
# https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files
|
||||
local path="$1"
|
||||
local mode="${2:-0644}"
|
||||
local owner="${3:-root:root}"
|
||||
local encoding="${4:-text/plain}"
|
||||
local append="${5:-false}"
|
||||
# Defaults used are the same as for full cloud-init "spec":
|
||||
# https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files
|
||||
local path="$1"
|
||||
local mode="${2:-0644}"
|
||||
local owner="${3:-root:root}"
|
||||
local encoding="${4:-text/plain}"
|
||||
local append="${5:-false}"
|
||||
|
||||
if [ "$append" != "true" ] && [ "$append" != "false" ]; then
|
||||
log err "append must be true or false"
|
||||
return
|
||||
fi
|
||||
if [ "$append" != "true" ] && [ "$append" != "false" ]; then
|
||||
log err "append must be true or false"
|
||||
return
|
||||
fi
|
||||
|
||||
local tmpfile="$(mktemp $TINY_CLOUD_VAR/user-data.write_files.XXXXXX)"
|
||||
local tmpfile="$(mktemp $TINY_CLOUD_VAR/user-data.write_files.XXXXXX)"
|
||||
|
||||
case "$encoding" in
|
||||
gzip|gz|gz+base64|gzip+base64|gz+b64|gzip+b64)
|
||||
base64 -d | gzip -d > "$tmpfile"
|
||||
;;
|
||||
base64|b64)
|
||||
base64 -d > "$tmpfile"
|
||||
;;
|
||||
text/plain)
|
||||
cat > "$tmpfile"
|
||||
;;
|
||||
esac
|
||||
case "$encoding" in
|
||||
gzip|gz|gz+base64|gzip+base64|gz+b64|gzip+b64)
|
||||
base64 -d | gzip -d > "$tmpfile"
|
||||
;;
|
||||
base64|b64)
|
||||
base64 -d > "$tmpfile"
|
||||
;;
|
||||
text/plain)
|
||||
cat > "$tmpfile"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$append" = "true" ]; then
|
||||
cat "$tmpfile" >> "$path"
|
||||
else
|
||||
cat "$tmpfile" > "$path"
|
||||
fi
|
||||
rm -f "$tmpfile"
|
||||
if [ "$append" = "true" ]; then
|
||||
cat "$tmpfile" >> "$path"
|
||||
else
|
||||
cat "$tmpfile" > "$path"
|
||||
fi
|
||||
rm -f "$tmpfile"
|
||||
|
||||
chmod "$mode" "$path"
|
||||
# mocked as we do not know which users we could use in testing
|
||||
# this way we can check the proper invocation at least
|
||||
$MOCK chown "$owner" "$path"
|
||||
chmod "$mode" "$path"
|
||||
# mocked as we do not know which users we could use in testing
|
||||
# this way we can check the proper invocation at least
|
||||
$MOCK chown "$owner" "$path"
|
||||
}
|
||||
|
||||
init__userdata_write_files() {
|
||||
local files="$(get_userdata write_files)"
|
||||
local files="$(get_userdata write_files)"
|
||||
|
||||
for i in $files; do
|
||||
local path="$(get_userdata write_files/$i/path)"
|
||||
if [ -z "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
for i in $files; do
|
||||
local path="$(get_userdata write_files/$i/path)"
|
||||
if [ -z "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$ROOT/$path")"
|
||||
get_userdata write_files/$i/content | write_file "$ROOT/$path" \
|
||||
"$(get_userdata write_files/$i/permissions)" \
|
||||
"$(get_userdata write_files/$i/owner)" \
|
||||
"$(get_userdata write_files/$i/encoding)" \
|
||||
"$(get_userdata write_files/$i/append)"
|
||||
done
|
||||
mkdir -p "$(dirname "$ROOT/$path")"
|
||||
get_userdata write_files/$i/content | write_file "$ROOT/$path" \
|
||||
"$(get_userdata write_files/$i/permissions)" \
|
||||
"$(get_userdata write_files/$i/owner)" \
|
||||
"$(get_userdata write_files/$i/encoding)" \
|
||||
"$(get_userdata write_files/$i/append)"
|
||||
done
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# CloudConfig UserData Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
# TODO
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
# Missing UserData Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
init__missing_userdata() {
|
||||
log -i -t "$phase" notice "$ACTION: no user-data found"
|
||||
log -i -t "$phase" notice "$ACTION: no user-data found"
|
||||
}
|
||||
|
||||
INIT_ACTIONS_MAIN="missing_userdata ${INIT_ACTIONS_MAIN}"
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
# Script UserData Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
init__run_userdata() {
|
||||
local log="$TINY_CLOUD_LOGS/user-data.log"
|
||||
local exit="$TINY_CLOUD_LOGS/user-data.exit"
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
local log="$TINY_CLOUD_LOGS/user-data.log"
|
||||
local exit="$TINY_CLOUD_LOGS/user-data.exit"
|
||||
local userdata="$TINY_CLOUD_VAR/user-data"
|
||||
|
||||
chmod u+x "$userdata"
|
||||
{ "$userdata" 2>& 1; echo $? > "$exit"; } | tee "$log"
|
||||
chmod u+x "$userdata"
|
||||
{ "$userdata" 2>& 1; echo $? > "$exit"; } | tee "$log"
|
||||
|
||||
return $(cat "$exit")
|
||||
return $(cat "$exit")
|
||||
}
|
||||
|
||||
# add init actions
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
# Unknown UserData Functions
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
# shellcheck shell=sh
|
||||
|
||||
init__unknown_userdata() {
|
||||
local type="$(userdata_type)"
|
||||
log -i -t "$phase" warn "$ACTION: unable to process '$type' user-data"
|
||||
local type="$(userdata_type)"
|
||||
log -i -t "$phase" warn "$ACTION: unable to process '$type' user-data"
|
||||
}
|
||||
|
||||
INIT_ACTIONS_MAIN="unknown_userdata ${INIT_ACTIONS_MAIN}"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=4 et:
|
||||
# vim:set ft=sh:
|
||||
|
||||
set -e
|
||||
|
||||
@ -10,33 +10,33 @@ cd "$IFACE_DIR"
|
||||
|
||||
cat > "$IFACE_CFG.new" <<EOT
|
||||
# NOTE: $0 rewrites this file. Edit files in
|
||||
# /etc/network/interfaces.d/ to persist any customizations.
|
||||
# /etc/network/interfaces.d/ to persist any customizations.
|
||||
|
||||
EOT
|
||||
|
||||
# existing loopback and eths
|
||||
for i in $ROOT/sys/class/net/*; do
|
||||
IFACE="$(basename "$i")"
|
||||
case $IFACE in
|
||||
lo|eth*)
|
||||
[ ! -f "$IFACE" ] && sed -e "s/%%/$IFACE/g" DEFAULT > "$IFACE"
|
||||
printf "%s\n\n" "$(cat "$IFACE")" >> "$IFACE_CFG.new"
|
||||
;;
|
||||
*) continue ;;
|
||||
esac
|
||||
IFACE="$(basename "$i")"
|
||||
case $IFACE in
|
||||
lo|eth*)
|
||||
[ ! -f "$IFACE" ] && sed -e "s/%%/$IFACE/g" DEFAULT > "$IFACE"
|
||||
printf "%s\n\n" "$(cat "$IFACE")" >> "$IFACE_CFG.new"
|
||||
;;
|
||||
*) continue ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# all the rest
|
||||
for i in "$IFACE_DIR"/*; do
|
||||
IFACE="$(basename "$i")"
|
||||
case $IFACE in
|
||||
DEFAULT|lo|eth*)
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
printf "%s\n\n" "$(cat "$IFACE")" >> "$IFACE_CFG.new"
|
||||
;;
|
||||
esac
|
||||
IFACE="$(basename "$i")"
|
||||
case $IFACE in
|
||||
DEFAULT|lo|eth*)
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
printf "%s\n\n" "$(cat "$IFACE")" >> "$IFACE_CFG.new"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# install new interfaces config
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim: ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
|
||||
# Sync interface's network configuration with IMDS
|
||||
|
||||
@ -21,129 +21,129 @@ let RTABLE+=10000
|
||||
|
||||
# ip [+F] [-4|-6] <object> <command> [<parameters>]
|
||||
ip() {
|
||||
local fail_ok v=-4 cmd level
|
||||
[ "$1" = '+F' ] && fail_ok=1 && shift
|
||||
if [ "$1" = '-4' ] || [ "$1" = '-6' ]; then
|
||||
v="$1"
|
||||
shift
|
||||
fi
|
||||
cmd="$2"
|
||||
[ "$cmd" = show ] && level=debug || level=info
|
||||
if /sbin/ip "$v" "$@" || [ -n "$fail_ok" ]; then
|
||||
log -s "$level" "OK: ip $v $*"
|
||||
else
|
||||
log -s err "FAIL: ip $v $*"
|
||||
fi
|
||||
local fail_ok v=-4 cmd level
|
||||
[ "$1" = '+F' ] && fail_ok=1 && shift
|
||||
if [ "$1" = '-4' ] || [ "$1" = '-6' ]; then
|
||||
v="$1"
|
||||
shift
|
||||
fi
|
||||
cmd="$2"
|
||||
[ "$cmd" = show ] && level=debug || level=info
|
||||
if /sbin/ip "$v" "$@" || [ -n "$fail_ok" ]; then
|
||||
log -s "$level" "OK: ip $v $*"
|
||||
else
|
||||
log -s err "FAIL: ip $v $*"
|
||||
fi
|
||||
}
|
||||
|
||||
# get secondary IPv4s currently on the interface
|
||||
iface_ip4s() {
|
||||
ip -4 addr show "$IFACE" secondary |
|
||||
sed -E -e '/inet /!d' -e 's/.*inet ([0-9.]+).*/\1/'
|
||||
ip -4 addr show "$IFACE" secondary |
|
||||
sed -E -e '/inet /!d' -e 's/.*inet ([0-9.]+).*/\1/'
|
||||
}
|
||||
|
||||
# get IPv6s currently on the interface
|
||||
iface_ip6s() {
|
||||
ip -6 addr show "$IFACE" scope global |
|
||||
sed -E -e '/inet6/!d' -e 's/.*inet6 ([0-9a-f:]+).*/\1/'
|
||||
ip -6 addr show "$IFACE" scope global |
|
||||
sed -E -e '/inet6/!d' -e 's/.*inet6 ([0-9a-f:]+).*/\1/'
|
||||
}
|
||||
|
||||
imds_ip4s() {
|
||||
local ip4=$(imds "@nic:$IFACE,@ipv4")
|
||||
local ip4s=$(echo "$ip4" | tail +2) # secondary IPv4s
|
||||
local ip4p ip4_cidr ip4_gw
|
||||
local ip4=$(imds "@nic:$IFACE,@ipv4")
|
||||
local ip4s=$(echo "$ip4" | tail +2) # secondary IPv4s
|
||||
local ip4p ip4_cidr ip4_gw
|
||||
|
||||
# non-eth0 interfaces need custom route tables
|
||||
#
|
||||
if [ "$IFACE" != eth0 ] && [ -n "$ip4s" ] &&
|
||||
[ -z $(ip +F -4 route show table "$RTABLE" 2>/dev/null) ]; then
|
||||
ip4p=$(echo "$ip4" | head -1) # primary IPv4
|
||||
ip4_cidr=$(imds "@nic:$IFACE,@ipv4-net") # TODO: get from iface instead?
|
||||
# TODO: this may not hold true for non-AWS clouds
|
||||
ip4_gw=$(echo "$ip4_cidr" | cut -d/ -f1 |
|
||||
awk -F. '{ print $1"."$2"."$3"."$4+1 }')
|
||||
ip -4 route add default via "$ip4_gw" dev "$IFACE" table "$RTABLE"
|
||||
ip -4 route add "$ip4_cidr" dev "$IFACE" proto kernel scope link \
|
||||
src "$ip4p" table "$RTABLE"
|
||||
fi
|
||||
echo "$ip4s"
|
||||
# non-eth0 interfaces need custom route tables
|
||||
#
|
||||
if [ "$IFACE" != eth0 ] && [ -n "$ip4s" ] &&
|
||||
[ -z $(ip +F -4 route show table "$RTABLE" 2>/dev/null) ]; then
|
||||
ip4p=$(echo "$ip4" | head -1) # primary IPv4
|
||||
ip4_cidr=$(imds "@nic:$IFACE,@ipv4-net") # TODO: get from iface instead?
|
||||
# TODO: this may not hold true for non-AWS clouds
|
||||
ip4_gw=$(echo "$ip4_cidr" | cut -d/ -f1 |
|
||||
awk -F. '{ print $1"."$2"."$3"."$4+1 }')
|
||||
ip -4 route add default via "$ip4_gw" dev "$IFACE" table "$RTABLE"
|
||||
ip -4 route add "$ip4_cidr" dev "$IFACE" proto kernel scope link \
|
||||
src "$ip4p" table "$RTABLE"
|
||||
fi
|
||||
echo "$ip4s"
|
||||
}
|
||||
|
||||
# TODO: 3.18+ when we use dhcpcd for ipv4 & ipv6, we only need to do secondary IPv6s
|
||||
# circle back and see how amazon-ec2-net-utils is handling everything these days
|
||||
imds_ip6s() {
|
||||
local ip6s gw tries=20
|
||||
ip6s=$(imds "@nic:$IFACE,@ipv6")
|
||||
local ip6s gw tries=20
|
||||
ip6s=$(imds "@nic:$IFACE,@ipv6")
|
||||
|
||||
# non-eth0 interfaces need custom route tables
|
||||
#
|
||||
# NOTE: busybox iproute2 doesn't do 'route show table' properly for IPv6,
|
||||
# so iproute2-minimal package is required!
|
||||
#
|
||||
if [ "$IFACE" != eth0 ] && [ -n "$ip6s" ] &&
|
||||
[ -z $(ip +F -6 route show table "$RTABLE" 2>/dev/null) ]; then
|
||||
while true; do
|
||||
gw=$(ip -6 route show dev "$IFACE" default | awk '{ print $3 }')
|
||||
[ -n "$gw" ] && break
|
||||
let tries--
|
||||
if [ "$tries" -eq 0 ]; then
|
||||
log -s warn "Unable to get IPv6 gateway RA after 10s"
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
ip -6 route add default via "$gw" dev "$IFACE" table "$RTABLE"
|
||||
# TODO? match imds_ip4s() with ip -6 route add "ip6_cidr" dev "$IFACE" ...
|
||||
fi
|
||||
echo "$ip6s"
|
||||
# non-eth0 interfaces need custom route tables
|
||||
#
|
||||
# NOTE: busybox iproute2 doesn't do 'route show table' properly for IPv6,
|
||||
# so iproute2-minimal package is required!
|
||||
#
|
||||
if [ "$IFACE" != eth0 ] && [ -n "$ip6s" ] &&
|
||||
[ -z $(ip +F -6 route show table "$RTABLE" 2>/dev/null) ]; then
|
||||
while true; do
|
||||
gw=$(ip -6 route show dev "$IFACE" default | awk '{ print $3 }')
|
||||
[ -n "$gw" ] && break
|
||||
let tries--
|
||||
if [ "$tries" -eq 0 ]; then
|
||||
log -s warn "Unable to get IPv6 gateway RA after 10s"
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
ip -6 route add default via "$gw" dev "$IFACE" table "$RTABLE"
|
||||
# TODO? match imds_ip4s() with ip -6 route add "ip6_cidr" dev "$IFACE" ...
|
||||
fi
|
||||
echo "$ip6s"
|
||||
}
|
||||
|
||||
in_list() {
|
||||
echo "$2" | grep -q "^$1$"
|
||||
echo "$2" | grep -q "^$1$"
|
||||
}
|
||||
|
||||
# ip_addr {4|6} {add|del} <ip>
|
||||
ip_addr() {
|
||||
local mask=32 # IPv4 always /32
|
||||
[ "$1" -eq 6 ] && mask=128 # IPv6 always /128
|
||||
ip -"$1" addr "$2" "$3/$mask" dev "$IFACE"
|
||||
local mask=32 # IPv4 always /32
|
||||
[ "$1" -eq 6 ] && mask=128 # IPv6 always /128
|
||||
ip -"$1" addr "$2" "$3/$mask" dev "$IFACE"
|
||||
|
||||
# TODO? delegated ipv[46] prefixes?
|
||||
# TODO? delegated ipv[46] prefixes?
|
||||
|
||||
# non-eth0 interfaces get rules associating IPs with route tables
|
||||
[ "$IFACE" = eth0 ] && return
|
||||
ip -"$1" rule "$2" from "$3" lookup "$RTABLE"
|
||||
ip -"$1" rule "$2" to "$3" lookup "$RTABLE"
|
||||
# non-eth0 interfaces get rules associating IPs with route tables
|
||||
[ "$IFACE" = eth0 ] && return
|
||||
ip -"$1" rule "$2" from "$3" lookup "$RTABLE"
|
||||
ip -"$1" rule "$2" to "$3" lookup "$RTABLE"
|
||||
}
|
||||
|
||||
# sync_ips {4|6} "<imds-ips>" "<iface-ips>"
|
||||
sync_ips() {
|
||||
local i
|
||||
# remove extra IPs
|
||||
for i in $3; do
|
||||
in_list "$i" "$2" || ip_addr "$1" del "$i"
|
||||
done
|
||||
# add missing IPs
|
||||
# NOTE: this adds an extra <IPv4>/32 for the primary IP
|
||||
for i in $2; do
|
||||
in_list "$i" "$3" || ip_addr "$1" add "$i"
|
||||
done
|
||||
local i
|
||||
# remove extra IPs
|
||||
for i in $3; do
|
||||
in_list "$i" "$2" || ip_addr "$1" del "$i"
|
||||
done
|
||||
# add missing IPs
|
||||
# NOTE: this adds an extra <IPv4>/32 for the primary IP
|
||||
for i in $2; do
|
||||
in_list "$i" "$3" || ip_addr "$1" add "$i"
|
||||
done
|
||||
}
|
||||
|
||||
imds_iface_sync() {
|
||||
log -s info "SYNCING: $IFACE"
|
||||
sync_ips 4 "$(imds_ip4s)" "$(iface_ip4s)"
|
||||
sync_ips 6 "$(imds_ip6s)" "$(iface_ip6s)"
|
||||
log -s info "FINISHED: $IFACE"
|
||||
log -s info "SYNCING: $IFACE"
|
||||
sync_ips 4 "$(imds_ip4s)" "$(iface_ip4s)"
|
||||
sync_ips 6 "$(imds_ip6s)" "$(iface_ip6s)"
|
||||
log -s info "FINISHED: $IFACE"
|
||||
}
|
||||
|
||||
case "$PHASE" in
|
||||
post-up)
|
||||
# TODO: daemonize this
|
||||
imds_iface_sync
|
||||
;;
|
||||
pre-down)
|
||||
# TODO: kill daemon, maybe some cleanup
|
||||
;;
|
||||
*)
|
||||
post-up)
|
||||
# TODO: daemonize this
|
||||
imds_iface_sync
|
||||
;;
|
||||
pre-down)
|
||||
# TODO: kill daemon, maybe some cleanup
|
||||
;;
|
||||
*)
|
||||
esac
|
||||
|
||||
140
sbin/tiny-cloud
140
sbin/tiny-cloud
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim:set ts=4 et ft=sh:
|
||||
# vim:set ft=sh:
|
||||
|
||||
# Tiny Cloud
|
||||
|
||||
@ -9,69 +9,69 @@ set -e
|
||||
. "$LIBDIR/tiny-cloud/common"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [-h | --help] { early | net | main | final | --bootstrap [complete|incomplete|status] | --setup }
|
||||
EOF
|
||||
cat <<-EOF
|
||||
Usage: ${0##*/} [-h | --help] { early | net | main | final | --bootstrap [complete|incomplete|status] | --setup }
|
||||
EOF
|
||||
}
|
||||
|
||||
bootstrap_complete() {
|
||||
touch "$TINY_CLOUD_VAR/.bootstrap-complete"
|
||||
touch "$TINY_CLOUD_VAR/.bootstrap-complete"
|
||||
}
|
||||
bootstrap_incomplete() {
|
||||
rm -f "$TINY_CLOUD_VAR/.bootstrap-complete"
|
||||
rm -f "$TINY_CLOUD_VAR/.bootstrap-complete"
|
||||
}
|
||||
is_bootstrap_complete() {
|
||||
[ -f "$TINY_CLOUD_VAR/.bootstrap-complete" ]
|
||||
[ -f "$TINY_CLOUD_VAR/.bootstrap-complete" ]
|
||||
}
|
||||
|
||||
args=$(getopt -o hsb: --long help,setup,bootstrap: -n ${0##*/} -- "$@") || { usage >&2; exit 1; }
|
||||
if [ $# -eq 0 ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-b|--bootstrap) shift
|
||||
case "$1" in
|
||||
complete) # indicate bootstrap is done
|
||||
bootstrap_complete
|
||||
log -i notice 'bootstrap marked complete';;
|
||||
incomplete) # indicate bootstrap isn't done
|
||||
bootstrap_incomplete
|
||||
log -i warn 'bootstrap marked incomplete';;
|
||||
status) is_bootstrap_complete && echo 'complete' || echo 'incomplete' ;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
exit 0;;
|
||||
-s|--setup) # just openrc for now
|
||||
for phase in -early -net '' -final; do
|
||||
rc-update -a del "tiny-cloud$phase" || true
|
||||
done
|
||||
rc-update add tiny-cloud-early boot
|
||||
rc-update add tiny-cloud-net default
|
||||
rc-update add tiny-cloud default
|
||||
rc-update add tiny-cloud-final default
|
||||
exit 0;;
|
||||
--) shift; break;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
shift
|
||||
case "$1" in
|
||||
-h|--help) usage; exit 0;;
|
||||
-b|--bootstrap) shift
|
||||
case "$1" in
|
||||
complete) # indicate bootstrap is done
|
||||
bootstrap_complete
|
||||
log -i notice 'bootstrap marked complete';;
|
||||
incomplete) # indicate bootstrap isn't done
|
||||
bootstrap_incomplete
|
||||
log -i warn 'bootstrap marked incomplete';;
|
||||
status) is_bootstrap_complete && echo 'complete' || echo 'incomplete' ;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
exit 0;;
|
||||
-s|--setup) # just openrc for now
|
||||
for phase in -early -net '' -final; do
|
||||
rc-update -a del "tiny-cloud$phase" || true
|
||||
done
|
||||
rc-update add tiny-cloud-early boot
|
||||
rc-update add tiny-cloud-net default
|
||||
rc-update add tiny-cloud default
|
||||
rc-update add tiny-cloud-final default
|
||||
exit 0;;
|
||||
--) shift; break;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
phase="$1"
|
||||
shift
|
||||
|
||||
case "$phase" in
|
||||
early|net|main|final) ;;
|
||||
*) usage >&2; exit 1;;
|
||||
early|net|main|final) ;;
|
||||
*) usage >&2; exit 1;;
|
||||
esac
|
||||
|
||||
# is initial bootstrap already done?
|
||||
if is_bootstrap_complete; then
|
||||
log -i -t "$phase" info "already bootstrapped"
|
||||
exit 0;
|
||||
log -i -t "$phase" info "already bootstrapped"
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
# load init functions
|
||||
@ -81,48 +81,48 @@ fi
|
||||
|
||||
# should we skip this action?
|
||||
skip_action() {
|
||||
local action="$1"
|
||||
for i in $SKIP_INIT_ACTIONS; do
|
||||
[ "$i" = "$action" ] && return 0
|
||||
done
|
||||
return 1
|
||||
local action="$1"
|
||||
for i in $SKIP_INIT_ACTIONS; do
|
||||
[ "$i" = "$action" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# mandatory final action...
|
||||
init__bootstrap_complete() {
|
||||
bootstrap_complete
|
||||
bootstrap_complete
|
||||
}
|
||||
INIT_ACTIONS_FINAL="${INIT_ACTIONS_FINAL} bootstrap_complete"
|
||||
|
||||
### let's do stuff!
|
||||
|
||||
case "$phase" in
|
||||
early) INIT_ACTIONS="$INIT_ACTIONS_EARLY";;
|
||||
net) INIT_ACTIONS="$INIT_ACTIONS_NET";;
|
||||
main) INIT_ACTIONS="$INIT_ACTIONS_MAIN";;
|
||||
final) INIT_ACTIONS="$INIT_ACTIONS_FINAL";;
|
||||
*) usage >&2; exit 1
|
||||
early) INIT_ACTIONS="$INIT_ACTIONS_EARLY";;
|
||||
net) INIT_ACTIONS="$INIT_ACTIONS_NET";;
|
||||
main) INIT_ACTIONS="$INIT_ACTIONS_MAIN";;
|
||||
final) INIT_ACTIONS="$INIT_ACTIONS_FINAL";;
|
||||
*) usage >&2; exit 1
|
||||
esac
|
||||
|
||||
printf '\n' >&2
|
||||
for ACTION in $INIT_ACTIONS; do
|
||||
if skip_action "$ACTION"; then
|
||||
printf ' -- ' >&2
|
||||
log -i -t "$phase" notice "$ACTION: skipped"
|
||||
continue
|
||||
fi
|
||||
printf ' ++ ' >&2
|
||||
log -i -t "$phase" info "$ACTION: starting"
|
||||
RESULT="unknown"
|
||||
LEVEL="err"
|
||||
if type "init__$ACTION" | grep -q -w "function"; then
|
||||
if "init__$ACTION" "$@"; then
|
||||
RESULT="done"
|
||||
LEVEL="info"
|
||||
else
|
||||
RESULT="failed"
|
||||
fi
|
||||
fi
|
||||
printf ' ++ ' >&2
|
||||
log -i -t "$phase" "$LEVEL" "$ACTION: $RESULT"
|
||||
if skip_action "$ACTION"; then
|
||||
printf ' -- ' >&2
|
||||
log -i -t "$phase" notice "$ACTION: skipped"
|
||||
continue
|
||||
fi
|
||||
printf ' ++ ' >&2
|
||||
log -i -t "$phase" info "$ACTION: starting"
|
||||
RESULT="unknown"
|
||||
LEVEL="err"
|
||||
if type "init__$ACTION" | grep -q -w "function"; then
|
||||
if "init__$ACTION" "$@"; then
|
||||
RESULT="done"
|
||||
LEVEL="info"
|
||||
else
|
||||
RESULT="failed"
|
||||
fi
|
||||
fi
|
||||
printf ' ++ ' >&2
|
||||
log -i -t "$phase" "$LEVEL" "$ACTION: $RESULT"
|
||||
done
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -2,27 +2,27 @@
|
||||
|
||||
prog=${0##*/}
|
||||
usage() {
|
||||
cat <<EOF
|
||||
usage: wget [-cqS] [--spider] [-O FILE] [-o LOGFILE] [--header STR]
|
||||
[--post-data STR | --post-file FILE] [-Y on/off]
|
||||
[-P DIR] [-U AGENT] [-T SEC] URL...
|
||||
cat <<-EOF
|
||||
usage: wget [-cqS] [--spider] [-O FILE] [-o LOGFILE] [--header STR]
|
||||
[--post-data STR | --post-file FILE] [-Y on/off]
|
||||
[-P DIR] [-U AGENT] [-T SEC] URL...
|
||||
|
||||
Retrieve files via HTTP or FTP
|
||||
Retrieve files via HTTP or FTP
|
||||
|
||||
--spider Only check URL existence: \$? is 0 if exists
|
||||
--header STR Add STR (of form 'header: value') to headers
|
||||
--post-data STR Send STR using POST method
|
||||
--post-file FILE Send FILE using POST method
|
||||
-c Continue retrieval of aborted transfer
|
||||
-q Quiet
|
||||
-P DIR Save to DIR (default .)
|
||||
-S Show server response
|
||||
-T SEC Network read timeout is SEC seconds
|
||||
-O FILE Save to FILE ('-' for stdout)
|
||||
-o LOGFILE Log messages to FILE
|
||||
-U STR Use STR for User-Agent header
|
||||
-Y on/off Use proxy
|
||||
EOF
|
||||
--spider Only check URL existence: \$? is 0 if exists
|
||||
--header STR Add STR (of form 'header: value') to headers
|
||||
--post-data STR Send STR using POST method
|
||||
--post-file FILE Send FILE using POST method
|
||||
-c Continue retrieval of aborted transfer
|
||||
-q Quiet
|
||||
-P DIR Save to DIR (default .)
|
||||
-S Show server response
|
||||
-T SEC Network read timeout is SEC seconds
|
||||
-O FILE Save to FILE ('-' for stdout)
|
||||
-o LOGFILE Log messages to FILE
|
||||
-U STR Use STR for User-Agent header
|
||||
-Y on/off Use proxy
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
# vim:set ft=sh
|
||||
# shellcheck shell=sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vim: set ts=8 noet:
|
||||
#!/bin/sh
|
||||
# vim:set ft=sh:
|
||||
|
||||
# Tiny Cloud IMDS ifupdown-ng executor
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user