4 # get_zone_form(&in, &zinfo)
5 # Returns a form for editing a zone
8 local ($in, $zinfo) = @_;
9 local $form = new Webmin::Form("save_zone.cgi");
10 $form->set_input($in);
11 $form->add_hidden("zone", $zinfo->{'name'});
12 local $section = new Webmin::Section($text{'edit_common'}, 4, undef, "100%");
13 $form->add_section($section);
15 $section->add_row($text{'edit_name'}, "<tt>$in{'zone'}</tt>");
16 $section->add_row($text{'edit_status'}, &nice_status($zinfo->{'status'}));
17 $section->add_row($text{'edit_zonepath'}, "<tt>$zinfo->{'zonepath'}</tt>");
18 local $auto = new Webmin::Select("autoboot", $zinfo->{'autoboot'},
19 [ [ "true", $text{'yes'} ],
20 [ "false", $text{'no'} ] ]);
21 $section->add_input($text{'edit_autoboot'}, $auto);
22 local $pool = &pool_object("pool", $zinfo->{'pool'});
23 $section->add_input($text{'edit_pool'}, $pool);
24 $section->add_row($text{'edit_brand'}, "$zinfo->{'brand'}");
26 local @actions = &zone_status_actions($zinfo, 1);
27 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
28 $form->add_button_spacer();
29 foreach my $a (@actions) {
30 $form->add_button(new Webmin::Submit($a->[1], $a->[0]));
32 $form->add_button_spacer() if (@actions);
33 $form->add_button(new Webmin::Submit($text{'edit_delete'}, "delete"));
39 local ($name, $value) = @_;
40 local $rv = new Webmin::OptTextbox($name, $value, 10, $text{'pool_none'});
41 $rv->set_validation_regexp('^\S+$', $text{'save_epool'});
45 # get_confirm_page(&in, type, &zinfo, from-list)
48 local ($in, $action, $zinfo, $list) = @_;
49 local $p = new Webmin::ConfirmPage(&zone_title($zinfo->{'name'}),
50 $text{$action.'_title'},
51 &text($action.'_rusure', "<tt>$zinfo->{'name'}</tt>"),
52 "save_zone.cgi", $in, $text{'edit_'.$action}, $text{'ui_cancel'});
54 $p->add_footer("index.cgi", $text{'index_return'});
57 $p->add_footer("edit_zone.cgi?zone=$zinfo->{'name'}",
58 $text{'edit_return'});
63 # get_execute_page(action, &zinfo, from-list, action-args)
66 local ($action, $zinfo, $list, $args) = @_;
67 local $p = new Webmin::Page(&zone_title($zinfo->{'name'}),
68 $text{$action.'_title'});
69 local $d = new Webmin::DynamicWait(\&execute_action, [ $action, $zinfo, $args ]);
71 $d->set_message($text{$action.'_doing'});
73 if ($list || $action eq "delete") {
74 $p->add_footer("index.cgi", $text{'index_return'});
77 $p->add_footer("edit_zone.cgi?zone=$zinfo->{'name'}",
78 $text{'edit_return'});
85 my ($d, $action, $zinfo, $args) = @_;
88 if ($action eq "delete") {
89 # Halt and un-install before deleting
90 if ($zinfo->{'status'} ne 'configured') {
91 if ($zinfo->{'status'} ne 'installed' &&
92 $zinfo->{'status'} ne 'incomplete') {
93 ($out, $ex) = &run_zone_command($zinfo, "halt");
96 ($out, $ex) = &run_zone_command($zinfo, "uninstall -F");
100 &delete_zone($zinfo);
104 # Just run zoneadm to execute action
105 ($out, $ex) = &run_zone_command($zinfo,
106 $action.($args ? " $args" : ""), 1);
110 $p->add_error($text{'reboot_failed'}, $out);
113 $p->add_message($text{'reboot_ok'});
114 if ($action eq "delete") {
115 unlink(&zone_sysidcfg_file($zinfo->{'name'}));
117 &webmin_log($action, "zone", $zinfo->{'name'});
121 # get_net_form(&in, &zinfo, &net)
124 local ($in, $zinfo, $net) = @_;
125 local ($new, $active, $address, $netmask);
126 local $form = new Webmin::Form("save_net.cgi", "post");
127 $form->add_hidden("zone", $zinfo->{'name'});
128 if ($net->{'address'}) {
129 $active = &get_active_interface($net);
130 ($address, $netmask) = &get_address_netmask($net, undef);
131 $form->add_hidden("old", $net->{'address'});
134 $net = { 'physical' => &get_default_physical() };
136 $form->add_hidden("new", 1);
138 $form->set_input($in);
139 local $section = new Webmin::Section($text{'net_header'}, 2);
140 $form->add_section($section);
142 local $ainput = new Webmin::Textbox("address", $address, 20);
143 $ainput->set_mandatory(1);
144 $ainput->set_validation_func(\&validate_address);
145 $section->add_input($text{'net_address'}, $ainput);
147 local $pinput = &physical_object("physical", $net->{'physical'});
148 $section->add_input($text{'net_physical'}, $pinput);
150 local $ninput = new Webmin::OptTextbox("netmask", $netmask, 20,
152 $ninput->set_validation_func(\&validate_netmask);
153 $section->add_input($text{'net_netmask'}, $ninput);
156 $section->add_row($text{'net_broadcast'},
157 "<tt>$active->{'broadcast'}</tt>");
161 $form->add_button(new Webmin::Submit($text{'create'}, "create"));
164 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
165 $form->add_button(new Webmin::Submit($text{'delete'}, "delete"));
170 # physical_object(name, value)
171 # Returns an input for selecting a real interface
174 local ($name, $value) = @_;
175 return new Webmin::Select($name, $value,
176 [ map { [ $_->{'name'} ] } grep { $_->{'virtual'} eq '' }
177 &net::active_interfaces() ], 0, $value ? 1 : 0);
182 return &check_ipaddress($_[0]) ? undef : $text{'net_eaddress'};
187 return &check_ipaddress($_[0]) ? undef : $text{'net_enetmask'};
190 # get_pkg_form(&in, &zinfo, &pkg)
193 local ($in, $zinfo, $pkg) = @_;
195 local $form = new Webmin::Form("save_pkg.cgi", "post");
196 $form->set_input($in);
197 $form->add_hidden("zone", $zinfo->{'name'});
199 $form->add_hidden("old", $pkg->{'dir'});
203 $form->add_hidden("new", 1);
205 local $section = new Webmin::Section($text{'pkg_header'}, 2);
206 $form->add_section($section);
208 local $dinput = new Webmin::File("dir", $pkg->{'dir'}, 50, 1);
209 $dinput->set_mandatory(1);
210 $dinput->set_validation_func(\&validate_dir);
211 $section->add_input($text{'pkg_dir'}, $dinput);
214 $form->add_button(new Webmin::Submit($text{'create'}, "create"));
217 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
218 $form->add_button(new Webmin::Submit($text{'delete'}, "delete"));
225 return -d $_[0] ? undef : $text{'pkg_edir'};
228 # get_attr_form(&in, &zinfo, &attr)
231 local ($in, $zinfo, $pkg) = @_;
233 local $form = new Webmin::Form("save_attr.cgi", "post");
234 $form->set_input($in);
235 $form->add_hidden("zone", $zinfo->{'name'});
236 if ($attr->{'name'}) {
237 $form->add_hidden("old", $attr->{'name'});
241 $form->add_hidden("new", 1);
243 local $section = new Webmin::Section($text{'attr_header'}, 2);
244 $form->add_section($section);
246 local $ninput = new Webmin::Textbox("name", $attr->{'name'}, 30);
247 $ninput->set_mandatory(1);
248 $ninput->set_validation_regexp('^\S+$', $text{'attr_ename'});
249 $section->add_input($text{'attr_name'}, $ninput);
251 local $tinput = new Webmin::Select("type", $attr->{'type'} || "string",
252 [ map { [ $_, $text{'attr_'.$_} ] }
253 &list_attr_types() ], 0, 1);
254 $section->add_input($text{'attr_type'}, $tinput);
256 local $vinput = new Webmin::Textbox("value", $attr->{'value'}, 30);
257 $vinput->set_validation_func(\&validate_value);
258 $vinput->set_mandatory(1);
259 $section->add_input($text{'attr_value'}, $vinput);
262 $form->add_button(new Webmin::Submit($text{'create'}, "create"));
265 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
266 $form->add_button(new Webmin::Submit($text{'delete'}, "delete"));
273 local ($value, $name, $form) = @_;
274 if ($form->get_value("type") eq 'int') {
275 $value =~ /^\-?\d+$/ || return $text{'attr_eint'};
277 elsif ($form->get_value("type") eq 'uint') {
278 $value =~ /^\d+$/ || return $text{'attr_euint'};
280 elsif ($form->get_value("type") eq 'boolean') {
281 $value eq "true" || $value eq "false" ||
282 return $text{'attr_uboolean'};
287 # get_fs_form(in, &zinfo, &fs, type)
290 local ($in, $zinfo, $fs, $type) = @_;
291 local ($new, $mount);
292 local $form = new Webmin::Form("save_fs.cgi", "post");
293 $form->set_input($in);
294 $form->add_hidden("zone", $zinfo->{'name'});
296 $form->add_hidden("old", $fs->{'dir'});
297 $mount = &get_active_mount($zinfo, $fs);
301 $form->add_hidden("new", 1);
302 $form->add_hidden("type", $type);
304 local $section = new Webmin::Section($text{'fs_header'}, 2);
305 $form->add_section($section);
307 $section->add_row($text{'fs_type'},
308 &mount::fstype_name($type)." (".uc($type).")");
312 ($total, $free) = &mount::disk_space($mount->[2], $mount->[0]);
313 $section->add_row($text{'fs_status'},
314 $total ? &text('fs_mountedsp', &nice_size($total*1024),
315 &nice_size($free*1024)) :
316 $text{'fs_mounted'});
319 $section->add_row($text{'fs_status'}, $text{'fs_unmounted'});
323 $section->add_row($text{'fs_mount'},
324 &ui_yesno_radio("mount", $zinfo->{'status'} eq 'running' ?
328 local $dinput = new Webmin::File("dir", $fs->{'dir'}, 50);
329 $dinput->set_mandatory(1);
330 $dinput->set_validation_func(\&validate_fsdir);
331 $section->add_input($text{'fs_dir'}, $dinput);
333 if (&indexof($type, &mount::list_fstypes()) >= 0) {
334 # A supported filesystem, which means we can show nice options
336 "<table border width=100%><tr><td><table>".
337 &capture_function_output(\&mount::generate_location, $type,
339 "</table></td></tr></table>";
340 $section->add_row($text{'fs_special'}, $shtml);
342 &mount::parse_options($type, $fs->{'options'});
344 "<table border width=100%><tr><td><table>".
345 &capture_function_output(\&mount::generate_options, $type,
347 "</table></td></tr></table>";
348 $section->add_row($text{'fs_options'}, $ohtml);
351 # Un-supported, so show just text fields
352 local $sinput = new Webmin::Textbox("special", $fs->{'special'}, 40);
353 $sinput->set_mandatory(1);
354 $sinput->set_validation_func(\&validate_special);
355 $section->add_input($text{'fs_special'}, $sinput);
357 local $oinput = new Webmin::Textbox("options", $fs->{'options'}, 40);
358 $oinput->set_mandatory(1);
359 $oinput->set_validation_func(\&validate_options);
360 $section->add_input($text{'fs_options'}, $oinput);
364 $form->add_button(new Webmin::Submit($text{'create'}, "create"));
367 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
368 $form->add_button(new Webmin::Submit($text{'delete'}, "delete"));
375 return $_[0] =~ /^\/\S/ ? undef : $text{'fs_edir'};
380 return $_[0] =~ /\S/ ? undef : $text{'fs_especial'};
385 return $_[0] =~ /^\S*$/ ? undef : $text{'fs_eoptions'};
388 # get_rctl_form(&in, &zinfo, &rctl)
391 local ($in, $zinfo, $rctl) = @_;
392 local ($new, $mount);
393 local $form = new Webmin::Form("save_rctl.cgi", "post");
394 $form->set_input($in);
395 $form->add_hidden("zone", $zinfo->{'name'});
396 if ($rctl->{'name'}) {
397 $form->add_hidden("old", $rctl->{'name'});
401 $form->add_hidden("new", 1);
403 local $section = new Webmin::Section($text{'rctl_header'}, 2);
404 $form->add_section($section);
406 local $ninput = new Webmin::Select("name", $rctl->{'name'},
407 [ map { [ $_ ] } grep { /^zone\./ } &list_rctls() ],
408 0, $in{'new'} ? 0 : 1);
409 $section->add_input($text{'rctl_name'}, $ninput);
411 local $table = new Webmin::InputTable([ $text{'rctl_priv'},
413 $text{'rctl_action'} ]);
414 $form->add_section($table);
415 local $pinput = new Webmin::Select("priv", undef,
417 [ "privileged", $text{'rctl_privileged'} ] ]);
418 local $linput = new Webmin::Textbox("limit", undef, 20);
419 $linput->set_mandatory(1);
420 $linput->set_validation_func(\&validate_limit);
421 local $ainput = new Webmin::Select("action", undef,
422 [ [ "none", $text{'rctl_none'} ],
423 [ "deny", $text{'rctl_deny'} ] ]);
424 $table->set_inputs([ $pinput, $linput, $ainput ]);
425 local @values = split(/\0/, $rctl->{'value'});
426 foreach my $v (@values, "") {
427 ($priv, $limit, $action) = &get_rctl_value($v);
428 ($actionn, $actionv) = split(/=/, $action);
429 $table->add_values([ $priv, $limit, $actionn ]);
431 $table->set_emptymsg("No RCTLs defined yet");
432 $table->set_all_sortable(0);
433 $table->set_control(0);
436 $form->add_button(new Webmin::Submit($text{'create'}, "create"));
439 $form->add_button(new Webmin::Submit($text{'save'}, "save"));
440 $form->add_button(new Webmin::Submit($text{'delete'}, "delete"));
447 return $_[0] =~ /^\d+$/ ? undef : $text{'rctl_elimit'};
453 local $form = new Webmin::Form("create_zone.cgi", "post");
454 $form->set_input($in);
455 local $section = new Webmin::Section($text{'create_header'}, 2);
456 $form->add_section($section);
457 &foreign_require("time", "time-lib.pl");
459 local $name = new Webmin::Textbox("name", undef, 20);
460 $name->set_mandatory(1);
461 $name->set_validation_func(\&validate_zone_name);
462 $section->add_input($text{'edit_name'}, $name);
464 local $path = new Webmin::OptTextbox("path", undef, 30,
465 &text('create_auto', $config{'base_dir'}),
466 $text{'create_sel'});
467 $path->set_validation_func(\&validate_zone_path);
468 $section->add_input($text{'create_path'}, $path);
470 local $brand = new Webmin::Select("brand",undef, [ &list_brands() ], 0, 0, $value ? 1 : 0);
471 $section->add_input($text{'create_brand'}, $brand);
473 local $address = new Webmin::OptTextbox("address", undef, 20,
474 $text{'create_noaddress'});
475 $address->set_validation_func(\&validate_address);
476 $section->add_input($text{'create_address'}, $address);
478 local $physical = &physical_object("physical", &get_default_physical());
479 $section->add_input($text{'net_physical'}, $physical);
481 local $install = new Webmin::Radios("install", 0, [ [ 1, $text{'yes'} ],
482 [ 0, $text{'no'} ] ]);
483 $section->add_input($text{'create_install'}, $install);
485 local $webmin = new Webmin::Radios("webmin", 0, [ [ 1, $text{'yes'} ],
486 [ 0, $text{'no'} ] ]);
487 $section->add_input($text{'create_webmin'}, $webmin);
489 local $inherit = new Webmin::Radios("inherit", 1, [ [ 1, $text{'pkg_inherit_yes'} ],
490 [ 0, $text{'pkg_inherit_no'} ] ]);
491 $section->add_input($text{'pkg_inherit'}, $inherit);
494 local $pkgs = new Webmin::Multiline("pkgs", undef, 5, 50);
495 $section->add_input($text{'create_pkgs'}, $pkgs);
497 $section->add_separator();
499 local $cfg = new Webmin::Radios("cfg", 1, [ [ 1, $text{'create_cfgyes'} ],
500 [ 0, $text{'create_cfgno'} ] ]);
501 $section->add_input($text{'create_cfg'}, $cfg);
503 local $hostname = new Webmin::OptTextbox("hostname", undef, 20,
504 $text{'create_samehost'});
505 $hostname->set_validation_func(\&validate_zone_hostname);
506 $section->add_input($text{'create_hostname'}, $hostname);
508 local $root = new Webmin::OptTextbox("root", undef, 20,
509 $text{'create_same'});
510 $section->add_input($text{'create_root'}, $root);
512 local $currtz = &time::get_current_timezone();
513 local $timezone = new Webmin::OptTextbox("timezone", undef, 25,
514 &text('create_same2', $currtz));
515 $timezone->set_validation_func(\&validate_zone_timezone);
516 $section->add_input($text{'create_timezone'}, $timezone);
518 local $currlc = &get_global_locale();
519 local $locale = new Webmin::OptTextbox("locale", undef, 25,
520 &text('create_same2', $currlc));
521 $locale->set_validation_func(\&validate_zone_locale);
522 $section->add_input($text{'create_locale'}, $locale);
524 local $terminal = new Webmin::OptTextbox("terminal", undef, 25,
525 $text{'create_vt100'});
526 $terminal->set_validation_func(\&validate_zone_terminal);
527 $section->add_input($text{'create_terminal'}, $terminal);
529 local $dns = &net::get_dns_config();
530 local ($resolv) = grep { $_ ne "files" } split(/\s+/, $dns->{'order'});
532 local $rinput = new Webmin::Radios("resolv", $resolv,
533 [ [ "none", $text{'create_none'} ],
534 [ "dns", $text{'create_dns'} ],
535 [ "nis", $text{'create_nis'} ],
536 [ "nis+", $text{'create_nis+'} ] ]);
537 $section->add_input($text{'create_name'}, $rinput);
539 local $domain = $resolv eq "dns" ? $dns->{'domain'}->[0] :
540 $resolv eq "nis" || $resolv eq "nis+" ? &net::get_domainname()
542 local $dinput = new Webmin::Textbox("domain", $domain, 20);
543 $dinput->set_validation_func(\&validate_zone_domain);
544 $dinput->set_disable_code("form.resolv[0].checked");
545 $section->add_input($text{'create_domain'}, $dinput);
547 local (@servers, $server);
548 if ($resolv eq "dns") {
549 @servers = map { &to_ipaddress($_) || &to_ip6address($_) || $_ }
550 @{$dns->{'nameserver'}};
551 $server = join(" ", @servers);
553 elsif ($resolv eq "nis" || $resolv eq "nis+") {
557 local $server = new Webmin::Textbox("server", $server, 40);
558 $server->set_validation_func(\&validate_zone_server);
559 $server->set_disable_code("form.resolv[0].checked");
560 $section->add_input($text{'create_server'}, $server);
562 local ($router) = &net::get_default_gateway();
564 # Use active settings
565 foreach my $r (&net::list_routes()) {
566 $router = $r->{'gateway'} if ($r->{'dest'} eq '0.0.0.0');
569 local $rinput = new Webmin::OptTextbox("router", $router, 20,
570 $text{'create_none'});
571 $rinput->set_validation_func(\&validate_zone_router);
572 $section->add_input($text{'create_router'}, $rinput);
574 $form->add_button(new Webmin::Submit($text{'create_ok'}));
578 sub validate_zone_name
580 return $text{'create_ename'} if ($_[0] !~ /^[a-z0-9\.\-\_]+$/i);
581 my ($clash) = grep { $_->{'name'} eq $in{'name'} } &list_zones();
582 return $text{'create_eclash'} if ($clash);
586 sub validate_zone_path
588 return $_[0] =~ /^\// ? undef : $text{'create_epath'};
591 sub validate_zone_pkgs
593 my @pkgs = split(/[\r\n]+/, $in{'pkgs'});
594 foreach my $p (@pkgs) {
595 $p =~ /^\/\S/ || return &text('create_epkg', $p);
600 sub validate_zone_hostname
602 return $_[0] =~ /^[a-z0-9\.\-\_]+$/ ? undef : $text{'create_ehostname'};
605 sub validate_zone_timezone
607 return $_[0] =~ /^\S+$/ ? undef : $text{'create_etimezone'};
610 sub validate_zone_locale
612 return $_[0] =~ /^\S+$/ ? undef : $text{'create_elocale'};
615 sub validate_zone_domain
617 return undef if ($_[2]->get_value("resolv") eq "none");
618 return $_[0] =~ /^[a-z0-9\.\-\_]+$/ ? undef : $text{'create_edomain'};
621 sub validate_zone_server
623 return undef if ($_[2]->get_value("resolv") eq "none");
624 local @servers = split(/\s+/, $in{'server'});
625 foreach my $n (@servers) {
626 return &text('create_eserver', $n) if (!&to_ipaddress($n));
628 return @servers ? undef : $text{'create_eservers'};
631 sub validate_zone_router
633 return &check_ipaddress($_[0]) ? undef : $text{'create_erouter'};
636 sub validate_zone_terminal
638 return $_[0] =~ /^\S+$/ ? undef : $text{'create_eterminal'};