X-Git-Url: http://git.pjr.cc/?a=blobdiff_plain;f=plugins%2Frepo.php;h=0f325049229df92c7b70e530a4d715b70c2d1f52;hb=c9cd2c7a60256b5d5d82610424c48706695bad5d;hp=a908f03f13f838dbc5633716e79c8021ae342af0;hpb=a2a5bfaf87f03c6b1de4d63c488eba76d56d4f7b;p=glcas.git diff --git a/plugins/repo.php b/plugins/repo.php index a908f03..0f32504 100644 --- a/plugins/repo.php +++ b/plugins/repo.php @@ -1,6 +1,7 @@ "; + $uconf = unserialize($this->config->getConfigVar("repodata")); + $repostore = $this->config->getConfigVar("storagelocation"); + //print_r($uconf); + //echo ""; + + foreach($uconf as $rkey => $repo) { + echo "Repo $rkey: ".$repo["desc"]."
"; + if(isset($repo["frozen"])) { + error_log("repo froze set"); + $repofrozen = $repo["frozen"]; + } else { + error_log("repo froze not set"); + $repofrozen = false; + } + if(!isset($repo["expiretime"])) { + echo " - Expire time not set, setting to 2 days by default
"; + $uconf[$rkey]["expiretime"] = 2; + $repo["expiretime"] = 2; + $this->config->setConfigVar("repodata", serialize($uconf)); + $this->config->saveConfig(); + } + + if(!isset($repo["repotype"])) { + echo "Repo type not set for repo, setting to yum
"; + $uconf[$rkey]["repotype"] = "YUM"; + $this->config->setConfigVar("repodata", serialize($uconf)); + $this->config->saveConfig(); + } else if($repo["repotype"] == "YUM") { + if($repofrozen) { + error_log("repo frozen"); + echo " - Repo Frozen
"; + } else { + if(file_exists("$repostore/$rkey/repodata/repoupdate.lock")) { + echo " - Repo locked for update
"; + + } + + // we still do this next bit, even if its locked because it may be a stray file + echo " - Expire time is ".$repo["expiretime"]." days, checking repo
"; + error_log("checking $repostore/$rkey/repodata/repomd.xml"); + $tdiff = time() - filemtime("$repostore/$rkey/repodata/repomd.xml"); + $maxtdiff = $repo["expiretime"] * 24 * 3600; + if($tdiff > $maxtdiff) { + echo " - updating repo
"; + $this->updateRepo($rkey); + } else { + echo " - not updating repo
"; + } + } + } else if($repo["repotype"] == "APT") { + if($repofrozen) { + error_log("repo frozen"); + echo " - Repo Frozen
"; + } else { + if(file_exists("$repostore/$rkey/update.lock")) { + echo " - Repo locaked for update
"; + } + echo " - Expire time is ".$repo["expiretime"]." days, checking repo
"; + $maxtdiff = $repo["expiretime"] * 24 * 3600; + // now we check for outdated release files + $dh = opendir("$repostore/$rkey/dists/"); + $needsupdate = false; + while(($fn = readdir($dh))!==false) { + if($fn != "." && $fn != "..") { + if(file_exists("$repostore/$rkey/dists/$fn/Release")) { + $tdiff = time() - filemtime("$repostore/$rkey/dists/$fn/Release"); + if($tdiff > $maxtdiff) $needsupdate = true; + } + } + } + if($needsupdate) { + echo " - Spawn updater
"; + $this->updateRepo($rkey); + } else { + echo " - Up to date
"; + } + } + } + } + } function go($url) { @@ -125,6 +210,7 @@ class GLCASRepo { header("HTTP/1.0 404 Not Found"); return; } + // something was matched, so now we reconstruct the file component of the url @@ -136,7 +222,20 @@ class GLCASRepo { // so, the ultimate url for the file we need is: $actualfile = "$repostore/$matched/$file"; error_log("Atcualfile is $actualfile"); - + + // now check for a block in that repo + if(isset($uconf[$matched]["blocklist"])) { + foreach($uconf[$matched]["blocklist"] as $blockers) { + $rfile = ltrim($file, "/"); + error_log("checking $blockers against $rfile"); + if(preg_match("/$blockers/", $rfile) > 0) { + error_log("should block"); + header("HTTP/1.0 404 Not Found"); + return; + } + } + } + // if its a directory, lets do a print if(is_dir($actualfile)) { $this->printDir($actualfile, $file, $url); @@ -217,7 +316,7 @@ class GLCASRepo { // iterate over its length, send 8k at a time while(!feof($localfile)) { // read and send data - $data = fread($localfile, 8192); + $data = fread($localfile, 32768); echo $data; // flush so the client sees the data @@ -233,7 +332,8 @@ class GLCASRepo { // TODO: this is the function im working on // the alternative to this function is that if a file is in the process of being // downloaded, we simply serve from upstream... not a good idea tho unless we create - // a local proxy right here + // a local proxy right here - this function is a race condition waiting to be had + // lets hope its a good one! function downloadAndServe($filename, $repoid, $remoteurl) { @@ -277,8 +377,34 @@ class GLCASRepo { // or a range (watching and sending) // TODO: it may be advicable to start the download as a seperate cli process rather then something goin on here // so it definitely cant be interrupted. - - + + // check for a 404 file and wait 2 if it exists - i should really check the timestamp for an updated + // file, but thats too much effort for now: TODO: check timestamp on 404 file + $slept = 0; + while(!file_exists("$filename")) { + clearstatcache(); + sleep(1); + $slept += 1; + error_log("Sleeping waiting for file"); + + // if 404 file exists, we wait much less time + if(file_exists("$filename.404") && $slept > 2) { + header("HTTP/1.0 404 Not Found"); + return; + } + if($slept > 10) { + header("HTTP/1.0 404 Not Found"); + return; + } + } + + clearstatcache(); + if(is_dir($filename)) { + + header("Location: ".$_SERVER["REQUEST_URI"]."/"); + return; + } + // first, getting and sending - this is easy. if (!$ranged) { @@ -287,7 +413,8 @@ class GLCASRepo { // this is where the fun starts - but this one isnt too bad. error_log("OTHERDOWNLOAD: im another downloader, please work"); - $fsize = file_get_contents("$filename.size"); + if(file_exists("$filename.size")) $fsize = file_get_contents("$filename.size"); + else $fsize = filesize($filename); header("Content-Length: $fsize"); $sgotten = 0; while(!feof($localfile)) { @@ -461,7 +588,7 @@ class GLCASRepo { error_log("background downloader, start"); global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL; if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) { - $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/downloadfile.php '$url' '$file' > /dev/null 2>&1 &"; + $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/downloadfile.php '$url' '$file' > /tmp/dllog 2>&1 &"; system($scall); } else { error_log("cant find download helper... dieing"); @@ -469,206 +596,7 @@ class GLCASRepo { } // this is a nightmare - function getRepoForUrlOld($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; - - // first we check for /repo/repoid as a url - $startat = 0; - if($xurl[0] == "repo") { - $repid = $xurl[1]; - error_log("trying to get repo for repoid, $repid"); - if(isset($uconf[$repid])) { - $matched = ((int)($repid)); - error_log("set matched, $matched, $repid"); - $startat +=2; - } - } - - - $prematch = false; - if($matched < 0) 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++; - } - } - } - - - if($matched < 0) 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 < 0) { - echo "No such repo
"; - return; - } - - - // 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"; - error_log("Atcualfile is $actualfile"); - //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); - } - } - - $reqhead = print_r($_REQUEST, true); - $sevhead = print_r($_SERVER, true); - error_log("req $reqhead"); - error_log("sev $sevhead"); - - $rangestart = -1; - $rangelength = -1; - $rangesstr = ""; - if(isset($_SERVER["HTTP_RANGE"])) { - // oh shit - $rangesa = explode("=", $_SERVER["HTTP_RANGE"]); - $rangesb = explode(",", $rangesa[1]); - $rangesstr = $rangesb[0]; - $ranges = explode("-", $rangesb[0]); - $rangestart = $ranges[0]; - $rangelength = $ranges[1] - $ranges[0] +1; - error_log("going ranges at $rangestart, $rangelength,".$rangesa[1].",".$rangesb[0]); - } - - // i have to support http_range cause REDHAT/CENTOS IS annoying as all hell. christ, why do this? - if(is_file($actualfile)) { - // file is stored locally, away we go - if($rangelength != -1) { - header("HTTP/1.1 206 Partial Content"); - header("Content-Length: ".$rangelength); - header("Content-Range: bytes $rangesstr/".filesize($actualfile)); - //header("Content-Length: ".filesize($actualfile)); - } else { - header("Content-Length: ".filesize($actualfile)); - } - $type = mime_content_type($actualfile); - header("Content-type: $type"); - $localfile = fopen($actualfile, "r"); - if($rangestart!=-1) fseek($localfile, $rangestart, SEEK_SET); - while(!feof($localfile)) { - // cant make this high cause centos is crap - if($rangelength!=-1) { - $data = fread($localfile, $rangelength); - error_log("data size was ".strlen($data)); - } else { - $data = fread($localfile, 2048); - } - - echo $data; - flush(); - - if($rangelength!=-1) { - fclose($localfile); - exit(0); - } - } - 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 - ignore_user_abort(true); - $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)) { - $clen = $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"); - $localsizefile = fopen($actualfile.".tmp.data.deleteme.size", "w"); - fwrite($localsizefile, "$clen"); - fclose($localsizefile); - 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 ""; - } function printDir($dir, $localfile, $baseurl) { @@ -679,8 +607,31 @@ class GLCASRepo { $content .= "Index of $localfile

