How to download a package from a custom channel? RHN Satellite take care of generating repodata directory structure as primary.xml, but package location are reference to getPackage/full_package.rpm and the RHN Satellite 5.6 downloadFile.do does not handle correctly them if not handled by cobbler.
So, to solve it, I wrote a small program based on RHN Satellite API: rhn_downloadFile.php
<?php
/*
Copyright 2015, Pascal TROUVIN, O4S.FR Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
class RpcClient {
private $_methods;
private $_context;
private $_url;
private $key;
private $debug=0;
function __construct ($url, $user, $passwd) {
if( isset($user) && $user!=NULL ){
$auth = base64_encode(sprintf('%s:%s', $user,$passwd));
$this->_context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => "Content-Type: text/xml\r\n".
"Authorization: Basic $auth" ,
)
));
} else {
$this->_context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => "Content-Type: text/xml\r\n",
)
));
}
$this->_url = $url;
$this->registerMethod ("auth.login");
$this->registerMethod ("auth.logout");
$this->registerMethod ("packages.search.name");
$this->registerMethod ("packages.search.advanced");
$this->registerMethod ("packages.getPackage");
$this->registerMethod ("packages.getPackageUrl");
}
function debug($debug){
$this->debug=$debug;
}
function login($user, $passwd){
$this->key=$this->__call("auth.login",array($user,$passwd));
return $this->key;
}
function logout(){
return $this->__call("auth.logout",array($this->key));
}
function getPackage($name){
header("X-Debug-getPackage: name($name)");
$ls=$this->__call("packages.search.name",array($this->key,$name));
$this->getPackageCore($name,$ls);
}
function getPackageAdvanced($name, $version, $release, $arch){
header("X-Debug-getPackageAdvanced: name($name) version($version) release($release) arch($arch)");
$luceneQuery="name:$name AND version:$version AND release:$release AND arch:$arch";
header("X-Debug-luceneQuery: $luceneQuery");
$ls=$this->__call("packages.search.advanced",array($this->key,$luceneQuery));
$this->getPackageCore($name,$ls);
}
function getPackageCore($name,$ls){
if( $this->debug>0 )
print_r($ls);
else {
# filter strict equality to name
$pkgs=array();
if(count($ls)==1)
$pkgs=$ls;
else
foreach($ls as $p){
if( strpos($p['name'],$name)!==false )
array_push($pkgs, $p);
else
header("X-Package-refused: ".$p['name'],false);
}
if( count($pkgs)>1 ){
# more than one rpm, so list them
header("Content-Type: text/html",true);
echo "<p>List of package named: $name</p>\n<ul>\n";
foreach($pkgs as $p){
echo "<li>(".$p['id'].")".$p['name']."</li>\n";
}
echo "</ul>\n";
} else {
foreach($pkgs as $p){
header("X-GetPackage: (".$p['id'].")".$p['name'],false);
#$this->getPackageId($p['name'], $p['id'], $p['version'], $p['release'], $p['arch']);
$this->getPackageUrl($p['id']);
}
}
}
}
function getPackageUrl($id){
$pkgurl=$this->__call("packages.getPackageUrl",array($this->key,intval($id)));
header("Location: $pkgurl",true);
exit;
}
function __call($methodName, $params) {
if (array_key_exists($methodName,$this->_methods)) {
// on appelle la fonction RPC
#$m = str_replace('_', '.', $methodName);
$m=$methodName;
$r = xmlrpc_encode_request($m, $params,array('verbosity'=>'newlines_only'));
$c = $this->_context;
stream_context_set_option($c,'http','content',$r);
$f = file_get_contents($this->_url,false,$c);
$resp = xmlrpc_decode($f);
return $resp;
} else {
// on appelle la fonction de l'objet
call_user_method_array($methodName, $this,$params);
}
}
function registerMethod ($method) {
$this->_methods[$method] = true;
}
}
$id=isset($_GET['id']) ? $_GET['id'] : '';
$name=isset($_GET['name']) ? $_GET['name'] : '';
if( strlen($name)==0 && strlen($id)==0 ){
echo "Missing parameter 'name' or 'id'\n";
exit;
}
$debug=isset($_GET['debug']) ? $_GET['debug'] : 0;
if($debug>0){
header("X-Debug-Name: $name");
header("X-Debug-Id: $id");
}
$rpc=new RpcClient("http://RHN_SERVER/rpc/api",NULL,NULL);
$rpc->debug($debug);
if( $debug>1 )
print_r($rpc);
$r=$rpc->login("RHN_USERNAME","RHN_PASSWORD");
if( $debug>1 )
print_r($r);
if( strlen($id)!=0 ){
#$rpc->getPackageId((strlen($name)>0 ? $name:'download' ).".rpm",$id);
$rpc->getPackageUrl($id);
} else {
# $name is defined
if( preg_match('/(.*)[.\-]([0-9]+[.\-][0-9]+)[.\-]([0-9]+)[.\-](x86_64|i386|i486|i586|i686|noarch)\.rpm$/', $name, $regs) ){
$rpc->getPackageAdvanced($regs[1], $regs[2], $regs[3], $regs[4]);
} else {
$rpc->getPackage($name);
}
}
$rpc->logout();
?>