Changeset View
Standalone View
sysutils/docker-freebsd/files/docker.in
#!/bin/sh | #!/bin/sh | ||||
# PROVIDE: docker | # PROVIDE: docker | ||||
# REQUIRE: DAEMON | # REQUIRE: DAEMON | ||||
# KEYWORD: nojail shutdown | # KEYWORD: nojail shutdown | ||||
. /etc/rc.subr | . /etc/rc.subr | ||||
name="docker" | name="docker" | ||||
rcvar="docker_enable" | rcvar="docker_enable" | ||||
startpre_cmd="docker_precmd" | |||||
stop_cmd="docker_stop" | stop_cmd="docker_stop" | ||||
start_cmd="docker_start" | start_cmd="docker_start" | ||||
command="%%PREFIX%%/bin/docker" | command="%%PREFIX%%/bin/docker" | ||||
load_rc_config $name | load_rc_config $name | ||||
: ${docker_enable=NO} | : ${docker_enable:=NO} | ||||
: ${docker_dir=/usr/docker} | : ${docker_dir:=/usr/docker} | ||||
: ${docker_nat_pf=YES} | : ${docker_nat_iface:=NONE} | ||||
: ${docker_nat_iface=NONE} | : ${docker_flags:=} | ||||
: ${docker_flags=} | : ${docker_log_file:=/var/log/docker.log} | ||||
: ${docker_zpool_name:=zroot} | |||||
: ${docker_zpool_file:=/usr/local/docker.img} | |||||
: ${docker_zpool_file_size:=4G} | |||||
: ${docker_zfs_name:=docker} | |||||
docker_start() | docker_precmd() | ||||
{ | { | ||||
if [ ! -d "${docker_dir}" ] ; then | local fs_type \ | ||||
echo "Missing ${docker_dir}! Please create / mount a ZFS dataset at this location." | make_zfs \ | ||||
exit 1 | zfs_mountpoint \ | ||||
fi | zfs_name \ | ||||
zpool_name \ | |||||
zpool_size \ | |||||
module | |||||
dteske: Initialization to NULL is required for all but module and for purposes of minimal diffs, prefer… | |||||
Done Inline ActionsWe should put "local" (without quotes) before each of these (non-blank) lines dteske: We should put "local" (without quotes) before each of these (non-blank) lines | |||||
if [ -e "/var/run/docker.pid" ] ; then | for module in zfs pf linux linux64; do | ||||
dteskeUnsubmitted Done Inline ActionsPreferred for minimal diffs: [tab]for module in \ dteske: Preferred for minimal diffs:
[tab]for module in \
[tab][tab]zfs \
[tab][tab]pf \
[tab]… | |||||
lifanovAuthorUnsubmitted Done Inline ActionsYou don't need a semicolon here if do is on the next line. lifanov: You don't need a semicolon here if do is on the next line. | |||||
dteskeUnsubmitted Not Done Inline ActionsThe reason why you should use: [tab][tab]linux64 \ Instead of: [tab][tab]linux64 Is because list management (e.g., sorting with sort, moving items manually for ordered operation, etc.) is possible when all the elements have a trailing backslash. By making the last element not have a trailing backslash, a future diff that appends a new item to the end will not just be a diff with a single "+" line but instead a "-" and "+" pair where the backslash had to be added to the now-previous last-line in the list. This also prevents mistakes. dteske: The reason why you should use:
[tab][tab]linux64 \
[tab]; do
Instead of:
[tab][tab]linux64… | |||||
pgrep -F /var/run/docker.pid 2>/dev/null >/dev/null | kldstat -qm $module || kldload $module || die | ||||
if [ $? -eq 0 ] ; then | done | ||||
echo "Docker already running? /var/run/docker.pid" | [ -d "$docker_dir" ] || mkdir -p "$docker_dir" | ||||
Done Inline ActionsWe'll want a "local module" (w/o quotes) at the top of the function (first line after curly) to localize the variable used here in the for-loop dteske: We'll want a "local module" (w/o quotes) at the top of the function (first line after curly) to… | |||||
exit 1 | |||||
fi | |||||
fi | |||||
echo "Starting docker..." | # | ||||
daemon -p /var/run/docker.pid ${command} -d -e jail -s zfs -g ${docker_dir} -D ${docker_flags} >/var/log/docker.log 2>/var/log/docker.log | # If ZFS filesystem is already mounted on $docker_dir, do nothing. | ||||
# If $docker_dir is inside existing ZFS filesystem, | |||||
# create new filesystem. | |||||
# | |||||
# Otherwise, create $docker_zpool_file to contain pool and filesystem. | |||||
# | |||||
fstype=$( df -T "$docker_dir" 2> /dev/null | awk 'NR>1,$0=$2' ) | |||||
case "$fstype" in | |||||
zfs) | |||||
zfs_mountpoint=$( zfs get -Ho value mountpoint "$docker_dir" ) | |||||
zfs_name=$( zfs get -Ho name mountpoint "$docker_dir" ) | |||||
[ "$docker_dir" = "$zfs_mountpoint" ] || make_zfs=filesystem | |||||
;; | |||||
*) | |||||
zfs_name="$docker_zpool_name" | |||||
make_zfs=pool | |||||
esac | |||||
zpool_name="${zfs_name%%/*}" | |||||
# Check for linux 64bit support and enable | # | ||||
kldstat | grep -q 'linux64' | # Setup ZFS pool if required | ||||
if [ $? -ne 0 -a -e "/boot/kernel/linux64.ko" ] ; then | # | ||||
kldload linux64 | case "$make_zfs" in | ||||
fi | pool) | ||||
# | |||||
# Expand desired pool size to bytes | |||||
# | |||||
zpool_size=$( awk -v size="$docker_zpool_file_size" ' | |||||
BEGIN { | |||||
suffixen = "KMGTPEZYXWV" # ... Yotta Xenna Weka Vendeka | |||||
size = toupper(size) | |||||
sub(sprintf("[^[:digit:].%s].*", suffixen), "", size) | |||||
if (match(size, sprintf("[%s]", suffixen))) { | |||||
suffix = substr(size, RSTART, 1) | |||||
size = substr(size, 1, RSTART - 1) | |||||
match(suffixen, suffix) | |||||
size = size * 1024 ** RSTART | |||||
} | |||||
printf "%i\n", size | |||||
exit | |||||
} | |||||
Done Inline ActionsLet's reduce the indentation of these lines by a single tab dteske: Let's reduce the indentation of these lines by a single tab | |||||
' ) | |||||
# Check for NAT support via PF | # | ||||
# This is an ugly experimental hack for now, eventually will go away | # Initialize the file using dd(1) piped through dpv(1) | ||||
if [ "${docker_nat_pf}" != "YES" ] ; then return ; fi | # | ||||
msg="Creating ZFS pool file ($docker_zpool_file_size size) ..." | |||||
truncate -s "$docker_zpool_file_size" "$docker_zpool_file" | |||||
Done Inline ActionsLet's remove this line -- it's not necessary unless using the dpv/cat pipe-through to redirect method dteske: Let's remove this line -- it's not necessary unless using the dpv/cat pipe-through to redirect… | |||||
# Load PF if not already | # | ||||
kldstat | grep -q 'pf.ko' | # Create zpool | ||||
if [ $? -ne 0 -a -e "/boot/kernel/pf.ko" ] ; then | # | ||||
kldload pf | echo "Creating ZFS pool from file $docker_zpool_file ..." | ||||
zpool create "$docker_zpool_name" "$docker_zpool_file" | |||||
;; | |||||
esac | |||||
# | |||||
# Setup ZFS filesystem | |||||
# | |||||
if [ "$make_zfs" ]; then | |||||
echo "Creating ZFS filesystem $zpool_name/$docker_zfs_name ..." | |||||
zfs create -o mountpoint="$docker_dir" \ | |||||
"$zpool_name/$docker_zfs_name" | |||||
fi | fi | ||||
Done Inline ActionsSince renaming docker_zfs_dir to docker_dir (reduction of 4 letters), is that enough to fit this all one one line that is 79 characters-or-less? (if no, retain line continuation) dteske: Since renaming docker_zfs_dir to docker_dir (reduction of 4 letters), is that enough to fit… | |||||
Done Inline ActionsIt still doesn't fit in 79 cols :( lifanov: It still doesn't fit in 79 cols :( | |||||
Done Inline ActionsThanks for checking ;D dteske: Thanks for checking ;D | |||||
Not Done Inline ActionsThe 80's called, they're telling me they had wider terminals back then and we have not had that limitations since before FreeBSD was born. mat: The 80's called, they're telling me they had wider terminals back then and we have not had that… | |||||
Not Done Inline ActionsReligion called, they want their hate back. dteske: Religion called, they want their hate back. | |||||
# Check if PF rules already loaded | # Check if PF rules already loaded | ||||
/sbin/pfctl -s nat 2>/dev/null | grep -q 172.17 | /sbin/pfctl -s nat 2>/dev/null | grep -q 172.17 | ||||
if [ $? -eq 0 ] ; then return ; fi | if [ $? -eq 0 ] ; then return ; fi | ||||
if [ "${docker_nat_iface}" != "NONE" ] ; then | if [ "${docker_nat_iface}" != "NONE" ] ; then | ||||
iface="${docker_nat_iface}" | iface="${docker_nat_iface}" | ||||
else | else | ||||
iface=`/usr/bin/netstat -f inet -nrW | grep '^default' | awk '{ print $6 }'` | iface=`/usr/bin/netstat -f inet -nrW | grep '^default' | awk '{ print $6 }'` | ||||
fi | fi | ||||
echo "nat on ${iface} from 172.17.0.0/16 to any -> (${iface})" > /tmp/pf-nat-docker.$$ | echo "nat on ${iface} from 172.17.0.0/16 to any -> (${iface})" > /tmp/pf-nat-docker.$$ | ||||
/sbin/pfctl -f /tmp/pf-nat-docker.$$ 2>/dev/null | /sbin/pfctl -f /tmp/pf-nat-docker.$$ 2>/dev/null | ||||
/sbin/pfctl -e 2>/dev/null | /sbin/pfctl -e 2>/dev/null | ||||
rm /tmp/pf-nat-docker.$$ | rm /tmp/pf-nat-docker.$$ | ||||
} | |||||
docker_start() | |||||
{ | |||||
if [ ! -d "${docker_dir}" ] ; then | |||||
echo "Missing ${docker_dir}! Please create / mount a ZFS dataset at this location." | |||||
exit 1 | |||||
fi | |||||
if [ -e "/var/run/docker.pid" ] ; then | |||||
pgrep -F /var/run/docker.pid 2>/dev/null >/dev/null | |||||
dteskeUnsubmitted Done Inline ActionsThere should be a space after > and 2> but more importantly, this is preferred: [tab][tab]pgrep -F /var/run/docker.pid > /dev/null 2>&1 dteske: There should be a space after > and 2> but more importantly, this is preferred:
[tab]… | |||||
lifanovAuthorUnsubmitted Done Inline ActionsThis isn't portable, but our sh supports it. lifanov: This isn't portable, but our sh supports it. | |||||
dteskeUnsubmitted Not Done Inline ActionsWhat isn't portable? Space after the redirect operator? The duplication of fd1 to fd2 (to send stderr the same place as stdout)? Ordered file descriptor operations? All of those things are portable and no system I have touched in 20 years of using UNIX has ever balked at any of these. I would be shocked if you could find any variant of shell that balks at any of these (note: csh/tcsh/zsh don't count; things like ksh, dash, ash, do count -- it has to be a bourne shell variant, bash included since CentOS, Mac OS X, etc. use bash as /bin/sh). dteske: What isn't portable? Space after the redirect operator? The duplication of fd1 to fd2 (to send… | |||||
Not Done Inline ActionsBeen thinking a lot that we should make the pidfile able to be set in rc.conf(5). E.g., docker_pidfile dteske: Been thinking a lot that we should make the pidfile able to be set in rc.conf(5). E.g. | |||||
if [ $? -eq 0 ] ; then | |||||
echo "Docker already running? /var/run/docker.pid" | |||||
exit 1 | |||||
fi | |||||
dteskeUnsubmitted Done Inline ActionsPreferred: [tab][tab]if pgrep -F /var/run/docker.pid > /dev/null 2>&1; then dteske: Preferred:
[tab][tab]if pgrep -F /var/run/docker.pid > /dev/null 2>&1; then
[tab][tab]… | |||||
fi | |||||
echo "Starting docker..." | |||||
Not Done Inline Actions$docker_pidfile instead of hard-coded value repeated throughout dteske: $docker_pidfile instead of hard-coded value repeated throughout | |||||
daemon -p /var/run/docker.pid ${command} -d -e jail -s zfs -g ${docker_dir} -D ${docker_flags} >${docker_log_file} 2>${docker_log_file} | |||||
} | } | ||||
docker_stop() | docker_stop() | ||||
{ | { | ||||
if [ -e "/var/run/docker.pid" ] ; then | if [ -e "/var/run/docker.pid" ] ; then | ||||
Not Done Inline Actions$docker_pidfile instead of hard-coded value repeated throughout dteske: $docker_pidfile instead of hard-coded value repeated throughout | |||||
echo "Stopping docker..." | echo "Stopping docker..." | ||||
pkill -F /var/run/docker.pid | pkill -F /var/run/docker.pid | ||||
Not Done Inline Actions$docker_pidfile instead of hard-coded value repeated throughout dteske: $docker_pidfile instead of hard-coded value repeated throughout | |||||
fi | fi | ||||
} | } | ||||
run_rc_command "$1" | run_rc_command "$1" | ||||
Initialization to NULL is required for all but module and for purposes of minimal diffs, prefer making these separate statements
[tab]local module
[tab]local fs_type=
[tab]local make_zfs=
[tab]local zfs_mountpoint=
[tab]local zfs_name=
[tab]local zpool_name=
[tab]local zpool_size=