]> git.ipfire.org Git - people/ms/network.git/blob - src/functions/functions.zone
zone: Automatically bring up all configs after creation
[people/ms/network.git] / src / functions / functions.zone
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
22 zone_dir() {
23 local zone=${1}
24
25 echo "${NETWORK_ZONE_DIR}/zones/${zone}"
26 }
27
28 zone_exists() {
29 local zone=${1}
30 assert isset zone
31
32 [ -d "$(zone_dir ${zone})" ]
33 }
34
35 zone_match() {
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
46 zone_name_is_valid() {
47 local zone=${1}
48
49 # Don't accept empty strings.
50 [ -z "${zone}" ] && return ${EXIT_FALSE}
51
52 [[ ${zone} =~ $(zone_match) ]]
53 }
54
55 zone_is_local() {
56 local zone=${1}
57
58 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
59 }
60
61 zone_is_nonlocal() {
62 local zone=${1}
63
64 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
65 }
66
67 zone_get_hook() {
68 local zone=${1}
69 assert isset zone
70
71 config_get_hook $(zone_dir ${zone})/settings
72 }
73
74 zone_start() {
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
81 service_start "network@${zone}.service"
82 }
83
84 zone_start_auto() {
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
106 zone_stop() {
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
113 service_stop "network@${zone}.service"
114 }
115
116 zone_reload() {
117 local zone="${1}"
118 assert zone_exists "${zone}"
119
120 service_reload "network@${zone}.service"
121 }
122
123 zone_hotplug_event() {
124 local zone="${1}"
125 assert isset zone
126
127 hotplug_assert_in_hotplug_event
128
129 zone_cmd "hotplug" "${zone}"
130 }
131
132 zone_enable() {
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
152 zone_disable() {
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
172 zone_is_enabled() {
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
184 zone_is_active() {
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
195 zone_is_enabled_or_active() {
196 local zone="${1}"
197 assert isset zone
198
199 zone_is_enabled "${zone}" || zone_is_active "${zone}"
200 }
201
202 zone_cmd() {
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
213 hook_exec zone "${hook}" "${cmd}" "${zone}" $@
214 }
215
216 zone_new() {
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
231 if ! hook_zone_exists ${hook}; then
232 error "Hook '${hook}' does not exist."
233 return ${EXIT_ERROR}
234 fi
235
236 mkdir -p $(zone_dir ${zone})
237
238 # Create directories for configs and ports
239 mkdir -p $(zone_dir ${zone})/{configs,ports}
240
241 hook_zone_exec "${hook}" "new" "${zone}" $@
242 local ret=$?
243
244 # Maybe the zone new hook did not exit correctly.
245 # If this is the case we remove the created zone immediately.
246 if [ "${ret}" = "${EXIT_ERROR}" ]; then
247 zone_destroy_now "${zone}"
248 return ${EXIT_ERROR}
249 fi
250
251 # Automatically enable zone.
252 zone_enable "${zone}"
253
254 # Bring up the zone immediately after
255 zone_start "${zone}"
256 }
257
258 zone_edit() {
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
267 # Check if the zone is tagged for removal.
268 if zone_has_destroy_tag ${zone}; then
269 error "You cannot edit a zone that is tagged for removal."
270 return ${EXIT_ERROR}
271 fi
272
273 local hook="$(zone_get_hook "${zone}")"
274 if [ -z "${hook}" ]; then
275 error "Config file did not provide any hook."
276 return ${EXIT_ERROR}
277 fi
278
279 if ! hook_zone_exists ${hook}; then
280 error "Hook '${hook}' does not exist."
281 return ${EXIT_ERROR}
282 fi
283
284 hook_zone_exec ${hook} edit ${zone} $@
285 }
286
287
288 zone_destroy() {
289 local zone="${1}"
290 assert zone_exists "${zone}"
291
292 # Make the zone for removal.
293 touch "$(zone_dir "${zone}")/.destroy"
294
295 log INFO "Zone '${zone}' has been tagged for removal."
296 }
297
298 zone_has_destroy_tag() {
299 local zone="${1}"
300 assert zone_exists "${zone}"
301
302 [ -e "$(zone_dir "${zone}")/.destroy" ]
303 }
304
305 # This function will remove the given zone
306 # RIGHT NOW. Use zone_destroy to remove it
307 # at the next status change.
308 zone_destroy_now() {
309 local zone="${1}"
310 assert zone_exists "${zone}"
311
312 log INFO "Removing zone '${zone}' right now."
313
314 # Force the zone down.
315 zone_is_active "${zone}" && zone_stop "${zone}"
316
317 # Disable zone.
318 zone_disable "${zone}"
319
320 rm -rf "$(zone_dir "${zone}")"
321 }
322
323 zone_up() {
324 local zone=${1}
325 shift
326
327 if ! zone_exists ${zone}; then
328 error "Zone '${zone}' does not exist."
329 return ${EXIT_ERROR}
330 fi
331
332 # Check if a zone has got the remove tag.
333 if zone_has_destroy_tag ${zone}; then
334 error "Cannot bring up any zone which is to be removed."
335 return ${EXIT_ERROR}
336 fi
337
338 local hook="$(zone_get_hook "${zone}")"
339 if [ -z "${hook}" ]; then
340 error "Config file did not provide any hook."
341 return ${EXIT_ERROR}
342 fi
343
344 if ! hook_zone_exists ${hook}; then
345 error "Hook '${hook}' does not exist."
346 return ${EXIT_ERROR}
347 fi
348
349 zone_db ${zone} starting
350
351 hook_zone_exec ${hook} up ${zone} $@
352
353 zone_db ${zone} started
354
355 # Execute all triggers after the zone got up
356 triggers_execute_all "up" ZONE="${zone}"
357 }
358
359 zone_down() {
360 local zone=${1}
361 shift
362
363 if ! zone_exists ${zone}; then
364 error "Zone '${zone}' does not exist."
365 return ${EXIT_ERROR}
366 fi
367
368 local hook="$(zone_get_hook "${zone}")"
369 if [ -z "${hook}" ]; then
370 error "Config file did not provide any hook."
371 return ${EXIT_ERROR}
372 fi
373
374 if ! hook_zone_exists ${hook}; then
375 error "Hook '${hook}' does not exist."
376 return ${EXIT_ERROR}
377 fi
378
379 zone_db ${zone} stopping
380
381 hook_zone_exec ${hook} down ${zone} $@
382
383 zone_db ${zone} stopped
384
385 # Execute all triggers after the zone went down
386 triggers_execute_all "down" ZONE="${zone}"
387
388 # Remove the zone, if it has got a remove tag.
389 if zone_has_destroy_tag "${zone}"; then
390 zone_destroy_now "${zone}"
391 fi
392 }
393
394 zone_status() {
395 local zone="${1}"
396 assert isset zone
397 shift
398
399 if ! zone_exists "${zone}"; then
400 error "Zone '${zone}' does not exist."
401 return ${EXIT_ERROR}
402 fi
403
404 local hook="$(zone_get_hook "${zone}")"
405 if [ -z "${hook}" ]; then
406 error "Config file did not provide any hook."
407 return ${EXIT_ERROR}
408 fi
409
410 if ! hook_zone_exists "${hook}"; then
411 error "Hook '${hook}' does not exist."
412 return ${EXIT_ERROR}
413 fi
414
415 hook_zone_exec "${hook}" "status" "${zone}" "$@"
416
417 # Show that the zone it to be removed soon.
418 if zone_has_destroy_tag ${zone}; then
419 warning "This zone is tagged for removal."
420 fi
421 }
422
423 zone_get_ports() {
424 local zone=${1}
425
426 assert isset zone
427
428 local port
429 for port in $(zone_dir ${zone})/ports/*; do
430 port=$(basename ${port})
431
432 if port_exists ${port}; then
433 echo "${port}"
434 fi
435 done
436 }
437
438 zone_get_ports_num() {
439 local zone="${1}"
440 assert isset zone
441
442 local counter=0
443 local port
444 for port in $(zone_dir "${zone}")/ports/*; do
445 port="$(basename "${port}")"
446
447 if port_exists "${port}"; then
448 counter=$(( ${counter} + 1 ))
449 fi
450 done
451
452 echo "${counter}"
453 return ${EXIT_OK}
454 }
455
456 zone_has_port() {
457 # Check, if the given port is configured
458 # in this zone.
459
460 local zone=${1}
461 local port=${2}
462 shift 2
463
464 assert isset zone
465 assert isset port
466
467 [ -e "$(zone_dir ${zone})/ports/${port}" ]
468 }
469
470 zone_config() {
471 local zone="${1}"
472 local cmd="${2}"
473 shift 2
474
475 assert isset zone
476 assert isset cmd
477 assert zone_exists "${zone}"
478
479 case "${cmd}" in
480 new)
481 zone_config_new "${zone}" "$@"
482 ;;
483 destroy)
484 zone_config_destroy "${zone}" "$@"
485 ;;
486 edit)
487 zone_config_edit "${zone}" "$@"
488 ;;
489 *)
490 error "Unrecognized argument: ${cmd}"
491 cli_usage root-zone-config-subcommands
492 exit ${EXIT_ERROR}
493 ;;
494 esac
495 }
496
497 zone_config_cmd() {
498 assert [ $# -gt 2 ]
499
500 local cmd="${1}"
501 local zone="${2}"
502 shift 2
503
504 local hook="$(zone_get_hook "${zone}")"
505 assert isset hook
506
507 hook_zone_exec "${hook}" "config_${cmd}" "${zone}" "$@"
508 }
509
510 zone_config_new() {
511 local zone="${1}"
512 shift
513
514 # Create a new configuration, but exit when that was
515 # not successful.
516 zone_config_cmd "new" "${zone}" "$@" || return ${?}
517
518 # If the config could be created, we will try to bring
519 # it up if the zone is up, too.
520 if zone_is_up "${zone}"; then
521 zone_configs_up "${zone}"
522 fi
523 }
524
525 zone_config_destroy() {
526 zone_config_cmd "destroy" "$@"
527 }
528
529 zone_config_edit() {
530 zone_config_cmd "edit" "$@"
531 }
532
533 zone_config_show() {
534 zone_config_cmd "show" "$@"
535 }
536
537 zone_show() {
538 local zone=${1}
539
540 echo "${zone}"
541 echo " Type: $(zone_get_hook ${zone})"
542 echo
543 }
544
545 zones_show() {
546 local zone
547
548 for zone in $(zones_get $@); do
549 zone_show ${zone}
550 done
551 }
552
553 zones_get_all() {
554 local zone
555 for zone in $(zone_dir)/*; do
556 zone=$(basename ${zone})
557 zone_exists ${zone} || continue
558
559 echo "${zone}"
560 done
561 }
562
563 zones_get_local() {
564 local zone
565 for zone in $(zones_get_all); do
566 zone_is_local ${zone} && echo "${zone}"
567 done
568 }
569
570 zones_get_nonlocal() {
571 local zone
572 for zone in $(zones_get_all); do
573 zone_is_nonlocal ${zone} && echo "${zone}"
574 done
575 }
576
577 zones_get() {
578 local local=1
579 local remote=1
580
581 local zones
582
583 while [ $# -gt 0 ]; do
584 case "${1}" in
585 --local-only)
586 local=1
587 remote=0
588 ;;
589 --remote-only)
590 local=0
591 remote=1
592 ;;
593 --all)
594 local=1
595 remote=1
596 ;;
597 *)
598 if zone_name_is_valid ${1}; then
599 zones="${zones} ${1}"
600 else
601 warning "Unrecognized argument '${1}'"
602 fi
603 ;;
604 esac
605 shift
606 done
607
608 if [ -n "${zones}" ]; then
609 local zone
610 for zone in ${zones}; do
611 zone_exists ${zone} && echo "${zone}"
612 done
613 exit ${EXIT_OK}
614 fi
615
616 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
617 zones_get_all
618 elif [ ${local} -eq 1 ]; then
619 zones_get_local
620 elif [ ${remote} -eq 1 ]; then
621 zones_get_nonlocal
622 fi
623 }
624
625 zone_ports_list() {
626 local zone=${1}
627
628 local port
629 for port in $(zone_dir ${zone})/ports/*; do
630 [ -e "${port}" ] || continue
631
632 echo $(basename ${port})
633 done
634 }
635
636 zone_port_attach() {
637 local zone="${1}"
638 assert isset zone
639
640 local port="${2}"
641 assert isset port
642
643 shift 2
644
645 # Check if the port actually exists.
646 if ! port_exists "${port}"; then
647 error "Cannot attach port '${port}' which does not exist"
648 return ${EXIT_ERROR}
649 fi
650
651 # Check if the port is already connected to this or any other zone.
652 local z
653 for z in $(zones_get_all); do
654 if zone_has_port "${z}" "${port}"; then
655 error "Port '${port}' is already attached to zone '${z}'"
656 return ${EXIT_ERROR}
657 fi
658 done
659
660 local hook="$(zone_get_hook "${zone}")"
661 assert isset hook
662
663 hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
664 local ret="${?}"
665
666 case "${ret}" in
667 ${EXIT_OK})
668 log INFO "${port} has been attached to ${zone}"
669
670 # Automatically connect the port
671 zone_port_start "${zone}" "${port}"
672 ;;
673 *)
674 log CRITICAL "${port} could not be attached to ${zone}"
675 ;;
676 esac
677
678 return ${ret}
679 }
680
681 zone_port_edit() {
682 local zone="${1}"
683 assert isset zone
684
685 local port="${2}"
686 assert isset port
687
688 shift 2
689
690 # Check if the port actually exists.
691 if ! port_exists "${port}"; then
692 error "Port '${port}' does not exist"
693 return ${EXIT_ERROR}
694 fi
695
696 # Check if the zone actually has this port.
697 if ! zone_has_port "${zone}" "${port}"; then
698 error "Port '${port}' is not attached to zone '${zone}'"
699 return ${EXIT_ERROR}
700 fi
701
702 local hook=$(zone_get_hook "${zone}")
703 assert isset hook
704
705 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
706 }
707
708 zone_port_detach() {
709 local zone="${1}"
710 assert isset zone
711
712 local port="${2}"
713 assert isset port
714
715 shift 2
716
717 # Check if the zone actually has this port.
718 if ! zone_has_port "${zone}" "${port}"; then
719 error "Port '${port}' is not attached to zone '${zone}'"
720 return ${EXIT_ERROR}
721 fi
722
723 local hook=$(zone_get_hook "${zone}")
724 assert isset hook
725
726 hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
727 local ret="${?}"
728
729 case "${ret}" in
730 ${EXIT_OK})
731 log INFO "${port} has been detached from ${zone}"
732
733 # Bring down the port if needed
734 zone_port_stop "${zone}" "${port}"
735 ;;
736 *)
737 log CRITICAL "${port} could not be detached from ${zone}"
738 ;;
739 esac
740
741 return ${ret}
742 }
743
744 zone_port_cmd() {
745 local cmd="${1}"
746 assert isset cmd
747
748 local zone="${2}"
749 assert isset zone
750
751 local port="${3}"
752 assert isset port
753
754 shift 3
755
756 local hook="$(zone_get_hook "${zone}")"
757 assert isset hook
758
759 # Dispatch command to hook
760 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" $@
761 }
762
763 zone_port_create() {
764 zone_port_cmd "port_create" $@
765 }
766
767 zone_port_remove() {
768 zone_port_cmd "port_remove" $@
769 }
770
771 zone_port_up() {
772 zone_port_cmd "port_up" $@
773 }
774
775 zone_port_down() {
776 zone_port_cmd "port_down" $@
777 }
778
779 # The next two functions automagically bring up and down
780 # port that are attached to a bridge or similar.
781 # The problem that is tried to overcome here is that there
782 # are ports which exist all the time (like ethernet ports)
783 # and therefore do not dispatch a hotplug event when
784 # port_create is called.
785
786 zone_port_start() {
787 local zone="${1}"
788 local port="${2}"
789
790 if zone_is_active "${zone}"; then
791 if device_exists "${port}"; then
792 zone_port_up "${zone}" "${port}"
793 return ${?}
794 else
795 zone_port_create "${zone}" "${port}"
796 return ${?}
797 fi
798 fi
799
800 return ${EXIT_OK}
801 }
802
803 zone_port_stop() {
804 local zone="${1}"
805 local port="${2}"
806
807 # Shut down the port if necessary
808 if zone_is_active "${zone}" && port_is_up "${port}"; then
809 zone_port_down "${zone}" "${port}"
810 fi
811
812 # Remove the port
813 zone_port_remove "${zone}" "${port}"
814 }
815
816 zone_port_status() {
817 zone_port_cmd "port_status" $@
818 }
819
820 zone_ports_cmd() {
821 local cmd="${1}"
822 assert isset cmd
823
824 local zone="${2}"
825 assert isset zone
826
827 shift 2
828
829 local hook="$(zone_get_hook "${zone}")"
830
831 local port
832 for port in $(zone_get_ports ${zone}); do
833 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" $@
834 done
835 }
836
837 zone_ports_create() {
838 zone_ports_cmd "port_create" $@
839 }
840
841 zone_ports_remove() {
842 zone_ports_cmd "port_remove" $@
843 }
844
845 zone_ports_up() {
846 zone_ports_cmd "port_up" $@
847 }
848
849 zone_ports_down() {
850 zone_ports_cmd "port_down" $@
851 }
852
853 zone_ports_status() {
854 zone_ports_cmd "port_status" $@
855 }
856
857 zone_configs_cmd() {
858 assert [ $# -ge 2 ]
859
860 local cmd="${1}"
861 local zone="${2}"
862 shift 2
863
864 assert zone_exists "${zone}"
865
866 local config
867 for config in $(zone_configs_list "${zone}"); do
868 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
869 assert isset config_hook
870
871 hook_config_exec "${config_hook}" "${cmd}" "${zone}" "${config}" $@
872 done
873 }
874
875 zone_configs_up() {
876 zone_configs_cmd "up" $@
877 }
878
879 zone_configs_down() {
880 zone_configs_cmd "down" $@
881 }
882
883 zone_configs_status() {
884 zone_configs_cmd "status" $@
885 }
886
887 zone_configs_list() {
888 local zone=${1}
889
890 local config
891 for config in $(zone_dir ${zone})/configs/*; do
892 [ -e "${config}" ] || continue
893
894 basename ${config}
895 done
896 }
897
898 zone_config_get_hook() {
899 assert [ $# -eq 2 ]
900
901 local zone="${1}"
902 assert isset zone
903
904 local config="${2}"
905 assert isset config
906
907 local HOOK
908 zone_config_settings_read "${zone}" "${config}" \
909 --ignore-superfluous-settings HOOK
910
911 print "${HOOK}"
912 }
913
914 zone_has_ip() {
915 device_has_ip $@
916 }
917
918 zone_db() {
919 local zone=${1}
920 local action=${2}
921 shift 2
922
923 case "${action}" in
924 starting|started|stopping|stopped)
925 db_connection_update ${zone} ${action}
926 ;;
927 esac
928 }
929
930 zone_is_up() {
931 local zone=${1}
932
933 device_is_up ${zone}
934 }
935
936 zone_is_down() {
937 ! zone_is_up $@
938 }
939
940 zone_get_supported_port_hooks() {
941 local zone=${1}
942
943 local hook=$(zone_get_hook ${zone})
944
945 hook_zone_ports_get_all ${hook}
946 }
947
948 zone_get_supported_config_hooks() {
949 hook_config_get_all
950 }
951
952 zone_file() {
953 local zone=${1}
954
955 assert isset zone
956
957 echo "$(zone_dir ${zone})/settings"
958 }
959
960 zone_settings_read() {
961 local zone=${1}
962 assert isset zone
963 shift
964
965 local args
966 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then
967 list_append args ${HOOK_SETTINGS}
968 else
969 list_append args $@
970 fi
971
972 # Save the HOOK variable.
973 local hook="${HOOK}"
974
975 settings_read "$(zone_file "${zone}")" ${args}
976
977 # Restore hook.
978 HOOK="${hook}"
979 }
980
981 zone_settings_write() {
982 local zone="${1}"
983 assert isset zone
984
985 local args
986 if function_exists "hook_check_settings"; then
987 list_append args "--check=\"hook_check_settings\""
988 fi
989 list_append args ${HOOK_SETTINGS}
990
991 settings_write "$(zone_file ${zone})" ${args}
992 }
993
994 zone_settings_set() {
995 local zone=${1}
996 shift
997 local args="$@"
998
999 assert isset zone
1000
1001 (
1002 zone_settings_read ${zone}
1003
1004 for arg in ${args}; do
1005 eval "${arg}"
1006 done
1007
1008 zone_settings_write ${zone}
1009 )
1010 }
1011
1012 zone_settings_get() {
1013 local zone=${1}
1014 local key=${2}
1015
1016 assert isset zone
1017 assert isset key
1018
1019 (
1020 zone_settings_read "${zone}" "${key}" \
1021 --ignore-superfluous-settings
1022
1023 echo "${!key}"
1024 )
1025 }
1026
1027 zone_config_settings_read() {
1028 assert [ $# -ge 2 ]
1029
1030 local zone="${1}"
1031 local config="${2}"
1032 shift 2
1033
1034 local args
1035 if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then
1036 list_append args ${HOOK_CONFIG_SETTINGS}
1037 else
1038 list_append args $@
1039 fi
1040
1041 local path="$(zone_dir "${zone}")/configs/${config}"
1042 settings_read "${path}" ${args}
1043 }
1044
1045 zone_config_settings_write() {
1046 assert [ $# -ge 2 ]
1047
1048 local zone="${1}"
1049 local config="${2}"
1050 shift 2
1051
1052 local args
1053 if function_exists "hook_check_config_settings"; then
1054 list_append args "--check=\"hook_check_config_settings\""
1055 fi
1056 list_append args ${HOOK_CONFIG_SETTINGS}
1057
1058 local path="$(zone_dir "${zone}")/configs/${config}"
1059 settings_write "${path}" ${args}
1060 }
1061
1062 zone_port_settings_read() {
1063 assert [ $# -ge 2 ]
1064
1065 local zone="${1}"
1066 local port="${2}"
1067 shift 2
1068
1069 local args
1070 if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
1071 list_append args ${HOOK_PORT_SETTINGS}
1072 else
1073 list_append args $@
1074 fi
1075
1076 local path="$(zone_dir "${zone}")/ports/${port}"
1077 settings_read "${path}" ${args}
1078 }
1079
1080 zone_port_settings_write() {
1081 assert [ $# -ge 2 ]
1082
1083 local zone="${1}"
1084 local port="${2}"
1085 shift 2
1086
1087 local args
1088 if function_exists "hook_check_port_settings"; then
1089 list_append args "--check=\"hook_check_port_settings\""
1090 fi
1091 list_append args ${HOOK_PORT_SETTINGS}
1092
1093 local path="$(zone_dir "${zone}")/ports/${port}"
1094 settings_write "${path}" ${args}
1095 }
1096
1097 zone_port_settings_remove() {
1098 assert [ $# -eq 2 ]
1099
1100 local zone="${1}"
1101 local port="${2}"
1102
1103 local path="$(zone_dir "${zone}")/ports/${port}"
1104 settings_remove "${path}"
1105 }