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