if(isset($_REQUEST["action"])) {
switch($_REQUEST["action"]) {
- case "addrepo":
- GLCASpageBuilder($this,"doAddRepoForm");
+ case "updaterepo":
+ error_log("in updaterepo");
+ GLCASpageBuilder($this,"doUpdateRepo");
+ return;
+ case "reponext":
+ error_log("in reponext");
+ GLCASpageBuilder($this,"doRepoNextForm");
return;
break;
+ case "addrepoyum":
+ GLCASpageBuilder($this,"doAddRepoYum");
+ return;
+ case "deleterepo":
+ error_log("call delete repo");
+ GLCASpageBuilder($this, "doRemoveRepo");
+ return;
+ case "setstorage":
+ error_log("call setstorage");
+ GLCASpageBuilder($this, "setStorage");
+ return;
case "scanrepo":
break;
}
$this->mainBody($url);
}
- function doAddRepoForm($url)
+ function doRemoveRepo($url)
+ {
+ $repo = $_REQUEST["repo"];
+ $myRep = new GLCASRepo($this->config);
+
+
+ error_log("called delete repo on $repo");
+ $myRep->deleteRepo($repo);
+
+ global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
+ header("Location: $BASE_URL/admin/");
+ }
+
+
+ function setStorage($url)
+ {
+
+ }
+
+ function doRepoNextForm($url)
{
$myRep = new GLCASRepo($this->config);
$os = $glt["OS"];
$version = $glt["version"];
$arch = $glt["arch"];
- echo "<form method=\"post\" action=\"repoaddreal\">";
- echo "OS: <input type=\"text\" name=\"OS\" value=\"$os\"><br>";
- echo "Version: <input type=\"text\" name=\"version\" value=\"$version\"><br>";
- echo "Architecture: <input type=\"text\" name=\"Architecture\" value=\"$arch\"><br>";
- echo "Short URL <input type=\"text\" name=\"shorturl\"><br>";
- echo "URL Prefix (blank for none) <input type=\"text\" name=\"shorturl\"><br>";
- echo "<input type=\"submit\" name=\"Add\" value=\"add\"><br>";
+ $other = $glt["other"];
+ $repourl = $_REQUEST["repourl"];
+ echo "<form method=\"post\" action=\"?action=addrepoyum\">";
+ echo "<input type=\"hidden\" name=\"repourl\" value=\"$repourl\">";
+ echo "<table>";
+ echo "<tr><td>Description</td><td><input type=\"text\" name=\"desc\" value=\"$os, $version, $arch - $other\"></td></tr>";
+ echo "<tr><td>OS</td><td><input type=\"text\" name=\"OS\" value=\"$os\"></td></tr>";
+ echo "<tr><td>Version</td><td><input type=\"text\" name=\"version\" value=\"$version\"></td></tr>";
+ echo "<tr><td>Architecture</td><td><input type=\"text\" name=\"arch\" value=\"$arch\"></td></tr>";
+ echo "<tr><td>Other (OS, Updates, etc)</td><td><input type=\"text\" name=\"other\" value=\"$other\"></td></tr>";
+ echo "<tr><td>Short URL</td><td><input type=\"text\" name=\"shorturl\"></td></tr>";
+ echo "<tr><td>URL Prefix (blank for none)</td><td><input type=\"text\" name=\"prefix\"></td></tr>";
+ echo "<tr><td>Do Initial Update (can take a while)</td><td><input type=\"checkbox\" name=\"initial\" checked></td></tr>";
+ echo "<tr><td><input type=\"submit\" name=\"Add\" value=\"Add\"></td></tr>";
+ echo "</table>";
echo "</form>";
} else {
// apt is much tricker cause one repo can provide multiple versions, OS's and architectures.
}
}
+ function doAddRepoYum($url)
+ {
+ $repo = new GLCASRepo($this->config);
+
+ $desc = $_REQUEST["desc"];
+ $OS = $_REQUEST["OS"];
+ $version = $_REQUEST["version"];
+ $arch = $_REQUEST["arch"];
+ $other = $_REQUEST["other"];
+ $shorturl = $_REQUEST["shorturl"];
+ $prefix = $_REQUEST["prefix"];
+ $repurl = $_REQUEST["repourl"];
+ $init = false;
+ if(isset($_REQUEST["initial"])) $init = true;
+
+
+
+ $repo->addRepo($desc, $OS, $version, $arch, $other, $shorturl, $prefix, $repurl, "YUM", $init);
+
+ global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
+ header("Location: $BASE_URL/admin/");
+ }
+
+ function doUpdateRepo($url)
+ {
+ $rkey = $_REQUEST["repo"];
+
+ $repo = new GLCASRepo($this->config);
+
+ $repo->updateRepo($rkey);
+ global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
+ header("Location: $BASE_URL/admin/");
+ }
+
function mainBody($url)
{
// first, list available repos
- echo "<h3>Repositories</h3><br><table>";
- echo "<tr><th>Name</th><th>Type</th><th>Version</th><th>Browse</th><th>Control</th></tr>";
+ echo "<h3>Repositories</h3>";
+ echo "<br><table border=\"1\">";
+ echo "<tr><th>Name</th><th>Type</th><th>OS</th><th>Version</th><th>Architecture</th><th>Other</th><th>Prefix</th><th>Short URL</th><th>Browse</th><th>Control</th></tr>";
+
+ // now iterate thru the repos and print them
+ $repo = new GLCASRepo($this->config);
+ $repos = $repo->getRepos();
+
+ foreach($repos as $rkey => $rval) {
+ $desc = $rval["desc"];
+ $os = $rval["os"];
+ $version = $rval["version"];
+ $arch = $rval["arch"];
+ $other = $rval["other"];
+ $repotype = $rval["repotype"];
+ $prefix = $rval["prefix"];
+ $shorturl = $rval["shorturl"];
+ if($prefix == "") $prefix = "-";
+ if($shorturl == "") $shorturl = "-";
+ echo "<tr><td>$desc</td><td>$repotype</td><td>$os</td><td>$version</td><td>$arch</td><td>$other</td><td>$prefix</td><td>$shorturl</td>";
+
+ // get url
+ echo "<td><a href=\"/asdf/asdf\">Browse</td><td>";
+
+ // Edit
+ echo "<a href=\"?action=editrepo&repo=$rkey\">Edit</a> ";
+ // update
+ echo "<a href=\"?action=updaterepo&repo=$rkey\">Update</a> ";
+ // freeze
+ echo "<a href=\"?action=freezerepo&repo=$rkey\">Freeze</a> ";
+ // deactivate
+ echo "<a href=\"?action=disablerepo&repo=$rkey\">Disable</a> ";
+ // clean
+ echo "<a href=\"?action=cleanrepo&repo=$rkey\">Clean</a> ";
+ // Remove
+ echo "<a href=\"?action=deleterepo&repo=$rkey\">Delete</a>";
+
+ echo "</td>";
+ echo "</tr>";
+ }
+
echo "</table><br><hr>";
+ //echo "<pre>";
+ //if($repos !== false) print_r($repos);
+ //echo "</pre>";
// wrap all this in a table
echo "<table><tr><td valign=\"top\">";
// now, add a repo
echo "<h3>Add A Repo</h3>";
- echo "<form method=\"post\" action=\"?action=addrepo\">";
+ echo "<form method=\"post\" action=\"?action=reponext\">";
echo "Type <select name=\"repotype\">";
echo "<option value=\"yumbase\">YUM (Base URL)</option>";
- echo "<option value=\"yummirrorlist\">YUM (Mirror List)</option>";
- echo "<option value=\"apt\">APT</option>";
+ echo "<option value=\"yummirrorlist\">YUM (Mirror List) - not implemented</option>";
+ echo "<option value=\"apt\">APT - not implemented</option>";
echo "</select><br>";
echo "URL <input type=\"text\" name=\"repourl\"><br>";
echo "<input type=\"submit\" name=\"Add\" value=\"Add\"><br>";
- echo "</form><hr>";
+ echo "</form>";
echo "</td><td valign=\"top\">";
// now scan for a repo
- echo "<h3>Scan For Repos</h3>";
+ echo "<h3>Scan For Repos - not implemented</h3>";
echo "<form method=\"post\" action=\"?action=scanrepo\">";
echo "Hint <select name=\"repohint\">";
echo "<option value=\"fedora\">Fedora</option>";
echo "<input type=\"submit\" name=\"Scan\" value=\"Scan\"><br>";
echo "</form>";
- echo "</td></tr></table>";
+ echo "</td></tr></table><hr>";
+
+ // repo storage location
+ echo "<h3>Storage<h3><br>";
+ echo "<form method=\"post\" action=\"?action=setstorage\">";
+ $storloc = $this->config->getConfigVar("storagelocation");
+ echo "<input type=\"text\" name=\"storageloc\" value=\"$storloc\" size=\"100\">";
+ echo "<input type=\"submit\" name=\"Set\" value=\"Set\">";
+ echo "</form>";
}
private $config;
function __construct($config)
{
$this->config = $config;
+ if($this->config->getConfigVar("storagelocation") == false) {
+ global $WEB_ROOT_FS;
+ $storloc = "$WEB_ROOT_FS/../var/glcas/cache/";
+ if(!file_exists($storloc)) mkdir($storloc);
+ $this->config->setConfigVar("storagelocation", realpath($storloc));
+ $this->config->saveConfig();
+ error_log("set storage location, $storloc");
+ }
}
function go($url)
{
error_log("repo:go called");
- GLCASpageBuilder($this, "body");
+
+ // figure out what we're doing
+ switch($url) {
+ case "list":
+ GLCASpageBuilder($this, "body");
+ break;
+ default:
+ $this->getRepoForUrl($url);
+ }
}
function body($url)
{
- echo "for the repo, i am the repo $url";
+ // this is how this will work
+ //$this->decodeUrl();
+ if(strncasecmp("list", $url, 4)==0) {
+ echo "i am the repo list";
+ return;
+ }
+ echo "i am the repo, $url";
+ }
+
+ function getRepoForUrl($url)
+ {
+ // the way we breakdown a url is to explode it
+ $xurl = split("[/,]", $url);
+
+ // we first check if [0] is a prefix
+ // if now, we check for it being a shorturl (lets just do that for now)
+ $uconf = unserialize($this->config->getConfigVar("repodata"));
+ $repostore = $this->config->getConfigVar("storagelocation");
+
+ $matched = -1;
+ $startat = 0;
+ $prematch = false;
+ foreach($uconf as $key => $var) {
+ $pre = $var["prefix"];
+
+ if($pre!="") {
+ //echo "Checking pre $pre against ".$xurl[0]."\n";
+ if(strcasecmp($pre, $xurl[0])==0) {
+ //echo "Matched pre\n";
+ $prematch = true;
+ $startat++;
+ }
+ }
+ }
+
+
+ foreach($uconf as $key => $var) {
+ // if we matched a pre, then we check against the second url component
+
+ $short = $var["shorturl"];
+
+ if($short!="") {
+ //echo "Checking short $short against ".$xurl[$startat]."\n";
+ if(strcasecmp($xurl[$startat], $short)==0) {
+ //echo "Matched\n";
+ $matched = $key;
+ $startat++;
+ }
+ }
+ }
+
+ if($matched > -1) {
+ //echo "Match on $key\n";
+ }
+
+
+ // now we find an actual file
+ $file = "/";
+ if(count($xurl) > $startat) for($i=$startat; $i < count($xurl); $i++) {
+ $file .= "/".$xurl[$i];
+ }
+
+ // now we want to find repostore/$matched/$file;
+ $actualfile = "$repostore/$matched/$file";
+ //echo "Start file for $actualfile\n";
+
+ // first check any directories in $file are in existence
+ $splfile = explode("/", $file);
+ if(count($splfile) > 1) {
+ $tomake = "$repostore/$matched/";
+ for($i = 0; $i < count($splfile)-1; $i++) {
+ $tomake .= "/".$splfile[$i];
+ //error_log("making directory $tomake");
+ if(!is_dir($tomake)) mkdir($tomake);
+ }
+ }
+
+
+ if(is_file($actualfile)) {
+ // file is stored locally, away we go
+ header("Content-Length: ".filesize($actualfile));
+ $type = mime_content_type($actualfile);
+ header("Content-type: $type");
+ $localfile = fopen($actualfile, "r");
+ while(!feof($localfile)) {
+ $data = fread($localfile, 16384);
+ echo $data;
+ flush();
+ }
+ fclose($localfile);
+ } else if(is_dir($actualfile)) {
+ //echo "in dir for $actualfile\n";
+ // here we print the contents of the directory
+ $this->printDir($actualfile, $file, $url);
+ } else {
+ // ok, get the file
+ //echo "in getcheck\n";
+ $remotefile = $uconf[$matched]["url"]."/$file";
+
+ // TODO: i should get remote contents with fopen/fread/fwrite as
+ // it should be more memory conservative and we can push to the end client
+ // straight away
+ $rf = fopen($remotefile, "r");
+ error_log("attempting to get remote file $remotefile");
+
+
+ // hopefully this works. if we get a 30x message, it means we tried to get a directory
+ // i cant think of another way of dealing with it - but this is UGLY
+ // also get content length and content type
+ $clen = 0;
+ foreach($http_response_header as $key => $val) {
+ if(preg_match("/HTTP.*30[1-9].*/", $val)) {
+ error_log("got a 30x, must be a directory");
+ mkdir($actualfile);
+ header("Location: ".$_SERVER["REQUEST_URI"]."/");
+ return;
+ }
+ // get content length form upstream and print
+ if(preg_match("/^Content-Length:.*/", $val)) {
+ header($val);
+ }
+ // get content type from upstream and print
+ if(preg_match("/^Content-Type:.*/", $val)) {
+ header($val);
+ }
+ }
+ //error_log("repsonse: $http_response_header");
+ if(!$rf) {
+ // return 404
+ header("HTTP/1.0 404 Not Found");
+ } else {
+ $localfile = fopen($actualfile.".tmp.data.deleteme", "w");
+ while(!feof($rf)) {
+ $data = fread($rf, 8192);
+ echo $data;
+ fwrite($localfile, $data);
+ flush();
+ }
+ fclose($localfile);
+ fclose($rf);
+ rename($actualfile.".tmp.data.deleteme", $actualfile);
+ error_log("got actualfile, tried to save as $actualfile, did it work?");
+ }
+ }
+
+ //echo "got ".$file." for $url which is $actualfile\n";
+
+ //echo "</html></pre>";
+ }
+
+ function printDir($dir, $localfile, $baseurl)
+ {
+ $uri = $_SERVER["REQUEST_URI"];
+ if(is_dir($dir)) {
+ echo "<html><head><title>Index of $localfile</title></head><body><h1>Index of $localfile</h1>";
+ echo "<table>";
+ $dh = opendir($dir);
+ while(($file = readdir($dh))!==false) {
+ if($file != "." && $file != "..") echo "<tr><td><a href=\"$uri/$file\">$file</a></td></tr>";
+ }
+ echo "</table></body></html>";
+
+ } else return false;
}
function getRepoDetailsYum($url, $ismirrorlist=false)
if(!$ld) return false;
- $glt["OS"] = "Fedora";
- $glt["version"] = "15";
- $glt["arch"] = "x86_64";
+ // ok, now we tokenize the url and try and guess at the content
+ $spurl = explode("/", $url);
+ // first, find the OS
+ $kos = getKnownOSList();
+ $glt["OS"] = "unknown";
+ $glt["verison"] = "unknown";
+ $glt["arch"] = "unknown";
+ $glt["other"] = "unknown";
+ foreach($spurl as $comp) {
+
+ // find a name
+ foreach($kos["os"]["short"] as $kosname => $koslong) {
+ //error_log("Comparing $kosname and $koslong with $comp");
+ if(strcasecmp($kosname, $comp) == 0) {
+ //error_log("got $kosname, $koslong for $comp in $url");
+ //echo "<pre>inone\n"; print_r($koslong); echo "</pre>";
+ $glt["OS"] = $koslong;
+ }
+ }
+
+ // find a version, we assume its going to be something [numbers] and a . (optional)
+ if(preg_match("/^[0-9.]+$/", $comp)>0) {
+ error_log("version match of $comp");
+ $glt["version"] = $comp;
+ }
+
+ // now architecture, this can be either i?86 or x86_64 - can also be arm or otherwise, but lets just go with this for now
+ foreach($kos["arch"] as $archinter => $archname ) {
+ //error_log("Comparing $archinter, $archname with $comp");
+ if(strcasecmp($archname, $comp) == 0) {
+ error_log("arch match of $archname with $comp");
+ $glt["arch"] = $archname;
+ }
+ }
+
+ // other is a bt harder, we really have to guess at this one
+ if(strcasecmp("os", $comp) == 0) $glt["other"] = "OS";
+ if(strcasecmp("update", $comp) == 0) $glt["other"] = "Updates";
+ if(strcasecmp("updates", $comp) == 0) $glt["other"] = "Updates";
+ if(strcasecmp("everything", $comp) == 0) $glt["other"] = "OS";
+ }
+
+
return $glt;
}
+ function deleteRepo($rkey)
+ {
+ $uconf = $this->config->getConfigVar("repodata");
+ $repostore = $this->config->getConfigVar("storagelocation");
+
+ if($uconf !== false) {
+ $conf = unserialize($uconf);
+ foreach($conf as $key => $vla) {
+ if($key == $rkey) {
+ unset($conf["$rkey"]);
+ $nconf = serialize($conf);
+ system("rm -rf $repostore/$key");
+ error_log("remove repo as $rkey");
+ $this->config->setConfigVar("repodata", $nconf);
+ $this->config->saveConfig();
+ }
+ }
+ }
+ }
+
+ function addRepo($desc, $os, $version, $arch, $other, $shorturl, $prefix, $repurl, $repotype, $init)
+ {
+ $uconf = $this->config->getConfigVar("repodata");
+
+ $cs["desc"] = $desc;
+ $cs["os"] = $os;
+ $cs["version"] = $version;
+ $cs["arch"] = $arch;
+ $cs["other"] = $other;
+ $cs["shorturl"] = $shorturl;
+ $cs["prefix"] = $prefix;
+ $cs["url"] = $repurl;
+ $cs["repotype"] = $repotype;
+
+
+ $ckey = 0;
+ if($uconf !== false) {
+ $conf = unserialize($uconf);
+ foreach($conf as $key => $val) {
+ $ckey = $key;
+ }
+ $ckey++;
+ }
+
+ $conf[$ckey] = $cs;
+
+ $nconf = serialize($conf);
+
+ error_log("add repo as $ckey");
+ $this->config->setConfigVar("repodata", $nconf);
+ $this->config->saveConfig();
+
+ // now create the base structure in the repo
+ $repostore = $this->config->getConfigVar("storagelocation");
+
+
+ // now call update repo
+ if($init) $this->updateRepoYum($ckey);
+ }
+
+ function updateRepo($repokey)
+ {
+ // we only do yum yet
+ $this->updateRepoYum($repokey);
+ }
+
+ function updateRepoYum($repokey)
+ {
+ $repostore = $this->config->getConfigVar("storagelocation");
+
+ $repod = $this->getRepo($repokey);
+
+ $repourl = $repod["url"];
+
+ if(!file_exists("$repostore/$repokey")) {
+ mkdir("$repostore/$repokey");
+ }
+
+ if(!file_exists("$repostore/$repokey/repodata")) {
+ mkdir("$repostore/$repokey/repodata");
+ }
+
+ $actionurl = "$repourl/repodata/repomd.xml";
+ $repomdxml = file_get_contents($actionurl);
+ file_put_contents("$repostore/$repokey/repodata/repomd.xml", $repomdxml);
+
+ $xml = simplexml_load_file("$repostore/$repokey/repodata/repomd.xml");
+
+
+ foreach($xml as $key => $var) {
+ //echo "for key $key has:\n";
+ //print_r($var);
+ if($key == "data") {
+ $fileloc = $var->location["href"];
+ if(!file_exists("$repostore/$repokey/$fileloc")) {
+ error_log("getting $fileloc for $repokey on $repourl");
+ $dlfile = file_get_contents("$repourl/$fileloc");
+ file_put_contents("$repostore/$repokey/$fileloc", $dlfile);
+ } else {
+ error_log("Not getting $fileloc because we already have it");
+ }
+ }
+ }
+ }
+
+ function getRepo($id)
+ {
+ $uconf = $this->config->getConfigVar("repodata");
+ if($uconf !== false) {
+ $lconf = unserialize($uconf);
+ return $lconf[$id];
+ } else return false;
+
+ }
+
+ function getRepos()
+ {
+ $uconf = $this->config->getConfigVar("repodata");
+ if($uconf !== false) {
+ return unserialize($uconf);
+ } else return false;
+
+ }
+
private $config;
}