Commit 232992d4 authored by Russ Fish's avatar Russ Fish

Move newosid.in to the backend dir.

parent 69ae28a9
......@@ -12,10 +12,10 @@ UNIFIED = @UNIFIED_BOSS_AND_OPS@
include $(OBJDIR)/Makeconf
BIN_SCRIPTS = moduserinfo newgroup newmmlist editexp editimageid \
BIN_SCRIPTS = newosid moduserinfo newgroup newmmlist editexp editimageid \
editnodetype editsitevars newimageid editgroup \
newimageid_ez
WEB_BIN_SCRIPTS = webmoduserinfo webnewgroup webnewmmlist webeditexp \
WEB_BIN_SCRIPTS = webnewosid webmoduserinfo webnewgroup webnewmmlist webeditexp \
webeditimageid webeditnodetype webeditsitevars webnewimageid \
webeditgroup webnewimageid_ez
WEB_SBIN_SCRIPTS=
......
......@@ -16,7 +16,7 @@ SUBDIRS = nsgen
BIN_SCRIPTS = delay_config sshtb create_image node_admin link_config \
setdest loghole webcopy linkmon_ctl snmp-if-deref.sh \
template_record spewevents newosid \
template_record spewevents \
wbts_dump
SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
eventping grantnodetype import_commitlog daemon_wrapper \
......@@ -28,7 +28,7 @@ SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
WEB_SBIN_SCRIPTS= webnewnode webdeletenode webspewconlog webarchive_list \
webwanodecheckin webspewimage
WEB_BIN_SCRIPTS = webcreate_image websetdest weblinkmon_ctl webspewevents \
webdelay_config webnewosid
webdelay_config
LIBEXEC_SCRIPTS = spewleds webcopy spewsource webcvsweb xlogin webviewvc \
$(WEB_BIN_SCRIPTS) $(WEB_SBIN_SCRIPTS)
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use strict;
use Getopt::Std;
use XML::Simple;
use Data::Dumper;
#
# Create a new osid from a XML description.
#
sub usage()
{
print("Usage: newosid [-v] <xmlfile>\n");
exit(-1);
}
my $optlist = "dv";
my $debug = 0;
my $verify = 0; # Check data and return status only.
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
#
# Untaint the path
#
$ENV{'PATH'} = "$TB/bin:$TB/sbin:/bin:/usr/bin:/usr/bin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
use Project;
use OSinfo;
# Protos
sub fatal($);
sub UserError(;$);
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"v"})) {
$verify = 1;
}
if (@ARGV != 1) {
usage();
}
my $xmlfile = shift(@ARGV);
#
# Map invoking user to object.
# If invoked as "nobody" we are coming from the web interface and the
# current user context is "implied" (see tbauth.php3).
#
my $this_user;
if (getpwuid($UID) ne "nobody") {
$this_user = User->ThisUser();
if (! defined($this_user)) {
fatal("You ($UID) do not exist!");
}
fatal("You must have admin privledges to create new osids")
if (!$this_user->IsAdmin());
}
else {
#
# Check the filename when invoked from the web interface; must be a
# file in /tmp.
#
if ($xmlfile =~ /^([-\w\.\/]+)$/) {
$xmlfile = $1;
}
else {
fatal("Bad data in pathname: $xmlfile");
}
# Use realpath to resolve any symlinks.
my $translated = `realpath $xmlfile`;
if ($translated =~ /^(\/tmp\/[-\w\.\/]+)$/) {
$xmlfile = $1;
}
else {
fatal("Bad data in translated pathname: $xmlfile");
}
# The web interface (and in the future the xmlrpc interface) sets this.
$this_user = User->ImpliedUser();
if (! defined($this_user)) {
fatal("Cannot determine implied user!");
}
}
#
# These are the fields that we allow to come in from the XMLfile.
#
my $SLOT_OPTIONAL = 0x1; # The field is not required.
my $SLOT_REQUIRED = 0x2; # The field is required and must be non-null.
my $SLOT_ADMINONLY = 0x4; # Only admins can set this field.
#
# XXX We should encode all of this in the DB so that we can generate the
# forms on the fly, as well as this checking code.
#
my %xmlfields =
# XML Field Name DB slot name Flags Default
("description" => ["description", $SLOT_REQUIRED],
"osname" => ["osname" , $SLOT_REQUIRED],
"project" => ["pid", $SLOT_REQUIRED],
"OS" => ["OS", $SLOT_REQUIRED],
"version" => ["version", $SLOT_OPTIONAL, ""],
"path" => ["path", $SLOT_OPTIONAL, "NULL"],
"magic", => ["magic", $SLOT_OPTIONAL, ""],
"op_mode", => ["op_mode", $SLOT_REQUIRED],
"features", => ["osfeatures", $SLOT_OPTIONAL, ""],
"shared", => ["shared", $SLOT_ADMINONLY, 0],
"mustclean", => ["mustclean", $SLOT_ADMINONLY, 1],
"nextosid", => ["nextosid", $SLOT_ADMINONLY],
"reboot_waittime", => ["reboot_waittime", $SLOT_ADMINONLY]);
#
# Must wrap the parser in eval since it exits on error.
#
my $xmlparse = eval { XMLin($xmlfile,
VarAttr => 'name',
ContentKey => '-content',
SuppressEmpty => undef); };
fatal($@)
if ($@);
#
# Process and dump the errors (formatted for the web interface).
# We should probably XML format the errors instead but not sure I want
# to go there yet.
#
my %errors = ();
#
# Make sure all the required arguments were provided.
#
foreach my $key (keys(%xmlfields)) {
my (undef, $required, undef) = @{$xmlfields{$key}};
$errors{$key} = "Required value not provided"
if ($required & $SLOT_REQUIRED &&
! exists($xmlparse->{'attribute'}->{"$key"}));
}
UserError()
if (keys(%errors));
#
# We build up an array of arguments to pass to OSinfo->Create() as we check
# the attributes.
#
my %newosid_args = ();
foreach my $key (keys(%{ $xmlparse->{'attribute'} })) {
my $value = $xmlparse->{'attribute'}->{"$key"}->{'value'};
if ($debug) {
print STDERR "User attribute: '$key' -> '$value'\n";
}
$errors{$key} = "Unknown attribute"
if (!exists($xmlfields{$key}));
my ($dbslot, $required, $default) = @{$xmlfields{$key}};
if ($required & $SLOT_REQUIRED) {
# A slot that must be provided, so do not allow a null value.
if (!defined($value)) {
$errors{$key} = "Must provide a non-null value";
next;
}
}
if ($required & $SLOT_OPTIONAL) {
# Optional slot. If value is null skip it. Might not be the correct
# thing to do all the time?
if (!defined($value)) {
next
if (!defined($default));
$value = $default;
}
}
if ($required & $SLOT_ADMINONLY) {
# Admin implies optional, but thats probably not correct approach.
$errors{$key} = "Administrators only"
if (! $this_user->IsAdmin());
}
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "os_info", $dbslot, TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
$newosid_args{$dbslot} = $value;
}
UserError()
if (keys(%errors));
#
# Now do special checks.
#
my $project = Project->Lookup($newosid_args{"pid"});
if (!defined($project)) {
UserError("Project: No such project");
}
if (!$project->AccessCheck($this_user, TB_PROJECT_MAKEOSID())) {
UserError("Project: Not enough permission");
}
# OS must be in the allowed list.
if (! OSinfo->ValidOS($newosid_args{"OS"})) {
UserError("OS: Invalid");
}
# Ditto the opmode.
if (! OSinfo->ValidOpMode($newosid_args{"op_mode"})) {
UserError("OpMode: Invalid");
}
# Nextosid check. Must exist. admin check done above.
if (exists($newosid_args{"nextosid"})) {
my $nextos = OSinfo->Lookup($newosid_args{"nextosid"});
if (!defined($nextos)) {
UserError("Nextosid: Does not exist");
}
}
# Mere users have to supply a version, but admin people do not.
if (! $this_user->IsAdmin() &&
(!exists($newosid_args{"version"}) || $newosid_args{"version"} eq "")) {
UserError("Version: Required value not provided");
}
# reboot waittime default value is not set by an admin user.
if (! exists($newosid_args{"reboot_waittime"})) {
$newosid_args{"reboot_waittime"} =
OSinfo->RebootWaitTime($newosid_args{"OS"});
}
exit(0)
if ($verify);
#
# Now safe to create the OSID.
#
# We pass the osname along as an argument to Create(), so remove it from
# the argument array.
#
my $osname = $newosid_args{"osname"};
delete($newosid_args{"osname"});
# Ditto the pid.
delete($newosid_args{"pid"});
my $usrerr;
my $new_osinfo = OSinfo->Create($project, $this_user, $osname,
\%newosid_args, \$usrerr);
UserError($usrerr)
if (defined($usrerr));
fatal("Could not create new OSID!")
if (!defined($new_osinfo));
my $osid = $new_osinfo->osid();
# The web interface requires this line to be printed.
print "OSID $osname/$osid has been created\n";
exit(0);
sub fatal($)
{
my ($mesg) = @_;
print STDERR "*** $0:\n".
" $mesg\n";
# Exit with negative status so web interface treats it as system error.
exit(-1);
}
sub UserError(;$)
{
my ($mesg) = @_;
if (keys(%errors)) {
foreach my $key (keys(%errors)) {
my $val = $errors{$key};
print "${key}: $val\n";
}
}
print "$mesg\n"
if (defined($mesg));
# Exit with positive status so web interface treats it as user error.
exit(1);
}
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