summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am12
-rwxr-xr-xscripts/system/vyatta_update_login_user.pl172
-rwxr-xr-xscripts/system/vyatta_update_logrotate.pl50
-rwxr-xr-xscripts/system/vyatta_update_syslog.pl51
-rw-r--r--templates/system/domain-name/node.def15
-rw-r--r--templates/system/domain-search/domain/node.def12
-rw-r--r--templates/system/host-name/node.def24
-rw-r--r--templates/system/login/node.def3
-rw-r--r--templates/system/login/radius-server/node.def14
-rw-r--r--templates/system/login/radius-server/node.tag/port/node.def4
-rw-r--r--templates/system/login/radius-server/node.tag/secret/node.def2
-rw-r--r--templates/system/login/radius-server/node.tag/timeout/node.def3
-rw-r--r--templates/system/login/user/node.def17
-rw-r--r--templates/system/login/user/node.tag/authentication/encrypted-password/node.def2
-rw-r--r--templates/system/login/user/node.tag/authentication/node.def1
-rw-r--r--templates/system/login/user/node.tag/authentication/plaintext-password/node.def9
-rw-r--r--templates/system/login/user/node.tag/full-name/node.def2
-rw-r--r--templates/system/name-server/node.def17
-rw-r--r--templates/system/ntp-server/node.def17
-rw-r--r--templates/system/options/node.def1
-rw-r--r--templates/system/options/reboot-on-panic/node.def16
-rw-r--r--templates/system/package/auto-sync/node.def15
-rw-r--r--templates/system/package/node.def1
-rw-r--r--templates/system/package/repository/node.def14
-rw-r--r--templates/system/package/repository/node.tag/component/node.def2
-rw-r--r--templates/system/package/repository/node.tag/description/node.def2
-rw-r--r--templates/system/package/repository/node.tag/url/node.def2
-rw-r--r--templates/system/static-host-mapping/host-name/node.def4
-rw-r--r--templates/system/static-host-mapping/host-name/node.tag/alias/node.def33
-rw-r--r--templates/system/static-host-mapping/host-name/node.tag/inet/node.def30
-rw-r--r--templates/system/static-host-mapping/node.def1
-rw-r--r--templates/system/syslog/console/facility/node.def11
-rw-r--r--templates/system/syslog/console/facility/node.tag/level/node.def3
-rw-r--r--templates/system/syslog/console/node.def1
-rw-r--r--templates/system/syslog/file/node.def4
-rw-r--r--templates/system/syslog/file/node.tag/archive/files/node.def3
-rw-r--r--templates/system/syslog/file/node.tag/archive/node.def8
-rw-r--r--templates/system/syslog/file/node.tag/archive/size/node.def3
-rw-r--r--templates/system/syslog/file/node.tag/facility/node.def13
-rw-r--r--templates/system/syslog/file/node.tag/facility/node.tag/level/node.def3
-rw-r--r--templates/system/syslog/global/archive/files/node.def3
-rw-r--r--templates/system/syslog/global/archive/node.def8
-rw-r--r--templates/system/syslog/global/archive/size/node.def3
-rw-r--r--templates/system/syslog/global/facility/node.def11
-rw-r--r--templates/system/syslog/global/facility/node.tag/level/node.def3
-rw-r--r--templates/system/syslog/global/node.def1
-rw-r--r--templates/system/syslog/host/node.def3
-rw-r--r--templates/system/syslog/host/node.tag/facility/node.def11
-rw-r--r--templates/system/syslog/host/node.tag/facility/node.tag/level/node.def3
-rw-r--r--templates/system/syslog/node.def3
-rw-r--r--templates/system/syslog/user/node.def3
-rw-r--r--templates/system/syslog/user/node.tag/facility/node.def14
-rw-r--r--templates/system/syslog/user/node.tag/facility/node.tag/level/node.def3
-rw-r--r--templates/system/time-zone/node.def16
54 files changed, 682 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 8286e009..afaaf6b0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,5 @@
+cfgdir = $(datadir)/vyatta-cfg/templates
+
bin_SCRIPTS =
sbin_SCRIPTS =
sysconf_DATA =
@@ -9,9 +11,19 @@ sbin_SCRIPTS += scripts/rl-system.init
sbin_SCRIPTS += scripts/install-system
sbin_SCRIPTS += scripts/quick-install
sbin_SCRIPTS += scripts/standalone_root_pw_reset
+sbin_SCRIPTS += scripts/system/vyatta_update_login_user.pl
+sbin_SCRIPTS += scripts/system/vyatta_update_logrotate.pl
+sbin_SCRIPTS += scripts/system/vyatta_update_syslog.pl
sysconf_DATA += sysconf/hosts
sysconf_DATA += sysconf/logrotate_messages
sysconf_DATA += sysconf/motd.tail
sysconf_DATA += sysconf/syslog.conf
+cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \
+ cpio -0pd
+
+install-exec-hook:
+ mkdir -p $(DESTDIR)$(cfgdir)
+ cd templates; $(cpiop) $(DESTDIR)$(cfgdir)
+
diff --git a/scripts/system/vyatta_update_login_user.pl b/scripts/system/vyatta_update_login_user.pl
new file mode 100755
index 00000000..86c0074c
--- /dev/null
+++ b/scripts/system/vyatta_update_login_user.pl
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+
+use strict;
+use Fcntl;
+use POSIX qw(:unistd_h);
+
+# arg: login_name
+# returns the next available uid if login_name doesn't exist.
+# otherwise returns (undef, <passwd fields for login_name>).
+sub next_uid_if_not_exist {
+ my $login = shift;
+ my $min_uid = 1000;
+ my $max_uid = 60000;
+ if (open(LOGIN_DEF, "/etc/login.defs")) {
+ while (<LOGIN_DEF>) {
+ if (m/^\s*UID_MIN\s+(\d+)/) {
+ $min_uid = $1;
+ next;
+ }
+ if (m/^\s*UID_MAX\s+(\d+)/) {
+ $max_uid = $1;
+ next;
+ }
+ }
+ close LOGIN_DEF;
+ }
+
+ open(PASSWD, "/etc/passwd") or exit 1;
+ while (<PASSWD>) {
+ chomp;
+ my @passwd_fields = split /:/;
+ if ($passwd_fields[0] eq $login) {
+ close PASSWD;
+ return (undef, @passwd_fields);
+ }
+ if ($min_uid <= $passwd_fields[2]) {
+ next if ($passwd_fields[2] > $max_uid);
+ $min_uid = $passwd_fields[2] + 1;
+ next;
+ }
+ }
+ close PASSWD;
+ exit 2 if ($min_uid > $max_uid);
+ return ($min_uid);
+}
+
+# arg: login_name
+# returns the corresponding line in shadow or undef if login_name doesn't
+# exist.
+sub get_shadow_line {
+ my $login = shift;
+ open(SHADOW, "/etc/shadow") or exit 3;
+ while (<SHADOW>) {
+ chomp;
+ if (m/^$login:/) {
+ close SHADOW;
+ return $_;
+ }
+ }
+ close SHADOW;
+ return undef;
+}
+
+my $user = shift;
+my $full = shift;
+my $encrypted = shift;
+
+# emulate lckpwdf(3).
+# difference: we only try to lock it once (non-blocking). lckpwdf will block
+# for up to 15 seconds waiting for the lock.
+# note that the lock is released when file is closed (e.g., exit), so no need
+# for explicit unlock.
+my $flock = pack "ssa20", F_WRLCK, SEEK_SET, "\0";
+sysopen(PWDLCK, "/etc/.pwd.lock", O_WRONLY | O_CREAT, 0600) or exit 3;
+fcntl(PWDLCK, F_SETLK, $flock) or exit 3;
+
+if ($user eq "-d") {
+ $user = $full;
+ exit 4 if (!defined($user));
+
+ # check if user is using the system
+ my @pslines = `ps -U $user -u $user u`;
+ if ($#pslines != 0) {
+ # user is using the system
+ print STDERR "Delete failed: user \"$user\" is using the system\n";
+ exit 4;
+ }
+
+ my $ret = system("sed -i '/^$user:/d' /etc/passwd");
+ exit 5 if ($ret >> 8);
+ $ret = system("sed -i '/^$user:/d' /etc/shadow");
+ exit 6 if ($ret >> 8);
+ $ret = system("rm -rf /home/$user");
+ exit 7 if ($ret >> 8);
+ exit 0;
+}
+
+exit 4 if (!defined($user) || !defined($full) || !defined($encrypted));
+
+my $DEF_GROUP = "quagga";
+my $DEF_SHELL = "/bin/bash";
+
+open(GRP, "/etc/group") or exit 5;
+my $def_gid = undef;
+while (<GRP>) {
+ my @group_fields = split /:/;
+ if ($group_fields[0] eq $DEF_GROUP) {
+ $def_gid = $group_fields[2];
+ last;
+ }
+}
+exit 6 if (!defined($def_gid));
+
+my @vals = next_uid_if_not_exist($user);
+my ($new_user, $passwd_line, $shadow_line) = (0, "", "");
+if (defined($vals[0])) {
+ # add new user
+ $new_user = 1;
+ $passwd_line = "$user:x:$vals[0]:${def_gid}:$full:/home/$user:$DEF_SHELL";
+ my $sline = get_shadow_line($user);
+ exit 7 if (defined($sline));
+ my $seconds = `date +%s`;
+ my $days = int($seconds / 3600 / 24);
+ $shadow_line = "$user:$encrypted:$days:0:99999:7:::";
+} else {
+ # modify existing user
+ shift @vals;
+ $vals[4] = $full;
+ $passwd_line = join(':', @vals);
+ my $sline = get_shadow_line($user);
+ exit 8 if (!defined($sline));
+ @vals = split /:/, $sline;
+ $vals[1] = $encrypted;
+ for (my $padding = (9 - $#vals - 1); $padding > 0; $padding--) {
+ push @vals, '';
+ }
+ $shadow_line = join(':', @vals);
+}
+
+my $ret = 0;
+if (!$new_user) {
+ $ret = system("sed -i '/^$user:/d' /etc/passwd");
+ exit 9 if ($ret >> 8);
+ $ret = system("sed -i '/^$user:/d' /etc/shadow");
+ exit 10 if ($ret >> 8);
+}
+
+open(PASSWD, ">>/etc/passwd") or exit 11;
+print PASSWD "$passwd_line\n";
+close PASSWD;
+open(SHADOW, ">>/etc/shadow") or exit 12;
+print SHADOW "$shadow_line\n";
+close SHADOW;
+
+if (($new_user) && !(-e "/home/$user")) {
+ if (-d "/etc/skel") {
+ $ret = system("cp -a /etc/skel /home/$user");
+ exit 13 if ($ret >> 8);
+ $ret = system("chmod 755 /home/$user");
+ exit 14 if ($ret >> 8);
+ $ret = system("chown -R $user:$DEF_GROUP /home/$user");
+ exit 15 if ($ret >> 8);
+ } else {
+ $ret = system("mkdir -p /home/$user");
+ exit 16 if ($ret >> 8);
+ $ret = system("chmod 755 /home/$user");
+ exit 17 if ($ret >> 8);
+ }
+}
+
+exit 0;
+
diff --git a/scripts/system/vyatta_update_logrotate.pl b/scripts/system/vyatta_update_logrotate.pl
new file mode 100755
index 00000000..abc4a25a
--- /dev/null
+++ b/scripts/system/vyatta_update_logrotate.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+
+use strict;
+
+my $file = "messages";
+my $log_file = "/var/log/messages";
+if ($#ARGV == 3) {
+ $file = shift;
+ $log_file = "/var/log/user/$file";
+}
+my $files = shift;
+my $size = shift;
+my $set = shift;
+my $log_conf = "/etc/logrotate.d/$file";
+
+if (!defined($files) || !defined($size) || !defined($set)) {
+ exit 1;
+}
+
+if (!($files =~ m/^\d+$/) || !($size =~ m/^\d+$/)) {
+ exit 2;
+}
+
+# just remove it and make a new one below
+# (the detection mechanism in XORP doesn't work anyway)
+unlink $log_conf;
+
+open(OUT, ">>$log_conf") or exit 3;
+if ($set == 1) {
+ print OUT <<EOF;
+$log_file {
+ missingok
+ notifempty
+ rotate $files
+ size=${size}k
+ postrotate
+ kill -HUP `cat /var/run/syslogd.pid`
+ endscript
+}
+EOF
+}
+close OUT;
+
+sleep 1;
+if (system("/usr/sbin/invoke-rc.d sysklogd restart")) {
+ exit 4;
+}
+
+exit 0;
+
diff --git a/scripts/system/vyatta_update_syslog.pl b/scripts/system/vyatta_update_syslog.pl
new file mode 100755
index 00000000..a55fe615
--- /dev/null
+++ b/scripts/system/vyatta_update_syslog.pl
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+use strict;
+my $SYSLOG_CONF = '/etc/syslog.conf';
+
+my $match1 = shift;
+my $match2 = shift;
+my $update_line = shift;
+
+if (!defined($match1) || !defined($match2) || !defined($update_line)) {
+ exit 1;
+}
+
+if (system("touch $SYSLOG_CONF")) {
+ exit 2;
+}
+
+my $exp1 = "";
+my $exp2 = "";
+if ($match1 ne "") {
+ $exp1 = $match1;
+ if ($match2 ne "") {
+ $exp2 = $match2;
+ }
+} elsif ($match2 ne "") {
+ $exp1 = $match2;
+}
+
+if ($exp2 ne "") {
+ if (system("sed -i '/$exp1/{/$exp2/d}' $SYSLOG_CONF")) {
+ exit 2;
+ }
+} elsif ($exp1 ne "") {
+ if (system("sed -i '/$exp1/d' $SYSLOG_CONF")) {
+ exit 3;
+ }
+}
+
+open(OUT, ">>$SYSLOG_CONF") or exit 4;
+if ($update_line ne "") {
+ print OUT "$update_line";
+}
+close OUT;
+
+sleep 1;
+if (system("/usr/sbin/invoke-rc.d sysklogd restart")) {
+ exit 5;
+}
+
+exit 0;
+
diff --git a/templates/system/domain-name/node.def b/templates/system/domain-name/node.def
new file mode 100644
index 00000000..8f9d4579
--- /dev/null
+++ b/templates/system/domain-name/node.def
@@ -0,0 +1,15 @@
+type: txt
+help: "Configure system domain name"
+syntax: pattern $(@) "^[-a-zA-Z0-9.]{0,63}$" ; "invalid domain name $(@)"
+create: "sh -c \"if [ x$(@) == x ]; then exit 0; fi && \
+touch /etc/resolv.conf && \
+sed -i '/domain/d' /etc/resolv.conf && \
+echo \\\"domain\t $(@)\\\" >> /etc/resolv.conf\" "
+# also add localhost line into /etc/hosts (see host-name template)?
+update: "sh -c \"if [ x$(@) == x ]; then exit 0; fi && \
+touch /etc/resolv.conf && \
+sed -i '/domain/d' /etc/resolv.conf && \
+echo \\\"domain\t $(@)\\\" >> /etc/resolv.conf\" "
+# also update localhost line in /etc/hosts (see host-name template)?
+delete: "sh -c \"touch /etc/resolv.conf && \
+sed -i '/domain\\\\t $(@)/d' /etc/resolv.conf\" "
diff --git a/templates/system/domain-search/domain/node.def b/templates/system/domain-search/domain/node.def
new file mode 100644
index 00000000..d4e6c3c7
--- /dev/null
+++ b/templates/system/domain-search/domain/node.def
@@ -0,0 +1,12 @@
+multi:
+type: txt
+help: "Configure DNS domain completion order"
+syntax: pattern $(@) "^[-a-zA-Z0-9.]+$" ; "invalid domain name $(@)"
+create: "sh -c \"touch /etc/resolv.conf && \
+if grep -q 'search\t $(@)' /etc/resolv.conf; then exit 0; \
+else echo \\\"search\t $(@)\\\" >> /etc/resolv.conf; fi\" "
+update: "sh -c \"touch /etc/resolv.conf && \
+if grep -q 'search\t $(@)' /etc/resolv.conf; then exit 0; \
+else echo \\\"search\t $(@)\\\" >> /etc/resolv.conf; fi\" "
+delete: "sh -c \"touch /etc/resolv.conf && \
+sed -i '/search\\\\t $(@)/d' /etc/resolv.conf\" "
diff --git a/templates/system/host-name/node.def b/templates/system/host-name/node.def
new file mode 100644
index 00000000..fc7c91ba
--- /dev/null
+++ b/templates/system/host-name/node.def
@@ -0,0 +1,24 @@
+type: txt
+help: "Configure system host name"
+default: "vyatta"
+syntax: pattern $(@) "^[-a-zA-Z0-9.]+$" ; "invalid host name $(@)"
+create: "sh -c \"hostname '$(@)' && \
+touch /etc/hosts && \
+sed -i '/localhost/d' /etc/hosts && \
+echo \\\"127.0.0.1\t localhost $(@)\t #vyatta entry\\\" >> /etc/hosts && \
+if [ x$(../domain-name/@) != x ]; then \
+echo \\\"127.0.0.1\t localhost $(@).$(../domain-name/@)\t #vyatta entry\\\" \>> /etc/hosts; fi\" "
+# do we need to add ntpd restart here?
+update: "sh -c \"hostname '$(@)' && \
+touch /etc/hosts && \
+sed -i '/localhost/d' /etc/hosts && \
+echo \\\"127.0.0.1\t localhost $(@)\t #vyatta entry\\\" >> /etc/hosts && \
+if [ x$(../domain-name/@) != x ]; then \
+echo \\\"127.0.0.1\t localhost $(@).$(../domain-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; fi\" "
+# do we need to add ntpd restart here?
+delete: "sh -c \"echo > /etc/hostname.conf && hostname '' && \
+touch /etc/hosts && \
+sed -i '/localhost.*#vyatta entry/d' /etc/hosts && \
+if [ -f /etc/ntp/ntp.conf ] && grep -q 'server' /etc/ntp/ntp.conf; then \
+/opt/vyatta/sbin/ntpd.init restart; fi\" "
diff --git a/templates/system/login/node.def b/templates/system/login/node.def
new file mode 100644
index 00000000..12465148
--- /dev/null
+++ b/templates/system/login/node.def
@@ -0,0 +1,3 @@
+help: "Configure user access"
+delete: "sh -c \"echo User root cannot be deleted 1>&2 && exit 1\" "
+
diff --git a/templates/system/login/radius-server/node.def b/templates/system/login/radius-server/node.def
new file mode 100644
index 00000000..d12be764
--- /dev/null
+++ b/templates/system/login/radius-server/node.def
@@ -0,0 +1,14 @@
+tag:
+type: ipv4
+help: "Radius server authentication configuration"
+# need mandatory secret. also need port & timeout (default values?)
+create: "sh -c \"touch /etc/raddb/server && \
+sed -i '/$(@)/d' /etc/raddb/server && \
+echo \\\"$(@):$(port/@)\t$(secret/@)\t$(timeout/@)\\\" \
+>> /etc/raddb/server\" "
+update: "sh -c \"touch /etc/raddb/server && \
+sed -i '/$(@)/d' /etc/raddb/server && \
+echo \\\"$(@):$(port/@)\t$(secret/@)\t$(timeout/@)\\\" \
+>> /etc/raddb/server\" "
+delete: "sh -c \"touch /etc/raddb/server && \
+sed -i '/$(@)/d' /etc/raddb/server\" "
diff --git a/templates/system/login/radius-server/node.tag/port/node.def b/templates/system/login/radius-server/node.tag/port/node.def
new file mode 100644
index 00000000..8c856e78
--- /dev/null
+++ b/templates/system/login/radius-server/node.tag/port/node.def
@@ -0,0 +1,4 @@
+type: u32
+help: "Configure radius port"
+syntax: ($(@) > 0 && $(@) < 65536) ; "port must be between 1 and 65535"
+default: 1812
diff --git a/templates/system/login/radius-server/node.tag/secret/node.def b/templates/system/login/radius-server/node.tag/secret/node.def
new file mode 100644
index 00000000..eb08eca3
--- /dev/null
+++ b/templates/system/login/radius-server/node.tag/secret/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Secret for radius access"
diff --git a/templates/system/login/radius-server/node.tag/timeout/node.def b/templates/system/login/radius-server/node.tag/timeout/node.def
new file mode 100644
index 00000000..84bb4424
--- /dev/null
+++ b/templates/system/login/radius-server/node.tag/timeout/node.def
@@ -0,0 +1,3 @@
+type: u32
+help: "Timeout for radius session"
+default: 2
diff --git a/templates/system/login/user/node.def b/templates/system/login/user/node.def
new file mode 100644
index 00000000..0d09c4d0
--- /dev/null
+++ b/templates/system/login/user/node.def
@@ -0,0 +1,17 @@
+tag:
+type: txt
+help: "User account information"
+syntax: pattern $(@) "^[a-zA-Z_][a-zA-Z0-9_-]*\\$?$" ; "invalid user name $(@)"
+# line continuation and $() expansion are done by cli, not sh.
+# need mandatory encrypted password.
+end: "if [ -d /tmp/vyatta-delete-system-login-user-$(@).\\\$PPID ]; \
+then rm -rf /tmp/vyatta-delete-system-login-user-$(@).\\\$PPID && exit 0; \
+fi && \
+/opt/vyatta/sbin/vyatta_update_login_user.pl \
+'$(@)' '$(full-name/@)' '$(authentication/encrypted-password/@)'"
+delete: "if [ x$(@) == x ]; then exit 1; fi && \
+if [ x$(@) == xroot ]; then echo Cannot delete user \"root\" 1>&2 && exit 2; \
+fi && \
+if mkdir /tmp/vyatta-delete-system-login-user-$(@).\\\$PPID >& /dev/null; \
+then /opt/vyatta/sbin/vyatta_update_login_user.pl -d '$(@)'; \
+else exit 1; fi"
diff --git a/templates/system/login/user/node.tag/authentication/encrypted-password/node.def b/templates/system/login/user/node.tag/authentication/encrypted-password/node.def
new file mode 100644
index 00000000..33a87f59
--- /dev/null
+++ b/templates/system/login/user/node.tag/authentication/encrypted-password/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Configure encrypted password"
diff --git a/templates/system/login/user/node.tag/authentication/node.def b/templates/system/login/user/node.tag/authentication/node.def
new file mode 100644
index 00000000..8b0f3125
--- /dev/null
+++ b/templates/system/login/user/node.tag/authentication/node.def
@@ -0,0 +1 @@
+help: "Authentication password"
diff --git a/templates/system/login/user/node.tag/authentication/plaintext-password/node.def b/templates/system/login/user/node.tag/authentication/plaintext-password/node.def
new file mode 100644
index 00000000..78619d79
--- /dev/null
+++ b/templates/system/login/user/node.tag/authentication/plaintext-password/node.def
@@ -0,0 +1,9 @@
+type: txt
+help: "Configure plaintext password for encryption"
+# if plaintext is empty, assume this is left-over from blanking the plaintext
+# and do nothing. to set password to empty, user needs to set the
+# "encrypted-password" to an empty string (which actually allows login without
+# password).
+update: $(@) == "" \
+|| ($(../encrypted-password/@) = `/opt/vyatta/sbin/rl_passwd '$(@)' dummy` \
+ && $(@) = "")
diff --git a/templates/system/login/user/node.tag/full-name/node.def b/templates/system/login/user/node.tag/full-name/node.def
new file mode 100644
index 00000000..86b7c8d4
--- /dev/null
+++ b/templates/system/login/user/node.tag/full-name/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Full name of the user (use quotes for names with spaces)"
diff --git a/templates/system/name-server/node.def b/templates/system/name-server/node.def
new file mode 100644
index 00000000..2afe0b0d
--- /dev/null
+++ b/templates/system/name-server/node.def
@@ -0,0 +1,17 @@
+multi:
+type: ipv4
+help: "Configure domain name server"
+create: "sh -c \"touch /etc/resolv.conf && \
+if grep -q '$(@)' /etc/resolv.conf; then exit 0; \
+else echo \\\"nameserver\t $(@)\\\" >> /etc/resolv.conf; fi && \
+if [ -f /etc/ntp/ntp.conf ] && grep -q 'server' /etc/ntp/ntp.conf; then \
+/opt/vyatta/sbin/ntpd.init restart; fi\" "
+update: "sh -c \"touch /etc/resolv.conf && \
+if grep -q '$(@)' /etc/resolv.conf; then exit 0; \
+else echo \\\"nameserver\t $(@)\\\" >> /etc/resolv.conf; fi && \
+if [ -f /etc/ntp/ntp.conf ] && grep -q 'server' /etc/ntp/ntp.conf; then \
+/opt/vyatta/sbin/ntpd.init restart; fi\" "
+delete: "sh -c \"touch /etc/resolv.conf && \
+sed -i '/$(@)/d' /etc/resolv.conf && \
+if [ -f /etc/ntp/ntp.conf ] && grep -q 'server' /etc/ntp/ntp.conf; then \
+/opt/vyatta/sbin/ntpd.init restart; fi\" "
diff --git a/templates/system/ntp-server/node.def b/templates/system/ntp-server/node.def
new file mode 100644
index 00000000..230dd313
--- /dev/null
+++ b/templates/system/ntp-server/node.def
@@ -0,0 +1,17 @@
+multi:
+type: txt
+help: "Name or IP address of NTP server"
+update: "touch /etc/ntp.conf && \
+if ! grep -q 'server.*$(@)' /etc/ntp.conf; then \
+ echo \"server $(@)\" >> /etc/ntp.conf && \
+ /usr/sbin/invoke-rc.d ntp restart; \
+fi"
+delete: "touch /etc/ntp.conf && \
+if grep -q 'server.*$(@)' /etc/ntp.conf; then \
+ sed -i '/server $(@)/d' /etc/ntp.conf && \
+ if grep -q '^server ' /etc/ntp.conf; then \
+ /usr/sbin/invoke-rc.d ntp restart; \
+ else \
+ /usr/sbin/invoke-rc.d ntp stop; \
+ fi; \
+fi"
diff --git a/templates/system/options/node.def b/templates/system/options/node.def
new file mode 100644
index 00000000..1e49ee5b
--- /dev/null
+++ b/templates/system/options/node.def
@@ -0,0 +1 @@
+help: "Configure system options"
diff --git a/templates/system/options/reboot-on-panic/node.def b/templates/system/options/reboot-on-panic/node.def
new file mode 100644
index 00000000..d84abc74
--- /dev/null
+++ b/templates/system/options/reboot-on-panic/node.def
@@ -0,0 +1,16 @@
+type: bool
+help: "Configure if kernel panic causes reboot"
+default: true
+create: "sh -c \"if [ x$(@) == xfalse ]; \
+then \
+ echo 0 > /proc/sys/kernel/panic; \
+else \
+ echo 60 > /proc/sys/kernel/panic; \
+fi\" "
+update: "sh -c \"if [ x$(@) == xfalse ]; \
+then \
+ echo 0 > /proc/sys/kernel/panic; \
+else \
+ echo 60 > /proc/sys/kernel/panic; \
+fi\" "
+delete: "sh -c \"echo 60 > /proc/sys/kernel/panic\" "
diff --git a/templates/system/package/auto-sync/node.def b/templates/system/package/auto-sync/node.def
new file mode 100644
index 00000000..59f3e1e4
--- /dev/null
+++ b/templates/system/package/auto-sync/node.def
@@ -0,0 +1,15 @@
+# this will set APT::Periodic::Update-Package-Lists in /etc/apt/apt.conf
+# apt.conf is in turn read by the apt cron file loacted in /etc/cron.daily/apt
+# the /etc/crontab file must have the daily line for daily to be run
+type: u32
+default: 1
+help: "Update the the repository cache every n days. 0 disables auto-update."
+syntax: $(@) >= 0 && $(@) < 32 ; "auto-sync must be between 0 and 32 days"
+create: "sh -c \"touch /etc/apt/apt.conf && \
+sed -i '/APT::Periodic::Update-Package-Lists*/d' /etc/apt/apt.conf && \
+echo \\\"APT::Periodic::Update-Package-Lists \\\"$(@)\\\";\\\" >> /etc/apt/apt.conf\" "
+update: "sh -c \"touch /etc/apt/apt.conf && \
+sed -i '/APT::Periodic::Update-Package-Lists*/d' /etc/apt/apt.conf && \
+echo \\\"APT::Periodic::Update-Package-Lists \\\"$(@)\\\";\\\" >> /etc/apt/apt.conf\" "
+delete: "sh -c \"touch /etc/apt/apt.conf && \
+sed -i '/APT::Periodic::Update-Package-Lists*/d' /etc/apt/apt.conf\" "
diff --git a/templates/system/package/node.def b/templates/system/package/node.def
new file mode 100644
index 00000000..ce185fa9
--- /dev/null
+++ b/templates/system/package/node.def
@@ -0,0 +1 @@
+help: "Package Update Repository Configuration"
diff --git a/templates/system/package/repository/node.def b/templates/system/package/repository/node.def
new file mode 100644
index 00000000..104089a9
--- /dev/null
+++ b/templates/system/package/repository/node.def
@@ -0,0 +1,14 @@
+tag:
+type: txt
+help: "Repository name"
+# bug 1847: remove the previous repo line before adding new line.
+# need to prohibit '!' in repo name (sed delimiter)
+syntax: pattern $(@) "^[^!]+$" ; "Do not use '!' in repository name"
+create: "sh -c \"touch /etc/apt/sources.list && \
+sed -i '\\!/ $(@) !d' /etc/apt/sources.list && \
+echo \\\"deb $(url/@)/ $(@) $(component/@)\\\" >> /etc/apt/sources.list\" "
+update: "sh -c \"touch /etc/apt/sources.list && \
+sed -i '\\!/ $(@) !d' /etc/apt/sources.list && \
+echo \\\"deb $(url/@)/ $(@) $(component/@)\\\" >> /etc/apt/sources.list\" "
+delete: "sh -c \"touch /etc/apt/sources.list && \
+sed -i '\\! $(@) $(component/@)!d' /etc/apt/sources.list\" "
diff --git a/templates/system/package/repository/node.tag/component/node.def b/templates/system/package/repository/node.tag/component/node.def
new file mode 100644
index 00000000..e87f88de
--- /dev/null
+++ b/templates/system/package/repository/node.tag/component/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Repository component names"
diff --git a/templates/system/package/repository/node.tag/description/node.def b/templates/system/package/repository/node.tag/description/node.def
new file mode 100644
index 00000000..9ce7dac6
--- /dev/null
+++ b/templates/system/package/repository/node.tag/description/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Repository description"
diff --git a/templates/system/package/repository/node.tag/url/node.def b/templates/system/package/repository/node.tag/url/node.def
new file mode 100644
index 00000000..0e304b91
--- /dev/null
+++ b/templates/system/package/repository/node.tag/url/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Repository URL"
diff --git a/templates/system/static-host-mapping/host-name/node.def b/templates/system/static-host-mapping/host-name/node.def
new file mode 100644
index 00000000..ea0000af
--- /dev/null
+++ b/templates/system/static-host-mapping/host-name/node.def
@@ -0,0 +1,4 @@
+tag:
+type: txt
+help: "Map DNS names to system interfaces"
+syntax: pattern $(@) "^[-a-zA-Z0-9.]+$" ; "invalid host name $(@)"
diff --git a/templates/system/static-host-mapping/host-name/node.tag/alias/node.def b/templates/system/static-host-mapping/host-name/node.tag/alias/node.def
new file mode 100644
index 00000000..b6f897f3
--- /dev/null
+++ b/templates/system/static-host-mapping/host-name/node.tag/alias/node.def
@@ -0,0 +1,33 @@
+multi:
+type: txt
+help: "Alias for this address"
+create: "sh -c \"touch /etc/hosts && \
+sed -i '/$(../@).*#vyatta entry/d;/127\\.0\\.0\\.1.*#vyatta entry/d' \
+/etc/hosts && \
+echo \\\"$(../inet/@)\t $(../@) $(@) \t #vyatta entry\\\" \
+>> /etc/hosts && \
+if [ x$(../../../domain-name/@) == x ]; \
+then \
+echo \\\"127.0.0.1\t localhost $(../../../host-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+else \
+echo \\\"127.0.0.1\t localhost \
+$(../../../host-name/@).$(../../../domain-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+fi\" "
+update: "sh -c \"touch /etc/hosts && \
+sed -i '/$(../@).*#vyatta entry/d;/127\\.0\\.0\\.1.*#vyatta entry/d' \
+/etc/hosts && \
+echo \\\"$(../inet/@)\t $(../@) $(@) \t #vyatta entry\\\" \
+>> /etc/hosts && \
+if [ x$(../../../domain-name/@) == x ]; \
+then \
+echo \\\"127.0.0.1\t localhost $(../../../host-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+else \
+echo \\\"127.0.0.1\t localhost \
+$(../../../host-name/@).$(../../../domain-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+fi\" "
+delete: "sh -c \"touch /etc/hosts && \
+sed -i '/ $(../@) .*#vyatta entry/{/localhost/!d}' /etc/hosts\" "
diff --git a/templates/system/static-host-mapping/host-name/node.tag/inet/node.def b/templates/system/static-host-mapping/host-name/node.tag/inet/node.def
new file mode 100644
index 00000000..192273c3
--- /dev/null
+++ b/templates/system/static-host-mapping/host-name/node.tag/inet/node.def
@@ -0,0 +1,30 @@
+type: ipv4
+help: "Internet address"
+create: "sh -c \"touch /etc/hosts && \
+sed -i '/$(../@).*#vyatta entry/d;/127\\.0\\.0\\.1.*#vyatta entry/d' \
+/etc/hosts && \
+echo \\\"$(@)\t $(../@) \t #vyatta entry\\\" >> /etc/hosts && \
+if [ x$(../../../domain-name/@) == x ]; \
+then \
+echo \\\"127.0.0.1\t localhost $(../../../host-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+else \
+echo \\\"127.0.0.1\t localhost \
+$(../../../host-name/@).$(../../../domain-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+fi\" "
+update: "sh -c \"touch /etc/hosts && \
+sed -i '/$(../@).*#vyatta entry/d;/127\\.0\\.0\\.1.*#vyatta entry/d' \
+/etc/hosts && \
+echo \\\"$(@)\t $(../@) \t #vyatta entry\\\" >> /etc/hosts && \
+if [ x$(../../../domain-name/@) == x ]; \
+then \
+echo \\\"127.0.0.1\t localhost $(../../../host-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+else \
+echo \\\"127.0.0.1\t localhost \
+$(../../../host-name/@).$(../../../domain-name/@)\t #vyatta entry\\\" \
+>> /etc/hosts; \
+fi\" "
+delete: "sh -c \"touch /etc/hosts && \
+sed -i '/ $(../@) .*#vyatta entry/{/localhost/!d}' /etc/hosts\" "
diff --git a/templates/system/static-host-mapping/node.def b/templates/system/static-host-mapping/node.def
new file mode 100644
index 00000000..736413f6
--- /dev/null
+++ b/templates/system/static-host-mapping/node.def
@@ -0,0 +1 @@
+help: "Map DNS names to system interfaces"
diff --git a/templates/system/syslog/console/facility/node.def b/templates/system/syslog/console/facility/node.def
new file mode 100644
index 00000000..bfe3856f
--- /dev/null
+++ b/templates/system/syslog/console/facility/node.def
@@ -0,0 +1,11 @@
+tag:
+type: txt
+help: "Configure facility for console logging"
+create: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' '\\/dev\\/console' \
+\\\"$(@).\\\\\$LVL\t/dev/console\n\\\"\" "
+update: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' '\\/dev\\/console' \
+\\\"$(@).\\\\\$LVL\t/dev/console\n\\\"\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_syslog.pl \
+'$(@)\\.' '\\/dev\\/console' ''\" "
diff --git a/templates/system/syslog/console/facility/node.tag/level/node.def b/templates/system/syslog/console/facility/node.tag/level/node.def
new file mode 100644
index 00000000..9be459c6
--- /dev/null
+++ b/templates/system/syslog/console/facility/node.tag/level/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure the logging level"
+default: "err"
diff --git a/templates/system/syslog/console/node.def b/templates/system/syslog/console/node.def
new file mode 100644
index 00000000..e30721d4
--- /dev/null
+++ b/templates/system/syslog/console/node.def
@@ -0,0 +1 @@
+help: "Configure console logging"
diff --git a/templates/system/syslog/file/node.def b/templates/system/syslog/file/node.def
new file mode 100644
index 00000000..d62d2614
--- /dev/null
+++ b/templates/system/syslog/file/node.def
@@ -0,0 +1,4 @@
+tag:
+type: txt
+help: "Name of the syslog file to save log messages to"
+syntax: pattern $(@) "^[-a-zA-Z0-9_.]+$" ; "invalid file name $(@)"
diff --git a/templates/system/syslog/file/node.tag/archive/files/node.def b/templates/system/syslog/file/node.tag/archive/files/node.def
new file mode 100644
index 00000000..ca2bf175
--- /dev/null
+++ b/templates/system/syslog/file/node.tag/archive/files/node.def
@@ -0,0 +1,3 @@
+type: u32
+help: "Number of saved files"
+default: 5
diff --git a/templates/system/syslog/file/node.tag/archive/node.def b/templates/system/syslog/file/node.tag/archive/node.def
new file mode 100644
index 00000000..d0b0e230
--- /dev/null
+++ b/templates/system/syslog/file/node.tag/archive/node.def
@@ -0,0 +1,8 @@
+help: "Configure log file size and rotation characteristics"
+# need mandatory files & size
+create: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(../@)' '$(files/@)' '$(size/@)' 1\" "
+update: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(../@)' '$(files/@)' '$(size/@)' 1\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(../@)' '$(files/@)' '$(size/@)' 0\" "
diff --git a/templates/system/syslog/file/node.tag/archive/size/node.def b/templates/system/syslog/file/node.tag/archive/size/node.def
new file mode 100644
index 00000000..a5ace52e
--- /dev/null
+++ b/templates/system/syslog/file/node.tag/archive/size/node.def
@@ -0,0 +1,3 @@
+type: u32
+help: "Size of log files (kbytes)"
+default: 0
diff --git a/templates/system/syslog/file/node.tag/facility/node.def b/templates/system/syslog/file/node.tag/facility/node.def
new file mode 100644
index 00000000..3ef56e35
--- /dev/null
+++ b/templates/system/syslog/file/node.tag/facility/node.def
@@ -0,0 +1,13 @@
+tag:
+type: txt
+help: "Configure facility for file logging"
+create: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' \
+'\\/var\\/log\\/user\\/$(../@)' \
+\\\"$(@).\\\\\$LVL\t/var/log/user/$(../@) \n\\\"\" "
+update: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' \
+'\\/var\\/log\\/user\\/$(../@)' \
+\\\"$(@).\\\\\$LVL\t/var/log/user/$(../@) \n\\\"\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' \
+'\\/var\\/log\\/user\\/$(../@)' ''\" "
diff --git a/templates/system/syslog/file/node.tag/facility/node.tag/level/node.def b/templates/system/syslog/file/node.tag/facility/node.tag/level/node.def
new file mode 100644
index 00000000..9be459c6
--- /dev/null
+++ b/templates/system/syslog/file/node.tag/facility/node.tag/level/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure the logging level"
+default: "err"
diff --git a/templates/system/syslog/global/archive/files/node.def b/templates/system/syslog/global/archive/files/node.def
new file mode 100644
index 00000000..ca2bf175
--- /dev/null
+++ b/templates/system/syslog/global/archive/files/node.def
@@ -0,0 +1,3 @@
+type: u32
+help: "Number of saved files"
+default: 5
diff --git a/templates/system/syslog/global/archive/node.def b/templates/system/syslog/global/archive/node.def
new file mode 100644
index 00000000..dcfc2446
--- /dev/null
+++ b/templates/system/syslog/global/archive/node.def
@@ -0,0 +1,8 @@
+help: "Configure log file size and rotation characteristics"
+# need mandatory files & size
+create: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(files/@)' '$(size/@)' 1\" "
+update: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(files/@)' '$(size/@)' 1\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_logrotate.pl \
+'$(files/@)' '$(size/@)' 0\" "
diff --git a/templates/system/syslog/global/archive/size/node.def b/templates/system/syslog/global/archive/size/node.def
new file mode 100644
index 00000000..3c8da6e8
--- /dev/null
+++ b/templates/system/syslog/global/archive/size/node.def
@@ -0,0 +1,3 @@
+type: u32
+help: "Size of log files (kbytes)"
+default: 250
diff --git a/templates/system/syslog/global/facility/node.def b/templates/system/syslog/global/facility/node.def
new file mode 100644
index 00000000..cd037f6a
--- /dev/null
+++ b/templates/system/syslog/global/facility/node.def
@@ -0,0 +1,11 @@
+tag:
+type: txt
+help: "Configure facility for system logging"
+create: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '' '\\/var\\/log\\/messages' \
+\\\"$(@).\\\\\$LVL\t/var/log/messages \n\\\"\" "
+update: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '' '\\/var\\/log\\/messages' \
+\\\"$(@).\\\\\$LVL\t/var/log/messages \n\\\"\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_syslog.pl \
+'' '\\/var\\/log\\/messages' '*.warning\t/var/log/messages \n'\" "
diff --git a/templates/system/syslog/global/facility/node.tag/level/node.def b/templates/system/syslog/global/facility/node.tag/level/node.def
new file mode 100644
index 00000000..9be459c6
--- /dev/null
+++ b/templates/system/syslog/global/facility/node.tag/level/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure the logging level"
+default: "err"
diff --git a/templates/system/syslog/global/node.def b/templates/system/syslog/global/node.def
new file mode 100644
index 00000000..b5166459
--- /dev/null
+++ b/templates/system/syslog/global/node.def
@@ -0,0 +1 @@
+help: "Configure system logging"
diff --git a/templates/system/syslog/host/node.def b/templates/system/syslog/host/node.def
new file mode 100644
index 00000000..a349582c
--- /dev/null
+++ b/templates/system/syslog/host/node.def
@@ -0,0 +1,3 @@
+tag:
+type: txt
+help: "IP address or hostname of remote syslog server"
diff --git a/templates/system/syslog/host/node.tag/facility/node.def b/templates/system/syslog/host/node.tag/facility/node.def
new file mode 100644
index 00000000..2dc56e66
--- /dev/null
+++ b/templates/system/syslog/host/node.tag/facility/node.def
@@ -0,0 +1,11 @@
+tag:
+type: txt
+help: "Configure facility for host logging"
+create: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' '@$(../@) ' \
+\\\"$(@).\\\\\$LVL\t@$(../@) \n\\\"\" "
+update: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' '@$(../@) ' \
+\\\"$(@).\\\\\$LVL\t@$(../@) \n\\\"\" "
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_syslog.pl '$(@)\\.' \
+'@$(../@) ' ''\" "
diff --git a/templates/system/syslog/host/node.tag/facility/node.tag/level/node.def b/templates/system/syslog/host/node.tag/facility/node.tag/level/node.def
new file mode 100644
index 00000000..9be459c6
--- /dev/null
+++ b/templates/system/syslog/host/node.tag/facility/node.tag/level/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure the logging level"
+default: "err"
diff --git a/templates/system/syslog/node.def b/templates/system/syslog/node.def
new file mode 100644
index 00000000..04d3675e
--- /dev/null
+++ b/templates/system/syslog/node.def
@@ -0,0 +1,3 @@
+help: "Configure syslog daemon"
+delete: "sh -c \"/opt/vyatta/sbin/vyatta_update_syslog.pl \
+'' '\\/var\\/log\\/messages' '*.warning\t/var/log/messages \n'\" "
diff --git a/templates/system/syslog/user/node.def b/templates/system/syslog/user/node.def
new file mode 100644
index 00000000..ba731ca3
--- /dev/null
+++ b/templates/system/syslog/user/node.def
@@ -0,0 +1,3 @@
+tag:
+type: txt
+help: "Configure syslog user account output"
diff --git a/templates/system/syslog/user/node.tag/facility/node.def b/templates/system/syslog/user/node.tag/facility/node.def
new file mode 100644
index 00000000..1b227471
--- /dev/null
+++ b/templates/system/syslog/user/node.tag/facility/node.def
@@ -0,0 +1,14 @@
+tag:
+type: txt
+help: "Configure facility for user logging"
+create: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl \\\"$(@)\\.\\\\\$LVL\\\" \
+' $(../@) ' \
+\\\"$(@).\\\\\$LVL $(../@) \n\\\"\" "
+update: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl \\\"$(@)\\.\\\\\$LVL\\\" \
+' $(../@) ' \
+\\\"$(@).\\\\\$LVL $(../@) \n\\\"\" "
+delete: "sh -c \"LVL=`echo -n $(level/@) | tr '[a-z]' '[A-Z]'` && \
+/opt/vyatta/sbin/vyatta_update_syslog.pl \\\"$(@)\\.\\\\\$LVL\\\" \
+' $(../@) ' ''\" "
diff --git a/templates/system/syslog/user/node.tag/facility/node.tag/level/node.def b/templates/system/syslog/user/node.tag/facility/node.tag/level/node.def
new file mode 100644
index 00000000..9be459c6
--- /dev/null
+++ b/templates/system/syslog/user/node.tag/facility/node.tag/level/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure the logging level"
+default: "err"
diff --git a/templates/system/time-zone/node.def b/templates/system/time-zone/node.def
new file mode 100644
index 00000000..00da0133
--- /dev/null
+++ b/templates/system/time-zone/node.def
@@ -0,0 +1,16 @@
+type: txt
+help: "Configure local timezone"
+default: "GMT"
+update: "LTF=\"/usr/share/zoneinfo\" && \
+case \"$(@)\" in \
+ [Ll][Oo][Ss]*) LTF=\"\\\$LTF/US/Pacific\" ;; \
+ [Dd][Ee][Nn]*) LTF=\"\\\$LTF/US/Mountain\" ;; \
+ [Hh][Oo][Nn]*) LTF=\"\\\$LTF/US/Hawaii\" ;; \
+ [Nn][Ee][Ww]*) LTF=\"\\\$LTF/US/Eastern\" ;; \
+ [Cc][Hh][Ii]*) LTF=\"\\\$LTF/US/Central\" ;; \
+ [Aa][Nn][Cc]*) LTF=\"\\\$LTF/US/Alaska\" ;; \
+ [Pp][Hh][Oo]*) LTF=\"\\\$LTF/US/Arizona\" ;; \
+ *) LTF=\"\\\$LTF/Etc/$(@)\" ;; \
+esac && \
+ln -fs \\\$LTF /etc/localtime"
+delete: "ln -fs /usr/share/zoneinfo/GMT /etc/localtime"