# Automatically enable zone.
zone_enable "${zone}"
+
+ # Bring up the zone immediately after
+ zone_start "${zone}"
}
function zone_edit() {
fi
}
-function zone_port() {
- local zone=${1}
- local action=${2}
- shift 2
-
- assert isset zone
- assert isset action
- assert zone_exists ${zone}
-
- case "${action}" in
- add|edit|remove)
- zone_port_${action} ${zone} $@
- ;;
- *)
- error "Unrecognized argument: ${action}"
- cli_usage root-zone-port-subcommands
- exit ${EXIT_ERROR}
- ;;
- esac
-}
-
-function zone_port_add() {
- local zone="${1}"
- assert isset zone
-
- local port="${2}"
- assert isset port
-
- shift 2
-
- # Check if the port actually exists.
- if ! port_exists "${port}"; then
- error "Cannot add port '${port}' which does not exist"
- return ${EXIT_ERROR}
- fi
-
- # Check if the port is already connected to this or any other zone.
- local z
- for z in $(zones_get_all); do
- if zone_has_port "${z}" "${port}"; then
- error "Port '${port}' is already assigned to zone '${z}'"
- return ${EXIT_ERROR}
- fi
- done
-
- local hook=$(zone_get_hook "${zone}")
- assert isset hook
-
- hook_zone_exec "${hook}" "port_add" "${zone}" "${port}" "$@"
-}
-
-function zone_port_edit() {
- local zone="${1}"
- assert isset zone
-
- local port="${2}"
- assert isset port
-
- shift 2
-
- # Check if the port actually exists.
- if ! port_exists "${port}"; then
- error "Port '${port}' does not exist"
- return ${EXIT_ERROR}
- fi
-
- # Check if the zone actually has this port.
- if ! zone_has_port "${zone}" "${port}"; then
- error "Port '${port}' is not attached to zone '${zone}'"
- return ${EXIT_ERROR}
- fi
-
- local hook=$(zone_get_hook "${zone}")
- assert isset hook
-
- hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
-}
-
-function zone_port_remove() {
- local zone="${1}"
- assert isset zone
-
- local port="${2}"
- assert isset port
-
- shift 2
-
- # Check if the zone actually has this port.
- if ! zone_has_port "${zone}" "${port}"; then
- error "Port '${port}' is not attached to zone '${zone}'"
- return ${EXIT_ERROR}
- fi
-
- local hook=$(zone_get_hook "${zone}")
- assert isset hook
-
- hook_zone_exec "${hook}" "port_remove" "${zone}" "${port}" "$@"
-}
-
function zone_get_ports() {
local zone=${1}
done
}
-function zone_ports_cmd() {
- local cmd=${1}
- local zone=${2}
+function zone_port_attach() {
+ local zone="${1}"
+ assert isset zone
+
+ local port="${2}"
+ assert isset port
+
+ shift 2
+
+ # Check if the port actually exists.
+ if ! port_exists "${port}"; then
+ error "Cannot attach port '${port}' which does not exist"
+ return ${EXIT_ERROR}
+ fi
+
+ # Check if the port is already connected to this or any other zone.
+ local z
+ for z in $(zones_get_all); do
+ if zone_has_port "${z}" "${port}"; then
+ error "Port '${port}' is already attached to zone '${z}'"
+ return ${EXIT_ERROR}
+ fi
+ done
+
+ local hook="$(zone_get_hook "${zone}")"
+ assert isset hook
+
+ hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
+ local ret="${?}"
+
+ case "${ret}" in
+ ${EXIT_OK})
+ log INFO "${port} has been attached to ${zone}"
+
+ # Automatically connect the port
+ if zone_is_active "${zone}"; then
+ zone_port_create "${zone}" "${port}"
+ fi
+ ;;
+ *)
+ log CRITICAL "${port} could not be attached to ${zone}"
+ ;;
+ esac
+
+ return ${ret}
+}
+
+function zone_port_edit() {
+ local zone="${1}"
+ assert isset zone
+
+ local port="${2}"
+ assert isset port
+
+ shift 2
+
+ # Check if the port actually exists.
+ if ! port_exists "${port}"; then
+ error "Port '${port}' does not exist"
+ return ${EXIT_ERROR}
+ fi
+
+ # Check if the zone actually has this port.
+ if ! zone_has_port "${zone}" "${port}"; then
+ error "Port '${port}' is not attached to zone '${zone}'"
+ return ${EXIT_ERROR}
+ fi
+
+ local hook=$(zone_get_hook "${zone}")
+ assert isset hook
+
+ hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
+}
+
+function zone_port_detach() {
+ local zone="${1}"
+ assert isset zone
+
+ local port="${2}"
+ assert isset port
+
shift 2
+ # Check if the zone actually has this port.
+ if ! zone_has_port "${zone}" "${port}"; then
+ error "Port '${port}' is not attached to zone '${zone}'"
+ return ${EXIT_ERROR}
+ fi
+
+ local hook=$(zone_get_hook "${zone}")
+ assert isset hook
+
+ hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
+ local ret="${?}"
+
+ case "${ret}" in
+ ${EXIT_OK})
+ log INFO "${port} has been detached from ${zone}"
+
+ # Bring down the port if needed
+ if zone_is_active "${zone}"; then
+ zone_port_remove "${zone}" "${port}"
+ fi
+ ;;
+ *)
+ log CRITICAL "${port} could not be detached from ${zone}"
+ ;;
+ esac
+
+ return ${ret}
+}
+
+function zone_port_cmd() {
+ local cmd="${1}"
assert isset cmd
+
+ local zone="${2}"
assert isset zone
- assert zone_exists ${zone}
+ local port="${3}"
+ assert isset port
- local hook=$(zone_get_hook ${zone})
+ shift 3
+
+ local hook="$(zone_get_hook "${zone}")"
+ assert isset hook
+
+ # Dispatch command to hook
+ hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" $@
+}
+
+function zone_port_create() {
+ zone_port_cmd "port_create" $@
+}
+
+function zone_port_remove() {
+ zone_port_cmd "port_remove" $@
+}
+
+function zone_port_up() {
+ zone_port_cmd "port_up" $@
+}
+
+function zone_port_down() {
+ zone_port_cmd "port_down" $@
+}
+
+function zone_port_status() {
+ zone_port_cmd "port_status" $@
+}
+
+function zone_ports_cmd() {
+ local cmd="${1}"
+ assert isset cmd
+
+ local zone="${2}"
+ assert isset zone
+
+ shift 2
+
+ local hook="$(zone_get_hook "${zone}")"
local port
for port in $(zone_get_ports ${zone}); do
- hook_zone_exec ${hook} ${cmd} ${zone} ${port} $@
+ hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" $@
done
}
}
function zone_ports_up() {
- zone_ports_cmd port_up $@
+ zone_ports_cmd "port_up" $@
}
function zone_ports_down() {
- zone_ports_cmd port_down $@
+ zone_ports_cmd "port_down" $@
}
function zone_ports_status() {
- zone_ports_cmd port_status $@
+ zone_ports_cmd "port_status" $@
}
function zone_configs_cmd() {
}
function zone_port_settings_read() {
- assert [ $# -gt 2 ]
+ assert [ $# -ge 2 ]
local zone="${1}"
local port="${2}"
shift 2
+ local args
+ if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
+ list_append args ${HOOK_PORT_SETTINGS}
+ else
+ list_append args $@
+ fi
+
local path="$(zone_dir "${zone}")/ports/${port}"
- settings_read "${path}" "$@"
+ settings_read "${path}" ${args}
}
function zone_port_settings_write() {
if function_exists "hook_check_port_settings"; then
list_append args "--check=\"hook_check_port_settings\""
fi
- list_append args $@
+ list_append args ${HOOK_PORT_SETTINGS}
local path="$(zone_dir "${zone}")/ports/${port}"
settings_write "${path}" ${args}
exit ${EXIT_OK}
}
-function __parse_cmdline_args() {
- while [ $# -gt 0 ]; do
- case "${1}" in
- --priority=*)
- PRIORITY="$(cli_get_val ${1})"
- ;;
- --cost=*)
- COST="$(cli_get_val ${1})"
- ;;
- esac
- shift
- done
+function hook_check_port_settings() {
+ if isset COST; then
+ assert isinteger COST
+ fi
- return ${EXIT_OK}
+ if isset PRIORITY; then
+ assert isinteger PRIORITY
+ fi
}
-function hook_port_add() {
+function hook_port_attach() {
# Excepting at least two arguments here
assert [ $# -ge 2 ]
local port="${2}"
shift 2
- __parse_cmdline_args "$@"
- [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR}
-
- zone_port_settings_write "${zone}" "${port}" ${HOOK_PORT_SETTINGS}
-
- log INFO "Port '${port}' has been added to zone '${zone}'"
-
- exit ${EXIT_OK}
-}
-
-function hook_port_edit() {
- assert [ $# -ge 2 ]
-
- local zone="${1}"
- local port="${2}"
- shift 2
-
- zone_port_settings_read "${zone}" "${port}" ${HOOK_PORT_SETTINGS}
-
- __parse_cmdline_args "$@"
- [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR}
+ if zone_has_port "${zone}" "${port}"; then
+ zone_port_settings_read "${zone}" "${port}"
+ fi
- zone_port_settings_write "${zone}" "${port}" ${HOOK_PORT_SETTINGS}
+ local arg
+ local val
+ while read arg; do
+ case "${arg}" in
+ --cost=*)
+ COST="$(cli_get_val "${arg}")"
+ ;;
+ --priority=*)
+ PRIORITY="$(cli_get_val "${arg}")"
+ ;;
+ esac
+ done <<< "$(args $@)"
- log INFO "Port '${port}' (member of zone '${zone}') has been edited"
+ if ! zone_port_settings_write "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}
-function hook_port_destroy() {
+function hook_port_detach() {
assert [ $# -eq 2 ]
local zone="${1}"
# Shut down the port (if possible)
port_down "${port}"
- log INFO "Port '${port}' has been removed from zone '${zone}'"
- zone_port_settings_remove "${zone}" "${port}"
+ if ! zone_port_settings_remove "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}
+function hook_port_edit() {
+ hook_port_attach $@
+}
+
function hook_port_up() {
assert [ $# -eq 2 ]
local zone=${1}
assert isset zone
+ # If this zone's port is not set, we will return
+ # with EXIT_OK so that this zone will remain active,
+ # but we cannot start pppd.
+ local port=$(__hook_get_port "${zone}")
+ if ! isset port || ! port_exists "${port}"; then
+ log WARNING "Could not bring up zone '${zone}' because no port is attached"
+ exit ${EXIT_OK}
+ fi
+
zone_settings_read "${zone}"
# Bring up the port.
- local port=$(__hook_get_port "${zone}")
port_up "${port}"
# Start the ppp daemon.
return ${EXIT_ERROR}
}
-function hook_port_add() {
+function hook_port_attach() {
# Excepting at least two arguments here
assert [ $# -ge 2 ]
# PPPoE can only use one port
local ports_num="$(zone_get_ports_num "${zone}")"
if [ ${ports_num} -ge 1 ]; then
- local port=$(__hook_get_port "${zone}")
+ local ports="$(zone_get_ports "${zone}")"
error "The pppoe zone hook only supports assigning one port"
- error " port '${port}' has already been assigned to zone '${zone}'"
+ error " port '${ports}' has already been assigned to zone '${zone}'"
return ${EXIT_ERROR}
fi
- zone_port_settings_write "${zone}" "${port}"
- log INFO "Port '${port}' has been added to zone '${zone}'"
+ if ! zone_port_settings_write "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}
-function hook_port_remove() {
+function hook_port_detach() {
assert [ $# -eq 2 ]
local zone="${1}"
local port="${2}"
- # Shut down the port (if possible)
- port_down "${port}"
+ # Shut down the entire zone here, because it cannot
+ # run without a port any way and removing the port would
+ # create a hotplug event which will be processed after the
+ # port has already been detached...
+ zone_stop "${zone}"
- log INFO "Port '${port}' has been removed from zone '${zone}'"
- zone_port_settings_remove "${zone}" "${port}"
+ if ! zone_port_settings_remove "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}