Commit 39ae6fa1 authored by Jonathon Duerig's avatar Jonathon Duerig
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents 3723bbac 20955c3d
......@@ -138,7 +138,11 @@ $EXPT_RESOURCESHOSED = 0;
"firewall_rules",
"elabinelab_attributes",
"virt_tiptunnels",
"ipsubnets");
"ipsubnets",
"virt_blobs",
"virt_client_service_ctl",
"virt_client_service_hooks",
"virt_client_service_opts");
%physicalTables = ("delays" => ["node_id", "vname", "vnode0", "vnode1"],
"ipport_ranges" => undef,
......@@ -3507,6 +3511,135 @@ sub SetupProgramAgents($)
return 0;
}
#
# Convert virt_blobs into real blobs. We go to some pain to keep the same
# filenames associated with the same uuid to make sure caching doesn't get
# needlessly broken on the client (on a modify).
#
sub UploadBlobs($$)
{
my ($self,$update) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $pid = $self->pid();
my $eid = $self->eid();
my $idx = $self->idx();
my $virtexp = $self->GetVirtExperiment();
return -1
if (!defined($virtexp));
my %blobs = ();
my %virt_blobs = ();
#
# Grab the existing blobs tied to our experiment
#
my $qres = DBQueryFatal("select uuid,filename,vblob_id" .
" from blobs where exptidx=$idx");
if (defined($qres) && $qres->numrows()) {
while (my ($uuid,$filename,$vblob_id) = $qres->fetchrow_array()) {
$blobs{$vblob_id} = [ 0,$uuid,$filename ];
}
}
#
# Now grab our experiment virt blobs
#
my $virt_blobs_table = $virtexp->Table("virt_blobs");
foreach my $row ($virt_blobs_table->Rows()) {
my $vblob_id = $row->vblob_id();
my $filename = $row->filename();
$virt_blobs{$vblob_id} = $filename;
}
#
# Make sure each virt_blob is in the blobs table!
#
foreach my $vblob_id (keys(%virt_blobs)) {
my $vfilename = $virt_blobs{$vblob_id};
if (exists($blobs{$vblob_id})
&& $blobs{$vblob_id}->[2] eq $vfilename) {
# this one is a keeper, so mark it!
$blobs{$vblob_id}->[0] = 1;
}
else {
my $found = 0;
foreach my $rvblob_id (keys(%blobs)) {
# if this one's a keeper, skip it!
next
if ($blobs{$rvblob_id}->[0]);
# if the filenames match, we adjust the vblob_id field
# in the blobs table to match what we have -- this leaves
# the uuid<->filename mapping intact
if ($blobs{$rvblob_id}->[2] eq $vfilename) {
my $uuid = $blobs{$rvblob_id}->[1];
$blobs{$vblob_id} = [ 1,$blobs{$rvblob_id}->[1],
$blobs{$rvblob_id}->[2] ];
DBQueryFatal("replace into blobs (uuid,vblob_id)" .
" values ('$uuid','$vblob_id')");
$found = 1;
last;
}
}
if (!$found) {
# need to add this blob fresh!
my $swapperuid = $self->swapper();
DBQueryFatal("insert into blobs" .
" (uuid,filename,owner_uid,vblob_id,exptidx)" .
" values (UUID(),'$vfilename','$swapperuid'," .
" '$vblob_id',$idx)");
}
}
}
#
# Only remove real blobs if we're done using them (i.e., on a modify)
#
if ($update) {
foreach my $vblob_id (keys(%blobs)) {
my ($keep,$uuid,$filename) = @{$blobs{$vblob_id}};
if (!$keep) {
DBQueryFatal("delete from blobs" .
" where exptidx=$idx and vblob_id='${vblob_id}'");
}
}
}
return 0;
}
#
# Remove any real blobs that were a result of a virt blob (i.e., those
# blobs that have our exptidx and a valid vblob_id).
#
sub RemoveBlobs($$)
{
my ($self) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $idx = $self->idx();
my $qres = DBQueryFatal("delete from blobs using blobs" .
" left join virt_blobs as vblobs" .
" on blobs.vblob_id=vblobs.vblob_id" .
" where blobs.exptidx=$idx" .
" and vblobs.vblob_id is not NULL");
# XXX: probably should clean out blob_files stuff too!
return 0;
}
#
# Seed the virt_agents table. Each lan/link needs an agent to handle
# changes to delays or other link parameters, and that agent (might be
......
......@@ -73,6 +73,11 @@ my $debug = 0;
"virt_parameters" => [ "name", "value" ],
"virt_paths" => [ "pathname", "segmentname"],
"experiment_blobs" => [ "path", "action" ],
"virt_blobs" => [ "vblob_id", "filename" ],
"virt_client_service_ctl" => [ "vnode", "service_idx", "env", "whence" ],
"virt_client_service_hooks"=> [ "vnode", "service_idx", "env", "whence",
"hook_vblob_id" ],
"virt_client_service_opts" => [ "vnode", "opt_name", "opt_value" ],
);
#
......@@ -1198,6 +1203,27 @@ package VirtExperiment::VirtTableRow::experiment_blobs;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_blobs;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_ctl;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_hooks;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_opts;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -125,6 +125,18 @@ my %virtual_tables =
"experiment_blobs" => { rows => undef,
tag => "blobs",
row => "blob"},
"virt_blobs" => { rows => undef,
tag => "virt_blobs",
row => "virt_blob"},
"virt_client_service_ctl" => { rows => undef,
tag => "virt_client_service_ctl",
row => "virt_client_service_ctlrow"},
"virt_client_service_hooks"=> { rows => undef,
tag => "virt_client_service_hooks",
row => "virt_client_service_hook"},
"virt_client_service_opts" => { rows => undef,
tag => "virt_client_service_opts",
row => "virt_client_service_opt"},
# This is a fake table. See below. If we add more, lets generalize.
"external_sourcefiles" => { rows => undef,
tag => "nsfiles",
......
......@@ -218,7 +218,7 @@ CREATE TABLE `geni_rspecs` (
`idx` int(10) unsigned NOT NULL auto_increment,
`created` datetime default NULL,
`rspec` text,
PRIMARY KEY (`idx`),
PRIMARY KEY (`idx`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `geni_bindings`;
......
......@@ -106,6 +106,7 @@ sub ListResources()
my $available = $options->{'geni_available'};
my $compress = $options->{'geni_compressed'};
my $slice_urn = $options->{'geni_slice_urn'};
my $version = $options->{'rspec_version'} || undef;
my $xml = undef;
if ($slice_urn) {
......@@ -138,7 +139,8 @@ sub ListResources()
# No slice was specified, so get the advertisement RSpec.
my $discover_args = {
'credentials' => $credentials,
'available' => $available
'available' => $available,
'rspec_version' => $version,
};
my $response = GeniCMV2::DiscoverResources($discover_args);
if (GeniResponse::IsError($response)) {
......
......@@ -192,18 +192,19 @@ sub DiscoverResources($)
return $credential
if (GeniResponse::IsResponse($credential));
return DiscoverResourcesAux($available, $compress, [$credential]);
return DiscoverResourcesAux($available,
$compress, $version, [$credential]);
}
# Helper function for V2.
sub DiscoverResourcesAux($$$;$)
sub DiscoverResourcesAux($$$$)
{
my ($available, $compress, $credentials, $version) = @_;
my ($available, $compress, $version, $credentials) = @_;
my $user_urn = $ENV{'GENIRN'};
$version = "0.2"
if (!defined($version));
# Sanity check since this can come from client.
if (! ($version eq "0.1" || $version eq "0.2" ||$version eq "2.0")) {
if (! ($version eq "0.1" || $version eq "0.2" ||$version eq "2")) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper version request");
}
......
......@@ -299,7 +299,7 @@ sub DiscoverResources($)
if(!GeniResponse::IsResponse($cred));
}
return GeniCM::DiscoverResourcesAux($available, $compress,
$credential_objects);
$version, $credential_objects);
}
#
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -203,7 +203,8 @@ my %packlist =
"p5-Crypt-SSLeay>=0.57" => "/usr/ports/security/p5-Crypt-SSLeay",
"p5-Crypt-OpenSSL-X509" => "/usr/ports/security/p5-Crypt-OpenSSL-X509",
"p5-Crypt-X509" => "/usr/ports/security/p5-Crypt-X509",
"xerces-c2>=2.7.0" => "/usr/ports/textproc/xerces-c2"
"xerces-c2>=2.7.0" => "/usr/ports/textproc/xerces-c2",
"p5-XML-SemanticDiff" => "/usr/ports/textproc/p5-XML-SemanticDiff",
);
my $needpkgs = 0;
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -48,6 +48,7 @@ $GENI_DBNAME = "geni-cm";
use lib '@prefix@/lib';
use libdb qw(DBQueryFatal);
use Node;
use User;
require GeniDB;
require GeniCertificate;
require GeniComponent;
......
......@@ -38,6 +38,7 @@ my $CMCERT = "$TB/etc/genicm.pem";
my $geniuserid = "geniuser";
my $geniprojid = "GeniSlices";
my $SUDO = "/usr/local/bin/sudo";
my $MYSQLSHOW = "/usr/X11R6/bin/mysqlshow";
my $BATCHEXP = "$TB/bin/batchexp";
# un-taint path
......@@ -68,8 +69,6 @@ BEGIN
use libtestbed;
use libdb qw(TBSetSiteVar TBSiteVarExists TBGetSiteVar);
use Experiment;
use GeniDB;
use GeniCertificate;
#
# Check args.
......@@ -97,16 +96,26 @@ if (defined($options{"p"})) {
usage()
if (@ARGV);
OneShot()
if (!$verify);
if (!$verify && $UID != 0) {
fatal("Must be root to run this script\n");
}
#
# Apply the dbupdates using the Emulab utility, to all three DBs.
# If the DBs are not built yet (initsite not run) just exit.
# We will be back here later.
#
system("$MYSQLSHOW geni >/dev/null 2>&1");
if ($?) {
print "Protogeni DB does not exist yet. Skipping ...\n";
exit(0);
}
require GeniDB;
import GeniDB;
require GeniCertificate;
OneShot()
if (!$verify);
#
# Apply the dbupdates using the Emulab utility, to all three DBs.
#
......
......@@ -129,6 +129,8 @@ CREATE TABLE `blobs` (
`uuid` varchar(40) NOT NULL,
`filename` tinytext,
`owner_uid` varchar(8) NOT NULL default '',
`vblob_id` varchar(40) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
PRIMARY KEY (`uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......@@ -252,6 +254,59 @@ CREATE TABLE `checkups_temp` (
PRIMARY KEY (`object`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `client_service_ctl`
--
DROP TABLE IF EXISTS `client_service_ctl`;
CREATE TABLE `client_service_ctl` (
`obj_type` enum('node_type','node','osid') NOT NULL default 'node_type',
`obj_name` varchar(64) NOT NULL default '',
`service_idx` int(10) NOT NULL default '0',
`env` enum('load','boot') NOT NULL default 'boot',
`whence` enum('first','every') NOT NULL default 'every',
`alt_blob_id` varchar(40) NOT NULL default '',
`enable` tinyint(1) NOT NULL default '1',
`enable_hooks` tinyint(1) NOT NULL default '1',
`fatal` tinyint(1) NOT NULL default '1',
`user_can_override` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`obj_type`,`obj_name`,`service_idx`,`env`,`whence`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `client_service_hooks`
--
DROP TABLE IF EXISTS `client_service_hooks`;
CREATE TABLE `client_service_hooks` (
`obj_type` enum('node_type','node','osid') NOT NULL default 'node_type',
`obj_name` varchar(64) NOT NULL default '',
`service_idx` int(10) NOT NULL default '0',
`env` enum('load','boot') NOT NULL default 'boot',
`whence` enum('first','every') NOT NULL default 'every',
`hook_blob_id` varchar(40) NOT NULL default '',
`hook_op` enum('boot','shutdown','reconfig','reset') NOT NULL default 'boot',
`hook_point` enum('pre','post') NOT NULL default 'post',
`argv` varchar(255) NOT NULL default '',
`fatal` tinyint(1) NOT NULL default '0',
`user_can_override` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`obj_type`,`obj_name`,`service_idx`,`env`,`whence`,`hook_blob_id`,`hook_op`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `client_services`
--
DROP TABLE IF EXISTS `client_services`;
CREATE TABLE `client_services` (
`idx` int(10) NOT NULL default '0',
`service` varchar(64) NOT NULL default 'isup',
`env` enum('load','boot') NOT NULL default 'boot',
`whence` enum('first','every') NOT NULL default 'every',
`hooks_only` int(1) NOT NULL default '0',
PRIMARY KEY (`idx`,`service`,`env`,`whence`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `comments`
--
......@@ -3936,6 +3991,76 @@ CREATE TABLE `virt_agents` (
UNIQUE KEY `pideid` (`pid`,`eid`,`vname`,`vnode`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_blobs`
--
DROP TABLE IF EXISTS `virt_blobs`;
CREATE TABLE `virt_blobs` (
`pid` varchar(12) NOT NULL default '',
`eid` varchar(32) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`vblob_id` varchar(40) NOT NULL default '',
`filename` tinytext,
PRIMARY KEY (`exptidx`,`vblob_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_client_service_ctl`
--
DROP TABLE IF EXISTS `virt_client_service_ctl`;
CREATE TABLE `virt_client_service_ctl` (
`pid` varchar(12) NOT NULL default '',
`eid` varchar(32) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`vnode` varchar(32) NOT NULL default '',
`service_idx` int(10) NOT NULL default '0',
`env` enum('load','boot') NOT NULL default 'boot',
`whence` enum('first','every') NOT NULL default 'every',
`alt_vblob_id` varchar(40) NOT NULL default '',
`enable` tinyint(1) NOT NULL default '1',
`enable_hooks` tinyint(1) NOT NULL default '1',
`fatal` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`exptidx`,`vnode`,`service_idx`,`env`,`whence`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_client_service_hooks`
--
DROP TABLE IF EXISTS `virt_client_service_hooks`;
CREATE TABLE `virt_client_service_hooks` (
`pid` varchar(12) NOT NULL default '',
`eid` varchar(32) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`vnode` varchar(32) NOT NULL default '',
`service_idx` int(10) NOT NULL default '0',
`env` enum('load','boot') NOT NULL default 'boot',
`whence` enum('first','every') NOT NULL default 'every',
`hook_vblob_id` varchar(40) NOT NULL default '',
`hook_op` enum('boot','shutdown','reconfig','reset') NOT NULL default 'boot',
`hook_point` enum('pre','post') NOT NULL default 'post',
`argv` varchar(255) NOT NULL default '',
`fatal` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`exptidx`,`vnode`,`service_idx`,`env`,`whence`,`hook_vblob_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_client_service_opts`
--
DROP TABLE IF EXISTS `virt_client_service_opts`;
CREATE TABLE `virt_client_service_opts` (
`pid` varchar(12) NOT NULL default '',
`eid` varchar(32) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`vnode` varchar(32) NOT NULL default '',
`opt_name` varchar(32) NOT NULL default '',
`opt_value` varchar(64) NOT NULL default '',
PRIMARY KEY (`exptidx`,`vnode`,`opt_name`,`opt_value`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_firewalls`
--
......
......@@ -72,6 +72,47 @@ REPLACE INTO comments VALUES ('nseconfigs','','Table for storing NSE configurati
REPLACE INTO comments VALUES ('widearea_delays','','Delay and bandwidth metrics between WAN nodes');
REPLACE INTO comments VALUES ('virt_nodes','','Experiment virtual nodes');
--
-- Dumping data for table `client_services`
--
REPLACE INTO `client_services` VALUES (10,'rc.tbsetup','boot','every',1);
REPLACE INTO `client_services` VALUES (20,'rc.ipod','boot','every',0);
REPLACE INTO `client_services` VALUES (30,'rc.healthd','boot','every',0);
REPLACE INTO `client_services` VALUES (40,'rc.slothd','boot','every',0);
REPLACE INTO `client_services` VALUES (50,'rc.firewall','boot','every',0);
REPLACE INTO `client_services` VALUES (60,'rc.tpmsetup','boot','every',0);
REPLACE INTO `client_services` VALUES (70,'rc.misc','boot','every',0);
REPLACE INTO `client_services` VALUES (80,'rc.localize','boot','every',0);
REPLACE INTO `client_services` VALUES (90,'rc.keys','boot','every',0);
REPLACE INTO `client_services` VALUES (100,'rc.mounts','boot','every',0);
REPLACE INTO `client_services` VALUES (110,'rc.blobs','boot','every',0);
REPLACE INTO `client_services` VALUES (120,'rc.topomap','boot','every',0);
REPLACE INTO `client_services` VALUES (130,'rc.accounts','boot','every',0);
REPLACE INTO `client_services` VALUES (140,'rc.route','boot','every',0);
REPLACE INTO `client_services` VALUES (150,'rc.tunnels','boot','every',0);
REPLACE INTO `client_services` VALUES (160,'rc.ifconfig','boot','every',0);
REPLACE INTO `client_services` VALUES (170,'rc.delays','boot','every',0);
REPLACE INTO `client_services` VALUES (180,'rc.hostnames','boot','every',0);
REPLACE INTO `client_services` VALUES (190,'rc.lmhosts','boot','every',0);
REPLACE INTO `client_services` VALUES (200,'rc.trace','boot','every',0);
REPLACE INTO `client_services` VALUES (210,'rc.syncserver','boot','every',0);
REPLACE INTO `client_services` VALUES (220,'rc.trafgen','boot','every',0);
REPLACE INTO `client_services` VALUES (230,'rc.tarfiles','boot','every',0);
REPLACE INTO `client_services` VALUES (240,'rc.rpms','boot','every',0);
REPLACE INTO `client_services` VALUES (250,'rc.progagent','boot','every',0);
REPLACE INTO `client_services` VALUES (260,'rc.linkagent','boot','every',0);
REPLACE INTO `client_services` VALUES (270,'rc.tiptunnels','boot','every',0);
REPLACE INTO `client_services` VALUES (280,'rc.motelog','boot','every',0);
REPLACE INTO `client_services` VALUES (290,'rc.simulator','boot','every',0);
REPLACE INTO `client_services` VALUES (1000,'rc.canaryd','boot','every',1);
REPLACE INTO `client_services` VALUES (1010,'rc.linktest','boot','every',1);
REPLACE INTO `client_services` VALUES (1020,'rc.isup','boot','every',1);
REPLACE INTO `client_services` VALUES (1030,'rc.startcmd','boot','every',0);
REPLACE INTO `client_services` VALUES (1040,'rc.vnodes','boot','every',1);
REPLACE INTO `client_services` VALUES (1050,'rc.subnodes','boot','every',1);
--
-- Dumping data for table `event_eventtypes`
--
......@@ -149,6 +190,7 @@ REPLACE INTO exported_tables VALUES ('testsuite_preentables');
REPLACE INTO exported_tables VALUES ('webdb_table_permissions');
REPLACE INTO exported_tables VALUES ('emulab_pubs_month_map');
REPLACE INTO exported_tables VALUES ('event_triggertypes');
REPLACE INTO exported_tables VALUES ('client_services');
--
-- Dumping data for table `foreign_keys`
......@@ -1052,6 +1094,33 @@ REPLACE INTO table_regex VALUES ('images','decryption_key','text','regex','^[0-9
REPLACE INTO table_regex VALUES ('experiment_blobs','path','text','redirect','default:text',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiment_blobs','action','text','redirect','default:text',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_blobs','filename','text','redirect','default:tinytext',0,256,NULL);
REPLACE INTO table_regex VALUES ('virt_blobs','vblob_id','text','regex','^[-\\d\\w]+$',0,40,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','alt_vblob_id','text','regex','^[-\\d\\w]+$',0,40,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','enable','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','enable_hooks','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','env','text','regex','^(boot|load)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','fatal','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','service_idx','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','vnode','text','redirect','virt_nodes:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_ctl','whence','text','regex','^(first|every)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','argv','text','regex','^[-\\w\\s\"]*$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','env','text','regex','^(boot|load)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','fatal','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','hook_op','text','regex','^(boot|shutdown|reconfig|reset)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','hook_point','text','regex','^(pre|post)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','hook_vblob_id','text','regex','^[-\\d\\w]+$',0,40,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','op','text','regex','^(boot|shutdown|reconfig|reset)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','point','text','regex','^(pre|post)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','service_idx','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','vnode','text','redirect','virt_nodes:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_client_service_hooks','whence','text','regex','^(first|every)$',0,0,NULL);