[! use strict; use PVE::I18N; use PVE::ConfigServer; use PVE::HTMLControls; use PVE::HTMLForm; use PVE::HTMLGrid; use PVE::Utils; use PVE::HTMLUtils; use PVE::Cluster; use PVE::APLInfo; use PVE::QemuServer; use PVE::Storage; !] [- use strict; my $cinfo = $fdat{__cinfo}; my $form = PVE::HTMLForm->new (\%fdat); $fdat{hostcid} = $cinfo->{local}->{cid} if !defined ($fdat{hostcid}); my $conn = PVE::ConfigClient::connect ($udat{auth_cookie}); my $vzlist = $conn->cluster_vzlist()->result; my $resolvconf = PVE::Config::read_file ('resolvconf'); my $vmops = PVE::Config::read_file ("vmops"); my $rconn = $conn; if ($fdat{hostcid} != $cinfo->{local}->{cid}) { $rconn = PVE::ConfigClient::connect ($udat{auth_cookie}, $cinfo, $fdat{hostcid}); } my $status = $rconn->ping()->result; my $kvmversion = $status->{kvmversion}; my $has_openvz = $status->{openvz}; my $cpuinfo = $status->{cpuinfo}; my $stinfo = $rconn->storage_user_info ()->result; my $stcfg = $stinfo->{cfg}; if ($form->action eq 'create') { my $veid = int ($fdat{veid}); # filter leading zeros 0234 my $trackid; eval { check_write_mode ($udat{AM}); my $settings; $fdat{mac} = PVE::Utils::trim ($fdat{mac}); if ($fdat{virttype} eq 'openvz') { check_field (__("Memory"), $fdat{vzmem}, 'NOTEMPTY', 'NATURAL'); check_field (__("Swap"), $fdat{swap}, 'NOTEMPTY', 'NATURAL'); check_field (__("Template"), $fdat{ostemplate}, 'NOTEMPTY'); check_field (__("Hostname"), $fdat{hostname}, 'NOTEMPTY', 'NOWHITESPACES'); check_field (__("DNS Domain"), $fdat{dnsdomain}, 'NOTEMPTY', 'NOWHITESPACES'); check_field (__("Password"), $fdat{newpwd1}, 'NOTEMPTY'); check_field (__("Disk space"), $fdat{vzdisk}, 'NOTEMPTY', 'FLOAT'); check_field (__("MAC Address"), $fdat{mac}, 'NOTEMPTY', 'NOWHITESPACES', 'MAC') if $fdat{mac}; #check_range (__("CPUs"), $fdat{cpus}, 1, 16); die __("Passwords does not match") . "\n" if $fdat{newpwd1} ne $fdat{newpwd2}; die __("Password is too short") . "\n" if $fdat{newpwd1} && length ($fdat{newpwd1}) < 5; # always use fqdn for hostname if (($fdat{hostname} !~ m/\./) && $fdat{dnsdomain}) { $fdat{hostname} = "$fdat{hostname}.$fdat{dnsdomain}"; } $settings = { mem => $fdat{vzmem}, swap => $fdat{swap}, ostemplate => $fdat{ostemplate}, disk => $fdat{vzdisk}, onboot => $fdat{onboot} ? 'yes' : 'no', rootpasswd => PVE::Utils::_encrypt_pw ($fdat{newpwd1}), searchdomain => $fdat{dnsdomain}, hostname => $fdat{hostname}, cpus => 1, # $fdat{cpus}, }; if (my $pkginfo = PVE::APLInfo::pkginfo ($fdat{ostemplate})) { $settings->{description} = PVE::HTMLUtils::encode_description ($pkginfo->{headline}); } my $ns; push @$ns, $fdat{dnsserver1} if $fdat{dnsserver1} && ($fdat{dnsserver1} ne '0.0.0.0'); push @$ns, $fdat{dnsserver2} if $fdat{dnsserver2} && ($fdat{dnsserver2} ne '0.0.0.0'); $settings->{nameserver} = $ns; if ($fdat{nettype} eq 'veth') { $settings->{netif} = 'ifname=eth0'; $settings->{netif} .= ",mac=$fdat{mac}"; if ($fdat{bridge} && ($fdat{bridge} ne 'vmbr0')) { $settings->{netif} .= ",bridge=$fdat{bridge}"; } } else { $settings->{ipset} = $fdat{ipaddress}; } } else { check_field (__("Disk Storage"), $fdat{diskstore}, 'NOTEMPTY'); check_field (__("Memory"), $fdat{qmmem}, 'NOTEMPTY', 'NATURAL'); check_field (__("Name"), $fdat{name}, 'NOTEMPTY', 'NOWHITESPACES'); check_field (__("MAC Address"), $fdat{mac}, 'NOTEMPTY', 'NOWHITESPACES', 'MAC'); check_range (__("CPU Sockets"), $fdat{sockets}, 1, 16); my $scfg = PVE::Storage::storage_config ($stcfg, $fdat{diskstore}); my $storagespec; if ($scfg->{type} eq 'iscsi') { check_field (__("ISCSI Device"), $fdat{image}, 'NOTEMPTY'); $storagespec = $fdat{image}; } else { check_field (__("Disk space"), $fdat{qmdisk}, 'NOTEMPTY', 'FLOAT'); $storagespec = "$fdat{diskstore}:$fdat{qmdisk},format=$fdat{format}"; } my $network = "$fdat{nictype}=$fdat{mac}"; $settings = { memory => $fdat{qmmem}, cdrom => $fdat{cdrom}, onboot => $fdat{onboot} ? 'yes' : 'no', name => $fdat{name}, $fdat{bridge} => $network, ostype =>$fdat{ostype}, sockets => $fdat{sockets}, }; if ($fdat{disktype} eq 'ide') { $settings->{ide0} = $storagespec; $settings->{bootdisk} = 'ide0'; } elsif ($fdat{disktype} eq 'scsi') { $settings->{scsi0} = $storagespec; $settings->{bootdisk} = 'scsi0'; } elsif ($fdat{disktype} eq 'virtio') { $settings->{virtio0} = $storagespec; $settings->{bootdisk} = 'virtio0'; } } PVE::Cluster::check_vm_settings ($settings); $trackid = $conn->vmcommand_create ($fdat{hostcid}, $veid, $fdat{virttype}, $settings)->result; }; if ($@) { $udat{popup_error} = $@; } else { print OUT PVE::HTMLUtils::create_vmops_frame ($veid, $trackid); return; } } # try to set some reasonable default $udat{__create_virttype} = 'qemu' if $kvmversion && !$udat{__create_virttype}; $udat{__create_virttype} = 'openvz' if $has_openvz && !$udat{__create_virttype}; $udat{__create_virttype} = 'qemu' if !$udat{__create_virttype}; $udat{__create_virttype} = $fdat{virttype} if $fdat{virttype} ; $fdat{virttype} = $udat{__create_virttype} if !$fdat{virttype}; my $out = ''; my $has_hvm = $cpuinfo->{hvm}; if (!$cpuinfo->{hvm}) { my $msg = __("This CPU does not support KVM virtual machines (no Intel VT / AMD-V support)."); $out .= PVE::HTMLUtils::create_noteframe (__("Attention"), $msg); $out .= "
\n"; } elsif (!$kvmversion) { my $msg = __("KVM module not loaded. Maybe you need to enable Intel VT / AMD-V support in the BIOS."); $out .= PVE::HTMLUtils::create_noteframe (__("Attention"), $msg); $out .= "
\n"; $has_hvm = 0; } # we only display the warning about missing openvz if we have also no kvm if (!$has_openvz && !$has_hvm) { my $msg = __("This host does not have OpenVZ in the kernel."); $out .= PVE::HTMLUtils::create_noteframe (__("Attention"), $msg); $out .= "
\n"; } my $nextveid = PVE::Cluster::get_nextid($vzlist, $vmops); my $cidlist = PVE::HTMLUtils::cluster_format_cid_list ($cinfo); my $grid = PVE::HTMLGrid->new ('fw1', 'fw2', 'fw3:right', 'fw4'); my $osl = PVE::QemuServer::os_list_description(); my $oslist = []; foreach my $os (sort keys %$osl) { push @$oslist, [ $os, $osl->{$os} ]; } $out .= $form->create_header(); my $vtypes = []; push @$vtypes, ['openvz', 'Container (OpenVZ)'] if $has_openvz; push @$vtypes, [ 'qemu', "Fully virtualized (KVM)" ] if $has_hvm; $grid->add_row (__("Type") . ':', $form->create_element ('virttype', 'dynamicdropdown', $fdat{virttype}, $vtypes), "VMID:", $form->create_element ('veid', 'number', $fdat{veid} || $nextveid)); my $bridges = PVE::Utils::get_bridges (); if ($fdat{virttype} eq 'openvz') { my $tmp = $rconn->storage_list_vztmpl ('local')->result; my ($tmpllist, $default) = PVE::HTMLUtils::storage_format_vztmpl_list ($stcfg, $tmp); $fdat{ostemplate} = $default if !$fdat{ostemplate}; $grid->add_row (__("Template") . ':', $form->create_element ('ostemplate', 'dropdown', $fdat{ostemplate}, $tmpllist), __("Cluster Node") . ':', $form->create_element ('hostcid', 'dynamicdropdown', $fdat{hostcid}, $cidlist)); $grid->add_row (__("Hostname") . ':', $form->create_element ('hostname', 'text', $fdat{hostname}), __("Start at boot") . ':', $form->create_element ('onboot', 'bool', defined ($fdat{onboot}) ? $fdat{onboot} : 0)); $grid->add_row (__("Memory") . ' (MB):', $form->create_element ('vzmem', 'number', $fdat{vzmem} || 512), __("Disk space") . ' (GB):', $form->create_element ('vzdisk', 'float', $fdat{vzdisk} || "8")); $grid->add_row (__("Swap") . ' (MB):', $form->create_element ('swap', 'number', defined ($fdat{swap}) ? $fdat{swap} : 512)); # __("CPUs") . ':', $form->create_element ('cpus', 'rotext', $fdat{cpus} || 1)); $grid->add_row (__("Password") . ':', $form->create_element ('newpwd1', 'password', $fdat{newpwd1})); $grid->add_row (__("Confirm Password") . ':', $form->create_element ('newpwd2', 'password', $fdat{newpwd2})); } else { $fdat{isostore} = $stinfo->{iso_default} if !$fdat{isostore}; my $isostorelist = PVE::HTMLUtils::storage_format_storage_list($stinfo, 'iso'); $grid->add_row (__("ISO Storage") . ':', $form->create_element ('isostore', 'dynamicdropdown', $fdat{isostore}, $isostorelist), __("Cluster Node") . ':', $form->create_element ('hostcid', 'dynamicdropdown', $fdat{hostcid}, $cidlist)); my $tmp = $rconn->storage_list_iso ($fdat{isostore})->result; my $tmpllist = PVE::HTMLUtils::storage_format_iso_list ($stcfg, $tmp); # symbolic name for cdrom, because cdrom path can be different at each node unshift @$tmpllist, ['cdrom', 'cdrom device']; $grid->add_row (__("Installation Media") . ':', $form->create_element ('cdrom', 'dropdown', $fdat{cdrom}, $tmpllist), __("Start at boot") . ':', $form->create_element ('onboot', 'bool', defined ($fdat{onboot}) ? $fdat{onboot} : 0)); $fdat{diskstore} = $stinfo->{images_default} if !$fdat{diskstore}; my $diskstorelist = PVE::HTMLUtils::storage_format_storage_list ($stinfo); my ($defformat, $formatlist) = PVE::Storage::storage_default_format ($stcfg, $fdat{diskstore}); $fdat{format} = $defformat if !$fdat{format} || !grep {$_ eq $fdat{format}} @$formatlist; $grid->add_row (__("Disk Storage") . ':', $form->create_element ('diskstore', 'dynamicdropdown', $fdat{diskstore}, $diskstorelist), __("Image Format") . ':', $form->create_element ('format', 'dropdown', $fdat{format}, $formatlist)); my @ea; my $scfg = PVE::Storage::storage_config ($stcfg, $fdat{diskstore}); if ($scfg && $scfg->{type} eq 'iscsi') { my $tmp = $rconn->storage_list_volumes ($fdat{diskstore})->result; my $imagelist = PVE::HTMLUtils::storage_format_volume_list_iscsi ($stcfg, $tmp); push @ea, __("ISCSI Devive") . ':', $form->create_element ('image', 'dropdown', $fdat{image}, $imagelist); } else { push @ea, __("Disk space") . ' (GB):', $form->create_element ('qmdisk', 'float', $fdat{qmdisk} || "32"); } my $dtypes = [['ide', 'IDE'], ['scsi', 'SCSI'], ['virtio', 'VIRTIO']]; $grid->add_row (@ea, __("Disk type") . ':', $form->create_element ('disktype', 'dropdown', $fdat{disktype}, $dtypes)); $grid->add_row (__("Name") . ':', $form->create_element ('name', 'text', $fdat{name}), __("Guest Type") . ':', $form->create_element ('ostype', 'dropdown', $fdat{ostype} || 'other', $oslist)); $grid->add_row (__("Memory") . ' (MB):', $form->create_element ('qmmem', 'number', $fdat{qmmem} || 512), __("CPU Sockets") . ':', $form->create_element ('sockets', 'number', $fdat{sockets} || 1)); } my $html = $grid->html(); $out .= PVE::HTMLUtils::create_statusframe (undef, "Configuration", undef, $html); $out .= "
\n"; $fdat{bridge} = 'vmbr0' if !$fdat{bridge}; $fdat{mac} = PVE::QemuServer::random_ether_addr() if !$fdat{mac}; if ($fdat{virttype} eq 'openvz') { my $dns1 = @{$resolvconf->{nameservers}}[0] || '0.0.0.0'; my $dns2 = @{$resolvconf->{nameservers}}[1] || '0.0.0.0'; my $ntypes = [['', __("Virtual Network (venet)")], [ 'veth', __("Bridged Ethernet (veth)") ]]; $grid->add_row (__("Network Type") . ':', $form->create_element ('nettype', 'dynamicdropdown', $fdat{nettype}, $ntypes), __("DNS Domain") . ':', $form->create_element ('dnsdomain', 'text', $fdat{dnsdomain} || $resolvconf->{search}) ); $fdat{ipaddress} = "127.0.0.1" if !$fdat{ipaddress}; my @ea; if ($fdat{nettype} eq 'veth') { $grid->add_row (__("Bridge") . ':', $form->create_element ('bridge', 'dropdown', $fdat{bridge}, $bridges), __("First DNS Server") . ':', $form->create_element ('dnsserver1', 'ip', $fdat{dnsserver1} || $dns1)); @ea = (__("MAC Address") . ':', $form->create_element ('mac', 'text', $fdat{mac})); } else { $grid->add_row (__("IP Address") . ':', $form->create_element ('ipaddress', 'ip', $fdat{ipaddress}), __("First DNS Server") . ':', $form->create_element ('dnsserver1', 'ip', $fdat{dnsserver1} || $dns1)); @ea = ('', ''); } $grid->add_row (@ea, __("Second DNS Server") . ':', $form->create_element ('dnsserver2', 'ip', $fdat{dnsserver2} || $dns2) ); } else { my $nics = PVE::QemuServer::nic_models (); my $brg; foreach my $bn (@$bridges) { if ($bn =~ m/^vmbr([0-9]{1,4})$/) { push @$brg, [ "vlan$1", "vmbr$1" ]; } } push @$brg, [ "vlanu", "NAT (User Mode Network)" ]; $grid->add_row (__("Bridge") . ':', $form->create_element ('bridge', 'dropdown', $fdat{bridge}, $brg), __("Network Card") . ':', $form->create_element ('nictype', 'dropdown', $fdat{nictype}, $nics)); $grid->add_row ('', '', __("MAC Address") . ':', $form->create_element ('mac', 'text', $fdat{mac})); } my $html = $grid->html(); $out .= PVE::HTMLUtils::create_statusframe (undef, __("Network"), undef, $html); $out .= "
"; $out .= $form->create_cmdbutton ('create'); $out .= $form->create_footer(); print OUT $out; -]