Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
f070014e
Commit
f070014e
authored
Sep 14, 2015
by
Leigh B Stoller
Browse files
Tweaks to webtasks and exit status to avoid some errors going to tbops.
parent
064f04fe
Changes
6
Hide whitespace changes
Inline
Side-by-side
apt/manage_dataset.in
View file @
f070014e
...
...
@@ -83,6 +83,7 @@ use GeniXML;
# Protos
sub
fatal
($);
sub
uerror
($);
sub
DoCreate
();
sub
DoDelete
();
sub
DoRefresh
();
...
...
@@ -107,6 +108,11 @@ if (defined($options{"d"})) {
}
if
(
defined
(
$options
{"
t
"}))
{
$webtask_id
=
$options
{"
t
"};
$webtask
=
WebTask
->
LookupOrCreate
(
undef
,
$webtask_id
);
if
(
!
defined
(
$webtask
))
{
fatal
("
Could not create webtask object
");
}
$webtask
->
AutoStore
(
1
);
}
if
(
@ARGV
<
1
)
{
usage
();
...
...
@@ -297,14 +303,6 @@ sub DoCreate()
if
(
!
defined
(
$dataset
))
{
fatal
("
Internal error creating dataset object
");
}
# Now we can create.
if
(
defined
(
$webtask_id
))
{
$webtask
=
WebTask
->
Create
(
$dataset
->
uuid
(),
$webtask_id
);
if
(
defined
(
$webtask
))
{
# Convenient.
$webtask
->
AutoStore
(
1
);
}
}
# new dataset is returned locked. If we have instance, try to lock
# that now, else its a failure.
...
...
@@ -314,7 +312,17 @@ sub DoCreate()
goto
failed
;
}
}
#
# For IM datasets always create a webtask for tracking imaging status.
#
if
(
$type
eq
"
imdataset
")
{
$webtask
=
WebTask
->
Create
(
$dataset
->
uuid
());
if
(
!
defined
(
$webtask
))
{
$errmsg
=
"
Could not create webtask object
";
goto
failed
;
}
$webtask
->
AutoStore
(
1
);
}
#
# Ask the aggregate to create the dataset.
#
...
...
@@ -386,7 +394,7 @@ sub DoCreate()
#
sub
DoDelete
()
{
my
$errmsg
=
"
Could not delete dataset
";
my
$errmsg
=
"
Could not delete dataset
";
if
(
@ARGV
!=
1
)
{
fatal
("
usage: $0 delete pid/name
");
...
...
@@ -397,14 +405,19 @@ sub DoDelete()
fatal
("
No such dataset
");
}
if
(
$dataset
->
Lock
())
{
fatal
("
dataset is busy, cannot lock it
");
uerror
("
dataset is busy, cannot lock it
");
}
my
$response
=
$dataset
->
DeleteDataset
();
if
(
$response
->
code
()
!=
GENIRESPONSE_SUCCESS
&&
$response
->
code
()
!=
GENIRESPONSE_SEARCHFAILED
)
{
$response
->
code
()
!=
GENIRESPONSE_SEARCHFAILED
&&
$response
->
code
()
!=
GENIRESPONSE_BUSY
)
{
$errmsg
=
"
DeleteDataset failed:
"
.
$response
->
output
()
.
"
\n
";
goto
failed
;
}
if
(
$response
->
code
()
!=
GENIRESPONSE_BUSY
)
{
$dataset
->
Unlock
();
uerror
("
dataset was busy at the remote cluster, try again later
");
}
$dataset
->
Delete
();
return
0
;
...
...
@@ -430,7 +443,7 @@ sub DoRefresh()
fatal
("
No such dataset
");
}
if
(
$dataset
->
Lock
())
{
fatal
("
dataset is busy, cannot lock it
");
uerror
("
dataset is busy, cannot lock it
");
}
if
(
DoRefreshInternal
(
$dataset
,
\
$errmsg
))
{
goto
failed
;
...
...
@@ -451,7 +464,7 @@ sub DoRefreshInternal($$)
my
$response
=
$dataset
->
DescribeDataset
();
if
(
$response
->
code
()
!=
GENIRESPONSE_SUCCESS
)
{
if
(
$response
->
code
()
==
GENIRESPONSE_SEARCHFAILED
)
{
$$pmesg
=
"
Dataset no longer exists at the
target
\n
";
$$pmesg
=
"
Dataset no longer exists at the
remote cluster
\n
";
}
else
{
$$pmesg
=
"
DescribeDataset failed:
"
.
$response
->
output
()
.
"
\n
";
...
...
@@ -529,7 +542,7 @@ sub DoModify()
$blob
->
{'
write_access
'}
=
$write_access
;
}
if
(
$dataset
->
Lock
())
{
fatal
("
dataset is busy, cannot lock it
");
uerror
("
dataset is busy, cannot lock it
");
}
if
(
keys
(
%$blob
))
{
if
(
$dataset
->
Update
(
$blob
))
{
...
...
@@ -580,7 +593,7 @@ sub DoExtend()
fatal
("
No such dataset
");
}
if
(
$dataset
->
Lock
())
{
fatal
("
dataset is busy, cannot lock it
");
uerror
("
dataset is busy, cannot lock it
");
}
my
$response
=
$dataset
->
ExtendDataset
();
if
(
$response
->
code
()
!=
GENIRESPONSE_SUCCESS
)
{
...
...
@@ -645,20 +658,31 @@ sub DoSnapshot()
fatal
("
Could not find aggregate for
$nodeid
");
}
if
(
$dataset
->
Lock
())
{
fatal
("
dataset is busy, cannot lock it
");
uerror
("
dataset is busy, cannot lock it
");
}
if
(
$instance
->
Lock
())
{
# undef so we do not try to unlock it below.
$instance
=
undef
;
$errmsg
=
"
instance is busy, cannot lock it
";
goto
failed
$dataset
->
Unlock
();
uerror
("
instance is busy, cannot lock it
");
}
# Create a webtask for the caller, might be ignored but thats okay.
$webtask
=
WebTask
->
Create
(
$dataset
->
uuid
(),
$webtask_id
);
#
# Always create a webtask for tracking imaging status. Must be
# associated with the object.
#
if
(
defined
(
$webtask
))
{
# Convenient.
if
(
$webtask
->
object_uuid
()
ne
$dataset
->
uuid
())
{
$errmsg
=
"
Webtask not associated with dataset!
";
goto
failed
;
}
}
else
{
$webtask
=
WebTask
->
LookupOrCreate
(
$dataset
->
uuid
());
if
(
!
defined
(
$webtask
))
{
$errmsg
=
"
Could not create webtask object!
";
goto
failed
;
}
$webtask
->
AutoStore
(
1
);
}
if
(
DoSnapShotInternal
(
$dataset
,
$aggregate
,
$bsname
,
$nodeid
,
\
$errmsg
))
{
goto
failed
;
}
...
...
@@ -671,7 +695,7 @@ sub DoSnapshot()
return
0
;
failed:
$instance
->
Unlock
()
if
(
defined
(
$instance
))
;
$instance
->
Unlock
();
$dataset
->
Unlock
();
# This will set the webtask, see below.
fatal
(
$errmsg
);
...
...
@@ -773,7 +797,7 @@ sub PollDatasetStatus($$)
if
(
$dataset
->
state
()
eq
"
valid
")
{
$project
->
SendEmail
(
$this_user
->
email
(),
"
Your dataset is now ready to use
",
"
Dataset '
$dname
' is now
allocated and
ready to use.
\n
",
"
Dataset '
$dname
' is now ready to use.
\n
",
$project
->
LogsEmailAddress
(),
undef
,
$logfile
);
$webtask
->
Exited
(
0
)
if
(
defined
(
$webtask
));
...
...
@@ -797,12 +821,23 @@ sub fatal($)
$webtask
->
output
(
$mesg
);
$webtask
->
Exited
(
-
1
);
}
print
STDERR
"
*** $0:
\n
"
.
"
$mesg
\n
";
print
STDERR
"
$mesg
\n
";
# Exit with negative status so web interface treats it as system error.
exit
(
-
1
);
}
sub
uerror
($)
{
my
(
$mesg
)
=
@_
;
if
(
defined
(
$webtask
))
{
$webtask
->
output
(
$mesg
);
$webtask
->
Exited
(
1
);
}
print
STDERR
"
$mesg
\n
";
exit
(
1
);
}
sub
escapeshellarg
($)
{
my
(
$str
)
=
@_
;
...
...
apt/manage_instance.in
View file @
f070014e
...
...
@@ -185,7 +185,7 @@ sub DoSnapshot()
{
my
$errmsg
;
my
$logfile
;
my
$errcode
=
1
;
my
$errcode
=
-
1
;
my
$needunlock
=
0
;
my
$old_status
=
$instance
->
status
();
my
$node_id
;
...
...
@@ -415,7 +415,7 @@ sub DoSnapshot()
if
(
$image_host
ne
$authority_host
)
{
$errmsg
=
"
Not allowed to take a snapshot on this cluster
";
$errcode
=
1
;
goto
bad
;
goto
uerror
;
}
}
}
...
...
@@ -425,7 +425,9 @@ sub DoSnapshot()
$this_user
,
$project
);
}
if
(
$slice
->
Lock
())
{
fatal
("
Slice is busy, cannot lock it
");
$errmsg
=
"
Experiment is busy, please try again later.
";
$errcode
=
1
;
goto
uerror
;
}
$needunlock
=
1
;
...
...
@@ -576,12 +578,11 @@ sub DoSnapshot()
if
(
$failed
)
{
$errmsg
=
"
Imaging failed
"
if
(
!
defined
(
$errmsg
));
$errcode
=
1
;
goto
bad
;
}
elsif
(
!
$ready
)
{
$errmsg
=
"
Imaging timed out
";
$errcode
=
60
;
$errcode
=
-
2
;
goto
bad
;
}
elsif
(
defined
(
$update_profile
))
{
...
...
@@ -643,13 +644,6 @@ sub DoSnapshot()
else {
$instance
->SetStatus(
"
imaging
-
failed
"
);
}
print STDERR
"
$errmsg
\
n
"
;
if (defined(
$errmsg
) && defined(
$webtask
)) {
$webtask
->Exited(
$errcode
);
$webtask
->output(
$errmsg
);
}
$slice
->UnLock()
if (
$needunlock
);
if (defined(
$logfile
)) {
SENDMAIL(
$TBOPS
,
"
Snapshot
failed
"
,
...
...
@@ -658,6 +652,15 @@ sub DoSnapshot()
$TBOPS
, undef,
$logfile
);
unlink(
$logfile
);
}
uerror:
print STDERR
"
$errmsg
\
n
"
;
if (defined(
$errmsg
) && defined(
$webtask
)) {
$webtask
->Exited(
$errcode
);
$webtask
->output(
$errmsg
);
}
$slice
->UnLock()
if (
$needunlock
);
exit(
$errcode
);
}
...
...
apt/manage_profile.in
View file @
f070014e
...
...
@@ -115,16 +115,6 @@ if (! defined($this_user)) {
}
}
if
(
$action
eq
"
delete
")
{
exit
(
DeleteProfile
(
$ARGV
[
0
]));
}
elsif
(
$action
eq
"
publish
")
{
exit
(
PublishProfile
(
$ARGV
[
0
]));
}
elsif
(
!
(
$action
eq
"
create
"
||
$action
eq
"
update
"))
{
usage
();
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
...
...
@@ -144,9 +134,20 @@ if (defined($options{"t"})) {
$webtask_id
=
$options
{"
t
"};
}
if
(
$action
eq
"
update
")
{
usage
()
if
(
!
@ARGV
);
$update
=
1
;
$uuid
=
shift
(
@ARGV
);
}
elsif
(
$action
eq
"
delete
")
{
exit
(
DeleteProfile
(
$ARGV
[
0
]));
}
elsif
(
$action
eq
"
publish
")
{
exit
(
PublishProfile
(
$ARGV
[
0
]));
}
elsif
(
$action
ne
"
create
")
{
usage
();
}
my
$xmlfile
=
shift
(
@ARGV
);
#
...
...
@@ -436,12 +437,15 @@ if (defined($instance)) {
# commmand line, so that we can communicate with the script we
# call that does the work.
#
$webtask
=
WebTask
->
Create
(
$profile
->
uuid
(),
$webtask_id
);
if
(
!
defined
(
$webtask
))
{
$profile
->
Delete
(
1
);
$webtask
=
WebTask
->
Create
(
$profile
->
uuid
(),
$webtask_id
);
if
(
!
defined
(
$webtask
))
{
$profile
->
Delete
(
1
);
fatal
("
Could not create webtask for snapshot
");
}
$webtask
->
AutoStore
(
1
);
}
$webtask
->
AutoStore
(
1
);
if
(
$profile
->
Lock
())
{
$profile
->
Delete
(
1
);
fatal
("
Could not lock new profile
");
...
...
@@ -458,11 +462,16 @@ if (defined($instance)) {
#
my
$output
=
emutil::
ExecQuiet
(
$command
);
if
(
$?
)
{
my
$stat
=
$?
>>
8
;
$profile
->
Delete
(
1
);
$webtask
->
Delete
()
if
(
!
defined
(
$webtask_id
));
print
STDERR
$output
.
"
\n
";
fatal
("
Failed to create disk image!
");
if
(
$stat
<
0
)
{
fatal
("
Failed to create disk image!
");
}
UserError
(
$output
);
}
#
# The script helpfully put the new image urn in the webtask.
...
...
@@ -560,6 +569,10 @@ sub fatal($)
{
my
(
$mesg
)
=
@_
;
if
(
defined
(
$webtask
))
{
$webtask
->
output
(
$mesg
);
$webtask
->
Exited
(
-
1
);
}
print
STDERR
"
*** $0:
\n
"
.
"
$mesg
\n
";
# Exit with negative status so web interface treats it as system error.
...
...
@@ -568,8 +581,8 @@ sub fatal($)
#
# Generate a simple XML file that PHP can parse. The web interface
# relies on using the same name attributes for the errors, as for
#
the
incoming values.
# relies on using the same name attributes for the errors, as for
the
# incoming values.
This makes sense to use from Create/Update only.
#
sub
UserError
(
;
$
)
{
...
...
@@ -579,12 +592,23 @@ sub UserError(;$)
$errors
{"
error
"}
=
$msg
;
}
if
(
keys
(
%errors
))
{
print
"
<errors>
\n
";
foreach
my
$key
(
keys
(
%errors
))
{
print
"
<error name='
$key
'>
"
.
CGI::
escapeHTML
(
$errors
{
$key
});
print
"
</error>
\n
";
if
(
defined
(
$webtask_id
))
{
my
$xml
=
"
<errors>
\n
";
foreach
my
$key
(
keys
(
%errors
))
{
$xml
.=
"
<error name='
$key
'>
"
.
CGI::
escapeHTML
(
$errors
{
$key
});
$xml
.=
"
</error>
\n
";
}
$xml
.=
"
</errors>
\n
";
$webtask
->
Exited
(
1
);
$webtask
->
output
(
$xml
);
}
else
{
foreach
my
$key
(
keys
(
%errors
))
{
print
"
$key
:
"
.
$errors
{
$key
}
.
"
\n
";
}
}
print
"
</errors>
\n
";
}
# Exit with positive status so web interface treats it as user error.
exit
(
1
);
...
...
@@ -604,15 +628,26 @@ sub escapeshellarg($)
sub
DeleteProfile
($)
{
my
(
$name
)
=
@_
;
my
$errmsg
;
my
$profile
=
APT_Profile
->
Lookup
(
$name
);
if
(
!
defined
(
$profile
))
{
fatal
("
No such profile exists
");
}
if
(
defined
(
$webtask_id
))
{
$webtask
=
WebTask
->
LookupOrCreate
(
undef
,
$webtask_id
);
if
(
!
defined
(
$webtask
))
{
fatal
("
Could not lookup/create webtask
");
}
$webtask
->
AutoStore
(
1
);
}
if
(
!
$profile
->
IsHead
())
{
UserError
("
Only allowed to delete the most recent profile
");
$errmsg
=
"
Only allowed to delete the most recent profile
";
goto
uerror
;
}
if
(
!
CanDelete
(
$profile
))
{
UserError
("
Not allowed to delete this profile (version)
");
$errmsg
=
"
Not allowed to delete this profile (version)
";
goto
uerror
;
}
#
# Version zero is special of course.
...
...
@@ -626,7 +661,17 @@ sub DeleteProfile($)
$profile
->
Delete
(
1
)
==
0
or
fatal
("
Could not delete profile
");
}
# No need for this anymore.
$webtask
->
Delete
()
if
(
!
defined
(
$webtask
));
return
0
;
uerror:
if
(
defined
(
$webtask
))
{
$webtask
->
Exited
(
1
);
$webtask
->
output
(
$errmsg
);
}
print
STDERR
"
$errmsg
\n
";
return
1
;
}
#
...
...
@@ -635,16 +680,34 @@ sub DeleteProfile($)
sub
PublishProfile
($)
{
my
(
$name
)
=
@_
;
my
$errmsg
;
my
$profile
=
APT_Profile
->
Lookup
(
$name
);
if
(
!
defined
(
$profile
))
{
fatal
("
No such profile exists
");
}
if
(
defined
(
$webtask_id
))
{
$webtask
=
WebTask
->
LookupOrCreate
(
undef
,
$webtask_id
);
if
(
!
defined
(
$webtask
))
{
fatal
("
Could not lookup/create webtask
");
}
$webtask
->
AutoStore
(
1
);
}
if
(
!
$profile
->
IsHead
())
{
UserError
("
Only allowed to publish the most recent profile
");
$errmsg
=
"
Only allowed to publish the most recent profile
";
goto
uerror
;
}
$profile
->
Publish
()
==
0
or
fatal
("
Could not publish profile
");
return
0
;
uerror:
if
(
defined
(
$webtask
))
{
$webtask
->
Exited
(
1
);
$webtask
->
output
(
$errmsg
);
}
print
STDERR
"
$errmsg
\n
";
return
1
;
}
#
...
...
www/aptui/dataset.ajax
View file @
f070014e
...
...
@@ -57,14 +57,7 @@ function Do_CreateDataSet()
$command
=
"webcreatedataset "
;
}
else
{
$command
=
"webmanage_dataset "
;
# We are going to track imaging status.
if
(
$formfields
[
"dataset_type"
]
==
"imdataset"
)
{
$webtask_id
=
WebTask
::
GenerateID
();
$command
.
=
" -t "
.
$webtask_id
.
" -- "
;
}
$command
.
=
" create "
;
$command
=
"webmanage_dataset create "
;
}
$required
=
array
(
"dataset_pid"
,
"dataset_name"
,
"dataset_type"
,
"dataset_fstype"
,
"dataset_read"
,
"dataset_modify"
);
...
...
@@ -235,14 +228,6 @@ function Do_CreateDataSet()
$retval
=
SUEXEC
(
$this_uid
,
$pid
,
$command
,
SUEXEC_ACTION_CONTINUE
);
if
(
$retval
)
{
if
(
isset
(
$webtask_id
))
{
$webtask
=
WebTask
::
Lookup
(
$webtask_id
);
if
(
$webtask
)
{
$webtask
->
Delete
();
SPITAJAX_ERROR
(
1
,
$webtask
->
TaskValue
(
"output"
));
return
;
}
}
SPITAJAX_ERROR
(
1
,
$suexec_output
);
return
;
}
...
...
www/aptui/manage_profile.ajax
View file @
f070014e
...
...
@@ -109,22 +109,32 @@ function Do_DeleteProfile()
SPITAJAX_ERROR
(
1
,
"Not enough permission"
);
return
;
}
#
# Invoke backend.
#
$webtask
=
WebTask
::
CreateAnonymous
();
if
(
!
$webtask
)
{
SPITAJAX_ERROR
(
-
1
,
"Internal webtask Error"
);
return
;
}
$retval
=
SUEXEC
(
$this_uid
,
$profile
->
pid
(),
"webmanage_profile delete "
.
$profile
->
uuid
(),
SUEXEC_ACTION_CONTINUE
);
"webmanage_profile -t "
.
$webtask
->
task_id
()
.
" "
.
"delete "
.
$profile
->
uuid
(),
SUEXEC_ACTION_IGNORE
);
if
(
$retval
!=
0
)
{
$error
=
"Transient error; please try again later"
;
if
(
$retval
&&
count
(
$suexec_output_array
))
{
$error
=
$suexec_output_array
[
0
];
}
$webtask
->
Refresh
();
if
(
$retval
<
0
)
{
$error
=
"Internal Error; please try again later
\n\n
"
;
$error
.
=
$webtask
->
output
();
SUEXECERROR
(
SUEXEC_ACTION_CONTINUE
);
}
else
{
$error
=
$webtask
->
output
();
}
$webtask
->
Delete
();
SPITAJAX_ERROR
(
1
,
$error
);
return
;
}
$webtask
->
Delete
();
# Lookup next most recent version
$profile
=
Profile
::
Lookup
(
$profile
->
profileid
());
if
(
!
$profile
)
{
...
...
@@ -174,21 +184,30 @@ function Do_PublishProfile()
SPITAJAX_ERROR
(
1
,
"Not allowed to publish non-head version"
);
return
;
}
#
# Invoke backend.
#
$webtask
=
WebTask
::
CreateAnonymous
();
if
(
!
$webtask
)
{
SPITAJAX_ERROR
(
-
1
,
"Internal webtask Error"
);
return
;
}
$retval
=
SUEXEC
(
$this_uid
,
$profile
->
pid
(),
"webmanage_profile publish "
.
$profile
->
uuid
(),
SUEXEC_ACTION_CONTINUE
);
"webmanage_profile -t "
.
$webtask
->
task_id
()
.
" "
.
"publish "
.
$profile
->
uuid
(),
SUEXEC_ACTION_IGNORE
);
if
(
$retval
!=
0
)
{
$error
=
"Transient error; please try again later"
;
if
(
$retval
&&
count
(
$suexec_output_array
))
{
$error
=
$suexec_output_array
[
0
];
}
$webtask
->
Refresh
();
if
(
$retval
<
0
)
{
$error
=
"Internal Error; please try again later
\n\n
"
;
$error
.
=
$webtask
->
output
();
SUEXECERROR
(
SUEXEC_ACTION_CONTINUE
);
}
else
{
$error
=
$webtask
->
output
();
}
$webtask
->
Delete
();
SPITAJAX_ERROR
(
1
,
$error
);
return
;
}
$webtask
->
Delete
();
$profile
->
Refresh
();
SPITAJAX_RESPONSE
(
array
(
"published"
=>
$profile
->
published
()));
}
...
...
www/webtask.php
View file @
f070014e
<?php
#
# Copyright (c) 2006-201
4
University of Utah and the Flux Group.
# Copyright (c) 2006-201
5
University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
...
...
@@ -73,6 +73,40 @@ class WebTask {
return
WebTask
::
Lookup
(
$idx
);
}
#
# Create an anonymous web task (not associated with an object). This
# is useful when using a webtask to create a new object via a backend
# script.
#
function
CreateAnonymous
()
{
$task_id
=
WebTask
::
GenerateID
();
$query_result
=
DBQueryWarn
(
"insert into web_tasks set task_id='
$task_id
', "
.
" created=now(), object_uuid='
$task_id
'"
);
if
(
!
$query_result
||
!
mysql_num_rows
(
$query_result
))
{
return
null
;
}
return
WebTask
::
Lookup
(
$task_id
);
}
function
Refresh
(
$task_id
)
{
if
(
!
$this
->
IsValid
())
return
-
1
;
$task_id
=
$this
->
task_id
();
$query_result
=
DBQueryWarn
(
"select * from web_tasks "
.
"where task_id='
$task_id
'"
);
if
(
!
$query_result
||
!
mysql_num_rows
(
$query_result
))
{
$this
->
webtask
=
NULL
;