Commit eb8b1b87 authored by Leigh Stoller's avatar Leigh Stoller

Make it easier to share the same repository among different profiles:

If there is a directory called "profiles" and there is a file in that
directory named the same as the profile, and ends in a .py (or .rspec),
then use that as the profile source code instead of toplevel profile.py.
parent f2d8902c
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
# Copyright (c) 2000-2019 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -108,13 +108,14 @@ sub DoCommitList();
sub DoCommitInfo();
sub DoGetSource();
sub DoGetRepoSize();
sub GetRepoSource($;$);
sub GetRepoSource($;$$);
sub GetRepoSize($);
sub GetBranchList($);
sub GetTagList($);
sub GetCommitList($$);
sub GetCommitField($$$);
sub GetRepoName($);
sub GetProfile($);
sub GetDefaultBranch($);
sub RemoveRepo($);
......@@ -266,11 +267,12 @@ sub DoCheckRemote()
#
sub DoClone()
{
my $optlist = "o:rn:u";
my $optlist = "o:rn:uS:";
my $ofile;
my $remove;
my $reponame;
my $update;
my $sourcename;
my %options = ();
if (! getopts($optlist, \%options)) {
......@@ -290,6 +292,13 @@ sub DoClone()
if (defined($options{"r"})) {
$remove = 1;
}
if (defined($options{"S"})) {
$sourcename = $options{"S"};
# Silly taint check.
if ($sourcename =~ /^(.*)$/) {
$sourcename = $1;
}
}
if (defined($options{"u"})) {
$update = 1;
if (!defined($options{"n"})) {
......@@ -344,7 +353,7 @@ sub DoClone()
#
# Now get the geni-lib script or rspec, write it to the file or stdout.
#
my $source = GetRepoSource($reponame);
my $source = GetRepoSource($reponame, undef, $sourcename);
if (!defined($source)) {
RemoveRepo($reponame);
UserError("Could not find profile.py or profile.rspec in repository");
......@@ -405,6 +414,7 @@ sub DoUpdate()
my $ofile;
my $reponame;
my $repourl;
my $sourcename;
my %options = ();
if (! getopts($optlist, \%options)) {
......@@ -437,6 +447,7 @@ sub DoUpdate()
}
$reponame = $profile->reponame();
$repourl = $profile->repourl();
$sourcename = $profile->name();
}
else {
usage();
......@@ -484,9 +495,9 @@ sub DoUpdate()
#
# Now get the geni-lib script or rspec write it to the file or stdout.
#
my $source = GetRepoSource($reponame);
my $source = GetRepoSource($reponame, undef, $sourcename);
if (!defined($source)) {
UserError("Could not find profile.py or profile.rspec in repository");
UserError("Could not find profile source in repository");
}
#
......@@ -534,6 +545,7 @@ sub DoGetSource()
my $reponame;
my $ofile;
my $which;
my $profile;
my %options = ();
if (! getopts($optlist, \%options)) {
......@@ -543,6 +555,7 @@ sub DoGetSource()
$ofile = $options{"o"};
}
$which = shift(@ARGV) if (@ARGV);
$profile = GetProfile(\%options);
$reponame = GetRepoName(\%options);
$which = GetDefaultBranch($reponame) if (!defined($which));
......@@ -550,7 +563,8 @@ sub DoGetSource()
if ($which =~ /^(.*)$/) {
$which = $1;
}
my $source = GetRepoSource($reponame, $which);
my $source = GetRepoSource($reponame, $which,
defined($profile) ? $profile->name() : undef);
if (!defined($source)) {
UserError("Could not find profile.py or profile.rspec in repository");
}
......@@ -584,12 +598,18 @@ sub DoGetSource()
#
# Grab a file from the bare repo.
#
sub GetRepoSource($;$)
sub GetRepoSource($;$$)
{
my ($reponame, $refspec) = @_;
my ($reponame, $refspec, $name) = @_;
my $repodir = "$REPODIR/$reponame";
my $source;
# List of places to find the source.
my @locations = ("profiles/profile", "profile");
if (defined($name)) {
unshift(@locations, "profiles/$name", "$name");
}
$refspec = GetDefaultBranch($reponame)
if (!defined($refspec));
......@@ -601,15 +621,19 @@ sub GetRepoSource($;$)
chdir("$repodir") or
fatal("Could not chdir to $repodir: $!");
foreach my $maybe (@locations) {
if (system("$GIT cat-file -e ".
"$refspec:profile.py >/dev/null 2>&1") == 0) {
$source = "profile.py";
"$refspec:${maybe}.py >/dev/null 2>&1") == 0) {
$source = "${maybe}.py";
}
elsif (system("$GIT cat-file -e ".
" $refspec:profile.rspec >/dev/null 2>&1") == 0) {
$source = "profile.rspec";
" $refspec:${maybe}.rspec >/dev/null 2>&1") == 0) {
$source = "${maybe}.rspec";
}
else {
last
if ($source);
}
if (!$source) {
print STDERR "$repodir, $refspec\n";
print STDERR `/usr/bin/id`;
print STDERR `/bin/ls -la`;
......@@ -1105,6 +1129,27 @@ sub GetRepoName($)
return $reponame;
}
#
# Dig the profile out of the options list.
#
sub GetProfile($)
{
my ($options) = @_;
my %options = %{ $options };
if (defined($options{"p"})) {
my $profile = APT_Profile->Lookup($options{"p"});
if (!defined($profile)) {
fatal("No such profile");
}
if (!defined($profile->reponame())) {
fatal("No such repository associated with profile");
}
return $profile;
}
return undef;
}
#
# Estimated Repo size.
#
......
......@@ -299,7 +299,8 @@ sub CreateProfile()
my $repohash;
my $output =
emutil::ExecQuiet("$MANAGEGITREPO clone -n $reponame '$repourl'");
emutil::ExecQuiet("$MANAGEGITREPO clone -n $reponame ".
" -S " . $new_args{"name"} . " '$repourl'");
if ($?) {
UserError($output);
}
......
......@@ -1449,12 +1449,17 @@ $(function ()
changeRspec(json.value.script);
});
}
var args = {"repourl" : repourl};
// If there is profile name, pass that through so we can look
// for a script or rspec with the same name (instead of profile.py).
if ($.trim($('#profile_name').val()) != "") {
args["profile_name"] = $.trim($('#profile_name').val());
}
WaitWait("We are attempting to clone your repository. " +
"Patience please.");
var xmlthing = sup.CallServerMethod(ajaxurl,
"manage_profile",
"GetRepository",
{repourl : repourl});
"GetRepository", args);
xmlthing.done(callback);
}
......@@ -1524,7 +1529,7 @@ $(function ()
function SetupRepo()
{
//console.info("SetupRepo");
console.info("SetupRepo");
gitrepo.InitRepoPicker(version_uuid, reporefspec,
function(which) {
......
......@@ -1379,6 +1379,7 @@ function Do_GetRepository()
{
global $this_user;
global $ajax_args;
$nameopt = "";
$this_idx = $this_user->uid_idx();
$this_uid = $this_user->uid();
......@@ -1394,6 +1395,17 @@ function Do_GetRepository()
}
$repourl = escapeshellarg($repourl);
# Pass though profile name to use instead of profile.py.
if (isset($ajax_args["profile_name"])) {
if (!TBcheck_dbslot($ajax_args["profile_name"],
"apt_profiles", "name",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
SPITAJAX_ERROR(2, "Invalid profile name: " . TBFieldErrorString());
return;
}
$nameopt = "-S " . escapeshellarg($ajax_args["profile_name"]);
}
$webtask = WebTask::CreateAnonymous();
if (!$webtask) {
SPITAJAX_ERROR(-1, "Internal webtask Error");
......@@ -1409,15 +1421,15 @@ function Do_GetRepository()
SUEXEC_ACTION_IGNORE);
$webtask->Refresh();
if ($retval != 0) {
if ($retval < 0) {
$error = $webtask->TaskValue("output");
if (!$webtask->exited() || $retval < 0) {
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
SPITAJAX_ERROR(-1, "Internal error checking repository");
}
else {
$error = $webtask->TaskValue("output");
SPITAJAX_ERROR(1, $error);
}
$webtask->Delete();
SPITAJAX_ERROR(1, $error);
return;
}
$webtask->Reset();
......@@ -1426,20 +1438,20 @@ function Do_GetRepository()
$retval = SUEXEC($this_uid, "tbadmin",
"webmanage_gitrepo -t " . $webtask->task_id() . " " .
" clone -o $outfname -r $repourl",
" clone $nameopt -o $outfname -r $repourl",
SUEXEC_ACTION_IGNORE);
$webtask->Refresh();
if ($retval != 0) {
if ($retval < 0) {
$error = $webtask->TaskValue("output");
if (!$webtask->exited() || $retval < 0) {
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
SPITAJAX_ERROR(-1, "Internal error checking repository");
}
else {
$error = $webtask->TaskValue("output");
SPITAJAX_ERROR(1, $error);
}
$webtask->Delete();
unlink($outfname);
SPITAJAX_ERROR(1, $error);
return;
}
$blob = array("script" => file_get_contents($outfname),
......
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