Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Projets publics
Ravada-Mirror
Commits
3d0bbb36
Commit
3d0bbb36
authored
Sep 17, 2019
by
Francesc Guasch
Browse files
wip(request): pass ISO name and manage requests uid
issue #1136
parent
e743b04e
Changes
4
Show whitespace changes
Inline
Side-by-side
bin/rvd_request.pl
0 → 100755
View file @
3d0bbb36
#!/usr/bin/env perl
use
warnings
;
use
strict
;
use
Data::
Dumper
;
use
Getopt::
Long
;
use
JSON::
XS
qw(decode_json)
;
use
lib
'
./lib
';
use
Ravada
;
use
Ravada::
Request
;
use
Ravada::
Utils
;
no
warnings
"
experimental::signatures
";
use
feature
qw(signatures)
;
my
$ME
=
$
0
;
$ME
=~
s{.*/}{}
;
my
$USAGE
=
$ME
.
"
command [--help] [--wait] [options]
\n
"
.
"
- help: Help and usage message
\n
"
.
"
- wait: Wait for request to complete
"
;
my
(
$command
)
=
shift
@ARGV
if
$ARGV
[
0
]
&&
$ARGV
[
0
]
!~
/^-/
;
my
$WAIT
;
my
$HELP
;
my
%option
;
$command
=~
s/-/_/g
if
$command
;
GetOptions
(
\
%option
,
valid_options
(
$command
))
or
exit
;
$HELP
=
delete
$option
{
help
}
if
exists
$option
{
help
};
$command
=
shift
@ARGV
if
!
$command
&&
$HELP
&&
$ARGV
[
0
];
$command
=~
s/-/_/g
if
$command
;
help
(
$command
,
$option
{
doc
})
if
$HELP
;
die
"
$USAGE
\n
"
if
!
defined
$command
;
$WAIT
=
delete
$option
{
wait
}
if
exists
$option
{
wait
};
#################################################################
sub
valid_options
($command) {
my
@options
=
('
wait
','
help
','
doc=s
');
return
@options
if
!
$command
;
my
$definition
=
Ravada::Request::
valid_args
(
$command
)
or
die
"
Error: Unknown command
$command
\n
";
for
my
$field
(
keys
%$definition
)
{
$field
=~
s/_/-/g
;
if
(
$field
eq
'
uid
'
||
$field
=~
/^id_/
||
$field
=~
/^(at|timeout)$/
)
{
$field
.=
"
=i
";
}
else
{
$field
.=
"
=s
";
}
push
@options
,
$field
;
}
return
@options
;
}
sub
help
($command, $format=undef) {
if
(
$format
&&
$format
eq
'
rst
')
{
print
$ME
;
print
"
$command
"
if
$command
;
print
"
\n
"
.
("
=
"
x
4
)
.
"
\n
";
}
print
"
$USAGE
\n
"
if
!
$format
||
!
$command
;
if
(
!
$command
)
{
print
"
\n
Commands:
\n
"
.
('
-
'
x
4
)
.
"
\n
";
my
%valid
=
Ravada::Request::
valid_args
();
for
my
$field
(
sort
keys
%valid
)
{
print
"
-
$field
\n
";
}
exit
;
}
my
$definition
=
Ravada::Request::
valid_args_cli
(
$command
)
or
die
"
Error: Unknown command
$command
\n
";
delete
$definition
->
{
uid
};
print
"
\n
$command
\n
"
.
("
=
"
x
length
(
$command
))
.
"
\n
";
my
@mandatory
=
grep
{
$definition
->
{
$_
}
==
1
}
keys
%$definition
;
if
(
@mandatory
)
{
print
"
Mandatory arguments:
\n
"
.
('
-
'
x
4
)
.
"
\n
";
for
my
$option
(
sort
@mandatory
)
{
next
if
$definition
->
{
$option
}
!=
1
;
print
"
-
$option
"
.
info
(
$option
)
.
"
\n
";
delete
$definition
->
{
$option
};
}
print
"
\n
";
}
if
(
keys
%$definition
)
{
print
"
Optional arguments:
\n
"
.
('
-
'
x
4
)
.
"
\n
";
for
my
$option
(
sort
keys
%$definition
)
{
print
"
-
$option
"
.
info
(
$option
)
.
"
\n
";
}
}
exit
;
}
sub
info
($option) {
my
%info
=
(
uid
=>
"
User id that executes the request
"
,
at
=>
'
Run at a given time. Format time is seconds since epoch
'
,
after_request
=>
'
Run after request specified by id is done
'
,
id_domain
=>
"
Id of the domain or virtual machine
"
);
my
$text
=
$info
{
$option
};
return
''
if
!
$text
;
return
"
:
$text
";
}
sub
fix_options_slash
($option) {
for
my
$field
(
keys
%$option
)
{
if
(
$field
=~
/-/
)
{
my
$field2
=
$field
;
$field2
=~
s/-/_/g
;
$option
->
{
$field2
}
=
$option
->
{
$field
};
delete
$option
->
{
$field
};
}
}
}
sub
extract_data
($option) {
my
$json
=
$option
->
{
data
};
my
$data
=
decode_json
(
$json
);
$option
->
{
data
}
=
$data
;
}
#################################################################
my
$RVD_BACK
=
Ravada
->
new
();
$option
{
uid
}
=
Ravada::Utils::
user_daemon
->
id
if
!
exists
$option
{
uid
};
fix_options_slash
(
\
%option
);
extract_data
(
\
%option
)
if
$option
{
data
};
my
$request
=
Ravada::
Request
->
new_request
(
$command
,
%option
);
print
"
Requested
$command
id=
"
.
$request
->
id
.
"
\n
";
exit
if
!
$WAIT
;
my
$msg
=
'';
my
$t0
=
time
;
for
(;;)
{
my
$msg_curr
=
$request
->
status
;
if
(
$request
->
error
)
{
$msg_curr
.=
"
"
.
$request
->
error
;
}
if
(
$msg_curr
ne
$msg
||
time
-
$t0
>
2
)
{
print
localtime
.
"
"
.
$msg_curr
.
"
\n
";
$msg
=
$msg_curr
;
$t0
=
time
;
next
;
}
last
if
$request
->
status
eq
'
done
';
sleep
1
;
}
print
$request
->
output
.
"
\n
"
if
defined
$request
->
output
;
lib/Ravada.pm
View file @
3d0bbb36
...
...
@@ -1294,7 +1294,7 @@ sub _connect_dbh {
sleep
1
;
warn
"
Try
$try
$@
\n
";
}
die
(
$@
or
"
Can't connect to
$driver
$db
at
$host
");
confess
(
$@
or
"
Can't connect to
$driver
$db
at
$host
");
}
=head2 display_ip
...
...
@@ -1547,11 +1547,12 @@ sub create_domain {
}
}
my
$vm_name
=
delete
$args
{
vm
};
delete
$args
{
uid
};
my
$start
=
$args
{
start
};
my
$id_base
=
$args
{
id_base
};
my
$id_owner
=
$args
{
id_owner
}
or
confess
"
Error: missing id_owner
"
.
Dumper
(
\
%args
);
_check_args
(
\
%args
,
qw(iso_file id_base id_iso id_owner name active swap memory disk id_template start remote_ip request vm)
);
_check_args
(
\
%args
,
qw(iso_file id_base id_iso id_owner name active swap memory disk id_template start remote_ip request vm
iso_name
)
);
confess
"
ERROR: Argument vm required
"
if
!
$id_base
&&
!
$vm_name
;
...
...
@@ -2944,14 +2945,14 @@ sub _cmd_change_hardware {
);
}
sub
_cmd_shutdown
{
sub
_cmd_shutdown
_machine
{
my
$self
=
shift
;
my
$request
=
shift
;
my
$uid
=
$request
->
args
('
uid
');
my
$name
=
$request
->
defined_arg
('
name
');
my
$id_domain
=
$request
->
defined_arg
('
id_domain
');
my
$timeout
=
(
$request
->
arg
s
('
timeout
')
or
60
);
my
$timeout
=
(
$request
->
defined_
arg
('
timeout
')
or
60
);
my
$id_vm
=
$request
->
defined_arg
('
id_vm
');
confess
"
ERROR: Missing id_domain or name
"
if
!
$id_domain
&&
!
$name
;
...
...
@@ -3199,9 +3200,10 @@ sub _cmd_list_network_interfaces($self, $request) {
}
sub
_cmd_list_isos
($self, $request){
my
$vm_type
=
$request
->
args
('
vm_type
');
my
$vm_type
=
$request
->
defined_arg
('
vm_type
');
my
$vm
=
$self
->
vm
->
[
0
];
$vm
=
Ravada::
VM
->
open
(
type
=>
$vm_type
)
if
$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
));
...
...
@@ -3422,15 +3424,21 @@ sub _req_method {
clone
=>
\
&_cmd_clone
,
start
=>
\
&_cmd_start
,
start_domain
=>
\
&_cmd_start
,
start_clones
=>
\
&_cmd_start_clones
,
pause
=>
\
&_cmd_pause
,
create
=>
\
&_cmd_create
,
create_domain
=>
\
&_cmd_create
,
remove
=>
\
&_cmd_remove
,
remove_domain
=>
\
&_cmd_remove
,
resume
=>
\
&_cmd_resume
,
dettach
=>
\
&_cmd_dettach
,
cleanup
=>
\
&_cmd_cleanup
,
download
=>
\
&_cmd_download
,
shutdown
=>
\
&_cmd_shutdown
,
shutdown
=>
\
&_cmd_shutdown_machine
,
shutdown_domain
=>
\
&_cmd_shutdown_machine
,
hybernate
=>
\
&_cmd_hybernate
,
set_driver
=>
\
&_cmd_set_driver
,
screenshot
=>
\
&_cmd_screenshot
...
...
lib/Ravada/Request.pm
View file @
3d0bbb36
...
...
@@ -33,7 +33,7 @@ my $COUNT = 0;
our
%FIELD
=
map
{
$_
=>
1
}
qw(error output)
;
our
%FIELD_RO
=
map
{
$_
=>
1
}
qw(id name)
;
our
$args_manage
=
{
name
=>
1
,
uid
=>
1
};
our
$args_manage
=
{
name
=>
1
,
uid
=>
1
,
id_domain
=>
1
};
our
$args_prepare
=
{
id_domain
=>
1
,
uid
=>
1
};
our
$args_remove_base
=
{
id_domain
=>
1
,
uid
=>
1
};
our
$args_manage_iptables
=
{
uid
=>
1
,
id_domain
=>
1
,
remote_ip
=>
1
};
...
...
@@ -45,6 +45,7 @@ our %VALID_ARG = (
,
swap
=>
2
,
id_iso
=>
2
,
iso_file
=>
2
,
iso_name
=>
2
,
id_base
=>
2
,
id_owner
=>
1
,
id_template
=>
2
...
...
@@ -60,8 +61,11 @@ our %VALID_ARG = (
,
pause_domain
=>
$args_manage
,
resume_domain
=>
{
%$args_manage
,
remote_ip
=>
1
}
,
remove_domain
=>
$args_manage
,
shutdown_domain
=>
{
name
=>
2
,
id_domain
=>
2
,
uid
=>
1
,
timeout
=>
2
,
at
=>
2
,
shutdown
=>
{
alias
=>
'
shutdown_domain
'
,
args
=>
{
name
=>
2
,
id_domain
=>
1
,
uid
=>
1
,
timeout
=>
2
,
at
=>
2
,
id_vm
=>
2
}
},
,
force_shutdown_domain
=>
{
id_domain
=>
1
,
uid
=>
1
,
at
=>
2
,
id_vm
=>
2
}
,
screenshot_domain
=>
{
id_domain
=>
1
,
filename
=>
2
}
,
domain_autostart
=>
{
id_domain
=>
1
,
uid
=>
1
,
value
=>
2
}
...
...
@@ -107,10 +111,10 @@ our %VALID_ARG = (
,
list_network_interfaces
=>
{
uid
=>
1
,
vm_type
=>
1
,
type
=>
2
}
#isos
,
list_isos
=>
{
vm_type
=>
1
}
,
list_isos
=>
{
vm_type
=>
2
}
,
manage_pools
=>
{
uid
=>
2
,
id_domain
=>
2
}
,
ping_backend
=>
{}
,
ping_backend
=>
{
uid
=>
2
}
);
our
%CMD_SEND_MESSAGE
=
map
{
$_
=>
1
}
...
...
@@ -405,8 +409,8 @@ sub _check_args {
confess
"
Odd number of elements
"
.
Dumper
(
\
@
_
)
if
scalar
(
@
_
)
%
2
;
my
$args
=
{
@
_
};
my
$valid_args
=
$VALID_ARG
{
$sub
}
;
for
(
qw(at after_request)
)
{
my
$valid_args
=
valid_args
(
$sub
)
;
for
(
qw(at after_request
uid
)
)
{
$valid_args
->
{
$_
}
=
2
if
!
exists
$valid_args
->
{
$_
};
}
...
...
@@ -416,14 +420,71 @@ sub _check_args {
if
!
$valid_args
->
{
$_
};
}
for
(
keys
%
{
$VALID_ARG
{
$sub
}})
{
next
if
$VALID_ARG
{
$sub
}
->
{
$_
}
==
2
;
# optional arg
if
(
exists
$args
->
{
machine
}
&&
$VALID_ARG
{
$sub
}
->
{
id_domain
})
{
my
$id_domain
=
_search_id_domain
(
$args
->
{
machine
});
die
"
Error: provided id_domain=
$args
->{id_domain} and machine=
$args
->{machine}.
"
.
"
But
$args
->{machine} has a different id=
$id_domain
\n
"
if
exists
$args
->
{
id_domain
}
&&
$args
->
{
id_domain
}
&&
$args
->
{
id_domain
}
ne
$id_domain
;
die
"
Error: unknown machine '
$args
->{machine}'
\n
"
if
!
defined
$id_domain
;
$args
->
{
id_domain
}
=
$id_domain
;
}
my
$valid
=
valid_args
(
$sub
);
for
(
keys
%$valid
)
{
next
if
$valid
->
{
$_
}
==
2
;
# optional arg
confess
"
Missing argument
$_
"
if
!
exists
$args
->
{
$_
};
}
delete
$args
->
{
machine
}
if
exists
$args
->
{
machine
}
&&
exists
$args
->
{
id_domain
};
return
$args
;
}
sub
_valid_args_common
($command_req) {
my
%valid
;
my
$found
;
if
(
exists
$VALID_ARG
{
$command_req
})
{
%valid
=
%
{
$VALID_ARG
{
$command_req
}};
%valid
=
%
{
$valid
{
args
}}
if
exists
$valid
{
args
};
$found
++
;
}
else
{
for
my
$command
(
keys
%VALID_ARG
)
{
if
(
exists
$VALID_ARG
{
$command
}
->
{
alias
}
&&
$VALID_ARG
{
$command
}
->
{
alias
}
eq
$command_req
)
{
%valid
=
%
{
$VALID_ARG
{
$command
}
->
{
args
}};
$found
++
;
last
;
}
}
}
confess
"
Error: Unknown command '
$command_req
'
\n
"
if
!
$found
;
$valid
{
at
}
=
2
;
$valid
{
after_request
}
=
2
;
return
\
%valid
;
}
sub
valid_args_cli
($command) {
my
$valid
=
_valid_args_common
(
$command
);
if
(
exists
$valid
->
{
id_domain
})
{
$valid
->
{
machine
}
=
$valid
->
{
id_domain
};
delete
$valid
->
{
id_domain
};
}
return
$valid
;
}
sub
valid_args
($command=undef) {
return
%VALID_ARG
if
!
defined
$command
;
my
$valid
=
_valid_args_common
(
$command
);
if
(
exists
$valid
->
{
id_domain
})
{
$valid
->
{
machine
}
=
2
;
$valid
->
{
id_domain
}
=
2
;
}
return
$valid
;
}
=head2 force_shutdown_domain
Requests to stop a domain now !
...
...
@@ -468,7 +529,7 @@ sub shutdown_domain {
my
$self
=
{};
bless
(
$self
,
$class
);
return
$self
->
_new_request
(
command
=>
'
shutdown
'
,
args
=>
$args
);
return
$self
->
_new_request
(
command
=>
'
shutdown
_domain
'
,
args
=>
$args
);
}
sub
new_request
($self, $command, @args) {
...
...
@@ -644,6 +705,17 @@ sub _search_domain_name {
return
$sth
->
fetchrow
;
}
sub
_search_id_domain
($machine) {
return
$machine
if
$machine
=~
/^\d+$/
;
_init_connector
();
my
$sth
=
$$CONNECTOR
->
dbh
->
prepare
("
SELECT id FROM domains where name=?
");
$sth
->
execute
(
$machine
);
my
$id
=
$sth
->
fetchrow
;
return
$id
;
}
sub
_send_message
{
my
$self
=
shift
;
my
$status
=
shift
;
...
...
lib/Ravada/VM.pm
View file @
3d0bbb36
...
...
@@ -368,6 +368,7 @@ sub _around_create_domain {
my
$owner
=
Ravada::Auth::
SQL
->
search_by_id
(
$id_owner
)
or
confess
"
Unknown user id:
$id_owner
";
my
$base
;
my
$iso_name
=
delete
$args
{
iso_name
};
my
$volatile
=
delete
$args
{
volatile
};
my
$id_base
=
delete
$args
{
id_base
};
my
$id_iso
=
delete
$args
{
id_iso
};
...
...
@@ -404,6 +405,16 @@ sub _around_create_domain {
$args_create
{
spice_password
}
=
$self
->
_define_spice_password
(
$remote_ip
);
$self
->
_pre_create_domain
(
%args_create
);
if
(
$iso_name
)
{
my
$iso
=
$self
->
search_iso_image
(
$iso_name
);
die
"
Error: iso '
$iso_name
' not found
"
if
!
$iso
;
confess
"
Error: requested both id_iso=
$id_iso
&& iso_name=
$iso_name
(id=
$iso
->{id})
"
if
$id_iso
&&
$iso
->
{
id
}
!=
$id_iso
;
delete
$args_create
{
iso_name
};
$args_create
{
id_iso
}
=
$iso
->
{
id
};
}
my
$domain
=
$self
->
$orig
(
%args_create
,
volatile
=>
$volatile
);
$domain
->
add_volume_swap
(
size
=>
$swap
)
if
$swap
;
...
...
@@ -435,6 +446,15 @@ sub _around_create_domain {
return
$domain
;
}
sub
search_iso_image
($self, $name) {
_init_connector
();
my
$sth
=
$$CONNECTOR
->
dbh
->
prepare
("
SELECT * FROM iso_images WHERE name like ?
");
$sth
->
execute
(
$name
);
my
$row
=
$sth
->
fetchrow_hashref
;
return
$row
;
}
sub
_define_spice_password
($self, $remote_ip) {
my
$spice_password
=
Ravada::Utils::
random_name
(
4
);
if
(
$remote_ip
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment