Commit 8c38cb50 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Update "other" image listing for the Cloudlab portal by using the

imageserver database to collect images across all of the clusters.
parent 024fbc85
...@@ -131,6 +131,24 @@ class Aggregate ...@@ -131,6 +131,24 @@ class Aggregate
return Aggregate::Lookup($urn); return Aggregate::Lookup($urn);
} }
#
# Lookup using the short auth name (emulab.net).
#
function LookupByDomain($domain) {
if (! preg_match("/^[-\w\.]+$/", $domain)) {
return null;
}
$query_result =
DBQueryWarn("select urn from apt_aggregates ".
"where urn like 'urn:publicid:IDN+${domain}+%'");
if (!$query_result || !mysql_num_rows($query_result)) {
return null;
}
$row = mysql_fetch_array($query_result);
$urn = $row['urn'];
return Aggregate::Lookup($urn);
}
# #
# Generate the free nodes URL from the web url. # Generate the free nodes URL from the web url.
......
...@@ -25,6 +25,8 @@ chdir(".."); ...@@ -25,6 +25,8 @@ chdir("..");
include("defs.php3"); include("defs.php3");
chdir("apt"); chdir("apt");
include("quickvm_sup.php"); include("quickvm_sup.php");
include_once("instance_defs.php");
include_once("aggregate_defs.php");
$page_title = "Image List"; $page_title = "Image List";
# #
...@@ -61,6 +63,13 @@ if (!$this_user->SameUser($target_user)) { ...@@ -61,6 +63,13 @@ if (!$this_user->SameUser($target_user)) {
$target_idx = $target_user->uid_idx(); $target_idx = $target_user->uid_idx();
$projlist = $target_user->ProjectAccessList($TB_PROJECT_CREATEEXPT); $projlist = $target_user->ProjectAccessList($TB_PROJECT_CREATEEXPT);
$tmp = array();
$images = array();
$domain = $OURDOMAIN;
if ($TBMAINSITE) {
$domain = "emulab.net";
}
SPITHEADER(1); SPITHEADER(1);
echo "<link rel='stylesheet' echo "<link rel='stylesheet'
...@@ -69,101 +78,162 @@ echo "<link rel='stylesheet' ...@@ -69,101 +78,162 @@ echo "<link rel='stylesheet'
# Place to hang the toplevel template. # Place to hang the toplevel template.
echo "<div id='main-body'></div>\n"; echo "<div id='main-body'></div>\n";
if (ISADMIN() && $all) { if ($ISCLOUD) {
$joinclause = ""; $aggregates = array();
$whereclause = "";
}
else {
# #
# User is allowed to view the list of all global images, and all images # Look in the IMS database for images from all clusters.
# in his project. Include images in the subgroups too, since its okay
# for the all project members to see the descriptors. They need proper
# permission to use/modify the image/descriptor of course, but that is
# checked in the pages that do that stuff. In other words, ignore the
# shared flag in the descriptors.
# #
$uid_idx = $target_user->uid_idx(); $dblink = DBConnect("ims");
$joinclause =
"left join image_permissions as p1 on ".
" p1.imageid=i.imageid and p1.permission_type='group' ".
"left join image_permissions as p2 on ".
" p2.imageid=i.imageid and p2.permission_type='user' and ".
" p2.permission_idx='$uid_idx' ".
"left join group_membership as g on ".
" g.uid_idx='$uid_idx' and ".
" (g.pid_idx=i.pid_idx or ".
" g.gid_idx=p1.permission_idx) ";
$whereclause = "and (iv.global or p2.imageid is not null or ". if (ISADMIN() && $all) {
"g.uid_idx is not null) "; $joinclause = "";
} $whereclause = "";
$query = }
"select distinct iv.*,ov.* from images as i ". else {
"left join image_versions as iv on ". $joinclause = "";
" iv.imageid=i.imageid and iv.version=i.version ". $whereclause = "(iv.visibility='public')";
"left join os_info_versions as ov on ". }
" i.imageid=ov.osid and ov.vers=i.version ". $query =
"left join osidtoimageid as map on map.osid=i.imageid ". "SELECT i.*, iv.* ".
$joinclause . "FROM images as i ".
"where (iv.ezid = 1 or iv.isdataset = 1) $whereclause ". "JOIN ".
"order by i.imagename"; "( ".
" SELECT iv1.* FROM image_versions as iv1 ".
$query_result = DBQueryFatal($query); " JOIN ".
" ( ".
$images = array(); " SELECT urn,MAX(version) as maxVersion ".
$domain = $OURDOMAIN; " FROM image_versions ".
if ($TBMAINSITE) " GROUP BY urn ".
{ " ) iv2 ".
$domain = "emulab.net"; " ON iv1.urn = iv2.urn ".
} " AND iv1.version = iv2.maxVersion ".
") iv ".
"ON i.urn = iv.urn";
$query_result = DBQueryFatal($query, $dblink);
while ($row = mysql_fetch_array($query_result)) { while ($row = mysql_fetch_array($query_result)) {
$imageid = $row["imageid"];
$name = $row["imagename"]; $name = $row["imagename"];
$pid = $row["pid"]; $pid = "n/a";
$urn = "urn:publicid:IDN+${domain}+image+${pid}//${name}"; $pid_idx = 0;
$blob = array(); $blob = array();
# # Need to map creator/project to local.
# This is for the hidden search filter column. It indicates how list ($auth,$type,$id) = Instance::ParseURN($row["creator_urn"]);
# the user has access to the image. Creator, project, public. if ($auth == $domain) {
# $user = User::LookupByUid($id);
$filters = array();
if ($all && $row["creator_idx"] == $target_user->uid_idx()) {
$filters[] = "creator";
} }
if (array_key_exists($pid, $projlist)) { else {
$filters[] = "project"; $user = User::LookupNonLocal($row["creator_urn"]);
} }
if ($all) { if ($user) {
if ($pid == "emulab-ops") { $creator = $user->uid();
$filters[] = "system"; $creator_idx = $user->idx();
}
if ($row["global"] != "0") {
$filters[] = "public";
}
} }
else { else {
if ($pid == "emulab-ops" && $row["global"] != "0") { $creator = $id;
$filters[] = "system"; $creator_idx = 0;
}
list ($auth,$type,$id) = Instance::ParseURN($row["project_urn"]);
# project urn is in domain:project format.
if (preg_match("/^([^:]+)\:([^:]+)$/", $auth, $matches)) {
$project = Project::LookupByPid($matches[2]);
if ($project) {
$pid = $project->pid();
$pid_idx = $project->pid_idx();
} }
# If not in any filters and global, skip. else {
if (!count($filters) && $row["global"] != "0") { $pid = $matches[2];
continue;
} }
} }
# If none of the filters match, then mark as admin so we can show #
# those under a separate checkbox. # Lets try to get a url.
if (!count($filters)) { #
if ($all) { list ($imagedomain,$type,$id) = Instance::ParseURN($row["urn"]);
$filters[] = "admin"; if ($imagedomain == $domain) {
$url = "$TBBASE/showimageid.php3?imageid=" . $row["image_uuid"];
}
else {
if (array_key_exists($imagedomain, $aggregates)) {
$aggregate = $aggregates[$imagedomain];
} }
else { else {
continue; $aggregate = Aggregate::LookupByDomain($imagedomain);
if ($aggregate) {
$aggregates[$imagedomain] = $aggregate;
}
}
if ($aggregate) {
$url = $aggregate->weburl() .
"/showimageid.php3?imageid=" . $row["image_uuid"];
} }
} }
$blob["description"] = $row["description"];
$blob["imagename"] = $row["imagename"];
$blob["created"] = DateStringGMT($row["created"]);
$blob["pid"] = $pid;
$blob["pid_idx"] = $pid_idx;
$blob["global"] = $row["visibility"] == "public" ? 1 : 0;
$blob["creator"] = $creator;
$blob["creator_idx"] = $creator_idx;
$blob["project_urn"] = $row["project_urn"];
$blob["urn"] = $row["urn"];
if (isset($url)) {
$blob["url"] = $url;
}
$tmp[] = $blob;
}
}
else {
if (ISADMIN() && $all) {
$joinclause = "";
$whereclause = "";
}
else {
#
# User is allowed to view the list of all global images, and all images
# in his project. Include images in the subgroups too, since its okay
# for the all project members to see the descriptors. They need proper
# permission to use/modify the image/descriptor of course, but that is
# checked in the pages that do that stuff. In other words, ignore the
# shared flag in the descriptors.
#
$uid_idx = $target_user->uid_idx();
$joinclause =
"left join image_permissions as p1 on ".
" p1.imageid=i.imageid and p1.permission_type='group' ".
"left join image_permissions as p2 on ".
" p2.imageid=i.imageid and p2.permission_type='user' and ".
" p2.permission_idx='$uid_idx' ".
"left join group_membership as g on ".
" g.uid_idx='$uid_idx' and ".
" (g.pid_idx=i.pid_idx or ".
" g.gid_idx=p1.permission_idx) ";
$whereclause = "and (iv.global or p2.imageid is not null or ".
"g.uid_idx is not null) ";
}
$query =
"select distinct iv.*,ov.* from images as i ".
"left join image_versions as iv on ".
" iv.imageid=i.imageid and iv.version=i.version ".
"left join os_info_versions as ov on ".
" i.imageid=ov.osid and ov.vers=i.version ".
"left join osidtoimageid as map on map.osid=i.imageid ".
$joinclause .
"where (iv.ezid = 1 or iv.isdataset = 1) $whereclause ".
"order by i.imagename";
$query_result = DBQueryFatal($query);
while ($row = mysql_fetch_array($query_result)) {
$imageid = $row["imageid"];
$name = $row["imagename"];
$pid = $row["pid"];
$urn = "urn:publicid:IDN+${domain}+image+${pid}//${name}";
$blob = array();
$blob["imageid"] = $imageid; $blob["imageid"] = $imageid;
$blob["description"] = $row["description"]; $blob["description"] = $row["description"];
$blob["imagename"] = $row["imagename"]; $blob["imagename"] = $row["imagename"];
...@@ -174,12 +244,57 @@ while ($row = mysql_fetch_array($query_result)) { ...@@ -174,12 +244,57 @@ while ($row = mysql_fetch_array($query_result)) {
$blob["creator"] = $row["creator"]; $blob["creator"] = $row["creator"];
$blob["creator_idx"] = $row["creator_idx"]; $blob["creator_idx"] = $row["creator_idx"];
$blob["urn"] = $urn; $blob["urn"] = $urn;
$blob["filter"] = implode(",", $filters);
$blob["url"] = $TBBASE . "/" . $blob["url"] = $TBBASE . "/" .
CreateURL("showimageid", CreateURL("showimageid",
URLARG_IMAGEID, $imageid); URLARG_IMAGEID, $imageid);
$tmp[] = $blob;
}
}
$images[] = $blob; #
# This is for the hidden search filter column. It indicates how
# the user has access to the image. Creator, project, public.
#
foreach ($tmp as $blob) {
$name = $blob["imagename"];
$pid = $blob["pid"];
$filters = array();
if ($all && $blob["creator_idx"] == $target_user->uid_idx()) {
$filters[] = "creator";
}
if (array_key_exists($pid, $projlist)) {
$filters[] = "project";
}
if ($all) {
if ($pid == "emulab-ops") {
$filters[] = "system";
}
if ($blob["global"] != "0") {
$filters[] = "public";
}
}
else {
if ($pid == "emulab-ops" && $blob["global"] != "0") {
$filters[] = "system";
}
# If not in any filters and global, skip.
if (!count($filters) && $blob["global"] != "0") {
continue;
}
}
# If none of the filters match, then mark as admin so we can show
# those under a separate checkbox.
if (!count($filters)) {
if ($all) {
$filters[] = "admin";
}
else {
continue;
}
}
$blob["filter"] = implode(",", $filters);
$images[] = $blob;
} }
echo "<script type='text/plain' id='images-json'>\n"; echo "<script type='text/plain' id='images-json'>\n";
echo htmlentities(json_encode($images)) . "\n"; echo htmlentities(json_encode($images)) . "\n";
......
...@@ -11,6 +11,7 @@ $(function () ...@@ -11,6 +11,7 @@ $(function ()
// Image data // Image data
var images = JSON.parse(_.unescape($('#images-json')[0].textContent)); var images = JSON.parse(_.unescape($('#images-json')[0].textContent));
console.info("images", images);
// Generate the main template. // Generate the main template.
var html = mainTemplate({ var html = mainTemplate({
...@@ -70,8 +71,6 @@ $(function () ...@@ -70,8 +71,6 @@ $(function ()
widgetOptions: { widgetOptions: {
// include child row content while filtering, if true // include child row content while filtering, if true
filter_childRows : true, filter_childRows : true,
// include all columns in the search.
filter_anyMatch : true,
// search from beginning // search from beginning
filter_startsWith : false, filter_startsWith : false,
// Set this option to false for case sensitive search // Set this option to false for case sensitive search
......
...@@ -411,8 +411,6 @@ $(function () ...@@ -411,8 +411,6 @@ $(function ()
widgets: ["zebra", "filter"], widgets: ["zebra", "filter"],
widgetOptions: { widgetOptions: {
// include all columns in the search.
filter_anyMatch : true,
// search from beginning // search from beginning
filter_startsWith : false, filter_startsWith : false,
// Set this option to false for case sensitive search // Set this option to false for case sensitive search
......
...@@ -400,11 +400,9 @@ echo " <li class='divider'></li> ...@@ -400,11 +400,9 @@ echo " <li class='divider'></li>
<li><a href='create-dataset.php'>Create Dataset</a></li> <li><a href='create-dataset.php'>Create Dataset</a></li>
<li><a href='user-dashboard.php#datasets'> <li><a href='user-dashboard.php#datasets'>
My Datasets</a></li> My Datasets</a></li>
<li><a href='list-images.php'>My Disk Images</a></li>"; <li><a href='list-images.php'>My Disk Images</a></li>
if ($ISEMULAB || $ISPNET) { <li><a href='images.php'>Other Disk Images</a></li>
echo "<li><a href='images.php'>Other Disk Images</a></li>"; </ul>
}
echo "</ul>
</li> </li>
"; ";
} }
......
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
</div> </div>
<div class='panel-body panel-body-dashboard'> <div class='panel-body panel-body-dashboard'>
<div> <div>
<input class='form-control search' type='search' data-column='all' <input class='form-control search' type='search'
data-column='0,1,3'
id='classic-images-search' placeholder='Search'> id='classic-images-search' placeholder='Search'>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
......
...@@ -69,7 +69,8 @@ ...@@ -69,7 +69,8 @@
</span></a> </span></a>
</div> </div>
<div> <div>
<input class='form-control search' type='search' data-column='all' <input class='form-control search' type='search'
data-column='0,1,2,4'
id='images-search' placeholder='Search'> id='images-search' placeholder='Search'>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
...@@ -90,7 +91,7 @@ ...@@ -90,7 +91,7 @@
<% var project_re = /project/; %> <% var project_re = /project/; %>
<% _.each(images, function(value, index) { %> <% _.each(images, function(value, index) { %>
<tr> <tr>
<% if (isadmin) { %> <% if (isadmin && _.has(value, "url")) { %>
<td><a href="<%- value.url %>"><%= value.imagename %></a></td> <td><a href="<%- value.url %>"><%= value.imagename %></a></td>
<% } else { %> <% } else { %>
<td><%= value.imagename %></td> <td><%= value.imagename %></td>
......
Markdown is supported
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