home *** CD-ROM | disk | FTP | other *** search
- /**
- * 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);
- }
- }
-
- }
-