All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit eb8b1b87 authored by Leigh B Stoller's avatar Leigh B 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: $!");
if (system("$GIT cat-file -e ".
"$refspec:profile.py >/dev/null 2>&1") == 0) {
$source = "profile.py";
}
elsif (system("$GIT cat-file -e ".
" $refspec:profile.rspec >/dev/null 2>&1") == 0) {
$source = "profile.rspec";
foreach my $maybe (@locations) {
if (system("$GIT cat-file -e ".
"$refspec:${maybe}.py >/dev/null 2>&1") == 0) {
$source = "${maybe}.py";
}
elsif (system("$GIT cat-file -e ".
" $refspec:${maybe}.rspec >/dev/null 2>&1") == 0) {
$source = "${maybe}.rspec";
}
last
if ($source);
}
else {
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");
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
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");
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
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