ACC SHELL
/**
* File: include/autoinstall/io.ycp
* Package: Autoinstallation Configuration System
* Summary: I/O
* Authors: Anas Nashif<nashif@suse.de>
*
* $Id: io.ycp 61227 2010-03-10 12:47:14Z ug $
*/
{
textdomain "autoinst";
import "URL";
import "FTP";
import "Installation";
import "HTTP";
import "StorageDevices";
import "TFTP";
import "AutoinstConfig";
string GET_error = "";
/**
* Basename
* @param string path
* @return string basename
*/
define string basename (string filePath)
``{
list pathComponents = splitstring(filePath, "/");
string ret = pathComponents[size(pathComponents) -1 ]: "";
return ( ret );
}
/**
* Get directory name
* @param string path
* @return string dirname
*/
define string dirname (string filePath)
``{
list pathComponents = splitstring(filePath, "/");
string last = pathComponents[size(pathComponents) -1]:"";
string ret = substring(filePath, 0 , size(filePath) - size(last));
return (ret);
}
/**
* Get control files from different sources
* @return boolean true on success
*/
define boolean Get(string Scheme,
string Host,
string Path,
string Localfile)
``{
GET_error = "";
boolean ok = false;
map res = $[];
map toks = AutoinstConfig::urltok;
toks["scheme"] = Scheme;
toks["host"] = Host;
if (regexpsub(Path, "(.*)//(.*)", "\\1\/\\2")!= nil)
{
Path = regexpsub(Path, "(.*)//(.*)", "\\1\/\\2");
}
toks["path"] = Path;
string full_url = URL::Build(toks);
string tmp_dir = (string)WFM::Read(.local.tmpdir, []);
string mount_point = tmp_dir + "/tmp_mount";
WFM::Execute(.local.mkdir, mount_point );
if ( Scheme == "http" || Scheme == "https" )
{
HTTP::easySSL( true );
res = HTTP::Get(full_url, Localfile);
if (res["code"]:0 == 200)
{
GET_error = "";
return (true);
}
else
{
y2error("Can't find URL: %1", full_url);
// autoyast tried to read a file but had no success.
GET_error = sformat(_("Cannot find URL '%1' via protocol HTTP(S). Server returned code %2."),full_url,res["code"]:0);
return (false);
}
}
if ( Scheme == "ftp" )
{
res = FTP::Get(full_url, Localfile);
if ( ( res["code"]:-1 >= 200 && res["code"]:-1 < 300 ) && SCR::Read(.target.size, Localfile) > 0 )
{
GET_error = "";
return (true);
}
else
{
y2error("Can't find URL: %1", full_url);
// autoyast tried to read a file but had no success.
GET_error = sformat(_("Cannot find URL '%1' via protocol FTP. Server returned code %2."),full_url,res["code"]:0);
return (false);
}
}
else if (Scheme == "file")
{
string file = sformat("%1/%2", Installation::sourcedir, Path); // FIXME: I have doubts this will ever work. Too early.
if (SCR::Read(.target.size, file) > 0 )
{
string cpcmd = sformat("cp %1 %2", file, Localfile);
y2milestone("Copy profile: %1", cpcmd);
SCR::Execute(.target.bash, cpcmd);
}
else
{
GET_error = GET_error + sformat(_("Reading file on %1/%2 failed.\n"), Installation::sourcedir, Path);
string cpcmd = sformat("cp %1 %2", Path , Localfile);
y2milestone("Copy profile: %1", cpcmd);
SCR::Execute(.target.bash, cpcmd);
}
if (SCR::Read(.target.size, Localfile) > 0 )
{
GET_error = "";
ok = true;
} else {
GET_error = GET_error + sformat(_("Reading file on %1 failed.\n"), Path);
y2milestone("Trying to find file on installation media: %1", Installation::boot ());
if (Installation::boot () == "cd") {
string cdrom = (string)SCR::Read (.etc.install_inf.Cdrom);
string cdrom_device = "/dev/"+cdrom;
string already_mounted = "grep "+cdrom_device+" /proc/mounts ;";
map am = (map) SCR::Execute (.target.bash_output, already_mounted);
if (am["exit"]:-1 == 0 && size (am["stdout"]:"") > 0) {
y2warning ("%1 is already mounted, trying to bind mount...", cdrom_device);
string cmd = "mount -v --bind `grep "+cdrom_device+" /proc/mounts |cut -f 2 -d \\ ` "+mount_point+";";
map am1 = (map) SCR::Execute (.target.bash_output, cmd);
if (am1["exit"]:-1 == 0) {
ok=true;
} else {
y2warning ("can't bind mount %1 failing...", cdrom_device);
ok = false;
}
} else {
if (!(boolean)WFM::Execute(.local.mount, [cdrom_device, mount_point, Installation::mountlog] )) {
// autoyast tried to mount the CD but had no success.
GET_error = GET_error + sformat(_("Mounting %1 failed."), cdrom );
y2warning("Mount failed");
ok=false;
} else {
ok=true;
}
}
if (ok) {
string cpcmd = sformat("cp " + mount_point + "/%1 %2", Path , Localfile);
y2milestone("Copy profile: %1", cpcmd);
SCR::Execute(.target.bash, cpcmd);
WFM::Execute(.local.umount, mount_point);
if (SCR::Read(.target.size, Localfile) > 0 ) {
GET_error = "";
return (true);
}
}
}
// autoyast tried to read a file but had no success.
GET_error = GET_error + sformat(_("Reading a file on CD failed. Path: %1/%2."),mount_point,Path);
ok = false;
}
}
else if (Scheme == "nfs") // NFS
{
if (Installation::boot () != "nfs")
{
y2milestone("Starting portmap: %1", SCR::Execute (.target.bash, "/sbin/portmap") );
}
if( !(boolean)SCR::Execute(.target.mount, [ Host + ":" + dirname(Path), mount_point ], "-o nolock" ) &&
!(boolean)SCR::Execute(.target.mount, [ Host + ":" + dirname(Path), mount_point ], "-t nfs4" ) )
{
y2warning("Mount failed");
// autoyast tried to mount a NFS directory which failed
GET_error = sformat(_("Mounting %1 failed."), Host + ":" + dirname(Path) );
return (false);
}
string copyCmd = "/bin/cp " + mount_point + "/" + basename(Path) +
" " + Localfile;
y2milestone("Copy Command: %1", copyCmd);
if (WFM::Execute (.local.bash, copyCmd ) == 0)
{
GET_error = "";
ok = true;
}
else
{
// autoyast tried to copy a file via NFS which failed
GET_error = sformat(_("Remote file %1 cannot be retrieved"), mount_point + "/"+ basename(Path) );
y2error("remote file %1 can't be retrieved", mount_point + "/"
+ basename(Path));
}
WFM::Execute(.local.umount, mount_point);
}
else if (Scheme == "cifs") // CIFS
{
if (!(boolean)SCR::Execute(.target.mount,
[ "//" + Host + dirname(Path), mount_point ], "-t cifs -o guest,ro" ))
{
y2warning("Mount failed");
// autoyast tried to mount a NFS directory which failed
GET_error = sformat(_("Mounting %1 failed."), "//" + Host + dirname(Path) );
return (false);
}
string copyCmd = "/bin/cp " + mount_point + "/" + basename(Path) +
" " + Localfile;
y2milestone("Copy Command: %1", copyCmd);
if (WFM::Execute (.local.bash, copyCmd ) == 0)
{
GET_error = "";
ok = true;
}
else
{
// autoyast tried to copy a file via NFS which failed
GET_error = sformat(_("Remote file %1 cannot be retrieved"), mount_point + "/"+ basename(Path) );
y2error("remote file %1 can't be retrieved", mount_point + "/"
+ basename(Path));
}
WFM::Execute(.local.umount, mount_point);
}
else if (Scheme == "floppy")
{
if (StorageDevices::FloppyReady())
{
WFM::Execute(.local.mount, [StorageDevices::FloppyDevice(), mount_point]);
if (WFM::Execute (.local.bash, "/bin/cp " + mount_point + "/" + Path + " " + Localfile) != 0)
{
y2error("file %1 can't be retrieved", mount_point + "/" + Path );
}
else
{
GET_error = "";
ok = true;
}
SCR::Execute(.target.umount, mount_point);
}
}
else if (Scheme == "device" || Scheme == "usb" ) // Device or USB
{
if ( Path != "")
{
list<string> deviceList = [];
if( Host == "" ) {
list<map> disks = (Scheme == "device") ? (list<map>)SCR::Read(.probe.disk) : (list<map>)SCR::Read(.probe.usb);
foreach( map m, disks, ``{
if( Scheme == "usb" &&
m["bus"]:"USB" != "SCSI" )
continue;
if( haskey( m, "dev_name") ) {
integer i = 0;
string dev = m["dev_name"]:"";
deviceList = add( deviceList, substring( dev, 5 ) ); // not uncommon for USB sticks to have no partition
do {
i = i + 1;
dev = m["dev_name"]:"" + sformat("%1",i);
if( SCR::Read(.target.lstat, dev) != $[] )
deviceList = add( deviceList, substring( dev, 5 ) );
} while( SCR::Read(.target.lstat, dev) != $[] || i < 5 );
}
});
y2milestone("devices to look on: %1", deviceList);
} else {
/*
sometimes we have devices like /dev/cciss/c1d0p5
those "nested" devices will be catched here
as long as we find a directory where we expect a device,
we cut down the Path and enhance the Host (device name)
*/
while( SCR::Read( .target.dir, "/dev/"+Host ) != nil ) {
y2milestone("nested device found");
list<string> l = splitstring( Path, "/" );
Host = Host + "/" + l[0]:"";
l = remove(l,0);
Path = mergestring(l,"/");
y2milestone("Host=%1 Path=%2",Host,Path);
}
// catching nested devices done
deviceList = [ Host ];
}
foreach( string Host, deviceList, ``{
y2milestone("looking for profile on %1", Host);
string mounts = (string)(SCR::Read (.target.string, "/proc/mounts"));
list<string> mount_list = splitstring( mounts, "\n" );
boolean already_mounted = false;
foreach( string m, mount_list, ``{
list<string> entries = splitstring( m, " " );
if( entries[0]:"" == "/dev/"+Host ) {
already_mounted = true;
mount_point = entries[1]:"";
break;
}
});
y2milestone("already mounted=%1 mountpoint=%2",already_mounted,mount_point);
if( ! already_mounted &&
!(boolean)WFM::Execute(.local.mount, [sformat("/dev/%1", Host),
mount_point]) ) {
y2milestone("%1 is not mounted and mount failed", sformat("/dev/%1", Host));
GET_error = sformat(_("%1 is not mounted and mount failed"), sformat("/dev/%1", Host));
continue;
}
if (WFM::Execute (.local.bash, "/bin/cp " + mount_point + "/" + Path + " " + Localfile) != 0 )
{
// autoyast tried to copy a file but that file can't be found
GET_error = sformat(_("File %1 cannot be found"),mount_point + Path);
y2milestone("file %1 can't be found", mount_point + Path);
}
else
{
GET_error = "";
ok = true;
y2milestone("found");
}
if( ! already_mounted )
WFM::Execute(.local.umount, mount_point);
if( ok == true )
break;
});
}
}
else if (Scheme == "tftp") // Device
{
if (TFTP::Get( Host, Path, Localfile ))
{
GET_error = "";
ok = true;
}
else
{
GET_error = sformat(_("Cannot find URL '%1' via protocol TFTP."),Host+":"+Path);
y2error("file %1 can't be found", Path );
}
}
else
{
// the user wanted autoyast to fetch it's profile via an unknown protocol
GET_error = sformat(_("Unknown protocol %1."),Scheme);
y2error("Protocol not supported");
ok = false;
}
return ( ok );
}
/**
* Get a file froma given URL
*/
boolean GetURL(string url, string target)
{
AutoinstConfig::urltok=URL::Parse(url);
map toks = AutoinstConfig::urltok;
return Get(toks["scheme"]:"", toks["host"]:"", toks["path"]:"", target);
}
}
ACC SHELL 2018