Commit 4fed1a38 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

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

parents e68606d5 ad361010
......@@ -1487,14 +1487,13 @@ hmac_traverse(void *rock, char *name,
if (!strcmp(name, "__hmac__"))
return 1;
#ifdef ELVIN_COMPAT
/*
* The elvin gateway sticks this flag in, but we need to ignore it
* when doing hmac computation.
*/
if (!strcmp(name, "___elvin_ordered___"))
return 1;
#endif
switch (type) {
case INT32_TYPE:
HMAC_Update(ctx,
......
gcc -DELVIN_COMPAT -c ../lib/event.c -o event.o -I../lib/ -I../../lib/libtb/ \
-I../../.. -L../../../pubsub
gcc -DELVIN_COMPAT -c ../lib/util.c -o util.o -I../lib/ -I../../lib/libtb/ \
-I../../.. -L../../../pubsub
ar crv libevent.a event.o util.o
ranlib libevent.a
g++ -DELVIN_COMPAT -o simple-agent -Wall -I../lib/ -I../../lib/libtb/ \
-I../../.. -L../../../pubsub main.cc libevent.a -lpubsub -lssl
// main.cc
#include <cassert>
#include <cmath>
#include <ctime>
#include <string>
#include <map>
#include <list>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
// For getopt
#include <unistd.h>
#include "event.h"
#include "tbdefs.h"
enum { EVENT_BUFFER_SIZE = 50 };
namespace g
{
std::string experimentName;
bool debug = false;
}
void readArgs(int argc, char * argv[]);
void usage(char * name);
// Reads the map file, initializes the pipe and pipeVault data
// structure, and sets up the two subscription strings for events.
void writePidFile(string const & pidFile);
void initEvents(string const & server, string const & port,
string const & keyFile, string const & subscription);
void subscribe(event_handle_t handle, address_tuple_t eventTuple,
string const & subscription);
void callback(event_handle_t handle,
event_notification_t notification, void *data);
int main(int argc, char * argv[])
{
cerr << "Beginning program" << endl;
readArgs(argc, argv);
return 0;
}
void readArgs(int argc, char * argv[])
{
cerr << "Processing arguments" << endl;
string server;
string port;
string keyFile;
string subscription;
// Prevent getopt from printing an error message.
opterr = 0;
/* get params from the optstring */
char const * argstring = "s:p:dE:k:u:";
int option = getopt(argc, argv, argstring);
while (option != -1)
{
switch (option)
{
case 'd':
g::debug = true;
break;
case 's':
server = optarg;
break;
case 'p':
port = optarg;
break;
case 'E':
g::experimentName = optarg;
break;
case 'k':
keyFile = optarg;
break;
case 'u':
subscription = optarg;
break;
case '?':
default:
usage(argv[0]);
break;
}
option = getopt(argc, argv, argstring);
}
/*Check if all params are specified, otherwise, print usage and exit*/
if(server == "" || g::experimentName == "")
usage(argv[0]);
initEvents(server, port, keyFile, subscription);
}
void usage(char * name)
{
cerr << "Usage: " << name << " -E proj/exp -s server [-d] [-p port] "
<< "[-i pidFile] [-k keyFile] [-u subscription]" << endl;
exit(-1);
}
void initEvents(string const & server, string const & port,
string const & keyFile, string const & subscription)
{
cerr << "Initializing event system" << endl;
string serverString = "elvin://" + server;
event_handle_t handle;
if (port != "")
{
serverString += ":" + port;
}
cerr << "Server string: " << serverString << endl;
if (keyFile != "")
{
handle = event_register_withkeyfile(const_cast<char *>(serverString.c_str()), 0,
const_cast<char *>(keyFile.c_str()));
}
else
{
handle = event_register_withkeyfile(const_cast<char *>(serverString.c_str()), 0, NULL);
}
if (handle == NULL)
{
cerr << "Could not register with event system" << endl;
exit(1);
}
address_tuple_t eventTuple = address_tuple_alloc();
subscribe(handle, eventTuple, subscription);
address_tuple_free(eventTuple);
event_main(handle);
}
void subscribe(event_handle_t handle, address_tuple_t eventTuple,
string const & subscription)
{
cerr << "Link subscription names: " << subscription << endl;
eventTuple->objname = const_cast<char *>(subscription.c_str());
// eventTuple->objtype = TBDB_OBJECTTYPE_LINK;
eventTuple->objtype = ADDRESSTUPLE_ANY;
// eventTuple->eventtype = TBDB_EVENTTYPE_MODIFY;
eventTuple->eventtype = ADDRESSTUPLE_ANY;
eventTuple->expt = const_cast<char *>(g::experimentName.c_str());
eventTuple->host = ADDRESSTUPLE_ANY;
eventTuple->site = ADDRESSTUPLE_ANY;
eventTuple->group = ADDRESSTUPLE_ANY;
eventTuple->scheduler = 1;
if (event_subscribe(handle, callback, eventTuple, NULL) == NULL)
{
cerr << "Could not subscribe to " << eventTuple->eventtype << " event" << endl;
exit(1);
}
}
void callback(event_handle_t handle,
event_notification_t notification,
void * data)
{
char name[EVENT_BUFFER_SIZE];
char type[EVENT_BUFFER_SIZE];
char args[EVENT_BUFFER_SIZE];
time_t basicTime = time(NULL);
struct tm * structTime = gmtime(&basicTime);
char timestamp[1024];
strftime(timestamp, 1024, "%Y-%m-%dT%H:%M:%S", structTime);
if (event_notification_get_string(handle, notification, "OBJNAME", name, EVENT_BUFFER_SIZE) == 0)
{
cerr << timestamp << ": ERROR: Could not get the object name" << endl;
return;
}
if (event_notification_get_string(handle, notification, "EVENTTYPE", type, EVENT_BUFFER_SIZE) == 0)
{
cerr << timestamp << ": ERROR: Could not get the event type" << endl;
return;
}
if (event_notification_get_string(handle, notification,
"ARGS", args, EVENT_BUFFER_SIZE) == 0)
{
cerr << timestamp << ": ERROR: Could not get event arguments" << endl;
return;
}
istringstream line(args);
int sequence = 0;
line >> sequence;
cerr << timestamp << " name=" << name << " type=" << type
<< " sequence=" << sequence << endl;
}
......@@ -7,6 +7,10 @@
use strict;
use lib '@prefix@/lib';
# Do this early so that we talk to the right DB.
use vars qw($GENI_DBNAME $GENI_ISCLRHOUSE);
BEGIN { $GENI_DBNAME = "geni-ch"; $GENI_ISCLRHOUSE = 1; }
use GeniCredential;
use GeniCertificate;
use GeniAuthority;
......@@ -67,7 +71,7 @@ if($numArgs !=2) {
print "Please specify <user-urn> <ch-urn> as command line arguments\n\n";
}else{
my $val = CreateSpecialCredential @ARGV;
print STDERR $val->{"code"};
print STDERR $val->{"value"};
print $val->{"output"};
#print $val->{"output"};
#print $val->{"code"};
print $val->{"value"};
}
......@@ -26,29 +26,31 @@ from M2Crypto import X509
execfile( "test-common.py" )
TYPE = None
if len(REQARGS) == 1:
TYPE = REQARGS[0]
else:
print "You must supply a TYPE (users|slices|authorities) to list"
sys.exit(1)
pass
# sanity check on TYPE
if TYPE not in ["users", "slices", "authorities"]:
print "TYPE must be one of users|slices|authorities"
sys.exit(1)
#
# Get a credential for myself, that allows me to do things at the SA.
#
mycredential = get_self_credential()
#
# Ask the clearinghouse for a list of slices
#
params = {}
params["credential"] = mycredential
params["type"] = "slices"
rval,response = do_method("ch", "List", params)
if rval:
Fatal("Could not get the list from the ClearingHouse")
pass
print str(response["value"])
#
# Ask the clearinghouse for a list of authorities
#
# Ask the clearinghouse for a list of users|slices|authorities as specified
# by TYPE
params = {}
params["credential"] = mycredential
params["type"] = "authorities"
params["type"] = TYPE
rval,response = do_method("ch", "List", params)
if rval:
Fatal("Could not get the list from the ClearingHouse")
......
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2009-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import time
import re
execfile("test-common.py")
HRN = None
TYPE = None
if len(REQARGS) == 2:
HRN = REQARGS[0]
TYPE = REQARGS[1]
else:
print "You must supply a HRN and TYPE to resolve"
sys.exit(1)
pass
# sanity check on specified type
if TYPE not in ["SA", "CM", "Component", "Slice", "User"]:
print "TYPE must be one of SA|CM|Component|Slice|User"
sys.exit(1)
#
# Get special credentials from the command line, that allows me to do things at the CH.
#
if not selfcredentialfile:
print "Please specify special credentials with -c option."
sys.exit(1)
mycredential = get_self_credential()
print "Resolving at the CH"
params = {}
params["credential"] = mycredential
params["hrn"] = HRN
params["type"] = TYPE
rval,response = do_method("ch", "Resolve", params, version="2.0")
if rval:
Fatal("Could not resolve")
pass
value = response["value"]
print str(value)
......@@ -17,7 +17,9 @@
import getopt
import os
import re
import socket
import sys
import xml.dom.minidom
import xmlrpclib
from M2Crypto import X509
......@@ -40,6 +42,7 @@ def Usage():
-s file, --slicecredentials=file read slice credentials from file
[default: query from SA]
Commands:
copy <source> <dest> copy local dir/file <source> to remote <dest>
exec <command> run <command> on slice nodes
install <file> extract tape archive <file> onto slice nodes
list show IP addresses of node control interfaces"""
......@@ -47,6 +50,7 @@ Commands:
execfile( "test-common.py" )
NOTREADY = "---notready---"
RSYNC = "/usr/local/bin/rsync"
SSH = "/usr/bin/ssh"
#
......@@ -55,7 +59,13 @@ SSH = "/usr/bin/ssh"
commands = []
while args:
command = args.pop( 0 )
if command == "install":
if command == "copy":
if len( args ) < 2: Fatal( sys.argv[ 0 ] +
": command \"copy\" requires two parameters" )
source = args.pop( 0 )
dest = args.pop( 0 )
commands.append( ( command, source, dest ) )
elif command == "install":
if not args: Fatal( sys.argv[ 0 ] +
": command \"install\" requires a parameter" )
file = args.pop( 0 )
......@@ -98,11 +108,11 @@ if debug: print str( response[ "value" ] )
#
# Ask each manager for its relevant nodes. We talk to the component
# managers in parallel, but ask about each of its nodes serially: this
# managers in parallel, but send each of its requests serially: this
# ought to allow a reasonable amount of concurrency without excessively
# burdening any individual server.
#
params = { "credential" : slicecred }
params = { "slice_urn" : slice[ "urn" ], "credentials" : [ slicecred ] }
( pr, pw ) = os.pipe()
for cm in response[ "value" ]:
......@@ -124,33 +134,48 @@ for cm in response[ "value" ]:
print >> p, text
rval, response = do_method( None, "SliceStatus", params, cm[ "url" ],
True )
try:
rval, response = do_method( None, "SliverStatus", params, \
cm[ "url" ], True )
except:
print >> sys.stderr, "Warning: could not obtain sliver status " + \
"from " + cm[ "url" ]
os._exit( 1 )
if not rval:
if response[ "value" ][ "status" ] == "ready":
# We have a list of node IDs: now iterate over them, and hunt
# through all the details looking for the control address for
# each one.
for node in response[ "value" ][ "details" ].keys():
params[ "type" ] = "Node"
params[ "uuid" ] = node
rval, response = do_method( None, "Resolve", params,
cm[ "url" ] )
if rval:
print >> sys.stderr, "Could not resolve node " + \
node
os._exit( 1 )
if "physctrl" in response[ "value" ]:
Say( response[ "value" ][ "physctrl" ] )
elif "interfaces" in response[ "value" ]:
for interface in response[ "value" ][ "interfaces" ]:
if interface[ "role" ] == "ctrl":
Say( interface[ "IP" ] )
break
else:
print >> sys.stderr, "No address available for " + \
node
os._exit( 1 )
# There is a sliver here for us. Look up its name...
rval, response = do_method( None, "Resolve",
{ "urn" : slice[ "urn" ],
"credentials" : [ slicecred ] },
cm[ "url" ], True )
if rval:
print >> sys.stderr, "Could not resolve slice " + \
slice[ "urn" ]
os._exit( 1 )
sliver = response[ "value" ][ "sliver_urn" ];
# Now we have the sliver name, and can resolve it to
# obtain the manifest.
rval, response = do_method( None, "Resolve",
{ "urn" : sliver,
"credentials" : [ slicecred ] },
cm[ "url" ], True )
if rval:
print >> sys.stderr, "Could not resolve sliver " + sliver
os._exit( 1 )
# Wade through the manifest, and look for all node elements,
# noting the host name of each one.
doc = xml.dom.minidom.parseString( response[ "value" ] \
[ "manifest" ] )
for node in filter( lambda x: x.nodeName == "node",
doc.documentElement.childNodes ):
if node.hasAttribute( "hostname" ):
Say( socket.gethostbyname( node.getAttribute( \
"hostname" ) ) )
else:
Say( NOTREADY )
......@@ -189,7 +214,25 @@ for cm in response[ "value" ]:
nodes.sort()
for command in commands:
if command[ 0 ] == "exec":
if command[ 0 ] == "copy":
print "Copying \"" + command[ 1 ] + "\" to \"" + command[ 2 ] + "\"..."
child = {}
for node in nodes:
pid = os.fork()
if pid:
child[ pid ] = node
else:
os.execl( RSYNC, "rsync", "-a", "-e",
SSH + " -T -o 'BatchMode yes' " +
"-o 'StrictHostKeyChecking no' " +
"-o 'EscapeChar none'",
command[ 1 ], node + ":" + command[ 2 ] )
os._exit( 1 )
for node in nodes:
( pid, status ) = os.wait()
print " (finished on node " + child[ pid ] + ")"
elif command[ 0 ] == "exec":
print "Executing command \"" + command[ 1 ] + "\"..."
for node in nodes:
if not os.fork():
......
......@@ -137,9 +137,28 @@ def Fatal(message):
sys.exit(1)
def PassPhraseCB(v, prompt1='Enter passphrase:', prompt2='Verify passphrase:'):
passphrase = open(PASSPHRASEFILE).readline()
passphrase = passphrase.strip()
return passphrase
"""Acquire the encrypted certificate passphrase by reading a file
or prompting the user.
This is an M2Crypto callback. If the passphrase file exists and is
readable, use it. If the passphrase file does not exist or is not
readable, delegate to the standard M2Crypto passphrase
callback. Return the passphrase.
"""
if os.path.exists(PASSPHRASEFILE):
try:
passphrase = open(PASSPHRASEFILE).readline()
passphrase = passphrase.strip()
return passphrase
except IOError, e:
print 'Error reading passphrase file %s: %s' % (PASSPHRASEFILE,
e.strerror)
else:
if debug:
print 'passphrase file %s does not exist' % (PASSPHRASEFILE)
# Prompt user if PASSPHRASEFILE does not exist or could not be read.
from M2Crypto.util import passphrase_callback
return passphrase_callback(v, prompt1, prompt2)
#
# Call the rpc server.
......
Supports Markdown
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