Commit 54f55585 authored by Leigh Stoller's avatar Leigh Stoller

Here is a checkpoint of the admission control stuff I have been working on.

The last part is the stuff to hook it in from assign_wrapper, and some
additional support in assign that Rob is adding for me. This comment is
from the top of new file db/libadminctrl.pm.in and describes everything in
detail.

# Admission control policies. These are the ones I could think of, although
# not all of these are implemented.
#
#  * Number of experiments per type/class (only one expt using robots).
#
#  * Number of experiments per project
#  * Number of experiments per subgroup
#  * Number of experiments per user
#
#  * Number of nodes per project      (nodes really means pc testnodes)
#  * Number of nodes per subgroup
#  * Number of nodes per user
#
#  * Number of nodes of a class per project
#  * Number of nodes of a class per group
#  * Number of nodes of a class per user
#
#  * Number of nodes of a type per project
#  * Number of nodes of a type per group
#  * Number of nodes of a type per user
#
#  * Number of nodes with attribute(s) per project
#  * Number of nodes with attribute(s) per group
#  * Number of nodes with attribute(s) per user
#
# So we have group (pid/gid) policies and user policies. These are stored
# into two different tables, group_policies and user_policies, indexed in
# the obvious manner. Each row of the table defines a count (experiments,
# nodes, etc) and a type of thing being counted (experiments, nodes, types,
# classes, etc). When we test for admission, we look for each matching row
# and test each condition. All conditions must pass. No conditions means a
# pass. There is also some "auxdata" which holds extra information needed
# for the policy (say, the type of node being restricted).
#
#      uid:     a uid
#   policy:     'experiments', 'nodes', 'type', 'class', 'attribute'
#    count:     a number
#  auxdata:     a string (optional)
#
# Example: A user policy of ('mike', 'nodes', 10) says that poor mike is
# not allowed to have more 10 nodes at a time, while ('mike', 'type',
# '10', 'pc850') says that mike cannot allocate more than 10 pc850s.
#
# The group_policies table:
#
#      pid:     a pid
#      gid:     a gid
#   policy:     'experiments', 'nodes', 'type', 'class', 'attribute'
#    count:     a number
#  auxdata:     a string (optional)
#
# Example: A project policy of ('testbed', 'testbed', 'experiments', 10)
# says that the testbed project may not have more then 10 experiments
# swapped in at a time, while ('testbed', 'TG1', 'nodes', 10) says that the
# TG1 subgroup of the testbed project may not use more than 10 nodes at
# time.
#
# In addition to group and user policies (which are policies that apply to
# specific users/projects/subgroups), we also need policies that apply to
# all users/projects/subgroups (ie: do not want to specify a particular
# restriction for every user!). To indicate such a policy, we use a special
# tag in the tables (for the user or pid/gid):
#
#      '+'  -  The policy applies to all users (or project/groups).
#
# Example: ('+','experiments',10) says that no user may have more then 10
# experiments swapped in at a time. The rule overrides anything more
# specific (say a particular user is restricted to 20 experiments; the above
# rule overrides that and the user (all users) is restricted to 10.
#
# Sometimes, you want one of these special rules to apply to everyone, but
# *allow* it to be overridden by a more specific rule. For that we use:
#
#      '-'  -  The policy applies to all users (or project/groups),
#              but can be overridden by a more specific rule.
#
# Example: The rules:
#
#	('-','type',0, 'garcia')
#       ('testbed', 'testbed', 'type', 10, 'garcia')
#
# says that no one is allowed to allocate garcias, unless there is specific
# rule that allows it; in this case the testbed project can allocate them.
#
# There are other global policies we would like to enforce. For example,
# "only one experiment can be using the robot testbed." Encoding this kind
# of policy is harder, and leads down a path that can get arbitrarily
# complex. Tha path leads to ruination, and so we want to avoid it at
# all costs.
#
# Instead we define a simple global policies table that applies to all
# experiments currently active on the testbed:
#
#   policy:     'nodes', 'type', 'class', 'attribute'
#     test:     'max', others I cannot think of right now ...
#    count:     a number
#  auxdata:     a string
#
# Example: A global policy of ('nodes', 'max', 10, '') say that the maximum
# number of nodes that may be allocated across the testbed is 10. Thats not
# a very realistic policy of course, but ('type', 'max', 1, 'garcia') says
# that a max of one garcia can be allocated across the testbed, which
# effectively means only one experiment will be able to use them at once.
# This is of course very weak, but I want to step back and give it some
# more thought before I redo this part.
#
# Is that clear? Hope so, cause it gets more complicated. Some admission
# control tests can be done early in the swap phase, before we really do
# anything (before assign_wrapper). Others (type and class) tests cannot
# be done here; only assign can figure out how an experiment is going to map
# to physical nodes (remember virtual types too), and in that case we need
# to tell assign what the "constraints" are and let it figure out what is
# possible.
#
# So, in addition to the simple checks we can do, we also generate an array
# to return to assign_wrapper with the maximum counts of each node type and
# class that is limited by the policies. assign_wrapper will dump those
# values into the ptop file so that assign can enforce those maximum values
# regardless of what hardware is actually available to use. As per discussion
# with Rob, that will look like:
#
#	set-type-limit <type> <limit>
#
# and assign will spit out a new type of violation that assign_wrapper will
# parse.
#
# NOTES:
#
#  1) Admission control is skipped in admin mode; returns okay.
#  2) Admission control is skipped when the pid is emulab-ops; returns okay.
#  3) When calculating current usage, nodes reserved to emulab-ops are
#     ignored.
#  4) The sitevar "swap/use_admission_control" controls the use of admission
#     control; defaults to 1 (on).
#  5) The current policies can be viewed in the web interface. See
#     https://www.emulab.net/showpolicies.php3
#  6) The global policy stuff is weak. I plan to step back and think about it
#     some more before redoing it, but it will tide us over for now.
#
parent 602e1c6d
......@@ -1890,7 +1890,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf db/nodelog db/webnodelog db/unixgroups \
db/dbcheck db/interswitch db/dbboot db/schemacheck \
db/sitevarscheck db/dbfillcheck \
db/sitevarscheck db/dbfillcheck db/libadminctrl.pm \
db/grabron db/webnfree db/stategraph db/readycount \
db/idletimes db/idlemail db/webidlemail db/xmlconvert \
db/webnewwanode db/libdb.py db/elabinelab_bossinit \
......
......@@ -597,7 +597,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf db/nodelog db/webnodelog db/unixgroups \
db/dbcheck db/interswitch db/dbboot db/schemacheck \
db/sitevarscheck db/dbfillcheck \
db/sitevarscheck db/dbfillcheck db/libadminctrl.pm \
db/grabron db/webnfree db/stategraph db/readycount \
db/idletimes db/idlemail db/webidlemail db/xmlconvert \
db/webnewwanode db/libdb.py db/elabinelab_bossinit \
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
......@@ -18,7 +18,7 @@ SBIN_SCRIPTS = avail inuse showgraph if2port backup webcontrol node_status \
idletimes idlemail setsitevar audit changeuid \
elabinelab_bossinit
LIBEXEC_SCRIPTS = webnodelog webnfree webnewwanode webidlemail xmlconvert
LIB_SCRIPTS = libdb.pm Node.pm libdb.py
LIB_SCRIPTS = libdb.pm Node.pm libdb.py libadminctrl.pm
# Stuff installed on plastic.
USERSBINS = genelists.proxy
......
This diff is collapsed.
......@@ -31,7 +31,7 @@ use vars qw(@ISA @EXPORT);
PROJROOT GROUPROOT USERROOT TBOPSPID
PLABMOND_PID PLABMOND_EID PLABHOLDING_PID PLABHOLDING_EID
TBTrustConvert TBMinTrust TBGrpTrust TBProjTrust
TBTrustConvert TBMinTrust TBGrpTrust TBProjTrust MapNumericUID
TB_NODEACCESS_READINFO TB_NODEACCESS_MODIFYINFO
TB_NODEACCESS_LOADIMAGE TB_NODEACCESS_REBOOT
......
......@@ -465,6 +465,18 @@ CREATE TABLE foreign_keys (
PRIMARY KEY (table1,column1)
) TYPE=MyISAM;
--
-- Table structure for table `global_policies`
--
CREATE TABLE global_policies (
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
test varchar(32) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (policy,auxdata)
) TYPE=MyISAM;
--
-- Table structure for table `group_membership`
--
......@@ -481,6 +493,19 @@ CREATE TABLE group_membership (
KEY gid (gid)
) TYPE=MyISAM;
--
-- Table structure for table `group_policies`
--
CREATE TABLE group_policies (
pid varchar(12) NOT NULL default '',
gid varchar(12) NOT NULL default '',
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (pid,gid,policy,auxdata)
) TYPE=MyISAM;
--
-- Table structure for table `group_stats`
--
......@@ -1292,8 +1317,8 @@ CREATE TABLE plab_slice_nodes (
eid varchar(32) NOT NULL default '',
slicename varchar(64) NOT NULL default '',
node_id varchar(32) NOT NULL default '',
leaseend datetime default NULL,
nodemeta text,
leaseend datetime default NULL,
PRIMARY KEY (node_id)
) TYPE=MyISAM;
......@@ -1660,6 +1685,18 @@ CREATE TABLE unixgroup_membership (
PRIMARY KEY (uid,gid)
) TYPE=MyISAM;
--
-- Table structure for table `user_policies`
--
CREATE TABLE user_policies (
uid varchar(8) NOT NULL default '',
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (uid,policy,auxdata)
) TYPE=MyISAM;
--
-- Table structure for table `user_pubkeys`
--
......
......@@ -2367,3 +2367,31 @@ last_net_act,last_cpu_act,last_ext_act);
timeline or sequence.
alter table eventlist add parent varchar(64) not null default '';
1.307: Policy stuff. See long comment in db/libadminctrl.pm.
CREATE TABLE global_policies (
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
test varchar(32) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (policy,auxdata)
) TYPE=MyISAM;
CREATE TABLE group_policies (
pid varchar(12) NOT NULL default '',
gid varchar(12) NOT NULL default '',
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (pid,gid,policy,auxdata)
) TYPE=MyISAM;
CREATE TABLE user_policies (
uid varchar(8) NOT NULL default '',
policy varchar(32) NOT NULL default '',
auxdata varchar(64) NOT NULL default '',
count int(10) NOT NULL default '0',
PRIMARY KEY (uid,policy,auxdata)
) TYPE=MyISAM;
......@@ -43,3 +43,4 @@ INSERT INTO sitevariables VALUES ('general/autoswap_threshold',NULL,'16','Number
INSERT INTO sitevariables VALUES ('general/autoswap_mode',NULL,'0','Control whether autoswap defaults to on or off in the Begin Experiment page');
INSERT INTO sitevariables VALUES ('webcam/anyone_can_view',NULL,'0','Turn webcam viewing on/off for mere users; default is off');
INSERT INTO sitevariables VALUES ('webcam/admins_can_view',NULL,'1','Turn webcam viewing on/off for admin users; default is on');
INSERT INTO sitevariables VALUES ('swap/use_admission_control',NULL,'1','Use admission control when swapping in experiments');
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
#
# Standard Testbed Header
#
PAGEHEADER("Experiment Admission Control Policies");
#
#
# Only known and logged in users allowed.
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Only admin people can see this page.
#
if (!$isadmin && !STUDLY()) {
USERERROR("You are not allowed to view this page!", 1);
}
#
# Global policies.
#
$query_result = DBQueryFatal("select * from global_policies ".
"order by policy,test");
if (mysql_num_rows($query_result)) {
echo "<br>
<center><h3>Global Policies</h3></center>
<table border=2 cellpadding=0 cellspacing=2 align='center'>\n";
echo "<tr>
<th>Policy</th>
<th>Test</th>
<th>Count</th>
<th>Aux Data</th>
</tr>\n";
while ($row = mysql_fetch_array($query_result)) {
$policy = $row["policy"];
$test = $row["test"];
$count = $row["count"];
$auxdata = $row["auxdata"];
if (!$auxdata)
$auxdata = "&nbsp";
echo "<tr>
<td>$test</td>
<td>$policy</td>
<td>$count</td>
<td>$auxdata</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
}
#
# Group policies.
#
$query_result = DBQueryFatal("select * from group_policies ".
"order by pid,gid,policy");
if (mysql_num_rows($query_result)) {
echo "<br>
<center><h3>Group Policies</h3></center>
<table border=2 cellpadding=0 cellspacing=2 align='center'>\n";
echo "<tr>
<th>Pid</th>
<th>Gid</th>
<th>Policy</th>
<th>Count</th>
<th>Aux Data</th>
</tr>\n";
while ($row = mysql_fetch_array($query_result)) {
$pid = $row["pid"];
$gid = $row["gid"];
$policy = $row["policy"];
$count = $row["count"];
$auxdata = $row["auxdata"];
if (!$auxdata)
$auxdata = "&nbsp";
echo "<tr>
<td><a href='showproject.php3?pid=$pid'>$pid</a></td>
<td><a href='showgroup.php3?pid=$pid&gid=$gid'>$gid</a></td>
<td>$policy</td>
<td>$count</td>
<td>$auxdata</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
}
#
# User policies.
#
$query_result = DBQueryFatal("select * from user_policies ".
"order by uid,policy");
if (mysql_num_rows($query_result)) {
echo "<br>
<center><h3>User Policies</h3></center>
<table border=2 cellpadding=0 cellspacing=2 align='center'>\n";
echo "<tr>
<th>Uid</th>
<th>Policy</th>
<th>Count</th>
<th>Aux Data</th>
</tr>\n";
while ($row = mysql_fetch_array($query_result)) {
$puid = $row["uid"];
$policy = $row["policy"];
$count = $row["count"];
$auxdata = $row["auxdata"];
if (!$auxdata)
$auxdata = "&nbsp";
echo "<tr>
<td><A href='showuser.php3?target_uid=$puid'>$puid</a></td>
<td>$policy</td>
<td>$count</td>
<td>$auxdata</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
}
#
# Standard Testbed Footer
#
PAGEFOOTER();
?>
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