]> git.ipfire.org Git - people/stevee/network.git/blame - src/functions/functions.zone
Dropping port_dir()
[people/stevee/network.git] / src / functions / functions.zone
CommitLineData
1848564d
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
1c6a4e30 22zone_dir() {
1848564d
MT
23 local zone=${1}
24
d2a21d01 25 echo "${NETWORK_ZONE_DIR}/zones/${zone}"
1848564d
MT
26}
27
1c6a4e30 28zone_exists() {
1848564d 29 local zone=${1}
711ffac1
MT
30 assert isset zone
31
1848564d
MT
32 [ -d "$(zone_dir ${zone})" ]
33}
34
1c6a4e30 35zone_match() {
1848564d
MT
36 local match
37
38 local i
39 for i in ${VALID_ZONES}; do
40 match="${match}|${i}[0-9]{1,5}"
41 done
42
43 echo "${match:1:${#match}}"
44}
45
1c6a4e30 46zone_name_is_valid() {
1848564d 47 local zone=${1}
4fedddef
MT
48
49 # Don't accept empty strings.
50 [ -z "${zone}" ] && return ${EXIT_FALSE}
711ffac1 51
1848564d
MT
52 [[ ${zone} =~ $(zone_match) ]]
53}
54
1c6a4e30 55zone_is_local() {
1848564d
MT
56 local zone=${1}
57
7de0637a 58 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
5e42d659
MT
59}
60
1c6a4e30 61zone_is_nonlocal() {
5e42d659
MT
62 local zone=${1}
63
7de0637a 64 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
1848564d
MT
65}
66
1c6a4e30 67zone_get_hook() {
1848564d 68 local zone=${1}
711ffac1
MT
69 assert isset zone
70
1848564d
MT
71 config_get_hook $(zone_dir ${zone})/settings
72}
73
1c6a4e30 74zone_start() {
5bb2429a
MT
75 # This function will bring up the zone
76 # 'asynchronously' with help of systemd.
77
78 local zone=${1}
79 assert zone_exists ${zone}
80
1d08b9b3 81 service_start "network@${zone}.service"
5bb2429a
MT
82}
83
1c6a4e30 84zone_start_auto() {
2a969c27
MT
85 local zone="${1}"
86 assert zone_exists "${zone}"
87
88 # If the zone has already been started, we
89 # will reload it so the current configuration
90 # is re-applied.
91 if zone_is_active "${zone}"; then
92 zone_reload "${zone}"
93 return ${?}
94
95 # If the zone is still down, but in auto-start mode,
96 # we will start it.
97 elif zone_is_enabled "${zone}"; then
98 zone_start "${zone}"
99 return ${?}
100 fi
101
102 # Otherwise, nothing will be done.
103 return ${EXIT_OK}
104}
105
1c6a4e30 106zone_stop() {
5bb2429a
MT
107 # This function will bring down the zone
108 # 'asynchronously' with help of systemd.
109
110 local zone=${1}
111 assert zone_exists ${zone}
112
1d08b9b3 113 service_stop "network@${zone}.service"
5bb2429a
MT
114}
115
1c6a4e30 116zone_reload() {
e6fd23fd
MT
117 local zone="${1}"
118 assert zone_exists "${zone}"
119
120 service_reload "network@${zone}.service"
121}
122
1c6a4e30 123zone_hotplug_event() {
fb8c7c92 124 local zone="${1}"
2a969c27 125 assert isset zone
fb8c7c92 126
2a969c27 127 hotplug_assert_in_hotplug_event
fb8c7c92 128
2a969c27 129 zone_cmd "hotplug" "${zone}"
fb8c7c92
MT
130}
131
1c6a4e30 132zone_enable() {
5c5b8e36
SS
133 # This function will enable the zone
134 # with help of systemd.
135
136 local zone="${1}"
137 assert zone_exists "${zone}"
138
139 # Enable service for the zone
140 service_enable "network@${zone}.service"
141 local ret=$?
142
143 if [ ${ret} -eq ${EXIT_OK} ]; then
144 log INFO "Auto-start enabled for zone ${zone}"
145 return ${EXIT_OK}
146 fi
147
148 log ERROR "Could not enable zone ${zone}: ${ret}"
149 return ${ret}
150}
151
1c6a4e30 152zone_disable() {
5c5b8e36
SS
153 # This function will disable the zone
154 # with help of systemd.
155
156 local zone="${1}"
157 assert zone_exists "${zone}"
158
159 # Disable service for the zone
160 service_disable "network@${zone}.service"
161 local ret=$?
162
163 if [ ${ret} -eq ${EXIT_OK} ]; then
164 log INFO "Auto-start disabled for zone ${zone}"
165 return ${EXIT_OK}
166 fi
167
168 log ERROR "Could not disable zone ${zone}: ${ret}"
169 return ${ret}
170}
171
1c6a4e30 172zone_is_enabled() {
5c5b8e36
SS
173 local zone="${1}"
174 assert isset zone
175
176 # Ask systemd if the zone is enabled.
177 if service_is_enabled "network@${zone}.service"; then
178 return ${EXIT_TRUE}
179 fi
180
181 return ${EXIT_FALSE}
182}
183
1c6a4e30 184zone_is_active() {
e6fd23fd
MT
185 local zone="${1}"
186 assert isset zone
187
188 if service_is_active "network@${zone}.service"; then
189 return ${EXIT_TRUE}
190 fi
191
192 return ${EXIT_FALSE}
193}
194
1c6a4e30 195zone_is_enabled_or_active() {
2a969c27
MT
196 local zone="${1}"
197 assert isset zone
198
199 zone_is_enabled "${zone}" || zone_is_active "${zone}"
200}
201
1c6a4e30 202zone_cmd() {
2a969c27
MT
203 local cmd="${1}"
204 local port="${2}"
205 shift 2
206
207 assert isset cmd
208 assert isset zone
209
210 local hook="$(zone_get_hook ${zone})"
211 assert isset hook
212
2212045f 213 hook_exec zone "${hook}" "${cmd}" "${zone}" "$@"
2a969c27
MT
214}
215
1c6a4e30 216zone_new() {
1848564d
MT
217 local zone=${1}
218 local hook=${2}
219 shift 2
220
221 if ! zone_name_is_valid ${zone}; then
222 error "Zone name '${zone}' is not valid."
223 return ${EXIT_ERROR}
224 fi
225
226 if zone_exists ${zone}; then
227 error "Zone '${zone}' does already exist."
228 return ${EXIT_ERROR}
229 fi
230
d61a01d4 231 if ! hook_zone_exists ${hook}; then
1848564d
MT
232 error "Hook '${hook}' does not exist."
233 return ${EXIT_ERROR}
234 fi
235
236 mkdir -p $(zone_dir ${zone})
237
a5ebb169
MT
238 # Create directories for configs and ports
239 mkdir -p $(zone_dir ${zone})/{configs,ports}
943e3f7e 240
2212045f 241 hook_zone_exec "${hook}" "new" "${zone}" "$@"
1848564d
MT
242 local ret=$?
243
cf0fc8ab 244 # Maybe the zone new hook did not exit correctly.
1848564d 245 # If this is the case we remove the created zone immediately.
a63e51c6 246 if [ "${ret}" != "${EXIT_OK}" ]; then
285f779f 247 zone_destroy "${zone}"
5c5b8e36 248 return ${EXIT_ERROR}
1848564d 249 fi
5c5b8e36
SS
250
251 # Automatically enable zone.
252 zone_enable "${zone}"
ac694a6a
MT
253
254 # Bring up the zone immediately after
255 zone_start "${zone}"
1848564d
MT
256}
257
1c6a4e30 258zone_edit() {
1848564d
MT
259 local zone=${1}
260 shift
261
262 if ! zone_exists ${zone}; then
263 error "Zone '${zone}' does not exist."
264 return ${EXIT_ERROR}
265 fi
266
2472e0ea 267 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
268 if [ -z "${hook}" ]; then
269 error "Config file did not provide any hook."
270 return ${EXIT_ERROR}
271 fi
272
d61a01d4 273 if ! hook_zone_exists ${hook}; then
1848564d
MT
274 error "Hook '${hook}' does not exist."
275 return ${EXIT_ERROR}
276 fi
277
2212045f 278 hook_zone_exec ${hook} edit ${zone} "$@"
1848564d
MT
279}
280
2bb20bbd
SS
281zone_rename() {
282 assert [ $# -eq 2 ]
283
284 local zone="${1}"
285 local name="${2}"
286
287 assert zone_exists "${zone}"
2bb20bbd
SS
288 assert not zone_exists "${name}"
289
290 # The zone must be shut down before, is then renamed and
291 # potentially brought up again
292
293 # Save if the zone is running right now
294 zone_is_active "${zone}"
295 local zone_was_active="${?}"
296
297 # Save if the zone is enabled (i.e. auto-start)
298 zone_is_enabled "${zone}"
299 local zone_was_enabled="${?}"
300
301 # Stop the zone
302 zone_stop "${zone}"
303
304 # Disable the zone
305 zone_disable "${zone}"
306
307 # Rename the configuration files
308 mv -f "$(zone_dir "${zone}")" "$(zone_dir "${name}")"
309
310 # Enable the zone if it was enabled before
311 [ ${zone_was_enabled} -eq ${EXIT_TRUE} ] && zone_enable "${name}"
312
313 # Start the zone if it was up before
314 [ ${zone_was_active} -eq ${EXIT_TRUE} ] && zone_start "${name}"
315
316 log INFO "Zone ${zone} was renamed to ${name}"
317 return ${EXIT_OK}
318}
319
69ace22b 320
1c6a4e30 321zone_destroy() {
cf0fc8ab 322 local zone="${1}"
69ace22b 323
285f779f
MT
324 # Cannot delete a zone that does not exist
325 if ! zone_exists "${zone}"; then
326 log ERROR "Zone ${zone} does not exist"
327 return ${EXIT_ERROR}
328 fi
69ace22b 329
285f779f 330 log INFO "Destroying zone ${zone}"
1848564d 331
69ace22b 332 # Force the zone down.
d5c9bd17 333 zone_is_active "${zone}" && zone_stop "${zone}"
1848564d 334
285f779f 335 # Disable zone auto-start
5c5b8e36
SS
336 zone_disable "${zone}"
337
cf0fc8ab 338 rm -rf "$(zone_dir "${zone}")"
1848564d
MT
339}
340
1c6a4e30 341zone_up() {
1848564d
MT
342 local zone=${1}
343 shift
344
345 if ! zone_exists ${zone}; then
346 error "Zone '${zone}' does not exist."
347 return ${EXIT_ERROR}
348 fi
349
2472e0ea 350 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
351 if [ -z "${hook}" ]; then
352 error "Config file did not provide any hook."
353 return ${EXIT_ERROR}
354 fi
355
d61a01d4 356 if ! hook_zone_exists ${hook}; then
1848564d
MT
357 error "Hook '${hook}' does not exist."
358 return ${EXIT_ERROR}
359 fi
360
059469a8
MT
361 zone_db ${zone} starting
362
2212045f 363 hook_zone_exec ${hook} up ${zone} "$@"
d61a01d4 364
059469a8 365 zone_db ${zone} started
de3cecef
MT
366
367 # Execute all triggers after the zone got up
368 triggers_execute_all "up" ZONE="${zone}"
1848564d
MT
369}
370
1c6a4e30 371zone_down() {
1848564d
MT
372 local zone=${1}
373 shift
374
375 if ! zone_exists ${zone}; then
376 error "Zone '${zone}' does not exist."
377 return ${EXIT_ERROR}
378 fi
379
2472e0ea 380 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
381 if [ -z "${hook}" ]; then
382 error "Config file did not provide any hook."
383 return ${EXIT_ERROR}
384 fi
385
d61a01d4 386 if ! hook_zone_exists ${hook}; then
1848564d
MT
387 error "Hook '${hook}' does not exist."
388 return ${EXIT_ERROR}
389 fi
390
059469a8
MT
391 zone_db ${zone} stopping
392
2212045f 393 hook_zone_exec ${hook} down ${zone} "$@"
059469a8
MT
394
395 zone_db ${zone} stopped
69ace22b 396
de3cecef
MT
397 # Execute all triggers after the zone went down
398 triggers_execute_all "down" ZONE="${zone}"
1848564d
MT
399}
400
1c6a4e30 401zone_status() {
2472e0ea
MT
402 local zone="${1}"
403 assert isset zone
1848564d
MT
404 shift
405
2472e0ea 406 if ! zone_exists "${zone}"; then
1848564d
MT
407 error "Zone '${zone}' does not exist."
408 return ${EXIT_ERROR}
409 fi
410
2472e0ea 411 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
412 if [ -z "${hook}" ]; then
413 error "Config file did not provide any hook."
414 return ${EXIT_ERROR}
415 fi
416
2472e0ea 417 if ! hook_zone_exists "${hook}"; then
1848564d
MT
418 error "Hook '${hook}' does not exist."
419 return ${EXIT_ERROR}
420 fi
421
2472e0ea 422 hook_zone_exec "${hook}" "status" "${zone}" "$@"
1848564d
MT
423}
424
f5ee091e
MT
425zone_identify() {
426 assert [ $# -ge 1 ]
427
428 local zone="${1}"
429 shift
430
431 assert zone_exists "${zone}"
432
433 log INFO "Identifying zone ${zone}"
434 local pids
435
436 local pid
437 local port
438 for port in $(zone_get_ports "${zone}"); do
439 # Identify all the ports
2212045f 440 port_identify "${port}" --background "$@"
f5ee091e
MT
441
442 # Save the PIDs of the subprocesses
443 list_append pids "$(cmd_background_get_pid)"
444 done
445
446 # Wait until all port_identfy processes have finished
447 for pid in ${pids}; do
448 cmd_background_result "${pid}"
449 done
450
451 return ${EXIT_OK}
452}
453
1c6a4e30 454zone_get_ports() {
711ffac1
MT
455 local zone=${1}
456
457 assert isset zone
458
459 local port
60b1f378
MT
460 for port in $(list_directory "$(zone_dir ${zone})/ports"); do
461 if port_exists "${port}"; then
711ffac1
MT
462 echo "${port}"
463 fi
464 done
465}
466
1c6a4e30 467zone_get_ports_num() {
529141df
MT
468 local zone="${1}"
469 assert isset zone
470
471 local counter=0
472 local port
60b1f378 473 for port in $(list_directory "$(zone_dir "${zone}")/ports"); do
529141df
MT
474 if port_exists "${port}"; then
475 counter=$(( ${counter} + 1 ))
476 fi
477 done
478
479 echo "${counter}"
480 return ${EXIT_OK}
481}
482
1c6a4e30 483zone_has_port() {
3a7fef62
MT
484 # Check, if the given port is configured
485 # in this zone.
486
487 local zone=${1}
488 local port=${2}
489 shift 2
490
491 assert isset zone
492 assert isset port
493
494 [ -e "$(zone_dir ${zone})/ports/${port}" ]
495}
496
1c6a4e30 497zone_config() {
ea699552
MT
498 local zone="${1}"
499 local cmd="${2}"
a5ebb169
MT
500 shift 2
501
502 assert isset zone
ea699552
MT
503 assert isset cmd
504 assert zone_exists "${zone}"
a5ebb169 505
ea699552 506 case "${cmd}" in
2a6b2397
MT
507 new)
508 zone_config_new "${zone}" "$@"
509 ;;
510 destroy)
e9582016
JS
511 # usually ${1} is a valid hid
512 local hid=${1}
513 shift 1
514
515 # We convert the hid into an id
516 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
517
518 # If id isset the hid is valid and we can go on with the id
519 if isset id; then
520 zone_config_destroy "${zone}" "${id}" "$@"
521
522 # If we can't get a valid hid we check if we got a valid id
ea37ec0b 523 else
e9582016
JS
524 if zone_config_id_is_valid ${zone} ${hid}; then
525 zone_config_destroy "${zone}" ${hid} "$@"
526 else
527 log ERROR "${id} is not a valid id or hid"
528 fi
ea37ec0b 529 fi
a5ebb169 530 ;;
a5d2c758
JS
531 list)
532 zone_config_list "${zone}" "$@"
533 ;;
a5ebb169 534 *)
e9582016
JS
535 # usually ${1} is a valid hid
536 local hid=${cmd}
537 local cmd=${1}
538 shift 1
539
540 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
541
542 # If id isset the hid is valid and we can go on with the id
543 if isset id && [[ ${cmd} == "edit" ]]; then
544 zone_config_edit "${zone}" "${id}" "$@"
e6a03d56 545
e9582016 546 # If we didn't get a valid hid we check if we got a valid id
e6a03d56 547 else
e9582016
JS
548 if zone_config_id_is_valid ${zone} ${id} && [[ ${cmd} == "edit" ]]; then
549 shift 1
550 zone_config_edit "${zone}" "${id}" "$@"
551 else
552 # in ${hid} is saved the command after network zone ${zone} config
553 error "Unrecognized argument: ${hid}"
554 cli_usage root-zone-config-subcommands
555 exit ${EXIT_ERROR}
556 fi
e6a03d56 557 fi
a5ebb169
MT
558 ;;
559 esac
560}
561
1c6a4e30 562zone_config_cmd() {
ea699552 563 assert [ $# -gt 2 ]
a5ebb169 564
ea699552
MT
565 local cmd="${1}"
566 local zone="${2}"
567 shift 2
568
569 local hook="$(zone_get_hook "${zone}")"
a5ebb169
MT
570 assert isset hook
571
ea699552
MT
572 hook_zone_exec "${hook}" "config_${cmd}" "${zone}" "$@"
573}
574
2a6b2397 575zone_config_new() {
44b8ade9
SS
576 local zone="${1}"
577 shift
578
579 # Create a new configuration, but exit when that was
580 # not successful.
581 zone_config_cmd "new" "${zone}" "$@" || return ${?}
582
583 # If the config could be created, we will try to bring
584 # it up if the zone is up, too.
585 if zone_is_up "${zone}"; then
586 zone_configs_up "${zone}"
587 fi
ea699552
MT
588}
589
2a6b2397
MT
590zone_config_destroy() {
591 zone_config_cmd "destroy" "$@"
ea699552
MT
592}
593
2a6b2397
MT
594zone_config_edit() {
595 zone_config_cmd "edit" "$@"
ea699552
MT
596}
597
a5d2c758
JS
598zone_config_list() {
599 # This function list in an nice way all configs of a zone
600 local zone=${1}
601 assert isset zone
602
603 # Print a nice header
fc36aaf4
JS
604 local format="%-3s %-20s %-20s"
605 print "${format}" "ID" "HOOK" "HID"
a5d2c758
JS
606
607 local config
608 local hook
609 local id
fc36aaf4 610 local hid
a5d2c758
JS
611
612 # Print for all config:
613 # id and hook
a5d2c758
JS
614 for config in $(zone_configs_list "${zone}"); do
615 id=${config##*.}
616 hook=$(zone_config_get_hook "${zone}" "${config}")
fc36aaf4 617 hid=$(zone_config_get_hid "${zone}" "${config}")
a5d2c758 618 assert isset hook
fc36aaf4 619 print "${format}" "${id}" "${hook}" "${hid}"
a5d2c758
JS
620 done
621}
622
1c6a4e30 623zone_config_show() {
ea699552 624 zone_config_cmd "show" "$@"
a5ebb169
MT
625}
626
d2998dc2
JS
627# Returns a list of all used ids for a zone
628zone_config_list_ids() {
629 assert [ $# -eq 1 ]
630
631 local zone=${1}
632 local config
633 local ids
634
635 for config in $(zone_configs_list ${zone}); do
636 list_append ids "$(config_get_id_from_config ${config})"
637 done
638
639 echo ${ids}
640}
641
450afe05
JS
642# List all hids of a zone
643zone_config_list_hids() {
644 assert [ $# -eq 1 ]
645
646 local zone=${1}
647
648 local config
649 for config in $(zone_configs_list ${zone}); do
650 zone_config_get_hid "${zone}" "${config}"
651 done
652}
653
654# get the hid from a given config
655zone_config_get_hid() {
656 assert [ $# -eq 2 ]
657
658 local zone=${1}
659 local config=${2}
660
661 local hook="$(zone_config_get_hook "${zone}" "${config}")"
662
663 hook_exec "config" "${hook}" "hid" "${zone}" "${config}"
664}
665
666# Checks if a hid is valid for a given zone
667zone_config_hid_is_valid() {
668 assert [ $# -eq 2]
669
670 local zone=${1}
671 local hid=${2}
672
673 local _hid
674 for _hid in $(zone_config_list_hids "${zone}"); do
675 if [[ ${_hid} = ${hid} ]]; then
676 return ${EXIT_TRUE}
677 fi
678 done
679
680 return ${EXIT_FALSE}
681}
682
683# This function converts a hid to a id
684zone_config_convert_hid_to_id() {
685 assert [ $# -eq 2 ]
686
687 local zone=${1}
688 local hid=${2}
689
690 local config
691 for config in $(zone_configs_list ${zone}); do
692 # Get hook from config
693 local hook="$(zone_config_get_hook "${zone}" "${config}")"
694
695 if [[ "$(hook_exec "config" "${hook}" "hid" "${zone}" "${config}")" == "${hid}" ]]; then
696 config_get_id_from_config "${config}"
697 return ${EXIT_TRUE}
698 fi
699 done
700
701 return ${EXIT_FALSE}
702}
703
1c6a4e30 704zone_show() {
1848564d
MT
705 local zone=${1}
706
707 echo "${zone}"
708 echo " Type: $(zone_get_hook ${zone})"
709 echo
710}
711
1c6a4e30 712zones_show() {
1848564d
MT
713 local zone
714
2212045f 715 for zone in $(zones_get "$@"); do
1848564d
MT
716 zone_show ${zone}
717 done
718}
719
1c6a4e30 720zones_get_all() {
1848564d 721 local zone
60b1f378
MT
722 for zone in $(list_directory "$(zone_dir)"); do
723 if zone_exists ${zone}; then
724 echo "${zone}"
725 fi
03170817 726 done
1848564d
MT
727}
728
1ca5fe9f
JS
729zones_get_next_free() {
730 # This function return the next free zones.
731 # Example net0 upl0 upl1 are configured so the next free zones are:
732 # net1 upl2
733 local i
734 local zone_name
735 for zone_name in ${VALID_ZONES}; do
736 i=0
737
738 while true; do
739 local zone="${zone_name}${i}"
740 if ! zone_exists ${zone}; then
741 echo "${zone}"
742 break
743 fi
744 i=$(( i + 1 ))
745 done
746 done
747}
748
1c6a4e30 749zones_get_local() {
1848564d
MT
750 local zone
751 for zone in $(zones_get_all); do
752 zone_is_local ${zone} && echo "${zone}"
753 done
754}
755
1c6a4e30 756zones_get_nonlocal() {
1848564d
MT
757 local zone
758 for zone in $(zones_get_all); do
5e42d659 759 zone_is_nonlocal ${zone} && echo "${zone}"
1848564d
MT
760 done
761}
762
1c6a4e30 763zones_get() {
1848564d
MT
764 local local=1
765 local remote=1
766
767 local zones
768
769 while [ $# -gt 0 ]; do
770 case "${1}" in
771 --local-only)
772 local=1
773 remote=0
774 ;;
775 --remote-only)
776 local=0
777 remote=1
778 ;;
779 --all)
780 local=1
781 remote=1
782 ;;
783 *)
784 if zone_name_is_valid ${1}; then
785 zones="${zones} ${1}"
786 else
787 warning "Unrecognized argument '${1}'"
788 fi
789 ;;
790 esac
791 shift
792 done
793
794 if [ -n "${zones}" ]; then
795 local zone
796 for zone in ${zones}; do
797 zone_exists ${zone} && echo "${zone}"
798 done
799 exit ${EXIT_OK}
800 fi
801
802 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
803 zones_get_all
804 elif [ ${local} -eq 1 ]; then
805 zones_get_local
806 elif [ ${remote} -eq 1 ]; then
807 zones_get_nonlocal
808 fi
809}
810
1c6a4e30 811zone_ports_list() {
1848564d
MT
812 local zone=${1}
813
60b1f378 814 list_directory "$(zone_dir ${zone})/ports"
1848564d
MT
815}
816
1c6a4e30 817zone_port_attach() {
ac694a6a
MT
818 local zone="${1}"
819 assert isset zone
820
821 local port="${2}"
822 assert isset port
823
824 shift 2
825
826 # Check if the port actually exists.
827 if ! port_exists "${port}"; then
828 error "Cannot attach port '${port}' which does not exist"
829 return ${EXIT_ERROR}
830 fi
831
832 # Check if the port is already connected to this or any other zone.
833 local z
834 for z in $(zones_get_all); do
835 if zone_has_port "${z}" "${port}"; then
836 error "Port '${port}' is already attached to zone '${z}'"
837 return ${EXIT_ERROR}
838 fi
839 done
840
841 local hook="$(zone_get_hook "${zone}")"
842 assert isset hook
843
f5ee091e 844 # Make the port briefly flash if supported
01a079e0
MT
845 if device_exists ${port}; then
846 port_identify "${port}" --background
847 fi
f5ee091e 848
ac694a6a
MT
849 hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
850 local ret="${?}"
851
852 case "${ret}" in
853 ${EXIT_OK})
854 log INFO "${port} has been attached to ${zone}"
855
856 # Automatically connect the port
abba34c1 857 zone_port_start "${zone}" "${port}"
ac694a6a
MT
858 ;;
859 *)
860 log CRITICAL "${port} could not be attached to ${zone}"
861 ;;
862 esac
863
864 return ${ret}
865}
866
1c6a4e30 867zone_port_edit() {
ac694a6a
MT
868 local zone="${1}"
869 assert isset zone
870
871 local port="${2}"
872 assert isset port
873
874 shift 2
875
876 # Check if the port actually exists.
877 if ! port_exists "${port}"; then
878 error "Port '${port}' does not exist"
879 return ${EXIT_ERROR}
880 fi
881
882 # Check if the zone actually has this port.
883 if ! zone_has_port "${zone}" "${port}"; then
884 error "Port '${port}' is not attached to zone '${zone}'"
885 return ${EXIT_ERROR}
886 fi
887
888 local hook=$(zone_get_hook "${zone}")
889 assert isset hook
890
891 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
892}
893
1c6a4e30 894zone_port_detach() {
ac694a6a
MT
895 local zone="${1}"
896 assert isset zone
897
898 local port="${2}"
899 assert isset port
900
1848564d
MT
901 shift 2
902
ac694a6a
MT
903 # Check if the zone actually has this port.
904 if ! zone_has_port "${zone}" "${port}"; then
905 error "Port '${port}' is not attached to zone '${zone}'"
906 return ${EXIT_ERROR}
907 fi
908
909 local hook=$(zone_get_hook "${zone}")
910 assert isset hook
911
f5ee091e
MT
912 # Make the port briefly flash if supported
913 port_identify "${port}" --background
914
ac694a6a
MT
915 hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
916 local ret="${?}"
917
918 case "${ret}" in
919 ${EXIT_OK})
920 log INFO "${port} has been detached from ${zone}"
921
922 # Bring down the port if needed
abba34c1 923 zone_port_stop "${zone}" "${port}"
ac694a6a
MT
924 ;;
925 *)
926 log CRITICAL "${port} could not be detached from ${zone}"
927 ;;
928 esac
929
930 return ${ret}
931}
932
1c6a4e30 933zone_port_cmd() {
ac694a6a 934 local cmd="${1}"
711ffac1 935 assert isset cmd
ac694a6a
MT
936
937 local zone="${2}"
711ffac1 938 assert isset zone
1848564d 939
ac694a6a
MT
940 local port="${3}"
941 assert isset port
1848564d 942
ac694a6a
MT
943 shift 3
944
945 local hook="$(zone_get_hook "${zone}")"
946 assert isset hook
947
948 # Dispatch command to hook
2212045f 949 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
ac694a6a
MT
950}
951
1c6a4e30 952zone_port_create() {
2212045f 953 zone_port_cmd "port_create" "$@"
ac694a6a
MT
954}
955
1c6a4e30 956zone_port_remove() {
2212045f 957 zone_port_cmd "port_remove" "$@"
ac694a6a
MT
958}
959
1c6a4e30 960zone_port_up() {
2212045f 961 zone_port_cmd "port_up" "$@"
ac694a6a
MT
962}
963
1c6a4e30 964zone_port_down() {
2212045f 965 zone_port_cmd "port_down" "$@"
ac694a6a
MT
966}
967
abba34c1
MT
968# The next two functions automagically bring up and down
969# port that are attached to a bridge or similar.
970# The problem that is tried to overcome here is that there
971# are ports which exist all the time (like ethernet ports)
972# and therefore do not dispatch a hotplug event when
973# port_create is called.
974
1c6a4e30 975zone_port_start() {
abba34c1
MT
976 local zone="${1}"
977 local port="${2}"
978
979 if zone_is_active "${zone}"; then
980 if device_exists "${port}"; then
981 zone_port_up "${zone}" "${port}"
982 return ${?}
983 else
984 zone_port_create "${zone}" "${port}"
985 return ${?}
986 fi
987 fi
988
989 return ${EXIT_OK}
990}
991
1c6a4e30 992zone_port_stop() {
abba34c1
MT
993 local zone="${1}"
994 local port="${2}"
995
996 # Shut down the port if necessary
997 if zone_is_active "${zone}" && port_is_up "${port}"; then
998 zone_port_down "${zone}" "${port}"
999 fi
1000
1001 # Remove the port
1002 zone_port_remove "${zone}" "${port}"
1003}
1004
1c6a4e30 1005zone_port_status() {
2212045f 1006 zone_port_cmd "port_status" "$@"
ac694a6a
MT
1007}
1008
1c6a4e30 1009zone_ports_cmd() {
ac694a6a
MT
1010 local cmd="${1}"
1011 assert isset cmd
1012
1013 local zone="${2}"
1014 assert isset zone
1015
1016 shift 2
1017
1018 local hook="$(zone_get_hook "${zone}")"
711ffac1
MT
1019
1020 local port
1021 for port in $(zone_get_ports ${zone}); do
2212045f 1022 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
1848564d
MT
1023 done
1024}
1025
1c6a4e30 1026zone_ports_create() {
2212045f 1027 zone_ports_cmd "port_create" "$@"
1ba6a2bb
MT
1028}
1029
1c6a4e30 1030zone_ports_remove() {
2212045f 1031 zone_ports_cmd "port_remove" "$@"
1ba6a2bb
MT
1032}
1033
1c6a4e30 1034zone_ports_up() {
2212045f 1035 zone_ports_cmd "port_up" "$@"
1848564d
MT
1036}
1037
1c6a4e30 1038zone_ports_down() {
2212045f 1039 zone_ports_cmd "port_down" "$@"
711ffac1
MT
1040}
1041
1c6a4e30 1042zone_ports_status() {
2212045f 1043 zone_ports_cmd "port_status" "$@"
1848564d
MT
1044}
1045
1c6a4e30 1046zone_configs_cmd() {
2472e0ea 1047 assert [ $# -ge 2 ]
ea699552
MT
1048
1049 local cmd="${1}"
1050 local zone="${2}"
1848564d
MT
1051 shift 2
1052
ea699552 1053 assert zone_exists "${zone}"
1848564d 1054
1848564d 1055 local config
2472e0ea
MT
1056 for config in $(zone_configs_list "${zone}"); do
1057 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1058 assert isset config_hook
1059
2212045f 1060 hook_config_exec "${config_hook}" "${cmd}" "${zone}" "${config}" "$@"
1848564d
MT
1061 done
1062}
1063
1c6a4e30 1064zone_configs_up() {
2212045f 1065 zone_configs_cmd "up" "$@"
1848564d
MT
1066}
1067
1c6a4e30 1068zone_configs_down() {
2212045f 1069 zone_configs_cmd "down" "$@"
1848564d
MT
1070}
1071
1c6a4e30 1072zone_configs_status() {
2212045f 1073 zone_configs_cmd "status" "$@"
ea699552
MT
1074}
1075
1c6a4e30 1076zone_configs_list() {
ea699552
MT
1077 local zone=${1}
1078
60b1f378 1079 list_directory "$(zone_dir ${zone})/configs"
a5ebb169
MT
1080}
1081
0afedf0d
JS
1082zone_config_get_new_id() {
1083 # This functions returns the next free id for a zone
1084
1085 assert [ $# -eq 1 ]
1086 local zone=${1}
1087
1088 local zone_path=$(zone_dir ${zone})
1089 local i=0
1090
1091 while true; do
1092 if [ ! -f ${zone_path}/configs/*.${i} ]; then
1093 echo "${i}"
1094 return ${EXIT_OK}
1095 fi
1096 (( i++ ))
1097 done
1098}
1099
6727e4be
JS
1100zone_config_check_same_setting() {
1101 # This functions checks if a config hook
1102 # with the same setting is already configured for this zone.
1103 # Returns True when yes and False when no.
1104
1105 assert [ $# -eq 4 ]
1106
1107 local zone=${1}
1108 local hook=${2}
1109 local key=${3}
1110 local value=${4}
1111
1112 # The key should be local for this function
1113 local ${key}
1114 local config
1115
1116 for config in $(zone_configs_list ${zone}); do
1117 # Check if the config is from the given hook, when not continue
1118 if [[ $(zone_config_get_hook "${zone}" "${config}") != ${hook} ]]; then
1119 continue
1120 fi
1121 # Get the value of the key for a given function
1122 zone_config_settings_read "${zone}" "${config}" \
1123 --ignore-superfluous-settings "${key}"
1124 # Check if the value of the config and the passed value are eqal
1125 if [[ "${value}" == "${!key}" ]]; then
1126 return ${EXIT_TRUE}
1127 fi
1128 done
1129
1130 return ${EXIT_FALSE}
1131}
1132
1c6a4e30 1133zone_config_get_hook() {
2472e0ea
MT
1134 assert [ $# -eq 2 ]
1135
1136 local zone="${1}"
1137 assert isset zone
1138
1139 local config="${2}"
1140 assert isset config
1141
1142 local HOOK
1143 zone_config_settings_read "${zone}" "${config}" \
1144 --ignore-superfluous-settings HOOK
1145
1146 print "${HOOK}"
1147}
1148
41f8233d
JS
1149zone_config_hook_is_configured() {
1150 # Checks if a zone has already at least one config with the given hook.
1151 # Returns True when yes and False when no
1152
1153 assert [ $# -eq 2 ]
1154 local zone=${1}
1155 local hook=${2}
1156
1157 local config
1158 for config in $(zone_configs_list "${zone}"); do
1159 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1160 assert isset config_hook
1161 if [[ ${hook} == ${config_hook} ]]; then
1162 return ${EXIT_TRUE}
1163 fi
1164
1165 done
1166
1167 # If we get here the zone has no config with the given hook
1168 return ${EXIT_FALSE}
1169}
1170
f158dc66
JS
1171zone_config_id_is_valid() {
1172 # This function checks if a given id is valid for a zone
1173 # Return True when yes and false when no
1174
1175 assert [ $# -eq 2 ]
1176 local zone=${1}
1177 local id=${2}
1178
1179 local zone_path=$(zone_dir ${zone})
1180
1181 [ -f ${zone_path}/configs/*.${id} ];
1182}
1183
450afe05
JS
1184# This function checks if a given hid is valid for a zone
1185# Return True when yes and false when no
1186zone_config_hid_is_valid() {
1187 assert [ $# -eq 2 ]
1188 local zone=${1}
1189 local hid=${2}
1190
1191 local _hid
1192 for _hid in $(zone_config_list_hids ${zone}); do
1193 if [[ ${_hid} == ${hid} ]]; then
1194 return ${EXIT_TRUE}
1195 fi
1196 done
1197
1198 return ${EXIT_FALSE}
1199}
1200
cdf4266d
JS
1201zone_config_get_hook_from_id() {
1202 # Returns the hook for a given id
1203 assert [ $# -eq 2 ]
1204 local zone=${1}
1205 local id=${2}
1206
1207 local config
1208 for config in $(zone_configs_list "${zone}"); do
1209 if [[ ${config} == *.${id} ]]; then
1210 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1211 assert isset config_hook
1212 print "${config_hook}"
1213 return "${EXIT_OK}"
1214 fi
1215 done
1216
1217 # If we get here the zone has no config with the given id
1218 return ${EXIT_ERROR}
1219}
1220
1c6a4e30 1221zone_has_ip() {
2212045f 1222 device_has_ip "$@"
4231f419
MT
1223}
1224
1c6a4e30 1225zone_db() {
059469a8
MT
1226 local zone=${1}
1227 local action=${2}
1228 shift 2
1229
1230 case "${action}" in
1231 starting|started|stopping|stopped)
1232 db_connection_update ${zone} ${action}
1233 ;;
1234 esac
1235}
5e42d659 1236
1c6a4e30 1237zone_is_up() {
5e42d659
MT
1238 local zone=${1}
1239
1240 device_is_up ${zone}
1241}
1242
1c6a4e30 1243zone_is_down() {
2212045f 1244 ! zone_is_up "$@"
5e42d659 1245}
711ffac1 1246
1c6a4e30 1247zone_get_supported_port_hooks() {
711ffac1
MT
1248 local zone=${1}
1249
1250 local hook=$(zone_get_hook ${zone})
1251
1252 hook_zone_ports_get_all ${hook}
1253}
1254
1c6a4e30 1255zone_get_supported_config_hooks() {
ea699552 1256 hook_config_get_all
a5ebb169
MT
1257}
1258
1c6a4e30 1259zone_file() {
711ffac1
MT
1260 local zone=${1}
1261
1262 assert isset zone
1263
1264 echo "$(zone_dir ${zone})/settings"
1265}
1266
1c6a4e30 1267zone_settings_read() {
711ffac1 1268 local zone=${1}
711ffac1 1269 assert isset zone
52acd25f
MT
1270 shift
1271
1272 local args
1273 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then
1274 list_append args ${HOOK_SETTINGS}
1275 else
2212045f 1276 list_append args "$@"
52acd25f 1277 fi
711ffac1 1278
bfd6c282
MT
1279 # Save the HOOK variable.
1280 local hook="${HOOK}"
1281
52acd25f 1282 settings_read "$(zone_file "${zone}")" ${args}
bfd6c282
MT
1283
1284 # Restore hook.
1285 HOOK="${hook}"
711ffac1
MT
1286}
1287
1c6a4e30 1288zone_settings_write() {
1e6f187e 1289 local zone="${1}"
711ffac1
MT
1290 assert isset zone
1291
1e6f187e
MT
1292 local args
1293 if function_exists "hook_check_settings"; then
1294 list_append args "--check=\"hook_check_settings\""
1295 fi
1296 list_append args ${HOOK_SETTINGS}
1297
1298 settings_write "$(zone_file ${zone})" ${args}
711ffac1
MT
1299}
1300
1c6a4e30 1301zone_settings_set() {
711ffac1
MT
1302 local zone=${1}
1303 shift
1304 local args="$@"
1305
1306 assert isset zone
1307
1308 (
e9df08ad 1309 zone_settings_read ${zone}
711ffac1
MT
1310
1311 for arg in ${args}; do
1312 eval "${arg}"
1313 done
1314
e9df08ad 1315 zone_settings_write ${zone}
711ffac1
MT
1316 )
1317}
6b3f9c85 1318
1c6a4e30 1319zone_settings_get() {
6b3f9c85
MT
1320 local zone=${1}
1321 local key=${2}
1322
1323 assert isset zone
1324 assert isset key
1325
1326 (
1e6f187e
MT
1327 zone_settings_read "${zone}" "${key}" \
1328 --ignore-superfluous-settings
6b3f9c85
MT
1329
1330 echo "${!key}"
1331 )
1332}
e9df08ad 1333
1c6a4e30 1334zone_config_settings_read() {
c8132752 1335 assert [ $# -ge 2 ]
e9df08ad
MT
1336
1337 local zone="${1}"
1338 local config="${2}"
1339 shift 2
1340
c8132752
MT
1341 local args
1342 if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then
1343 list_append args ${HOOK_CONFIG_SETTINGS}
1344 else
2212045f 1345 list_append args "$@"
c8132752
MT
1346 fi
1347
e9df08ad 1348 local path="$(zone_dir "${zone}")/configs/${config}"
c8132752 1349 settings_read "${path}" ${args}
e9df08ad
MT
1350}
1351
1c6a4e30 1352zone_config_settings_write() {
c8132752 1353 assert [ $# -ge 2 ]
e9df08ad
MT
1354
1355 local zone="${1}"
0959b0b9
JS
1356 local hook="${2}"
1357 local id=${3}
1358
1359 if ! isset id; then
1360 id=$(zone_config_get_new_id ${zone})
1361 log DEBUG "ID for the config is: ${id}"
1362 fi
e9df08ad 1363
c8132752
MT
1364 local args
1365 if function_exists "hook_check_config_settings"; then
1366 list_append args "--check=\"hook_check_config_settings\""
1367 fi
1368 list_append args ${HOOK_CONFIG_SETTINGS}
1369
0959b0b9 1370 local path="$(zone_dir "${zone}")/configs/${hook}.${id}"
c8132752 1371 settings_write "${path}" ${args}
e9df08ad
MT
1372}
1373
ea96cf52
JS
1374zone_config_settings_destroy() {
1375 # This function deletes the config file for a given zone and config
1376 assert [ $# -ge 2 ]
1377 local zone="${1}"
1378 local config="${2}"
1379
1380 local path="$(zone_dir "${zone}")/configs/${config}"
1381
1382 # Check if path is valid
1383 if [ ! -f ${path} ]; then
1384 log ERROR "Path: '${path}' is not valid"
1385 return ${EXIT_ERROR}
1386 fi
1387
1388 log DEBUG "Deleting config file ${path}"
1389 rm -f "${path}"
1390
1391}
1c6a4e30 1392zone_port_settings_read() {
ac694a6a 1393 assert [ $# -ge 2 ]
e9df08ad
MT
1394
1395 local zone="${1}"
1396 local port="${2}"
1397 shift 2
1398
ac694a6a
MT
1399 local args
1400 if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
1401 list_append args ${HOOK_PORT_SETTINGS}
1402 else
2212045f 1403 list_append args "$@"
ac694a6a
MT
1404 fi
1405
e9df08ad 1406 local path="$(zone_dir "${zone}")/ports/${port}"
ac694a6a 1407 settings_read "${path}" ${args}
e9df08ad
MT
1408}
1409
1c6a4e30 1410zone_port_settings_write() {
02236ca6 1411 assert [ $# -ge 2 ]
e9df08ad
MT
1412
1413 local zone="${1}"
1414 local port="${2}"
1415 shift 2
1416
1e6f187e
MT
1417 local args
1418 if function_exists "hook_check_port_settings"; then
1419 list_append args "--check=\"hook_check_port_settings\""
1420 fi
ac694a6a 1421 list_append args ${HOOK_PORT_SETTINGS}
1e6f187e 1422
e9df08ad 1423 local path="$(zone_dir "${zone}")/ports/${port}"
1e6f187e 1424 settings_write "${path}" ${args}
e9df08ad
MT
1425}
1426
1c6a4e30 1427zone_port_settings_remove() {
e9df08ad
MT
1428 assert [ $# -eq 2 ]
1429
1430 local zone="${1}"
1431 local port="${2}"
1432
1433 local path="$(zone_dir "${zone}")/ports/${port}"
1434 settings_remove "${path}"
1435}
410d2e85
JS
1436
1437zone_get_color() {
1438 # This function return the color of a zone
1439 assert [ $# -eq 1 ]
1440
1441 local name=${1}
1442 color_read "zone" ${name}
1443}
5de34b4c
JS
1444
1445zone_get_description_title() {
1446 assert [ $# -eq 1 ]
1447
1448 local name=${1}
1449 description_title_read $(description_format_filename "zone" "${name}")
1450}