Commit 44d70584 authored by Francesc Guasch's avatar Francesc Guasch
Browse files

Merge branch 'fix/1104_mariadb' into hotfix/0.4.4

parents e33db069 cebc2d60
......@@ -15,12 +15,6 @@
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='full'>
<model fallback='forbid'>Penryn</model>
<feature policy='require' name='vme'/>
<feature policy='require' name='x2apic'/>
<feature policy='require' name='hypervisor'/>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
......@@ -138,12 +132,4 @@
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-a289e5a7-77c8-4447-b21e-177105598ec6</label>
<imagelabel>libvirt-a289e5a7-77c8-4447-b21e-177105598ec6</imagelabel>
</seclabel>
<seclabel type='dynamic' model='dac' relabel='yes'>
<label>+64055:+130</label>
<imagelabel>+64055:+130</imagelabel>
</seclabel>
</domain>
......@@ -12,9 +12,6 @@
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Penryn</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
......
......@@ -12,9 +12,6 @@
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Penryn</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
......
......@@ -12,9 +12,6 @@
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Penryn</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
......
......@@ -12,9 +12,6 @@
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Penryn</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
......
......@@ -145,12 +145,4 @@
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-7358e9e4-7472-416e-a2d2-c831491814e9</label>
<imagelabel>libvirt-7358e9e4-7472-416e-a2d2-c831491814e9</imagelabel>
</seclabel>
<seclabel type='dynamic' model='dac' relabel='yes'>
<label>+123:+131</label>
<imagelabel>+123:+131</imagelabel>
</seclabel>
</domain>
......@@ -986,11 +986,13 @@ sub _add_grant($self, $grant, $allowed, $description) {
my $sth_insert = $CONNECTOR->dbh->prepare(
"INSERT INTO grants_user (id_user, id_grant, allowed) VALUES(?,?,?) ");
$sth = $CONNECTOR->dbh->prepare("SELECT id,name FROM users WHERE is_temporary = 0");
$sth = $CONNECTOR->dbh->prepare("SELECT id,name,is_admin FROM users WHERE is_temporary = 0");
$sth->execute;
while (my ($id_user, $name) = $sth->fetchrow ) {
eval { $sth_insert->execute($id_user, $id_grant, $allowed) };
while (my ($id_user, $name, $is_admin) = $sth->fetchrow ) {
my $allowed_current = $allowed;
$allowed_current = 1 if $is_admin;
eval { $sth_insert->execute($id_user, $id_grant, $allowed_current ) };
die $@ if $@ && $@ !~/Duplicate entry /;
}
}
......@@ -1091,8 +1093,8 @@ sub _upgrade_table {
&& $new_size
&& $new_size != $row->{COLUMN_SIZE}) {
$dbh->do("alter table $table change $field $field $definition");
warn "INFO: changing $field $row->{COLUMN_SIZE} to $new_size in $table\n" if $0 !~ /\.t$/;
$dbh->do("alter table $table change $field $field $definition");
return;
}
......@@ -3053,6 +3055,15 @@ sub _cmd_list_network_interfaces($self, $request) {
$request->output(encode_json(\@ifs));
}
sub _cmd_list_isos($self, $request){
my $vm_type = $request->args('vm_type');
my $vm = Ravada::VM->open( type => $vm_type );
my @isos = sort { "\L$a" cmp "\L$b" } $vm->search_volume_path_re(qr(.*\.iso$));
$request->output(encode_json(\@isos));
}
sub _clean_requests($self, $command, $request=undef) {
my $query = "DELETE FROM requests "
." WHERE command=? "
......@@ -3315,6 +3326,9 @@ sub _req_method {
#networks
,list_network_interfaces => \&_cmd_list_network_interfaces
#isos
,list_isos => \&_cmd_list_isos
);
return $methods{$cmd};
}
......
......@@ -2092,6 +2092,20 @@ sub expose($self, @args) {
}
}
sub exposed_port($self, $search) {
confess "Error: you must supply a port number or name of exposed port"
if !defined $search || !length($search);
for my $port ($self->list_ports) {
if ( $search =~ /^\d+$/ ) {
return $port if $port->{internal_port} eq $search;
} else {
return $port if $port->{name} eq $search;
}
}
return;
}
sub _update_expose($self, %args) {
my $id = delete $args{id_port};
$args{internal_port} = delete $args{port}
......@@ -2327,6 +2341,7 @@ sub list_ports($self) {
$sth->execute($self->id);
my @list;
while (my $data = $sth->fetchrow_hashref) {
lock_hash(%$data);
push @list,($data);
}
return @list;
......
......@@ -580,12 +580,16 @@ Returns a reference to a list of the ISOs known by the system
=cut
sub iso_file {
my $self = shift;
my $vm = $self->search_vm('KVM');
my @isos = sort { "\L$a" cmp "\L$b" } $vm->search_volume_path_re(qr(.*\.iso$));
#TODO remove path from device
return \@isos;
sub iso_file ($self, $vm_type) {
my $req = Ravada::Request->list_isos(
vm_type => $vm_type
);
$self->wait_request($req);
return [] if $req->status ne 'done';
my $isos = decode_json($req->output());
return $isos;
}
=head2 list_lxc_templates
......@@ -884,6 +888,7 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) {
|| $command eq 'connect_node'
|| $command eq 'post_login'
|| $command eq 'list_network_interfaces'
|| $command eq 'list_isos'
;
next if ( $command eq 'force_shutdown'
|| $command eq 'start'
......
......@@ -101,6 +101,9 @@ our %VALID_ARG = (
#networks
,list_network_interfaces => { uid => 1, vm_type => 1, type => 2 }
#isos
,list_isos => { vm_type => 1 }
,ping_backend => {}
);
......@@ -137,7 +140,7 @@ our %COMMAND = (
,important=> {
limit => 20
,priority => 1
,commands => ['clone','start','start_clones','create','open_iptables','list_network_interfaces']
,commands => ['clone','start','start_clones','create','open_iptables','list_network_interfaces','list_isos']
}
,secondary => {
limit => 50
......
......@@ -174,6 +174,7 @@
$scope.list_ldap_attributes();
$scope.list_interfaces();
$scope.hardware_types = Object.keys(response.data.hardware);
$scope.copy_ram = $scope.showmachine.max_mem / 1024 / 1024;
});
};
$scope.list_interfaces = function() {
......@@ -309,6 +310,19 @@
$scope.refresh_machine();
});
};
$scope.copy_machine = function() {
$http.post('/machine/copy/'
, JSON.stringify({ 'id_base': $scope.showmachine.id
,'copy_number': $scope.copy_number
,'copy_ram': $scope.copy_ram
,'new_name': $scope.new_name
})
).then(function(response) {
$scope.getReqs();
$scope.refresh_machine();
});
};
//On load code
// $scope.showmachineId = window.location.pathname.split("/")[3].split(".")[0] || -1 ;
$scope.refresh_machine = function() {
......
......@@ -396,7 +396,7 @@ get '/iso_file.json' => sub {
return access_denied($c) unless _logged_in($c)
&& $USER->can_create_machine();
my @isos =('<NONE>');
push @isos,(@{$RAVADA->iso_file});
push @isos,(@{$RAVADA->iso_file('KVM')});
$c->render(json => \@isos);
};
......@@ -1852,7 +1852,7 @@ sub manage_machine {
$c->stash(errors => \@errors);
return $c->render(template => 'main/settings_machine'
, nodes => [$RAVADA->list_vms($domain->type)]
, isos => $RAVADA->iso_file()
, isos => $RAVADA->iso_file($domain->type)
, list_clones => [map { $_->{name} } $domain->clones]
, action => $c->req->url->to_abs->path
);
......@@ -2075,32 +2075,56 @@ sub copy_machine {
return login($c) if !_logged_in($c);
my $arg = decode_json($c->req->body);
my $id_base= $c->param('id_base') or confess "Missing param id_base";
my $ram = $c->param('copy_ram');
$ram = 0 if $ram !~ /^\d+(\.\d+)?$/;
my $number = $arg->{copy_number};
my $id_base= $arg->{id_base} or confess "Missing param id_base";
my $ram = $arg->{copy_ram};
$ram = 0 if !$ram || $ram !~ /^\d+(\.\d+)?$/;
$ram = int($ram*1024*1024);
my $disk= $c->param('copy_disk');
$disk = 0 if $disk && $disk !~ /^\d+(\.\d+)?$/;
$disk = int($disk*1024*1024*1024) if $disk;
my ($param_name) = grep /^copy_name_\d+/,(@{$c->req->params->names});
my $base = $RAVADA->search_domain_by_id($id_base) or confess "I can't find domain $id_base";
my $name = $c->req->param($param_name) if $param_name;
$name = $base->name."-".$USER->name if !$name;
my $name = ( $arg->{new_name} or $base->name."-".$USER->name );
my @create_args =( memory => $ram ) if $ram;
push @create_args , ( disk => $disk ) if $disk;
my $req2 = Ravada::Request->clone(
uid => $USER->id
my @reqs;
if ($number == 1 ) {
my $req2 = Ravada::Request->clone(
uid => $USER->id
,name => $name
, id_domain => $base->id
,@create_args
);
$c->redirect_to("/machine/manage/".$base->id.".html");# if !@error;
, id_domain => $base->id
,@create_args
);
push @reqs, ( $req2 );
} else {
push @reqs,(copy_machine_many($base, $number, \@create_args));
}
return $c->render(json => { request => [map { $_->id } @ reqs ] } );
}
sub copy_machine_many($base, $number, $create_args) {
my $domains = $RAVADA->list_domains;
my %domain_exists = map { $_->{name} => 1 } @$domains;
my @reqs;
for ( 1 .. $number ) {
my $n = $_;
my $name;
for ( ;; ) {
while (length($n) < length($number)) { $n = "0".$n };
$name = $base->name."-".$n;
last if !$domain_exists{$name}++;
$n++;
}
my $req2 = Ravada::Request->clone(
uid => $USER->id
,name => $name
, id_domain => $base->id
,@$create_args
);
push @reqs, ( $req2 );
}
return @reqs;
}
sub machine_is_public {
......
......@@ -6,4 +6,4 @@ CREATE TABLE `grant_types` (
UNIQUE(`name`),
UNIQUE(`description`),
PRIMARY KEY (`id`)
);
) CHARACTER SET 'utf8';
......@@ -9,5 +9,6 @@ CREATE TABLE `users` (
`language` char(3) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
);
)
CHARACTER SET 'utf8';
......@@ -8,4 +8,4 @@ create table volumes (
PRIMARY KEY (`id`),
UNIQUE (`id_domain`,`name`),
UNIQUE (`id_domain`,`n_order`)
);
)CHARACTER SET 'utf8';
......@@ -4,5 +4,4 @@ CREATE TABLE `grant_types` (
, `description` varchar(255) NOT NULL
, `enabled` integer default NULL
, UNIQUE(`name`)
, UNIQUE(`description`)
);
......@@ -979,6 +979,12 @@ sub start_node($node) {
is($connect,1
,"[".$node->type."] "
.$node->name." Expecting connection") or exit;
for ( 1 .. 60 ) {
$domain = _domain_node($node);
last if $domain->ip;
sleep 1;
diag("Waiting for connection to node ".$node->name." $_") if !($_ % 5);
}
eval { $node->run_command("hwclock","--hctosys") };
is($@,'',"Expecting no error setting clock on ".$node->name." ".($@ or ''));
......
......@@ -22,7 +22,7 @@ sub test_one_port($vm) {
flush_rules();
my $domain = create_domain($vm->type, user_admin ,'debian');
my $domain = create_domain($vm->type, user_admin ,'debian stretch');
my $remote_ip = '10.0.0.1';
my $local_ip = $vm->ip;
......@@ -45,6 +45,22 @@ sub test_one_port($vm) {
};
is($@,'',"[".$vm->type."] export port $internal_port");
my $port_info_no = $domain->exposed_port(456);
is($port_info_no,undef);
$port_info_no = $domain->exposed_port('no');
is($port_info_no,undef);
my $port_info = $domain->exposed_port($name_port);
ok($port_info) && do {
is($port_info->{name}, $name_port);
is($port_info->{internal_port}, $internal_port);
};
my $port_info2 = $domain->exposed_port($internal_port);
ok($port_info2);
is_deeply($port_info2, $port_info);
my @list_ports = $domain->list_ports();
is(scalar @list_ports,1);
......@@ -127,7 +143,7 @@ sub test_remove_expose {
my $vm = rvd_back->search_vm($vm_name);
my $domain = create_domain($vm_name, user_admin,'debian');
my $domain = create_domain($vm_name, user_admin,'debian stretch');
my $remote_ip = '10.0.0.1';
my $local_ip = $vm->ip;
......@@ -222,7 +238,7 @@ sub test_crash_domain($vm_name) {
my $vm = rvd_back->search_vm($vm_name);
my $domain = create_domain($vm_name, user_admin,'debian');
my $domain = create_domain($vm_name, user_admin,'debian stretch');
my $remote_ip = '10.0.0.1';
my $local_ip = $vm->ip;
......@@ -259,7 +275,7 @@ sub test_crash_domain($vm_name) {
# shutdown forced
shutdown_domain_internal($domain);
my $domain2 = create_domain($vm_name, user_admin,'debian');
my $domain2 = create_domain($vm_name, user_admin,'debian stretch');
$domain2->start(user => user_admin) if !$domain2->is_active;
$domain2->remove(user_admin);
......@@ -269,7 +285,7 @@ sub test_two_ports($vm) {
flush_rules();
my $domain = create_domain($vm, user_admin,'debian');
my $domain = create_domain($vm, user_admin,'debian stretch');
my $remote_ip = '10.0.0.1';
my $local_ip = $vm->ip;
......@@ -327,7 +343,7 @@ sub test_two_ports($vm) {
sub test_clone_exports($vm) {
my $base = create_domain($vm, user_admin,'debian');
my $base = create_domain($vm, user_admin,'debian stretch');
$base->expose(port => 22, name => "ssh");
my @base_ports = $base->list_ports();
......@@ -397,7 +413,7 @@ sub test_host_down {
my $vm = rvd_back->search_vm($vm_name);
my $domain = create_domain($vm_name, user_admin,'debian');
my $domain = create_domain($vm_name, user_admin,'debian stretch');
my $remote_ip = '10.0.0.1';
my $local_ip = $vm->ip;
......@@ -448,7 +464,7 @@ sub test_host_down {
sub test_req_expose($vm_name) {
flush_rules();
my $domain = create_domain($vm_name, user_admin,'debian');
my $domain = create_domain($vm_name, user_admin,'debian stretch');
my $remote_ip = '10.0.0.6';
......@@ -615,7 +631,7 @@ sub test_change_expose($vm, $restricted) {
}
sub test_change_expose_3($vm) {
my $domain = create_domain($vm->type, user_admin,'debian');
my $domain = create_domain($vm->type, user_admin,'debian stretch');
my $internal_port = 100;
my $name = "foo";
......@@ -625,9 +641,12 @@ sub test_change_expose_3($vm) {
$domain->expose(port => $internal_port+$n , restricted => $restricted);
}
my $remote_ip = '1.2.3.4';
my $remote_ip = '10.0.0.4';
$domain->start(user => user_admin, remote_ip => $remote_ip);
_wait_ip($vm->type, $domain);
rvd_back->_process_requests_dont_fork(1);
_wait_requests($domain);
_check_port_rules($domain, $remote_ip);
......
<div class="card-body">
<form method="post" action="/machine/copy">
<div class="form-group">
<div class="form-group row">
<div class="col-md-2 mt-2">
<label class="control-label" for="clone_number">Clones</label>
</div>
<div class="col-md-2">
<input class="form-control"
ng-model="copy_number" type="text" ng-init="copy_number=1"
size="3" value="1">
</div>
</div>
<div class="form-group row" ng-show="copy_number == 1">
<div class="col-md-2 mt-2">
<input class="form-control" type="hidden" name="id_base" value="{{showmachine.id}}">
<label class="control-label"
for="copy_name_{{showmachine.id}}"><%=l 'Name' %></label>
for="copy_name"><%=l 'Name' %></label>
</div>
<div class="col-md-5">
<input class="form-control" name="copy_name_{{showmachine.id}}" type="text" size="40"
value="{{showmachine.name}}-copy"
<input class="form-control"
type="text" size="40"
ng-model="new_name"
ng-change="validate_new_name(showmachine.name)"
>
......@@ -21,19 +30,20 @@
<label class="control-label" for="copy_ram">RAM (Gb)</label>
</div>
<div class="col-md-2">
<input class="form-control" name="copy_ram" type="text" size="3" value="1">
<input class="form-control" ng-model="copy_ram" type="text" size="3">
</div>
</div>
<button type="reset" class="btn btn-outline-secondary mr-2"><%=l 'Cancel' %></button>
<input type="submit" class="btn btn-primary" ng-disabled="new_name_duplicated || new_name_invalid || new_name === showmachine.name" value="<%=l 'Submit' %>">
<button class="btn btn-primary"
ng-click="copy_machine()"
ng-disabled="copy_number <1 || copy_number == 1 && (new_name_duplicated || new_name_invalid || new_name === showmachine.name)"><%=l 'Submit' %></button>
</div>
</form>
<div class="form-group has-error">
<label ng-show="new_name_duplicated"
<label ng-show="copy_number==1 && new_name_duplicated"
class="alert alert-danger col-form-label" for="new_name">
This name is duplicated
</label>
<label ng-show="new_name_invalid"
<label ng-show="copy_number==1 && new_name_invalid"
class="alert alert-danger col-form-label" for="new_name">
This name is invalid. It can only contain alphabetic, numbers, undercores and dashes
and must start by a letter.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment