service_start "network@${zone}.service"
}
+function zone_start_auto() {
+ local zone="${1}"
+ assert zone_exists "${zone}"
+
+ # If the zone has already been started, we
+ # will reload it so the current configuration
+ # is re-applied.
+ if zone_is_active "${zone}"; then
+ zone_reload "${zone}"
+ return ${?}
+
+ # If the zone is still down, but in auto-start mode,
+ # we will start it.
+ elif zone_is_enabled "${zone}"; then
+ zone_start "${zone}"
+ return ${?}
+ fi
+
+ # Otherwise, nothing will be done.
+ return ${EXIT_OK}
+}
+
function zone_stop() {
# This function will bring down the zone
# 'asynchronously' with help of systemd.
service_reload "network@${zone}.service"
}
+function zone_hotplug_event() {
+ local zone="${1}"
+ assert isset zone
+
+ hotplug_assert_in_hotplug_event
+
+ zone_cmd "hotplug" "${zone}"
+}
+
function zone_enable() {
# This function will enable the zone
# with help of systemd.
return ${EXIT_FALSE}
}
-function zone_create() {
+function zone_is_enabled_or_active() {
+ local zone="${1}"
+ assert isset zone
+
+ zone_is_enabled "${zone}" || zone_is_active "${zone}"
+}
+
+function zone_cmd() {
+ local cmd="${1}"
+ local port="${2}"
+ shift 2
+
+ assert isset cmd
+ assert isset zone
+
+ local hook="$(zone_get_hook ${zone})"
+ assert isset hook
+
+ hook_exec zone "${hook}" "${cmd}" "${zone}" $@
+}
+
+function zone_new() {
local zone=${1}
local hook=${2}
shift 2
# Create directories for configs and ports
mkdir -p $(zone_dir ${zone})/{configs,ports}
- hook_zone_exec ${hook} create ${zone} $@
+ hook_zone_exec "${hook}" "new" "${zone}" $@
local ret=$?
- # Maybe the zone create hook did not exit correctly.
+ # Maybe the zone new hook did not exit correctly.
# If this is the case we remove the created zone immediately.
if [ "${ret}" = "${EXIT_ERROR}" ]; then
- zone_remove_now ${zone}
+ zone_destroy_now "${zone}"
return ${EXIT_ERROR}
fi
# Automatically enable zone.
zone_enable "${zone}"
+
+ # Bring up the zone immediately after
+ zone_start "${zone}"
}
function zone_edit() {
fi
# Check if the zone is tagged for removal.
- if zone_has_remove_tag ${zone}; then
+ if zone_has_destroy_tag ${zone}; then
error "You cannot edit a zone that is tagged for removal."
return ${EXIT_ERROR}
fi
- local hook=$(config_get_hook $(zone_dir ${zone})/settings)
-
+ local hook="$(zone_get_hook "${zone}")"
if [ -z "${hook}" ]; then
error "Config file did not provide any hook."
return ${EXIT_ERROR}
}
-function zone_remove() {
- local zone=${1}
- assert zone_exists ${zone}
+function zone_destroy() {
+ local zone="${1}"
+ assert zone_exists "${zone}"
# Make the zone for removal.
- touch $(zone_dir ${zone})/.remove
+ touch "$(zone_dir "${zone}")/.destroy"
log INFO "Zone '${zone}' has been tagged for removal."
}
-function zone_has_remove_tag() {
- local zone=${1}
- assert zone_exists ${zone}
+function zone_has_destroy_tag() {
+ local zone="${1}"
+ assert zone_exists "${zone}"
- [ -e "$(zone_dir ${zone})/.remove" ]
+ [ -e "$(zone_dir "${zone}")/.destroy" ]
}
# This function will remove the given zone
-# RIGHT NOW. Use zone_remove to remove it
+# RIGHT NOW. Use zone_destroy to remove it
# at the next status change.
-function zone_remove_now() {
- local zone=${1}
- assert zone_exists ${zone}
+function zone_destroy_now() {
+ local zone="${1}"
+ assert zone_exists "${zone}"
log INFO "Removing zone '${zone}' right now."
# Force the zone down.
- zone_is_up ${zone} && zone_set_down ${zone}
+ zone_is_active "${zone}" && zone_stop "${zone}"
# Disable zone.
zone_disable "${zone}"
- rm -rf $(zone_dir ${zone})
+ rm -rf "$(zone_dir "${zone}")"
}
function zone_up() {
fi
# Check if a zone has got the remove tag.
- if zone_has_remove_tag ${zone}; then
+ if zone_has_destroy_tag ${zone}; then
error "Cannot bring up any zone which is to be removed."
return ${EXIT_ERROR}
fi
- local hook=$(config_get_hook $(zone_dir ${zone})/settings)
-
+ local hook="$(zone_get_hook "${zone}")"
if [ -z "${hook}" ]; then
error "Config file did not provide any hook."
return ${EXIT_ERROR}
return ${EXIT_ERROR}
fi
- local hook=$(config_get_hook $(zone_dir ${zone})/settings)
-
+ local hook="$(zone_get_hook "${zone}")"
if [ -z "${hook}" ]; then
error "Config file did not provide any hook."
return ${EXIT_ERROR}
zone_db ${zone} stopped
# Remove the zone, if it has got a remove tag.
- if zone_has_remove_tag ${zone}; then
- zone_remove_now ${zone}
+ if zone_has_destroy_tag "${zone}"; then
+ zone_destroy_now "${zone}"
fi
}
function zone_status() {
- local zone=${1}
+ local zone="${1}"
+ assert isset zone
shift
- if ! zone_exists ${zone}; then
+ if ! zone_exists "${zone}"; then
error "Zone '${zone}' does not exist."
return ${EXIT_ERROR}
fi
- local hook=$(config_get_hook $(zone_dir ${zone})/settings)
-
+ local hook="$(zone_get_hook "${zone}")"
if [ -z "${hook}" ]; then
error "Config file did not provide any hook."
return ${EXIT_ERROR}
fi
- if ! hook_zone_exists ${hook}; then
+ if ! hook_zone_exists "${hook}"; then
error "Hook '${hook}' does not exist."
return ${EXIT_ERROR}
fi
- hook_zone_exec ${hook} status ${zone} $@
+ hook_zone_exec "${hook}" "status" "${zone}" "$@"
# Show that the zone it to be removed soon.
- if zone_has_remove_tag ${zone}; then
+ if zone_has_destroy_tag ${zone}; then
warning "This zone is tagged for removal."
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}
[ -e "$(zone_dir ${zone})/ports/${port}" ]
}
-# XXX overwritten some lines below
function zone_config() {
- local zone=${1}
- shift
-
- if ! zone_exists ${zone}; then
- error "Zone '${zone}' does not exist."
- return ${EXIT_ERROR}
- fi
-
- local hook=$(config_get_hook $(zone_dir ${zone})/settings)
-
- if [ -z "${hook}" ]; then
- error "Config file did not provide any hook."
- return ${EXIT_ERROR}
- fi
-
- if ! hook_zone_exists ${hook}; then
- error "Hook '${hook}' does not exist."
- return ${EXIT_ERROR}
- fi
-
- hook_zone_exec ${hook} config ${zone} $@
-}
-
-function zone_config() {
- local zone=${1}
- local action=${2}
+ local zone="${1}"
+ local cmd="${2}"
shift 2
assert isset zone
- assert isset action
- assert zone_exists ${zone}
+ assert isset cmd
+ assert zone_exists "${zone}"
- # Aliases
- case "${action}" in
- del|delete|remove)
- action="rem"
+ case "${cmd}" in
+ create)
+ zone_config_create "${zone}" "$@"
;;
- esac
-
- case "${action}" in
- create|edit|rem)
- zone_config_${action} ${zone} $@
+ edit)
+ zone_config_edit "${zone}" "$@"
+ ;;
+ remove)
+ zone_config_remove "${zone}" "$@"
;;
*)
- error "Unrecognized argument: ${action}"
+ error "Unrecognized argument: ${cmd}"
cli_usage root-zone-config-subcommands
exit ${EXIT_ERROR}
;;
esac
}
-function zone_config_create() {
- local zone="${1}"
- assert isset zone
- shift
+function zone_config_cmd() {
+ assert [ $# -gt 2 ]
- local hook=$(zone_get_hook "${zone}")
+ local cmd="${1}"
+ local zone="${2}"
+ shift 2
+
+ local hook="$(zone_get_hook "${zone}")"
assert isset hook
- hook_zone_exec "${hook}" "config_create" "${zone}" "$@"
+ hook_zone_exec "${hook}" "config_${cmd}" "${zone}" "$@"
+}
+
+function zone_config_create() {
+ zone_config_cmd "create" "$@"
+}
+
+function zone_config_edit() {
+ zone_config_cmd "edit" "$@"
+}
+
+function zone_config_remove() {
+ zone_config_cmd "remove" "$@"
+}
+
+function zone_config_show() {
+ zone_config_cmd "show" "$@"
}
function zone_show() {
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
+ zone_port_start "${zone}" "${port}"
+ ;;
+ *)
+ 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
+ zone_port_stop "${zone}" "${port}"
+ ;;
+ *)
+ 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" $@
+}
+
+# The next two functions automagically bring up and down
+# port that are attached to a bridge or similar.
+# The problem that is tried to overcome here is that there
+# are ports which exist all the time (like ethernet ports)
+# and therefore do not dispatch a hotplug event when
+# port_create is called.
+
+function zone_port_start() {
+ local zone="${1}"
+ local port="${2}"
+
+ if zone_is_active "${zone}"; then
+ if device_exists "${port}"; then
+ zone_port_up "${zone}" "${port}"
+ return ${?}
+ else
+ zone_port_create "${zone}" "${port}"
+ return ${?}
+ fi
+ fi
+
+ return ${EXIT_OK}
+}
+
+function zone_port_stop() {
+ local zone="${1}"
+ local port="${2}"
+
+ # Shut down the port if necessary
+ if zone_is_active "${zone}" && port_is_up "${port}"; then
+ zone_port_down "${zone}" "${port}"
+ fi
+
+ # Remove the port
+ zone_port_remove "${zone}" "${port}"
+}
+
+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 $@
+function zone_ports_create() {
+ zone_ports_cmd "port_create" $@
}
-function zone_ports_down() {
- zone_ports_cmd port_down $@
+function zone_ports_remove() {
+ zone_ports_cmd "port_remove" $@
}
-function zone_ports_status() {
- zone_ports_cmd port_status $@
+function zone_ports_up() {
+ zone_ports_cmd "port_up" $@
}
-function zone_configs_list() {
- local zone=${1}
-
- local config
- for config in $(zone_dir ${zone})/configs/*; do
- [ -e "${config}" ] || continue
+function zone_ports_down() {
+ zone_ports_cmd "port_down" $@
+}
- basename ${config}
- done
+function zone_ports_status() {
+ zone_ports_cmd "port_status" $@
}
function zone_configs_cmd() {
- local cmd=${1}
- local zone=${2}
+ assert [ $# -ge 2 ]
+
+ local cmd="${1}"
+ local zone="${2}"
shift 2
- local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings)
+ assert zone_exists "${zone}"
- local hook_config
local config
- for config in $(zone_configs_list ${zone}); do
- hook_config=$(config_get_hook $(zone_dir ${zone})/configs/${config})
+ for config in $(zone_configs_list "${zone}"); do
+ local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
+ assert isset config_hook
- hook_zone_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} ${config} $@
+ hook_config_exec "${config_hook}" "${cmd}" "${zone}" "${config}" $@
done
}
function zone_configs_up() {
- zone_configs_cmd up $@
+ zone_configs_cmd "up" $@
}
function zone_configs_down() {
- zone_configs_cmd down $@
+ zone_configs_cmd "down" $@
}
function zone_configs_status() {
- zone_configs_cmd config_status $@
+ zone_configs_cmd "status" $@
+}
+
+function zone_configs_list() {
+ local zone=${1}
+
+ local config
+ for config in $(zone_dir ${zone})/configs/*; do
+ [ -e "${config}" ] || continue
+
+ basename ${config}
+ done
+}
+
+function zone_config_get_hook() {
+ assert [ $# -eq 2 ]
+
+ local zone="${1}"
+ assert isset zone
+
+ local config="${2}"
+ assert isset config
+
+ local HOOK
+ zone_config_settings_read "${zone}" "${config}" \
+ --ignore-superfluous-settings HOOK
+
+ print "${HOOK}"
}
function zone_has_ip() {
}
function zone_get_supported_config_hooks() {
- local zone=${1}
-
- local hook=$(zone_get_hook ${zone})
-
- hook_zone_configs_get_all ${hook}
+ hook_config_get_all
}
function zone_file() {
function zone_settings_read() {
local zone=${1}
-
assert isset zone
+ shift
+
+ local args
+ if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then
+ list_append args ${HOOK_SETTINGS}
+ else
+ list_append args $@
+ fi
# Save the HOOK variable.
local hook="${HOOK}"
- settings_read $(zone_file ${zone})
+ settings_read "$(zone_file "${zone}")" ${args}
# Restore hook.
HOOK="${hook}"
}
function zone_settings_write() {
- local zone=${1}
-
+ local zone="${1}"
assert isset zone
- settings_write $(zone_file ${zone}) ${HOOK_SETTINGS}
+ local args
+ if function_exists "hook_check_settings"; then
+ list_append args "--check=\"hook_check_settings\""
+ fi
+ list_append args ${HOOK_SETTINGS}
+
+ settings_write "$(zone_file ${zone})" ${args}
}
function zone_settings_set() {
assert isset key
(
- zone_settings_read ${zone}
+ zone_settings_read "${zone}" "${key}" \
+ --ignore-superfluous-settings
echo "${!key}"
)
}
function zone_config_settings_read() {
- assert [ $# -gt 2 ]
+ assert [ $# -ge 2 ]
local zone="${1}"
local config="${2}"
shift 2
+ local args
+ if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then
+ list_append args ${HOOK_CONFIG_SETTINGS}
+ else
+ list_append args $@
+ fi
+
local path="$(zone_dir "${zone}")/configs/${config}"
- settings_read "${path}" "$@"
+ settings_read "${path}" ${args}
}
function zone_config_settings_write() {
- assert [ $# -gt 2 ]
+ assert [ $# -ge 2 ]
local zone="${1}"
local config="${2}"
shift 2
+ local args
+ if function_exists "hook_check_config_settings"; then
+ list_append args "--check=\"hook_check_config_settings\""
+ fi
+ list_append args ${HOOK_CONFIG_SETTINGS}
+
local path="$(zone_dir "${zone}")/configs/${config}"
- settings_write "${path}" "$@"
+ settings_write "${path}" ${args}
}
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() {
- assert [ $# -gt 2 ]
+ assert [ $# -ge 2 ]
local zone="${1}"
local port="${2}"
shift 2
+ local args
+ if function_exists "hook_check_port_settings"; then
+ list_append args "--check=\"hook_check_port_settings\""
+ fi
+ list_append args ${HOOK_PORT_SETTINGS}
+
local path="$(zone_dir "${zone}")/ports/${port}"
- settings_write "${path}" "$@"
+ settings_write "${path}" ${args}
}
function zone_port_settings_remove() {