Index of $localfile

"; $content .= ""; $dh = opendir($dir); + $dirn = 0; + $filen = 0; while(($file = readdir($dh))!==false) { - if($file != "." && $file != "..") $content .= ""; + if($file != "." && $file != "..") { + if(is_dir("$dir/$file")) { + $dirlist[$dirn++] = "$file"; + } else { + $filelist[$filen++] = "$file"; + } + } + } + if(isset($dirlist)) { + sort($dirlist); + foreach($dirlist as $dirs) { + $icon = "/icons/folder.png"; + $content .= ""; + } + } + if(isset($filelist)) { + sort($filelist); + foreach($filelist as $files) { + $fsize = filesize("$dir/$files"); + $icon = "/icons/text.png"; + $content .= ""; + } } $content .= "
$file
$dirs
$files$fsize
"; @@ -688,6 +639,48 @@ class GLCASRepo { } else return false; } + + function getRepoDetailsApt($url) + { + $action1 = $url."/dists"; + + // we just want to make sure it exists really + error_log("in repo details apt for $url"); + if(!glcas_isRemoteDir($action1)) { + //echo "I cant find any valid APT dists's at $url
"; + return false; + } + + // ok, now scan for ubuntu dists as + $kos = getKnownOSList(); + + $repos = 0; + $existing_repo["isrepo"] = true; + foreach($kos["apt"] as $key => $val) { + //echo "
$key, $val
"; + //echo "now check, $action1/$key"; + if(glcas_isRemoteDir($action1."/$key")) { + $existing_repos["knownrepo"][$repos]["name"] = $key; + //echo "Found Distro $val
"; + if(glcas_fileExists($action1."/$key/Contents-amd64.gz")) $existing_repos["knownrepo"][$repos]["amd64"] = true; + else $existing_repos["knownrepo"][$repos]["amd64"] = false; + if(glcas_fileExists($action1."/$key/Contents-i386.gz")) $existing_repos["knownrepo"][$repos]["i386"] = true; + else $existing_repos["knownrepo"][$repos]["i386"] = false; + $repos++; + + } + } + $existing_repos["nrepos"] = $repos; + + // TODO: these need to be "calculated" + $existing_repos["distros"] = "Ubuntu, Debian"; + $existing_repos["versions"] = "8.04LTS, 9.10, 10.04LTS, 10.10, 11.04, 11.10"; + $existing_repos["arch"] = "x86_64, i386"; + + + return $existing_repos; + + } function getRepoDetailsYum($url, $ismirrorlist=false) { @@ -749,6 +742,36 @@ class GLCASRepo { return $glt; } + function freezeRepo($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) { + if(isset($conf["$rkey"]["frozen"])) { + if($conf["$rkey"]["frozen"]) { + $conf["$rkey"]["frozen"] = false; + error_log("Unfreeze repo"); + } else { + $conf["$rkey"]["frozen"] = true; + error_log("freeze repo"); + } + } else { + $conf["$rkey"]["frozen"] = true; + } + $nconf = serialize($conf); + error_log("freeze repo as $rkey"); + $this->config->setConfigVar("repodata", $nconf); + $this->config->saveConfig(); + } + } + } + } + function deleteRepo($rkey) { $uconf = $this->config->getConfigVar("repodata"); @@ -769,7 +792,7 @@ class GLCASRepo { } } - function addRepo($desc, $os, $version, $arch, $other, $shorturl, $prefix, $repurl, $repotype, $init) + function addRepo($desc, $os, $version, $arch, $other, $shorturl, $prefix, $repurl, $repotype, $init, $expiretime, $blocklist=null) { $uconf = $this->config->getConfigVar("repodata"); @@ -782,6 +805,10 @@ class GLCASRepo { $cs["prefix"] = $prefix; $cs["url"] = $repurl; $cs["repotype"] = $repotype; + $cs["expiretime"] = $expiretime; + if($blocklist != null) { + $cs["blocklist"] = $blocklist; + } $ckey = 0; @@ -812,7 +839,45 @@ class GLCASRepo { function updateRepo($repokey) { // we only do yum yet - $this->updateRepoYum($repokey); + $repod = $this->getRepo($repokey); + if(isset($repod["frozen"])) if($repod["frozen"]) { + error_log("in update repo for frozen repo, ignore update"); + return; + } + + error_log("in update repo"); + + if($repod["repotype"] == "YUM") $this->updateRepoYum($repokey); + if($repod["repotype"] == "APT") $this->updateRepoApt($repokey); + } + + function updateRepoApt($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/dists/")) { + mkdir("$repostore/$repokey/dists/"); + // no point trying to update if we have no dists directory + return; + } + + + error_log("background apt repo update, start"); + global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL; + if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) { + $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/updateaptrepo.php '$repourl' '$repostore/$repokey/' > /tmp/updateaptrepo.$repokey.log 2>&1 &"; + system($scall); + } else { + error_log("cant find download apt helper... dieing"); + } } function updateRepoYum($repokey) @@ -830,29 +895,18 @@ class GLCASRepo { if(!file_exists("$repostore/$repokey/repodata")) { mkdir("$repostore/$repokey/repodata"); } + + error_log("background yum repo update, start"); + global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL; + if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) { + $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/updateyumrepo.php '$repourl' '$repostore/$repokey/' > /tmp/updateyumrepo.$repokey.log 2>&1 &"; + system($scall); + } else { + error_log("cant find download yum helper... dieing"); + } + //ignore_user_abort(true); - $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)