Skip to content
GitLab
Menu
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
26f89fa3
Commit
26f89fa3
authored
Dec 03, 2014
by
Leigh B Stoller
Browse files
Checkpoint dataset and image changes. APT becomes the default for
all users. Cloudlab added to the list, but not exposed except to admins and studly users.
parent
d3674a3e
Changes
21
Hide whitespace changes
Inline
Side-by-side
apt/APT_Dataset.pm.in
View file @
26f89fa3
...
...
@@ -440,7 +440,7 @@ sub CreateDataset($)
if
(
defined
($
self
->
expires
()));
my
$
cmurl
=
$
authority
->
url
();
#
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
return
Genixmlrpc
::
CallMethod
($
cmurl
,
$
context
,
"CreateDataset"
,
$
args
);
}
...
...
@@ -471,7 +471,7 @@ sub DeleteDataset($)
$
speaksfor_credential
->
asString
()],
};
my
$
cmurl
=
$
authority
->
url
();
#
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
return
Genixmlrpc
::
CallMethod
($
cmurl
,
$
context
,
"DeleteDataset"
,
$
args
);
}
...
...
@@ -502,7 +502,7 @@ sub DescribeDataset($)
$
speaksfor_credential
->
asString
()],
};
my
$
cmurl
=
$
authority
->
url
();
#
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
$
cmurl
=~
s
/
protogeni
/
protogeni
\/
stoller
/;
return
Genixmlrpc
::
CallMethod
($
cmurl
,
$
context
,
"DescribeDataset"
,
$
args
);
}
...
...
apt/APT_Geni.pm.in
View file @
26f89fa3
...
...
@@ -53,6 +53,8 @@ sub GenCredentials($$;$)
{
my
($
target
,
$
geniuser
,
$
privs
)
=
@
_
;
my
($
speaksfor
,
$
credential
);
#
If
the
caller
does
not
want
a
speaksfor
,
do
not
generate
.
my
$
wantspeaksfor
=
wantarray
;
my
$
speaker_signer
=
$
GeniCredential
::
LOCALSA_FLAG
;
#
...
...
@@ -64,21 +66,6 @@ sub GenCredentials($$;$)
$
speaker_signer
=
"/usr/testbed/etc/utah-apt.sa"
;
}
#
#
The
Utah
SA
is
always
the
speaker
,
even
if
the
user
is
a
guest
#
with
the
alternate
CA
.
#
my
$
sa_certificate
=
GeniCertificate
->
LoadFromFile
($
SACERT
);
if
(
!defined($sa_certificate)) {
print
STDERR
"Could not load certificate from $SACERT
\n
"
;
goto
bad
;
}
my
$
sa_authority
=
GeniAuthority
->
Lookup
($
sa_certificate
->
urn
());
if
(
!defined($sa_authority)) {
prnt
STDERR
"Could not load SA authority object
\n
"
;
goto
bad
;
}
#
#
If
a
local
user
account
,
but
a
nonlocal
id
,
then
we
should
#
have
a
speaksfor
credential
stored
,
as
well
as
a
certificate
...
...
@@ -92,10 +79,12 @@ sub GenCredentials($$;$)
print
STDERR
"No stored speaksfor/certificate for $geniuser
\n
"
;
goto
bad
;
}
$
speaksfor
=
GeniCredential
->
CreateFromSigned
($
speaksfor_string
);
if
(
!defined($speaksfor)) {
print
STDERR
"Could not create speaksfor credential
\n
"
;
goto
bad
;
if
($
wantspeaksfor
)
{
$
speaksfor
=
GeniCredential
->
CreateFromSigned
($
speaksfor_string
);
if
(
!defined($speaksfor)) {
print
STDERR
"Could not create speaksfor credential
\n
"
;
goto
bad
;
}
}
my
$
certificate
=
GeniCertificate
->
LoadFromString
($
certificate_string
);
...
...
@@ -106,15 +95,31 @@ sub GenCredentials($$;$)
$
credential
=
GeniCredential
->
Create
($
target
,
$
certificate
);
}
else
{
$
speaksfor
=
GeniCredential
->
Create
($
geniuser
,
$
sa_authority
);
if
(
!defined($speaksfor)) {
print
STDERR
"Could not create speaksfor credential
\n
"
;
goto
bad
;
}
$
speaksfor
->
SetType
(
"speaksfor"
);
if
($
speaksfor
->
Sign
($
speaker_signer
))
{
print
STDERR
"Could not sign speaksfor credential
\n
"
;
goto
bad
;
if
($
wantspeaksfor
)
{
#
#
The
Utah
SA
is
always
the
speaker
,
even
if
the
user
is
a
guest
#
with
the
alternate
CA
.
#
my
$
sa_certificate
=
GeniCertificate
->
LoadFromFile
($
SACERT
);
if
(
!defined($sa_certificate)) {
print
STDERR
"Could not load certificate from $SACERT
\n
"
;
goto
bad
;
}
my
$
sa_authority
=
GeniAuthority
->
Lookup
($
sa_certificate
->
urn
());
if
(
!defined($sa_authority)) {
prnt
STDERR
"Could not load SA authority object
\n
"
;
goto
bad
;
}
$
speaksfor
=
GeniCredential
->
Create
($
geniuser
,
$
sa_authority
);
if
(
!defined($speaksfor)) {
print
STDERR
"Could not create speaksfor credential
\n
"
;
goto
bad
;
}
$
speaksfor
->
SetType
(
"speaksfor"
);
if
($
speaksfor
->
Sign
($
speaker_signer
))
{
print
STDERR
"Could not sign speaksfor credential
\n
"
;
goto
bad
;
}
}
$
credential
=
GeniCredential
->
Create
($
target
,
$
geniuser
);
}
...
...
@@ -134,7 +139,10 @@ sub GenCredentials($$;$)
print
STDERR
"Could not sign $target credential
\n
"
;
goto
bad
;
}
return
($
credential
,
$
speaksfor
);
if
(
wantarray
)
{
return
($
credential
,
$
speaksfor
);
}
return
$
credential
;
bad
:
return
();
}
...
...
apt/APT_Profile.pm.in
View file @
26f89fa3
...
...
@@ -672,14 +672,14 @@ sub Unlock($)
#
sub
UpdateDiskImage
($$)
{
my
($
self
,
$
image_ur
n
)
=
@
_
;
my
($
self
,
$
image_ur
l
)
=
@
_
;
my
$
rspec
=
GeniXML
::
Parse
($
self
->
rspec
());
if
(
! defined($rspec)) {
print
STDERR
"UpdateDiskImage: Could not parse rspec
\n
"
;
return
-
1
;
}
my
($
node
)
=
GeniXML
::
FindNodes
(
"n:node"
,
$
rspec
)->
get_nodelist
();
GeniXML
::
SetDiskImage
($
node
,
$
image_ur
n
);
GeniXML
::
SetDiskImage
($
node
,
$
image_ur
l
);
if
($
self
->
UpdateVersion
({
"rspec"
=>
GeniXML
::
Serialize
($
rspec
)}))
{
print
STDERR
"UpdateDiskImage: Could not update rspec
\n
"
;
return
-
1
;
...
...
@@ -687,12 +687,135 @@ sub UpdateDiskImage($$)
return
0
;
}
#
#
We
need
to
convert
from
using
URNs
to
using
URLs
for
disk
images
,
#
since
we
want
to
support
choosing
the
backend
.
This
list
is
the
#
list
as
of
the
conversion
,
at
the
APT
.
Before
we
instantiate
,
look
#
at
the
rspec
and
update
the
URNs
to
URLs
based
on
this
list
.
#
my
%
APTImages
=
(
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:demo-profile'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=3937a58c-7b2f-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=5ae4aeef-7b2f-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker-running-env'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=a130e3e1-7b2f-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:docker-running-env-02'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=f30dfd4d-7b2f-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Docker1'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=31d95a10-7b30-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ESA'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=72d8b175-7b35-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:firstclone'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=d49dc243-7b31-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:FPTaylorVM'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=f2e9010e-7b31-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:FrequentDirection'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=1c6b0966-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:geni-lib'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=441f3d1c-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:gimiovsomf6'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=6260f126-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:hadoop'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=ffa8648d-3524-11e4-8944-81966d62745f'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:hg'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=91dc43cb-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:imageusage'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=adc56dfa-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Iperf'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=d0c81a2d-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:labwikiXORP'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=eee561e4-7b32-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myapt'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=13ba0c1d-7b33-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myclone'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=301cb7f7-7b33-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myimage'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=03a2a844-7b2c-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myvm'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=6334311f-7a59-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:myvm2'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=aa8a9f6a-7a79-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ricci-cav-2014'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=b3d662b2-7b35-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:rob-profile'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=3126f6f2-7b34-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:robtestimage'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=4d4357cf-7b34-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlenodelime'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=608fcd94-7b34-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlenodelime-2'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=8db1ab6c-7b34-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:singlevmlime'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=b192160c-7b34-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:smack-cav2014-test'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=a458b87c-7b36-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:ubuntu1204maas'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=e5326c2e-7b36-11e4-9439-db9edc46fe2c'
,
'urn:publicid:IDN+utahddc.geniracks.net+image+emulab-net:Ubuntu1404'
=>
'https://www.apt.emulab.net/image_metadata.php?uuid=083830cf-7b37-11e4-9439-db9edc46fe2c'
,
);
sub
ConvertDiskImages
($)
{
my
($
self
)
=
@
_
;
my
$
modified
=
0
;
my
$
rspec
=
GeniXML
::
Parse
($
self
->
rspec
());
if
(
! defined($rspec)) {
print
STDERR
"Could not parse rspec
\n
"
;
return
-
1
;
}
foreach
my
$
ref
(
GeniXML
::
FindNodes
(
"n:node"
,
$
rspec
)->
get_nodelist
())
{
my
$
diskref
=
GeniXML
::
GetDiskImage
($
ref
);
next
if
(
!defined($diskref));
my
$
imageurn
=
GeniXML
::
GetText
(
"name"
,
$
diskref
);
next
if
(
!defined($imageurn));
if
(
exists
($
APTImages
{$
imageurn
}))
{
GeniXML
::
SetDiskImage
($
ref
,
$
APTImages
{$
imageurn
});
$
modified
=
1
;
}
}
if
($
modified
)
{
$
self
->{
'DBROW'
}->{
'rspec'
}
=
GeniXML
::
Serialize
($
rspec
);
my
$
profileid
=
$
self
->
profileid
();
my
$
version
=
$
self
->
version
();
my
$
safe_rspec
=
DBQuoteSpecial
($
self
->
rspec
());
DBQueryWarn
(
"update apt_profile_versions set rspec=$safe_rspec "
.
"where profileid='$profileid' and version='$version'"
)
if
(
1
);
}
return
0
;
}
#
Total
nonsense
,
to
be
thrown
away
.
sub
CheckImageConstraints
($$$)
{
my
($
self
,
$
iscloudlab
,
$
pmsg
)
=
@
_
;
my
$
cloudwww
=
"www.utah.cloudlab.us"
;
require
URI
;
my
$
rspec
=
GeniXML
::
Parse
($
self
->
rspec
());
if
(
! defined($rspec)) {
print
STDERR
"Could not parse rspec
\n
"
;
return
-
1
;
}
foreach
my
$
ref
(
GeniXML
::
FindNodes
(
"n:node"
,
$
rspec
)->
get_nodelist
())
{
my
$
client_id
=
GetVirtualId
($
ref
);
my
$
diskref
=
GeniXML
::
GetDiskImage
($
ref
);
next
if
(
!defined($diskref));
my
$
image_url
=
GeniXML
::
GetText
(
"url"
,
$
diskref
);
next
if
(
!defined($image_url));
#
Get
the
hostname
for
the
image
URL
.
my
$
uri
=
URI
->
new
($
image_url
);
if
(
!defined($uri)) {
print
STDERR
"Could not parse $image_url
\n
"
;
return
-
1
;
}
my
$
image_host
=
$
uri
->
host
();
if
($
iscloudlab
)
{
if
($
image_host
ne
$
cloudwww
)
{
$$
pmsg
=
"The disk image specified for node '$client_id' "
.
"will not run on the Cloudlab cluster"
;
return
-
1
;
}
}
else
{
if
($
image_host
eq
$
cloudwww
)
{
$$
pmsg
=
"The disk image specified for node '$client_id' "
.
"will not run on cluster you selected"
;
return
-
1
;
}
}
}
return
0
;
}
#
#
Check
blockstores
.
#
sub
CheckDatasets
($$$)
{
my
($
xml
,
$
project
,
$
pmsg
)
=
@
_
;
my
($
xml
,
$
ppid
,
$
pmsg
)
=
@
_
;
my
$
pid
=
$
ppid
;
my
$
rspec
=
GeniXML
::
Parse
($
xml
);
if
(
! defined($rspec)) {
print
STDERR
"CheckDatasets: Could not parse rspec
\n
"
;
...
...
@@ -703,11 +826,28 @@ sub CheckDatasets($$$)
$
ref
,
$
GeniXML
::
EMULAB_NS
)->
get_nodelist
())
{
my
$
leaseurn
=
GeniXML
::
GetText
(
"persistent"
,
$
blockref
);
if
(
defined
($
leaseurn
)
&&
!GeniHRN::IsValid($leaseurn)) {
#
#
We
only
care
about
datasets
here
,
we
let
the
backend
#
do
the
error
checking
on
ephemeral
blockstores
.
#
next
if
(
!defined($leaseurn));
if
(
!GeniHRN::IsValid($leaseurn)) {
$$
pmsg
=
"Persistent dataset name is not a valid URN"
;
return
1
;
}
my
($
authority
,
$
type
,
$
id
)
=
GeniXML
::
Parse
($
leaseurn
);
my
($
authority
,
$
type
,
$
id
)
=
GeniHRN
::
Parse
($
leaseurn
);
#
#
Separate
project
from
name
;
this
is
how
the
rspec
specifies
#
the
dataset
they
want
,
since
it
might
be
in
another
project
#
if
($
id
=~
/^([-\
w
]+)\/\/(.+)$/)
{
$
pid
=
$
1
;
$
id
=
$
2
;
}
#
#
Not
all
backends
have
blockstore
support
.
#
...
...
@@ -715,20 +855,33 @@ sub CheckDatasets($$$)
$$
pmsg
=
"Persistent dataset is not on a valid aggregate"
;
return
1
;
}
#
#
Dataset
must
already
exists
on
the
aggregate
.
#
my
$
pid
=
$
project
->
pid
();
my
$
dataset
=
APT_Dataset
->
Lookup
(
"$pid/$id"
);
if
(
!defined($dataset)) {
$$
pmsg
=
"Persistent dataset '$pid/$id' does not exist"
;
return
1
;
}
my
($
d_authority
)
=
GeniXML
::
Parse
($
dataset
->
aggregate_urn
());
#
#
Dataset
must
already
exists
on
the
aggregate
.
But
we
have
to
#
make
these
checks
again
at
instantiation
,
since
the
dataset
#
might
be
gone
,
or
it
might
have
different
permissions
#
settings
.
#
my
($
d_authority
)
=
GeniHRN
::
Parse
($
dataset
->
aggregate_urn
());
if
($
d_authority
ne
$
authority
)
{
$$
pmsg
=
"Persistent dataset '$pid/$id' in not on $authority"
;
return
1
;
}
#
#
Basic
permission
checks
,
very
little
support
at
the
moment
.
#
Just
make
sure
that
the
profile
and
the
dataset
are
in
the
#
same
pid
.
#
if
($
ppid
ne
$
dataset
->
pid
())
{
$$
pmsg
=
"Not allowed to use dataset '$pid/$id' in profile"
;
return
1
;
}
}
}
return
0
;
...
...
apt/create_instance.in
View file @
26f89fa3
...
...
@@ -46,8 +46,7 @@ sub usage()
my
$optlist
=
"
dvu:a:t:f
";
my
$debug
=
0
;
my
$verbose
=
1
;
my
$utahddc
=
1
;
my
$DDCURN
=
"
urn:publicid:IDN+utahddc.geniracks.net+authority+cm
";
my
$DEFAULT_URN
=
"
urn:publicid:IDN+utahddc.geniracks.net+authority+cm
";
my
$xmlfile
;
my
$webtask
;
my
$webtask_id
;
...
...
@@ -63,6 +62,7 @@ sub fatal($);
sub
UserError
($);
sub
SnapShot
($$$);
sub
GenCredentials
($$$$);
sub
CreateDatasetCreds
($$$$$);
#
# Configure variables
...
...
@@ -96,6 +96,7 @@ use libaudit;
use
APT_Profile
;
use
APT_Instance
;
use
APT_Geni
;
use
APT_Dataset
;
use
User
;
use
OSinfo
;
use
emutil
;
...
...
@@ -211,15 +212,8 @@ my $CMURN;
if
(
defined
(
$aggregate
))
{
$CMURN
=
$aggregate
;
}
elsif
(
$utahddc
)
{
$CMURN
=
$DDCURN
;
}
else
{
my
$cm_certificate
=
GeniCertificate
->
LoadFromFile
(
$CMCERT
);
if
(
!
defined
(
$cm_certificate
))
{
fatal
("
Could not load certificate from
$CMCERT
\n
");
}
$CMURN
=
$cm_certificate
->
urn
();
$CMURN
=
$DEFAULT_URN
;
}
my
$cm_authority
=
GeniAuthority
->
Lookup
(
$CMURN
);
if
(
!
defined
(
$cm_authority
))
{
...
...
@@ -228,6 +222,8 @@ if (!defined($cm_authority)) {
fatal
("
Could not load CM authority object
");
}
}
my
$cmurl
=
$cm_authority
->
url
();
#$cmurl =~ s/protogeni/protogeni\/stoller/;
#
# Must wrap the parser in eval since it exits on error.
...
...
@@ -283,10 +279,43 @@ my $profile_object = APT_Profile->Lookup($value);
if
(
!
defined
(
$profile_object
))
{
fatal
("
No such profile:
$value
");
}
#
# Temp hack; replace URNs with URLs.
#
if
(
1
&&
$profile_object
->
ConvertDiskImages
())
{
fatal
("
Not able to convert disk_image URNs to URLs.
");
}
my
$rspecstr
=
$profile_object
->
CheckFirewall
(
!
$localuser
);
$profile
=
$profile_object
->
profileid
();
$version
=
$profile_object
->
version
();
#
# Look for datasets; need to verify that the datasets being referenced
# still exist and are still permissible to use, and we have to generate
# credentials for those datasets (if not a global dataset). The tricky
# aspect is that while a dataset and a profile have project permissions,
# the experiment has no project association, so if the profile/dataset
# perms are okay, then we send over a credential that tells the CM to
# allow this experiment to use that dataset in that project.
#
my
$errmsg
=
"
Bad dataset
";
if
(
APT_Profile::
CheckDatasets
(
$rspecstr
,
$profile_object
->
pid
(),
\
$errmsg
))
{
UserError
(
$errmsg
);
}
#
# A temporary hack to make sure that the user does not try to run
# an x386 image on the Cloudlab cluster (ARMs). This will eventually
# get replaced with Jon's constraint checking code.
#
my
$iscloudlab
=
(
$CMURN
eq
"
urn:publicid:IDN+utah.cloudlab.us+authority+cm
"
?
1
:
0
);
if
(
$profile_object
->
CheckImageConstraints
(
$iscloudlab
,
\
$errmsg
))
{
UserError
(
$errmsg
);
}
fatal
("
fooey
");
#
# Use ssh-keygen to see if the key is valid and convertable. We first
# try to get the fingerprint, which will tells us if its already in
...
...
@@ -470,6 +499,15 @@ if ($geniuser->GetKeyBundle(\@sshkeys, 1) < 0 || !@sshkeys) {
fatal
("
No ssh keys to use for
$geniuser
!
");
}
# Generate the extra credentials that tells the backend this experiment
# can access the datasets.
my
@dataset_credentials
=
();
if
(
CreateDatasetCreds
(
$rspecstr
,
$profile_object
->
pid
(),
$geniuser
,
\
$errmsg
,
\
@dataset_credentials
))
{
fatal
(
$errmsg
);
}
#
# Now generate a slice registration and credential
#
...
...
@@ -583,7 +621,7 @@ $webtask->SetProcessID($PID)
# This creates the sliver and starts it.
#
my
$response
=
Genixmlrpc::
CallMethod
(
$cm
_authority
->
url
()
,
undef
,
Genixmlrpc::
CallMethod
(
$cmurl
,
undef
,
"
CreateSliver
",
{
"
slice_urn
"
=>
$slice_urn
,
"
rspec
"
=>
$rspecstr
,
...
...
@@ -593,7 +631,9 @@ my $response =
'
keys
'
=>
\
@sshkeys
}],
"
credentials
"
=>
[
$slice_credential
->
asString
(),
$speaksfor_credential
->
asString
()]});
$speaksfor_credential
->
asString
(),
@dataset_credentials
]});
if
(
!
defined
(
$response
)
||
$response
->
code
()
!=
GENIRESPONSE_SUCCESS
)
{
$slice
->
Delete
();
...
...
@@ -638,7 +678,7 @@ while ($seconds > 0) {
$seconds
-=
$interval
;
my
$response
=
Genixmlrpc::
CallMethod
(
$cm
_authority
->
url
()
,
undef
,
Genixmlrpc::
CallMethod
(
$cmurl
,
undef
,
"
SliverStatus
",
{
"
slice_urn
"
=>
$slice_urn
,
"
credentials
"
=>
...
...
@@ -698,6 +738,65 @@ else {
$slice
->
UnLock
();
exit
(
0
);
#
# Create credentials to access datasets.
#
sub
CreateDatasetCreds
($$$$$)
{
my
(
$xml
,
$pid
,
$user
,
$pmsg
,
$pref
)
=
@_
;
my
@credentials
=
();
my
$rspec
=
GeniXML::
Parse
(
$xml
);
if
(
!
defined
(
$rspec
))
{
print
STDERR
"
CreateDatasetCreds: Could not parse rspec
\n
";
return
-
1
;
}
foreach
my
$ref
(
GeniXML::
FindNodes
("
n:node
",
$rspec
)
->
get_nodelist
())
{
foreach
my
$blockref
(
GeniXML::
FindNodesNS
("
n:blockstore
",
$ref
,
$
GeniXML::
EMULAB_NS
)
->
get_nodelist
())
{
my
$leaseurn
=
GeniXML::
GetText
("
persistent
",
$blockref
);
#
# We only care about datasets here, we let the backend
# do the error checking on ephemeral blockstores.
#
next
if
(
!
defined
(
$leaseurn
));
my
(
$authority
,
$type
,
$id
)
=
GeniHRN::
Parse
(
$leaseurn
);
#
# Separate project from name; this is how the rspec specifies
# the dataset they want, since it might be in another project
#
if
(
$id
=~
/^([-\w]+)\/\/(.+)$/
)
{
$pid
=
$
1
;
$id
=
$
2
;
}
my
$dataset
=
APT_Dataset
->
Lookup
("
$pid
/
$id
");
if
(
!
defined
(
$dataset
))
{
$$pmsg
=
"
Persistent dataset '
$pid
/
$id
' does not exist
";
return
1
;
}
my
$certificate
=
$dataset
->
GetCertificate
();
if
(
!
defined
(
$certificate
))
{
$$pmsg
=
"
No certificate for dataset '
$pid
/
$id
'
";
return
-
1
;
}
my
$credential
=
APT_Geni::
GenCredentials
(
$certificate
,
$geniuser
,
["
blockstores
"]);
if
(
!
defined
(
$credential
))
{
$$pmsg
=
"
Could not create credential for dataset '
$pid
/
$id
'
";
return
-
1
;
}
push
(
@credentials
,
$credential
->
asString
());
}
}
@$pref
=
@credentials
;
return
0
;
}
sub
fatal
($)
{
my
(
$mesg
)
=
$_
[
0
];
...
...
apt/manage_dataset.in
View file @
26f89fa3
...
...
@@ -157,7 +157,7 @@ sub DoCreate()
my
$type
=
"
stdataset
";
my
$fstype
;
my
$optlist
=
"
ds:t:e:f:
";
my
$optlist
=
"
ds:t:e:f:
w:
";
my
%options
=
();
if
(
!
getopts
(
$optlist
,
\
%options
))
{
&$usage
();
...
...
@@ -387,7 +387,12 @@ sub DoRefreshInternal($$)
my
$response
=
$dataset
->
DescribeDataset
();
if
(
$response
->
code
()
!=
GENIRESPONSE_SUCCESS
)
{
$$pmesg
=
"
DescribeDataset failed:
"
.
$response
->
output
()
.
"
\n
";
if
(
$response
->
code
()
!=
GENIRESPONSE_SEARCHFAILED
)
{
$$pmesg
=
"
Dataset no longer exists at the target
\n
";
}
else
{
$$pmesg
=
"
DescribeDataset failed:
"
.
$response
->
output
()
.
"
\n
";
}
return
-
1
;
}
my
$blob
=
$response
->
value
();
...
...
apt/manage_instance.in
View file @
26f89fa3
...
...
@@ -159,7 +159,8 @@ sub DoSnapshot()
if
(
!
defined
(
$slice
))
{
fatal
("
No slice for quick VM:
$uuid
");
}
my
$authority
=
$instance
->
GetGeniAuthority
();
# The web interface (and in the future the xmlrpc interface) sets this.
my
$this_user
=
User
->
ImpliedUser
();
if
(
!
defined
(
$this_user
))
{
...
...
@@ -171,9 +172,9 @@ sub DoSnapshot()
#
# If we get an imagename on the command line, the caller is
# saying it is responsible. If we do not get one, we
create
# the name and update the underlying profile with the new
image
# urn.
# saying it is responsible
(clone)
. If we do not get one, we
#
create
the name and update the underlying profile with the new
#
image
urn.
#
my
$imagename
;
my
$node_id
;
...
...
@@ -202,16 +203,17 @@ sub DoSnapshot()
if
(
!
defined
(
$manifest
))
{
fatal
("
Could not parse manifest
");
}
my
$node
;
my
@nodes
=
GeniXML::
FindNodes
("
n:node
",
$manifest
)
->
get_nodelist
();
if
(
!
defined
(
$node_id
))
{
if
(
@nodes
!=
1
)
{
fatal
("
Too many nodes (> 1) to snapshot
");
}
my
(
$node
)
=
@nodes
;
(
$node
)
=
@nodes
;
$sliver_urn
=
GeniXML::
GetSliverId
(
$node
);
}
else
{
foreach
my
$node
(
@nodes
)
{
foreach
$node
(
@nodes
)
{
my
$client_id
=
GeniXML::
GetVirtualId
(
$node
);
if
(
$node_id
eq
$client_id
)
{
$sliver_urn
=
GeniXML::
GetSliverId
(
$node
);
...
...
@@ -222,11 +224,6 @@ sub DoSnapshot()