home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
AutoinstClone.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
18KB
|
555 lines
/**
* File:
* modules/AutoinstClone.ycp
*
* Package:
* Autoinstallation Configuration System
*
* Summary:
* Create a control file from an exisiting machine
*
* Authors:
* Anas Nashif <nashif@suse.de>
*
* $Id: AutoinstClone.ycp 33482 2006-10-18 08:50:05Z ug $
*
*
*/
{
module "AutoinstClone";
import "Mode";
import "XML";
import "Call";
import "Profile";
import "Y2ModuleConfig";
import "Misc";
import "Storage";
import "AutoinstConfig";
import "StorageDevices";
import "Storage";
import "Partitions";
import "Report";
include "autoinstall/xml.ycp";
global map Profile = $[];
integer bytes_per_unit = 0;
// spceial treatment for base resources
global list<string> base = [];
// aditional configuration resources o be cloned
global list<string> additional = [];
/**
* Constructor
*/
global define void AutoinstClone()
{
Mode::SetMode ("normal");
return;
}
/**
* Set root password
*/
define list root() ``{
list<map> shadow = (list<map>) SCR::Read(.etc.shadow);
map rootacct = (map) filter(map acct, shadow, ``(acct["username"]:"" == "root"))[0]:$[];
list users = [];
map rootacct_mod = $[];
rootacct_mod["user_password"] = rootacct["password"]:"";
rootacct_mod["encrypted"] = true;
rootacct_mod["username"] = "root";
users = add(users, rootacct_mod);
return users;
}
/**
* Find mount points in running system
* @param string device name
* @param map partition
* @param list mount points
* @return string
*/
define string findMountpoint(string device, map p, list<map> mounts)
{
string mountPoint = "";
foreach(map mount , mounts, ``{
string m = sformat("%1%2", device , p["nr"]:nil);
if (mount["spec"]:"" == m )
{
mountPoint = mount["file"]:"";
}
});
return mountPoint;
}
/**
* Convert units to size
* @param list region
* @return integer size
*/
define integer units_to_size (list region)
{
integer units = (integer) region[1]:0;
return (units * bytes_per_unit) - bytes_per_unit + 1;
};
/**
* Create a partition plan for the calling client
* @return list partition plan
*/
global define list Partitioning()
{
Mode::SetMode("normal");
StorageDevices::InitDone();
map<string, map> StorageMap = eval(Storage::GetTargetMap());
StorageMap=filter(string d, map p, StorageMap, ``( d != "/dev/evms" && size(p["partitions"]:[]) > 0));
y2milestone("Storagemap %1", StorageMap);
list evms_vgs = [];
list drives = maplist(string k, map v, StorageMap, ``{
list partitions = [];
list winp = [];
list<integer> usepartitions = [];
foreach(map pe, v["partitions"]:[], ``{
map new_pe = $[];
boolean skipwin = false;
if (haskey(pe,"enc_type")) {
new_pe["enc_type"] = pe["enc_type"]:`twofish;
new_pe["crypt_key"] = "ENTER KEY HERE";
new_pe["loop_fs"] = true;
new_pe["crypt_fs"] = true;
}
if (haskey(pe,"fsid"))
{
integer fsid = pe["fsid"]:131;
list wintypes = union(Partitions::fsid_wintypes, Partitions::fsid_dostypes);
list allwin = union(wintypes, Partitions::fsid_ntfstypes);
if (contains(allwin, fsid) && ! issubstring(pe["mount"]:"", "/boot") )
{
y2debug("Windows partitions found: %1", fsid );
winp = add(winp, pe["nr"]:0);
skipwin = true;
}
if( contains(allwin, fsid) && issubstring(pe["mount"]:"", "/boot") ) {
new_pe["partition_id"] = 259;
} else {
new_pe["partition_id"] = pe["fsid"]:131;
}
// PPC boot (/boot is just an indicator)
if( pe["fsid"]:0 == 65 ) {
//new_pe["mount"] = "/boot";
new_pe["format"] = false;
}
}
if( haskey(pe,"type") && pe["type"]:`x == `primary ) {
new_pe["partition_type"] = "primary"; // can we always copy that element?
}
if (haskey(pe,"region"))
{
// don't clone the exact region.
// I don't see any benefit in cloning that strict.
//new_pe["region"] = pe["region"]:[];
new_pe["size"] = sformat("%1", pe["size_k"]:0*1024);
}
if (haskey(pe,"label")) {
new_pe["label"] = pe["label"]:"";
}
if (haskey(pe,"mountby")) {
new_pe["mountby"] = pe["mountby"]:`nomb;
}
// LVM Group
if (haskey(pe,"used_by_type") && pe["used_by_type"]:`nothing == `UB_LVM)
{
new_pe["lvm_group"] = pe["used_by"]:"";
}
// EVMS Group
if (haskey(pe,"used_by_type") && pe["used_by_type"]:`nothing == `UB_EVMS) {
integer index = findlastof( pe["used_by"]:"", "/" );
new_pe["evms_group"] = substring( pe["used_by"]:"", index+1);
}
// LV
if (pe["type"]:`unknown == `lvm || pe["type"]:`unknown == `evms )
{
new_pe["lv_name"] = pe["name"]:"";
new_pe["size"] = sformat("%1", pe["size_k"]:0*1024);
}
if (haskey(pe,"used_by_type") && pe["used_by_type"]:`nothing == `UB_MD)
{
new_pe["raid_name"] = "/dev/"+pe["used_by"]:"";
}
// Used Filesystem
// Raid devices get the filesystem lying on them as
// detected_fs!
if (haskey(pe,"used_fs") && pe["fsid"]:0 != 253)
{
new_pe["filesystem"] = pe["used_fs"]:`reiser;
new_pe["format"] = pe["format"]:true;
}
if (haskey(pe,"nr") && pe["type"]:`unknown != `lvm)
{
if (!skipwin)
{
y2debug("Adding partition to be used: %1", pe["nr"]:0);
usepartitions = add(usepartitions, pe["nr"]:0);
}
new_pe["partition_nr"] = pe["nr"]:0;
}
if (pe["mount"]:"" != "")
{
new_pe["mount"] = pe["mount"]:"";
}
if (k == "/dev/md")
{
map raid_options = $[];
raid_options["persistent_superblock"] =
pe["persistent_superblock"]:false;
raid_options["raid_type"] = pe["raid_type"]:"raid0";
new_pe["raid_options"] = raid_options;
}
if (!skipwin && new_pe["partition_id"]:0 != 15 ) {
partitions=add(partitions,new_pe);
}
});
map drive = $[];
drive["partitions"] = partitions;
drive["device"] = k;
if( v["type"]:`CT_UNKNOWN==`CT_LVM)
{
drive["pesize"] = sformat("%1M", v["pesize"]:1 / (1024*1024) );
drive["type"] = `CT_LVM;
} else if( v["type"]:`CT_UNKNOWN==`CT_EVMS ) {
drive["pesize"] = sformat("%1M", v["pesize"]:1 / (1024*1024) );
drive["type"] = `CT_EVMS;
integer index = findlastof( drive["device"]:"", "/" );
string vg_name = substring(drive["device"]:"", index);
drive["device"] = "/dev"+vg_name;
evms_vgs = add( evms_vgs, "/dev"+vg_name );
}
if (haskey(v,"lvm2") && v["lvm2"]:false)
{
drive["lvm2"] = true;
}
if (size(partitions) > 0 )
{
if (size(winp) == 0 )
{
drive["use"] = "all";
}
else
{
list<string> up = [];
foreach(integer i, usepartitions, ``{
up = add (up, sformat("%1", i));
});
drive["use"] = mergestring(up, ",");
}
}
return drive;
});
drives = filter( map v, (list<map>)drives, ``{
if( ! (contains( evms_vgs, v["device"]:"") && v["type"]:`x == `CT_LVM ) )
return true;
y2milestone("kicking LVM %1 out of the profile because an EVMS with that name exists",v);
return false;
});
Mode::SetMode("autoinst_config");
return drives;
}
/**
* Return list of software packages of calling client
* @return map map of installed software package
* "patterns" -> list<string> addon selections
* "packages" -> list<string> user selected packages
* "remove-packages" -> list<string> packages to remove
*/
global define map<string, any > Software()
{
boolean ret = Pkg::TargetInit("/", false);
list<string> inst = Pkg::GetPackages(`installed, true);
list<map<string,any> > all_patterns = Pkg::ResolvableProperties ("", `pattern, "");
list<map<string,any> > all_xpatterns = Pkg::ResolvableDependencies ("", `pattern, "");
list<string> patterns = [];
foreach( map<string,any> m, all_patterns, ``{
if( m["status"]:`nothing == `installed )
patterns = add( patterns, m["name"]:"" );
});
Pkg::TargetFinish ();
string tmproot = AutoinstConfig::tmpDir;
SCR::Execute(.target.mkdir, tmproot + "/rootclone");
Pkg::TargetInit( tmproot + "/rootclone", true);
y2debug("SourceStartCache: %1", Pkg::SourceStartCache(false));
Pkg::SourceStartManager(true);
/* FIXME: if this would work, it would be the better solution
foreach(string p, patterns, ``{
Pkg::ResolvableInstall( p, `pattern );
});
Pkg::PkgSolve(false);
*/
list<string> packages = Pkg::FilterPackages(false, false, true, true);
Pkg::TargetFinish ();
// Remove kernel packages
list<string> userpackages = packages;
list<string> removepackages = [];
list<string> patternPackages = [];
foreach( string tmp_pattern, patterns, ``{
list<map<string,any> > xpattern = filter( map<string,any> p, all_xpatterns, ``( p["name"]:"" == tmp_pattern ) );
map<string,any> found = xpattern[0]:$[];
foreach( map<string,any> d, found["dependencies"]:[], ``{
if( d["res_kind"]:"" == "package" && d["dep_kind"]:"" == "requires" )
patternPackages = add(patternPackages, d["name"]:"");
});
});
map<string, any > software = $[];
if( size(patterns) > 0 ) {
foreach(string p, inst, ``{
if (!contains(patternPackages, p))
userpackages = add( userpackages, p );
});
foreach(string p, patternPackages, ``{
if (!contains(inst,p))
removepackages = add( removepackages, p );
});
}
software["packages"] = sort( filter(string pkg, userpackages, ``(! regexpmatch(pkg, "kernel-.*") || pkg == "kernel-uml")) );
software["patterns"] = sort( patterns );
software["remove-packages"] = sort( removepackages );
return software;
}
/**
* Bootloader options
* @return map bootloader options
*/
global define map Bootloader()
{
map bootloader = $[];
boolean readret = (boolean)Call::Function("bootloader_auto", ["Read", $[] ]);
if (readret)
{
bootloader = (map)Call::Function("bootloader_auto", ["Export", $[] ]);
}
return bootloader;
};
/**
* General options
* @return map general options
*/
global define map General()
{
import "Language";
import "Mode";
Mode::SetMode ("normal");
import "Keyboard";
import "Timezone";
map general = $[];
general["language"] = Language::language;
map keyboard = $[];
y2debug("Current Keyboard: %1", Keyboard::default_kbd);
keyboard["keymap"] = Keyboard::current_kbd;
general["keyboard"] = keyboard;
map clock = $[];
clock["timezone"] = Misc::SysconfigRead(.sysconfig.clock.TIMEZONE, Timezone::timezone );
string hwclock = "";
if ( size( Storage::GetWinPrimPartitions( Storage::GetTargetMap() ) ) > 0 )
{
// Win partitions present ==> assume local time.
hwclock = "--localtime";
y2debug("Assuming local time");
}
else
{
// No Win partitions ==> assume UTC.
hwclock = "-u";
y2debug("Assuming UTC");
}
string hwc = Misc::SysconfigRead(.sysconfig.clock.HWCLOCK, hwclock);
if (hwc == "--localtime")
{
clock["hwclock"] = "localtime";
}
else if (hwc == "-u")
{
clock["hwclock"] = "UTC";
}
else
{
clock["hwclock"] = "";
}
general["clock"] = clock;
map mouse = $[];
mouse["id"] = Misc::SysconfigRead(.sysconfig.mouse.YAST_MOUSE, "probe" );
general["mouse"] = mouse;
map mode = $[];
mode["confirm"] = false;
general["mode"] = mode;
Mode::SetMode ("autoinst_config");
return general;
}
/**
* Clone a Resource
* @param string resource
* @param map resource name
* @return list
*/
define boolean CommonClone(string resource, map resourceMap)
{
string data_type = resourceMap["X-SuSE-YaST-AutoInstDataType"]:"map";
string auto = resourceMap["X-SuSE-YaST-AutoInstClient"]:"";
resource = resourceMap["X-SuSE-YaST-AutoInstResource"]:resource;
Call::Function(auto , ["Read"]);
Call::Function(auto , ["SetModified"]);
return true;
}
/**
* Create a list of clonable resources
* @return list list to be used in widgets
*/
global define list createClonableList()
{
list items = [];
foreach(string def_resource, map resourceMap, Y2ModuleConfig::ModuleMap, ``{
y2debug("r: %1 => %2", def_resource, resourceMap["X-SuSE-YaST-AutoInstClonable"]:"false" );
boolean clonable = ( resourceMap["X-SuSE-YaST-AutoInstClonable"]:"false" == "true" );
if (clonable)
{
// Set resource name, if not using default value
string resource = resourceMap["X-SuSE-YaST-AutoInstResource"]:"";
if (resource == "")
resource = def_resource;
string name = resourceMap["Name"]:"";
if (resource != "")
{
items = add(items, `item(`id(resource), name ) );
}
else
{
items = add(items, `item(`id(def_resource), name ) );
}
}
});
return items;
}
/**
* Build the profile
* @return void
*/
global define void Process()
{
y2debug("Additional resources: %1 %2", base, additional);
Profile::Reset();
Profile::prepare = true;
foreach(string def_resource, map resourceMap, Y2ModuleConfig::ModuleMap, ``{
// Set resource name, if not using default value
string resource = resourceMap["X-SuSE-YaST-AutoInstResource"]:"";
if (resource == "")
resource = def_resource;
y2debug("current resource: %1", resource);
if (contains(additional, resource))
{
boolean ret = CommonClone(def_resource, resourceMap);
}
});
Call::Function("storage_auto" , ["Import", Partitioning()]);
Call::Function("storage_auto" , ["SetModified"]);
Call::Function("software_auto" , ["Import", Software()]);
Call::Function("software_auto" , ["SetModified"]);
Call::Function("bootloader_auto" , ["Import", Bootloader()]);
Call::Function("bootloader_auto" , ["SetModified"]);
Call::Function("general_auto" , ["Import", General()]);
Call::Function("general_auto" , ["SetModified"]);
Call::Function("report_auto" , ["Import", Report::Export()]);
Call::Function("report_auto" , ["SetModified"]);
Profile::Prepare();
return;
}
/**
* Write the profile to a defined path
* @param string outputFile Output file path
* @return boolean true on success
*/
global define boolean Write(string outputFile)
{
Process();
boolean ret = Profile::Save( outputFile );
return ret;
}
/**
* Export profile, Used only from within autoyast2
* @return void
*/
global define void Export()
``{
import "Profile";
Profile::Reset();
Process();
return;
}
}