Commit 111d93d7 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Checkpoint initial flyspray support. More to come ... but wanted it in

the repo in case I decide to stay in Switzerland, eating chocolate and
cheeseballs.
parent 9aa974b0
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ..
SUBDIR = bugdb
include $(OBJDIR)/Makeconf
SBIN_SCRIPTS = addbugdbproj addbugdbuser setbugdbgroups \
bugdbsetup
LIBEXEC_SCRIPTS =
CTRL_SBIN_SCRIPTS = bugdbproxy
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(SBIN_SCRIPTS) $(CTRL_SBIN_SCRIPTS) $(LIBEXEC_SCRIPTS)
include $(TESTBED_SRCDIR)/GNUmakerules
install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_SCRIPTS)) \
$(addprefix $(INSTALL_LIBEXECDIR)/, $(LIBEXEC_SCRIPTS)) \
$(addprefix $(INSTALL_DIR)/opsdir/sbin/, $(CTRL_SBIN_SCRIPTS))
boss-install: install
post-install:
chown root $(INSTALL_SBINDIR)/addbugdbproj
chmod u+s $(INSTALL_SBINDIR)/addbugdbproj
chown root $(INSTALL_SBINDIR)/addbugdbuser
chmod u+s $(INSTALL_SBINDIR)/addbugdbuser
chown root $(INSTALL_SBINDIR)/setbugdbgroups
chmod u+s $(INSTALL_SBINDIR)/setbugdbgroups
#
# Control node installation (okay, plastic)
#
control-install: $(addprefix $(INSTALL_SBINDIR)/, $(CTRL_SBIN_SCRIPTS))
clean:
rm -f *.o core
$(INSTALL_DIR)/opsdir/sbin/%: %
@echo "Installing $<"
-mkdir -p $(INSTALL_DIR)/opsdir/sbin
$(INSTALL) $< $@
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
#
# Add a project to the wiki on ops.
#
sub usage()
{
print STDOUT "Usage: addbugdbproj <pid>\n";
exit(-1);
}
my $optlist = "d";
my $debug = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $BUGDBSUPPORT= @BUGDBSUPPORT@;
my $SSH = "$TB/bin/sshtb";
my $BUGDBPROXY = "$TB/sbin/bugdbproxy";
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
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;
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be setuid! Maybe its a development version?\n");
}
#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
die("*** $0:\n".
" Please do not run this as root! Its already setuid!\n");
}
#
# If no wiki support, just exit.
#
if (! $BUGDBSUPPORT) {
print "Bug DB support is not enabled. Exit ...\n";
exit(0);
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (@ARGV != 1) {
usage();
}
my $pid = $ARGV[0];
#
# Untaint args.
#
if ($pid =~ /^([-\w]+)$/) {
$pid = $1;
}
else {
die("Bad data in pid: $pid");
}
# Valid project?
if (! ProjLeader($pid)) {
fatal("No such project $pid!");
}
#
# This script always does the right thing, so no permission checks.
# In fact, all it does it call over to ops to run a script over there.
#
# For ssh.
#
$UID = $EUID;
if ($CONTROL ne $BOSSNODE) {
my $optarg = ($debug ? "-d" : "");
print "Adding project $pid to the Bug DB on $CONTROL.\n";
if (system("$SSH -host $CONTROL $BUGDBPROXY ".
" $optarg addproject $pid")) {
fatal("$BUGDBPROXY failed on $CONTROL!");
}
}
exit(0);
sub fatal($)
{
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
#
# Add a user to the bugdb on ops.
#
sub usage()
{
print STDOUT "Usage: addbugdbuser [-m] <uid>\n";
exit(-1);
}
my $optlist = "dm";
my $debug = 0;
my $modify = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $BUGDBSUPPORT= @BUGDBSUPPORT@;
my $SSH = "$TB/bin/sshtb";
my $BUGDBPROXY = "$TB/sbin/bugdbproxy";
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
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;
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be setuid! Maybe its a development version?\n");
}
#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
die("*** $0:\n".
" Please do not run this as root! Its already setuid!\n");
}
#
# If no wiki support, just exit.
#
if (! $BUGDBSUPPORT) {
print "Bug DB support is not enabled. Exit ...\n";
exit(0);
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"m"})) {
$modify = 1;
}
if (@ARGV != 1) {
usage();
}
my $uid = $ARGV[0];
#
# Untaint args.
#
if ($uid =~ /^([-\w]+)$/) {
$uid = $1;
}
else {
die("Bad data in uid: $uid");
}
# Need the password hash ...
$query_result =
DBQueryFatal("select u.usr_pswd from users as u ".
"where u.uid='$uid'");
if ($query_result->numrows == 0) {
fatal("No such user $uid!");
}
my ($passhash) = $query_result->fetchrow_array();
# shell escape.
$passhash =~ s/\$/\\\$/g;
$passhash =~ s/\*/\\\*/g;
#
# This script always does the right thing, so no permission checks.
# In fact, all it does it call over to ops to run a script over there.
#
# For ssh.
#
$UID = $EUID;
if ($CONTROL ne $BOSSNODE) {
my $optarg = ($debug ? "-d" : "");
my $addarg = "";
if ($modify) {
print "Changing user $uid info in the Bug DB on $CONTROL.\n";
$addarg = "-m";
}
else {
print "Adding user $uid to the Bug DB on $CONTROL.\n";
}
if (system("$SSH -host $CONTROL $BUGDBPROXY ".
" $optarg adduser $addarg $uid '$passhash'")) {
fatal("$BUGDBPROXY failed on $CONTROL!");
}
}
exit(0);
sub fatal($)
{
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Errno;
#
# A wrapper for messing with the Bug DB from boss.
#
sub usage()
{
print "Usage: bugdbproxy adduser [-m] <uid> <passhash> or\n";
print " bugdbproxy deluser [-f] <uid> or\n";
print " bugdbproxy addproject <pid> or\n";
print " bugdbproxy addgroup <pid> <gid> or\n";
print " bugdbproxy setgroups <uid> <pid/gid> ...\n";
exit(-1);
}
my $optlist = "d";
my $debug = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $OURDOMAIN= "@OURDOMAIN@";
my $FLYCONF = "/usr/local/etc/flyspray.conf.php";
#
# Turn off line buffering on output
#
$| = 1;
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Only real root, cause the script has to read/write a pid file that
# cannot be accessed by the user.
#
if ($UID != 0) {
die("*** $0:\n".
" Must be root to run this script!\n");
}
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libtestbed;
use libtbdb;
# Locals
my $dbname;
my $dbuser;
my $dbpass;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (! @ARGV) {
usage();
}
#
# The DB user/passwd are stored in the flyspray config file, which is
# hopefully not group readable. Open and parse that file, then open a
# connection to the DB.
#
open(FLY, $FLYCONF) or
die("*** $0:\n".
" Could not open $FLYCONF for reading!\n");
while (<FLY>) {
if ($_ =~ /^([-\w]*)\s*=\s*"([-\w]*)"$/) {
if ($1 eq "dbname") {
$dbname = $2;
}
elsif ($1 eq "dbuser") {
$dbuser = $2;
}
elsif ($1 eq "dbpass") {
$dbpass = $2;
}
}
}
close(FLY);
# Make sure we have everything we need.
if (!defined($dbname) ||
!defined($dbuser) ||
!defined($dbpass)) {
fatal("Could not find db parameters in $FLYCONF!");
}
if (TBDBConnect($dbname, $dbuser, $dbpass) < 0) {
fatal("Could not connect to flyspray database!");
}
my $action = shift(@ARGV);
if ($action eq "adduser") {
exit(AddUser(@ARGV));
}
elsif ($action eq "deluser") {
exit(DelUser(@ARGV));
}
elsif ($action eq "addproject") {
exit(AddProject(@ARGV));
}
elsif ($action eq "addgroup") {
exit(AddGroup(@ARGV));
}
elsif ($action eq "setgroups") {
exit(SetGroups(@ARGV));
}
else {
die("*** $0:\n".
" Do not know what to do with '$action'!\n");
}
exit(0);
#
# Utility function to get the flyspray user_id for an Emulab user.
#
sub FlysprayUserid($)
{
my ($user) = @_;
my $query_result =
DBQueryFatal("select user_id from flyspray_users ".
"where user_name='$user'");
return -1
if (!$query_result->numrows);
my ($user_id) = $query_result->fetchrow_array();
return $user_id;
}
#
# And the flyspray project id for an Emulab pid.
#
sub FlysprayProjectid($)
{
my ($pid) = @_;
my $query_result =
DBQueryFatal("select flyspray_id from emulab_project_mapping ".
"where pid='$pid'");
return -1
if (!$query_result->numrows);
my ($project_id) = $query_result->fetchrow_array();
return $project_id;
}
#
# And the flyspray group id for an Emulab pid/gid.
#
sub FlysprayGroupid($$)
{
my ($project_id, $gname) = @_;
my $query_result =
DBQueryFatal("select group_id from flyspray_groups ".
"where belongs_to_project='$project_id' and ".
" group_name='$gname'");
return -1
if (!$query_result->numrows);
my ($group_id) = $query_result->fetchrow_array();
return $group_id;
}
#
# Create a new flyspray group in a project. Return the new ID.
# Note that "is_admin" is set *only* for global admin group (group 0).
#
sub NewFlySprayGroup($$$$)
{
my ($name, $title, $project_id, $isadmin) = @_;
#
# The only bit that twiddles for the "admin" group for a project,
# is the bit that says the user can "manage" the project. Otherwise,
# all users get all permissions. Might need to revisit this later.
#
DBQueryFatal("insert into flyspray_groups set ".
" group_id=NULL, ".
" group_name='$name' ,".
" group_desc='$title' ,".
" belongs_to_project='$project_id', ".
" is_admin=0, ".
" manage_project='$isadmin', ".
" view_tasks='1', ".
" open_new_tasks='1', ".
" modify_own_tasks='1', ".
" modify_all_tasks='1', ".
" view_comments='1', ".
" add_comments='1', ".
" edit_comments='1', ".
" delete_comments='1', ".
" view_attachments='1', ".
" create_attachments='1', ".
" delete_attachments='1', ".
" view_history='1', ".
" close_own_tasks='1', ".
" close_other_tasks='1', ".
" assign_to_self='1', ".
" assign_others_to_self='1', ".
" view_reports='$isadmin', ".
" group_open=1");
my $query_result =
DBQueryFatal("select group_id from flyspray_groups ".
"where group_name='$name'");
fatal("Error creating new flyspray group!")
if (!$query_result->numrows);
my ($group_id) = $query_result->fetchrow_array();
return $group_id;
}
#
# Add entry (or update password) for a user.
#
sub AddUser(@)
{
my ($user, $passhash);
my $user_id;
my $modify = 0;
usage()
if (@_ < 2 || @_ > 3);
if (@_ == 2) {
($user, $passhash) = @_;
$user_id = FlysprayUserid($user);
if ($user_id >= 0) {
print("*** $user already exists in the flyspray DB! Skipping\n");
return 0;
}
}
else {
($flag, $user, $passhash) = @_;
fatal("Unknown option '$flag' to AddUser!")
if ($flag ne "-m");
$user_id = FlysprayUserid($user);
if ($user_id < 0) {
print("*** $user does not exist in the flyspray DB! Skipping\n");
return 0;
}
$modify = 1;
}
#
# Grab the gcos field from the password file.
#
my (undef, undef, undef, undef, undef, undef, $gcos) = getpwnam($user);
fatal("Could not gcos field for user $user!")
if (!defined($gcos));
$gcos = DBQuoteSpecial($gcos);
$email = "${user}\@${OURDOMAIN}";
# Currently just the passhash and the gcos are modified.
if ($modify) {
DBQueryFatal("update flyspray_users set ".
" user_pass='$passhash' ,".
" real_name=$gcos ".
"where user_id=$user_id");
return 0;
}
# Easy ...
my $query_result =
DBQueryFatal("insert into flyspray_users set ".
" user_id=NULL, ".
" user_name='$user' ,".
" user_pass='$passhash' ,".
" real_name=$gcos ,".
" group_in=0 ,".
" jabber_id='' ,".
" email_address='$email' ,".
" notify_type=1 ,".
" account_enabled=1 ,".
" dateformat='' ,".
" dateformat_extended='' ,".
" magic_url='' ");
# Get the ID assigned.
$user_id = $query_result->insertid;
if ($user_id <= 0) {
fatal("Failed to create flyspray user table entry!");