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
/
Profile.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
22KB
|
672 lines
/**
* File: modules/Profile.ycp
* Module: Auto-Installation
* Summary: Profile handling
* Authors: Anas Nashif <nashif@suse.de>
*
* $Id: Profile.ycp 34426 2006-11-16 09:25:17Z ug $
*/
{
module "Profile";
textdomain "autoinst";
import "Stage";
import "Mode";
import "AutoinstConfig";
import "XML";
import "Popup";
import "ProductControl";
import "Directory";
import "PackageSystem";
include "autoinstall/xml.ycp";
// The Complete current Profile
global map<string,any> current = $[];
// defined in Y2ModuleConfig
global map<string, map> ModuleMap = $[];
global string Version = "";
string Description = "";
global boolean changed = false;
global boolean prepare = true;
/**
* Constructor
* @return void
*/
global define void Profile ()
{
//
// setup profile XML parameters for writing
//
profileSetup();
if (Stage::initial ())
{
SCR::Execute(.target.mkdir, AutoinstConfig::profile_dir);
}
return;
}
/**
* Detect Version
* @return string
*/
define string DetectVersion() {
return "";
}
/**
* compatibility to new storage lib in 10.0
*/
define void storageLibCompat() {
list<map> newPart = [];
foreach( map d, current["partitioning"]:[], {
if( haskey(d, "is_lvm_vg") && d["is_lvm_vg"]:false == true ) {
d = remove( d, "is_lvm_vg" );
d["type"] = `CT_LVM;
} else if( haskey(d, "device") && d["device"]:"" == "/dev/md" ) {
d["type"] = `CT_MD;
} else if( haskey(d, "is_evms_vg") && d["is_evms_vg"]:false == true ) {
d["type"] = `CT_EVMS;
} else if( ! haskey(d,"type") ) {
d["type"] = `CT_DISK;
}
// actually, this is not a compatibility hook for the new
// storage lib. It's a hook to be compatibel with the autoyast
// documentation for reusing partitions
//
d["partitions"] = maplist( map p, d["partitions"]:[], ``{
if( haskey(p, "create") && p["create"]:true == false &&
haskey(p, "partition_nr") ) {
p["usepart"] = p["partition_nr"]:0; // useless default
}
if( haskey(p, "partition_id") ) {
// that's a bit strange. There is a naming mixup between
// autoyast and the storage part of yast. Actually filesystem_id
// does not make sense at all but in autoyast it is the
// partition id (maybe that's because yast calls
// the partition id "fsid" internally).
// partition_id in the profile does not work at all, so we copy
// that value to filesystem_id
p["filesystem_id"] = p["partition_id"]:0;
}
return p;
});
newPart = add( newPart, d );
});
y2milestone("partitioning is now %1",newPart);
current["partitioning"] = newPart;
}
/**
* compatibility to new language,keyboard and timezone client in 10.1
*/
global define void generalCompat() {
if( haskey( current, "general" ) ) {
if( haskey( current["general"]:$[], "keyboard" ) ) {
current["keyboard"] = current["general","keyboard"]:$[];
current["general"] = remove( current["general"]:$[], "keyboard" );
}
if( haskey( current["general"]:$[], "language" ) ) {
current["language"] = $[ "language":current["general","language"]:"" ];
current["general"] = remove( current["general"]:$[], "language" );
}
if( haskey( current["general"]:$[], "clock" ) ) {
current["timezone"] = current["general","clock"]:$[];
current["general"] = remove( current["general"]:$[], "clock" );
}
if( haskey( current["software"]:$[], "additional_locales" ) ) {
if( ! haskey(current, "language") ) {
current["language"] = $[];
}
current["language","languages"] = mergestring( current["software","additional_locales"]:[], "," );
current["software"] = remove( current["software"]:$[], "additional_locales" );
}
}
}
/**
* Read Profile properties and Version
* @param map Profile Properties
* @return void
*/
global define void ReadProperties (map properties) {
Version = properties["version"]:"";
Description = properties["description"]:"";
if (Version != "3.0" || Version == "")
{
Version = DetectVersion();
if (Version == "")
{
y2milestone("Can't detect Profile Version");
return;
}
} else {
y2milestone("AutoYaST Profile Version %1 Detected.", Version);
}
return;
}
/**
* Import Profile
* @param map profile
* @return void
*/
global define void Import(map<string, any> profile)
{
y2milestone("importing profile");
current = profile;
ReadProperties(current["properties"]:$[]);
// old style
if (haskey(profile, "configure") || haskey(profile, "install")) {
map _configure = profile["configure"]:$[];
map _install = profile["install"]:$[];
current = remove( current, "configure" );
current = remove( current, "install" );
map tmp = (map<string, any>)union( _configure, _install );
current = (map<string, any>)union( tmp, current );
}
// should not be needed anymore with new libsax
//if (!current["x11", "configure_x11"]:false)
// ProductControl::DisabledModules=add(ProductControl::DisabledModules, "x11");
// raise the network immediately after configuring it
if( haskey(current, "networking") && ! haskey(current["networking"]:$[], "start_immediately") ) {
current["networking","start_immediately"] = true;
y2milestone("start_immediately set to true");
}
storageLibCompat(); // compatibility to new storage library (SL 10.0)
generalCompat(); // compatibility to new language,keyboard and timezone (SL10.1)
y2debug("Current Profile=%1", current );
return;
}
/**
* Prepare Profile for saving and remove empty data structs
* @return void
*/
global define void Prepare()
{
if (!prepare)
return;
Popup::ShowFeedback(_("Collecting configuration data..."),
_("This may take a while"));
list<string> e = [];
foreach(string p, map d, ModuleMap, {
//
// Set resource name, if not using default value
//
string resource = d["X-SuSE-YaST-AutoInstResource"]:"";
if (resource == "")
resource = p;
string tomerge = d["X-SuSE-YaST-AutoInstMerge"]:"";
string module_auto =d["X-SuSE-YaST-AutoInstClient"]:"none";
if ( (boolean) WFM::CallFunction(module_auto, ["GetModified"]))
{
any resource_data = WFM::CallFunction(module_auto, ["Export"]);
integer s = 0;
if ( tomerge == "") {
if ( d["X-SuSE-YaST-AutoInstDataType"]:"map" == "map" )
{
s = size((map)resource_data);
}
else
{
s = size((list)resource_data);
}
}
if ( s != 0 || tomerge != "")
{
if (size(tomerge) > 0 )
{
integer i = 0;
string tomergetypes = d["X-SuSE-YaST-AutoInstMergeTypes"]:"";
list MergeTypes = splitstring(tomergetypes, ",");
foreach( string res, (list<string>)splitstring(tomerge, ",") , ``{
if ( MergeTypes[i]:"map" == "map")
{
map<string,any> rd = (map<string,any>)resource_data;
current[res] = rd[res]:$[];
} else {
map<string,any> rd =(map<string,any>)resource_data;
current[res] = rd[res]:[];
}
i = i + 1;
});
} else {
current[resource] = resource_data;
}
}
else if (s == 0 )
{
e = add ( e, resource);
}
}
});
foreach(string k, any v, current, ``{
if (!haskey(current, k) && !contains(e, k ))
current[k] = v;
});
Popup::ClearFeedback();
prepare = false;
return;
}
/**
* Reset profile to initial status
* @return void
*/
global define void Reset ()
{
y2milestone("Resetting profile contents");
current = $[];
return;
}
/**
* Save YCP data into XML
* @param path to file
* @return boolean true on success
*/
global define boolean Save (string file)
{
Prepare();
y2debug("Saving data (%1) to XML file %2", current, file);
return (XML::YCPToXMLFile(`profile, current, file));
}
/**
* Save the current data into a file to be read after a reboot.
* @param -
* @return true on success
* @see Restore()
*/
global define boolean SaveProfileStructure ( string parsedControlFile)
{
y2milestone("Saving control file in YCP format");
return SCR::Write( .target.ycp, parsedControlFile, current );
}
/**
* Read YCP data as the control file
* @param ycp file
* @return boolean
*/
global define boolean ReadProfileStructure ( string parsedControlFile )
{
current = (map<string,any>) SCR::Read( .target.ycp, [ parsedControlFile, $[]] );
if (current == $[])
return false;
else
Import (current);
return true;
}
/**
* Provide Compatibility to older distributions.
* @param list lvm_standalone Stand alone LVM configuration
* @return list LVM configuration integrated into partitioning resource
*/
global define list<map> convertLVM (list<map> lvm_standalone )
{
list<map> all_lvm = [];
foreach (map group, lvm_standalone, ``{
map new_lvm = $[];
string vg = group["lvm_name"]:"";
new_lvm["device"] = sformat("/dev/%1", vg );
new_lvm["use"] = "all";
new_lvm["pesize"] = group["pesize"]:"";
list partitions = maplist(map lv, group["logical_volumes"]:[], ``{
symbol lv_fs = `reiser;
string lv_fs_tmp = lv["lv_fs"]:"reiser";
term tfs = toterm(lv_fs_tmp);
lv_fs = (symbol)symbolof(tfs);
return( $[ "filesystem": lv_fs,
"lv_name": lv["lv_name"]:"",
"mount": lv["lv_mount"]:"",
"size": lv["lv_size"]:"",
"stripes": lv["stripes"]:1
]);
});
new_lvm["partitions"] = partitions;
all_lvm = add (all_lvm, new_lvm);
});
y2milestone("Converted LVM: %1", all_lvm);
return (all_lvm);
}
/**
* Provide Compatibility to older distributions.
* @param list raid_standalone Stand alone RAID configuration
* @return map RAID configuration integrated into partitioning resource
*/
global define map convertRAID (list<map> raid_standalone )
{
map raid = $[];
raid["device"] = "/dev/md";
raid["use"] = "all";
list partitions = maplist(map r, raid_standalone, ``{
symbol fs = r["filesystem"]:`reiser;
map raid_options = $[];
raid_options["chunk_size"] = r["chunk_size"]:"";
raid_options["raid_type"] = r["raid_type"]:"raid1";
raid_options["parity_algorithm"] = r["parity_algorithm"]:"";
raid_options["persistent_superblock"] = r["persistent_superblock"]:false;
integer nr = tointeger(substring(r["device_name"]:"/dev/md0", 7));
map ret = $[
"raid_options" : raid_options,
"format" : r["format"]:false,
"partition_nr" : nr
];
if (haskey(r, "mount"))
{
ret["mount"] = r["mount"]:"";
}
if (haskey(r, "partition_id"))
{
ret["partition_id"] = r["partition_id"]:131;
}
if (haskey(r, "filesystem"))
{
ret["filesystem"] = fs;
}
if (haskey(r, "lvm_group"))
{
ret["lvm_group"] = r["lvm_group"]:"";
}
return (ret);
});
raid["partitions"] = partitions;
return (raid);
}
/**
* General compatibility issues
* @param current profile
* @return map converted profile
*/
define map<string, any> Compat(map<string, any> _current)
{
// scripts
if ( haskey(_current, "pre-scripts") ||
haskey(_current, "post-scripts") ||
haskey(_current, "chroot-scripts") )
{
list pre = _current["pre-scripts"]:[];
list post = _current["post-scripts"]:[];
list chroot = _current["chroot-scripts"]:[];
map scripts = $[
"pre-scripts":pre,
"post-scripts":post,
"chroot-scripts":chroot
];
_current = remove(_current, "pre-scripts");
_current = remove(_current, "post-scripts");
_current = remove(_current, "chroot-scripts");
_current["scripts"] = scripts;
}
// general
boolean old = false;
map<string, any> general_options
= _current["general"]:$[];
map security = _current["security"]:$[];
map report = _current["report"]:$[];
foreach(string k, any v, general_options , ``{
if (k == "keyboard" && is(v, string))
old = true;
else if (k == "mouse" && is(v, string))
old = true;
else if (k == "encryption_method")
old = true;
else if (k == "timezone" && is(v, string))
old = true;
});
map new_general = $[];
if (old) {
y2milestone("Old format, converting.....");
new_general["language"] = general_options["language"]:"";
map keyboard = $[];
keyboard["keymap"] = general_options["keyboard"]:"";
new_general["keyboard"] = keyboard;
map clock = $[];
clock["timezone"] = general_options["timezone"]:"";
if ( general_options["hwclock"]:"" == "localtime")
{
clock["hwclock"] = "localtime";
}
else if ( general_options["hwclock"]:"" == "GMT")
{
clock["hwclock"] = "GMT";
}
new_general["clock"] = clock;
map mode = $[];
if (haskey(general_options, "reboot")) {
mode["reboot"] = general_options["reboot"]:false;
}
if (haskey(report, "confirm")) {
mode["confirm"] = report["confirm"]:false;
report = remove(report, "confirm");
}
new_general["mode"] = mode;
if (haskey(general_options, "encryption_method"))
{
security["encryption"] = general_options["encryption_method"]:"";
}
map net = _current["networking"]:$[];
list<map<string, string> > ifaces = net["interfaces"]:[];
list newifaces = maplist(map<string, string> iface , ifaces, ``{
map newiface = mapmap(string k, string v, iface, ``{
return ($[tolower(k): v]);
});
return newiface;
});
net["interfaces"] = newifaces;
_current["general"] = new_general;
_current["report"] = report;
_current["security"] = security;
_current["networking"] = net;
}
// RAID
list<map> old_raid = _current["raid"]:[];
if (size(old_raid) > 0 )
{
map new_raid = convertRAID(old_raid);
list d = _current["partitioning"]:[];
d =add (d, new_raid );
_current["partitioning"] = d;
}
// LVM
list<map> old_lvm = _current["lvm"]:[];
if (size(old_lvm) > 0 )
{
list<map> new_lvm = convertLVM(old_lvm);
list<map> d = _current["partitioning"]:[];
d = (list<map>) union (d, new_lvm );
_current["partitioning"] = d;
}
return _current;
}
/**
* Read XML into YCP data
* @param path to file
* @return boolean
*/
global define boolean ReadXML (string file) {
y2debug("Reading %1", file);
current = XML::XMLToYCPFile(file);
if ( current != $[] && size(current) == 0 )
{
// autoyast has read the autoyast configuration file but something went wrong
string message = _("The XML parser reported an error while parsing the autoyast profile. The error message is:\n");
message = message + XML::XMLError();
Popup::Error ( message );
return (false);
}
Import (current);
return (true);
}
define map<string,any> setMValue( list<any> l, any v, map<string,any> m );
define list<any> setLValue( list<any> l, any v, list<any> m );
/*
setMValue together with setLValue are helper functions for
setElementyList
*/
map<string,any> setMValue( list<any> l, any v, map<string,any> m ) {
string i = (string)l[0]:"";
list<any> tmp = remove(l,0);
if( size(tmp) > 0 ) {
if( is( tmp[0]:nil, string ) ) {
m[i] = setMValue( tmp, v, m[i]:$[] );
} else {
y2milestone("I'm in else");
m[i] = setLValue( tmp, v, m[i]:[] );
}
} else {
y2milestone("setting %1 to %2",i,v);
m[i] = v;
}
return m;
}
list<any> setLValue( list<any> l, any v, list<any> m ) {
integer i = (integer)l[0]:0;
list<any> tmp = remove(l,0);
if( is( tmp[0]:nil, string ) ) {
m[i] = setMValue( tmp, v, m[i]:$[] );
} else {
m[i] = setLValue( tmp, v, m[i]:[] );
}
return m;
}
/**
* this function is a replacement for this code:
* list<any> l = [ "key1",0,"key3" ];
* m[ l ] = v;
* @return map
*/
global define map<string,any> setElementByList( list<any> l, any v, map<string,any> m ) {
m = setMValue( l, v, m );
return m;
}
global void checkProfile() {
string file = AutoinstConfig::tmpDir + "/" + "valid.xml";
Save(file);
string summary = "Some schema check failed!\nPlease attach your logfile to bug id 211014\n\n";
boolean valid = false;
list<list> validators = [
[
_("Checking XML with RNG validation..."),
"/usr/bin/xmllint --noout --relaxng "
+ Directory::schemadir + "/autoyast/rng/profile.rng", ""
]
];
if ( ! Stage::cont() && PackageSystem::Installed("jing") ) {
validators = add( validators, [
_("Checking XML with RNC validation..."),
"/usr/bin/jing >&2 -c "
+ Directory::schemadir + "/autoyast/rnc/profile.rnc", "jing_sucks"
] );
}
foreach (list i, validators, {
string header = i[0]:"";
string cmd = i[1]:"" + " " + file;
summary = summary + header + "\n";
map o = (map)SCR::Execute (.target.bash_output, cmd);
y2debug("validation output: %1", o);
summary = summary + cmd + "\n";
summary = summary + o["stderr"]:"" + "\n";
summary = summary + "\n";
if( o["exit"]:1 != 0 || (i[2]:"" == "jing_sucks" && size(o["stderr"]:"") > 0 ) )
valid = false;
});
if( ! valid ) {
Popup::Error(summary);
y2milestone("Profile check failed please attach the log to bug id 211014: %1",summary);
}
}
}