Author: lslezak Date: Mon Aug 11 12:02:47 2008 New Revision: 49917 URL: http://svn.opensuse.org/viewcvs/yast?rev=49917&view=rev Log: - added cross-architecture support (e.g. create a PPC installation iso image on an i386 machine, but does not work in the kiwi part) (fate#301883) - 2.17.6 - note: merged from tmp/lslezak/product-creator-cross-arch SVN branch Modified: trunk/product-creator/VERSION trunk/product-creator/package/yast2-product-creator.changes trunk/product-creator/src/ProductCreator.ycp trunk/product-creator/src/complex.ycp trunk/product-creator/src/dialogs.ycp trunk/product-creator/src/helps.ycp trunk/product-creator/src/wizards.ycp Modified: trunk/product-creator/VERSION URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/VERSION?rev=49917... ============================================================================== --- trunk/product-creator/VERSION (original) +++ trunk/product-creator/VERSION Mon Aug 11 12:02:47 2008 @@ -1 +1 @@ -2.17.5 +2.17.6 Modified: trunk/product-creator/package/yast2-product-creator.changes URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/package/yast2-pro... ============================================================================== --- trunk/product-creator/package/yast2-product-creator.changes (original) +++ trunk/product-creator/package/yast2-product-creator.changes Mon Aug 11 12:02:47 2008 @@ -1,4 +1,12 @@ ------------------------------------------------------------------- +Mon Aug 11 11:57:43 CEST 2008 - lslezak@suse.cz + +- added cross-architecture support (e.g. create a PPC installation + iso image on an i386 machine, but does not work in the kiwi part) + (fate#301883) +- 2.17.6 + +------------------------------------------------------------------- Fri Aug 1 15:36:32 CEST 2008 - jsuchome@suse.cz - Image Creator: added GUI to configure image compression Modified: trunk/product-creator/src/ProductCreator.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/src/ProductCreato... ============================================================================== --- trunk/product-creator/src/ProductCreator.ycp (original) +++ trunk/product-creator/src/ProductCreator.ycp Mon Aug 11 12:02:47 2008 @@ -26,6 +26,7 @@ import "Directory"; import "Profile"; import "AutoinstSoftware"; +// NOTE: do not use Arch:: directly in this module, use GetArch() function instead! import "Arch"; import "Package"; import "PackageAI"; @@ -93,6 +94,109 @@ */ global block<boolean> AbortFunction = nil; + +/* + Target architecture + Initialized to the current architecture +*/ + +// forward declaration +string ToPackageArch(string arch); + +// default is the system architecture +string _arch = nil; + +string ToPackageArch(string arch) +{ + if (arch == "s390_64") + { + arch = "s390x"; + } + if (arch == "s390_32") + { + arch = "s390"; + } + + if (!contains(["i386", "i486", "i586", "i686", "sparc", "sparc64", "mips", "mips64", "ppc", "ppc64", "alpha", "s390", "s390x", "ia64", "x86_64"], arch)) + { + y2error("Unknown architecture '%1'!", arch); + return nil; + } + + return arch; +} + +/** + Set the target package architecture + @param new_arch new architecture (i386, i486, i586, i686, sparc, sparc64, mips, mips64, ppc, ppc64, alpha, s390, s390x, ia64, x86_64) + @return true on success +*/ +global boolean SetPackageArch(string new_arch) +{ + string pkgarch = ToPackageArch(new_arch); + + if (pkgarch == nil) + { + return false; + } + + _arch = pkgarch; + y2milestone("Target architecture set to '%1'", new_arch); + + // set the architecture in the package manager + Pkg::SetArchitecture(_arch); + + return true; +} + +// convert package (like i686) arch to system arch (i386) +global string GetArch() +{ + string ret = _arch; + + // not set, use the current arch + if (ret == nil) + { + ret = Arch::architecture(); + } + + // convert x86 package archs to i386 system arch + if (contains(["i486", "i586", "i686"], ret)) + { + ret = "i386"; + } + else if (ret == "s390_64") + { + ret = "s390x"; + } + else if (ret == "s390_32") + { + ret = "s390"; + } + + return ret; +} + +// nil means not set +global string GetPackageArch() +{ + return _arch; +} + +global void ResetArch() +{ + _arch = nil; + + if (Pkg::GetArchitecture() != Pkg::SystemArchitecture()) + { + // set the system architecture in the package manager + y2milestone("Resetting the target architecture to '%1'", Pkg::SystemArchitecture()); + Pkg::SetArchitecture(Pkg::SystemArchitecture()); + } +} + + + /** * Data was modified? */ @@ -178,7 +282,7 @@ global boolean isCode10Source() { boolean code10 = false; - string arch = Arch::architecture (); + string arch = GetArch(); if (arch == "s390_64") arch = "s390x"; foreach (string url , ProductCreator::Config["sources"]:[], { @@ -619,7 +723,7 @@ } else { - string arch = Arch::architecture(); + string arch = GetArch(); if (arch == "s390_64") arch = "s390x"; bootconfig_path = sformat("boot/%1/loader/isolinux.cfg", arch); @@ -961,84 +1065,66 @@ boolean CopyPPCBoot(integer srcid, string target) { y2milestone("Copying PPC boot files"); + boolean ret = true; - list<string> lst = GetList(srcid, 1, ""); - if (lst == nil) + y2milestone("Copying /ppc subdirectory"); + boolean r = CopyDirectoryRecOpt(srcid, 1, "/ppc", target); + + if (!r) { - lst = []; + y2milestone("Directory listing may be missing, copying /ppc/bootinfo.txt"); + CopyFile(srcid, 1, "/ppc/bootinfo.txt", target + "/ppc"); } - boolean ret = true; + ret = ret && r; - if (contains(lst, "ppc/")) - { - y2milestone("Copying /ppc subdirectory"); - boolean r = CopyDirectoryRecOpt(srcid, 1, "/ppc", target); - if (!r) - { - y2milestone("Directory listing may be missing, copying /ppc/bootinfo.txt"); - CopyFile(srcid, 1, "/ppc/bootinfo.txt", target + "/ppc"); - } + y2milestone("Copying /PS3 subdirectory"); + r = CopyDirectoryRecOpt(srcid, 1, "/PS3", target); - ret = ret && r; + if (!r) + { + y2milestone("Directory listing may be missing, copying /ppc/bootinfo.txt"); + Exec(sformat("/bin/mkdir -p '%1/PS3/otheros'", String::Quote(target))); + CopyFile(srcid, 1, "/PS3/otheros/otheros.bld", target + "/PS3/otheros"); } - if (contains(lst, "PS3/")) - { - y2milestone("Copying /ppc subdirectory"); - boolean r = CopyDirectoryRecOpt(srcid, 1, "/PS3", target); + ret = ret && r; - if (!r) - { - y2milestone("Directory listing may be missing, copying /ppc/bootinfo.txt"); - Exec(sformat("/bin/mkdir -p '%1/PS3/otheros'", String::Quote(target))); - CopyFile(srcid, 1, "/PS3/otheros/otheros.bld", target + "/PS3/otheros"); - } - ret = ret && r; - } + y2milestone("Copying /suseboot subdirectory"); + r = CopyDirectoryRecOpt(srcid, 1, "/suseboot", target); + y2milestone("Result: %1", r); - if (contains(lst, "suseboot/")) + if (!r) { - y2milestone("Copying /suseboot subdirectory"); - boolean r = CopyDirectoryRecOpt(srcid, 1, "/suseboot", target); - y2milestone("Result: %1", r); - - if (!r) - { - list<string> files = [ - "/suseboot/inst32", "/suseboot/inst64", "/suseboot/os-chooser", - "/suseboot/yaboot", "/suseboot/yaboot.cnf", "/suseboot/yaboot.ibm", - "/suseboot/yaboot.txt" - ]; - - y2milestone("Directory listing may be missing using fixed list: %1", files); + list<string> files = [ + "/suseboot/inst32", "/suseboot/inst64", "/suseboot/os-chooser", + "/suseboot/yaboot", "/suseboot/yaboot.cnf", "/suseboot/yaboot.ibm", + "/suseboot/yaboot.txt" + ]; - foreach(string f, files, - { - CopyFile(srcid, 1, f, target + f); - } - ); - } + y2milestone("Directory listing may be missing using fixed list: %1", files); - ret = ret && r; + foreach(string f, files, + { + CopyFile(srcid, 1, f, target + f); + } + ); } - if (contains(lst, "etc/")) - { - y2milestone("Copying /etc subdirectory"); - boolean r = CopyDirectoryRecOpt(srcid, 1, "/etc", target); - if (!r) - { - y2milestone("Directory listing may be missing, copying /etc/yaboot.conf"); - CopyFile(srcid, 1, "/etc/yaboot.conf", target + "/etc"); - } + y2milestone("Copying /etc subdirectory"); + r = CopyDirectoryRecOpt(srcid, 1, "/etc", target); - ret = ret && r; + if (!r) + { + y2milestone("Directory listing may be missing, copying /etc/yaboot.conf"); + CopyOptionalFile(srcid, 1, "/etc/yaboot.conf", target + "/etc"); } + ret = ret && r; + return ret; } @@ -1356,7 +1442,7 @@ string sles_path = ""; integer sles_src = 0; string descr_dir = ""; - string arch = Arch::architecture(); + string arch = GetArch(); if (arch == "s390_64") arch = "s390x"; y2milestone("Config: %1", Config); @@ -1390,7 +1476,7 @@ if (bootable_product) { - if (Arch::i386() || Arch::x86_64()) + if (_arch == "i386" || _arch == "x86_64") { if (Config["code10"]:false) { @@ -1401,7 +1487,7 @@ Exec(sformat("/bin/mkdir -p '%1/boot/loader'", String::Quote(skel_root))); } } - else if (Arch::ppc() || Arch::ppc64()) + else if (_arch == "ppc" || _arch == "ppc64") { Exec(sformat("/bin/mkdir -p '%1/PS3'", String::Quote(skel_root))); Exec(sformat("/bin/mkdir -p '%1/ppc'", String::Quote(skel_root))); @@ -1473,7 +1559,7 @@ CopyFile(id, 1, "boot/rescue", sformat("%1/boot", skel_root)); } // Loader, x86 specific - if (Arch::i386() || Arch::x86_64()) + if (_arch == "i386" || _arch == "x86_64") { if (Config["code10"]:false) { @@ -1489,7 +1575,7 @@ CopyDirectoryRec(id, 1, "boot/loader", sformat("%1/boot", skel_root)); } } - else if (Arch::ppc() || Arch::ppc64()) + else if (_arch == "ppc" || _arch == "ppc64") { // recursive copy of /boot CopyDirectoryRec(id, 1, "boot", skel_root); @@ -1503,7 +1589,7 @@ { CopyDirectoryRec(id, 1, "boot", skel_root); - if (Arch::ppc() || Arch::ppc64()) + if (_arch == "ppc" || _arch == "ppc64") { CopyPPCBoot(id, skel_root); } @@ -1643,7 +1729,7 @@ } // Loader, x86 specific - if (Arch::i386() || Arch::x86_64()) + if (_arch == "i386" || _arch == "x86_64") { if (Config["code10"]:false) { @@ -1659,7 +1745,7 @@ CopyDirectoryRec(base_source, 1, "boot/loader", sformat("%1/boot", skel_root)); } } - else if (Arch::ppc() || Arch::ppc64()) + else if (_arch == "ppc" || _arch == "ppc64") { CopyPPCBoot(base_source, skel_root); @@ -1676,7 +1762,7 @@ { CopyDirectoryRec(base_source, 1, "boot", skel_root); - if (Arch::ppc() || Arch::ppc64()) + if (_arch == "ppc" || _arch == "ppc64") { CopyPPCBoot(base_source, skel_root); } @@ -2268,7 +2354,7 @@ global define boolean CopyMiscFiles() ``{ string cpCmd = ""; - string arch = Arch::architecture(); + string arch = GetArch(); if (arch == "s390_64") arch = "s390x"; y2debug("isolinux.cfg: %1", Config["bootconfig"]:"" ); if (Config["bootconfig"]:"" != "") Modified: trunk/product-creator/src/complex.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/src/complex.ycp?r... ============================================================================== --- trunk/product-creator/src/complex.ycp (original) +++ trunk/product-creator/src/complex.ycp Mon Aug 11 12:02:47 2008 @@ -11,7 +11,6 @@ textdomain "product-creator"; - import "Arch"; import "CommandLine"; import "Directory"; import "FileUtils"; @@ -61,6 +60,27 @@ boolean first_start = true; + // check if the selected configuration has the same target architecture as the machine architecture + // needed for creating kiwi images because kiwi cannot create cross-architecture images + boolean SameArchitecture() + { + string arch = ProductCreator::Config["arch"]:""; + string sysarch = Arch::architecture(); + + // is the target architecture different than the machine architecture? + if (arch != nil && arch != "" && arch != sysarch) + { + // error message: %1 and %2 are architecture names like i386, x86_64, ppc... + Report::Error(sformat(_("Target architecture of the current configuration (%1) +does not match the system architecture (%2). + +Kiwi cannot create images for different architectures."), arch, sysarch)); + return false; + } + + return true; + } + /** * Overview dialog * @return dialog result @@ -122,6 +142,8 @@ any ret = nil; while(true) { + // reset the current architecture (needed when going back) + ProductCreator::ResetArch(); ret = UI::UserInput(); @@ -174,6 +196,8 @@ Package::InstallAll (["kiwi", "kiwi-desc-isoboot"])) { string current = (string) UI::QueryWidget(`id(`table), `CurrentItem); ProductCreator::Config = ProductCreator::Configs[current]:$[]; + // check the architecture + if (!SameArchitecture()) continue; Kiwi::kiwi_task = "iso"; ret = `kiwi; break; @@ -182,6 +206,8 @@ Package::InstallAll (["kiwi", "kiwi-desc-xenboot"])) { string current = (string) UI::QueryWidget(`id(`table), `CurrentItem); ProductCreator::Config = ProductCreator::Configs[current]:$[]; + // check the architecture + if (!SameArchitecture()) continue; Kiwi::kiwi_task = "xen"; ret = `kiwi; break; @@ -190,6 +216,8 @@ Package::InstallAll (["kiwi", "kiwi-desc-usbboot"])) { string current = (string) UI::QueryWidget(`id(`table), `CurrentItem); ProductCreator::Config = ProductCreator::Configs[current]:$[]; + // check the architecture + if (!SameArchitecture()) continue; Kiwi::kiwi_task = "usb"; ret = `kiwi; break; @@ -198,6 +226,8 @@ Package::InstallAll (["kiwi", "kiwi-desc-vmxboot"])) { string current = (string) UI::QueryWidget(`id(`table), `CurrentItem); ProductCreator::Config = ProductCreator::Configs[current]:$[]; + // check the architecture + if (!SameArchitecture()) continue; Kiwi::kiwi_task = "vmx"; ret = `kiwi; break; @@ -209,6 +239,10 @@ y2error("unexpected retcode: %1", ret); continue; } + + if (ret == `kiwi) + { + } } return (symbol)ret; @@ -303,7 +337,7 @@ y2debug("bootconfig available"); string fname = (ProductCreator::Config["code10"]:false) - ? sformat("%1/boot/%2/loader/isolinux.cfg", ProductCreator::skel_root, Arch::architecture()) + ? sformat("%1/boot/%2/loader/isolinux.cfg", ProductCreator::skel_root, ProductCreator::GetArch()) : sformat("%1/boot/loader/isolinux.cfg", ProductCreator::skel_root); SCR::Write(.target.string, fname, ProductCreator::Config["bootconfig"]:"" ); @@ -369,7 +403,7 @@ { Popup::ShowFeedback(_("Creating CD Image..."), _("This may take a while")); } - string arch = Arch::architecture (); + string arch = ProductCreator::GetArch(); if (arch == "s390_64") arch = "s390x"; string command = sformat("/usr/lib/YaST2/bin/y2mkiso '%1' '%2' '%3'", String::Quote(isodir), String::Quote(isofile), String::Quote((ProductCreator::Config["code10"]:false) ? arch : "")); @@ -481,6 +515,12 @@ boolean success = true; + string arch = ProductCreator::Config["arch"]:""; + if (arch != nil && arch != "") + { + ProductCreator::SetPackageArch(arch); + } + Progress::NextStage(); Pkg::TargetFinish (); @@ -552,7 +592,7 @@ // skip isolinux configuration if the architecture // is not i386 or x86_64 - there is no isolinux - if (Arch::architecture() != "i386" && Arch::architecture() != "x86_64") + if (ProductCreator::GetArch() != "i386" && ProductCreator::GetArch() != "x86_64") { return `skip_isolinux; } Modified: trunk/product-creator/src/dialogs.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/src/dialogs.ycp?r... ============================================================================== --- trunk/product-creator/src/dialogs.ycp (original) +++ trunk/product-creator/src/dialogs.ycp Mon Aug 11 12:02:47 2008 @@ -16,7 +16,6 @@ import "SourceManager"; import "Report"; import "URL"; - import "Arch"; import "Label"; import "Popup"; import "URL"; @@ -25,6 +24,7 @@ import "CWM"; import "String"; import "Package"; + import "Arch"; include "product-creator/routines.ycp"; include "product-creator/helps.ycp"; @@ -198,6 +198,13 @@ } else if(ret == `next ) { + // set architecture if configured + string arch = ProductCreator::Config["arch"]:""; + if (arch != nil && arch != "") + { + ProductCreator::SetPackageArch(arch); + } + string name = (string)UI::QueryWidget(`id(`name), `Value); if (name == "") @@ -419,6 +426,170 @@ return (symbol)ret; } +string AskArch(string label, list<string> archs, string preselected) +{ + term widget1 = `VBox(); + term widget2 = `VBox(); + + const integer max_lines = 6; + + if (!contains(archs, preselected)) + { + y2warning("The preselected architecture is missing in the list!"); + // add the missing preselected arch + archs = prepend(archs, preselected); + } + + integer archsz = size(archs); + integer col1num = (archsz > max_lines) ? (archsz + 1) / 2 : archsz; + y2milestone("Number of archs in the first column: %1", col1num); + + // preselect the first item + foreach(string a, archs, + { + if (col1num > 0) + { + widget1 = add(widget1, `MinWidth(10, `Left(`RadioButton(`id(a), a, a == preselected)))); + } + else + { + widget2 = add(widget2, `MinWidth(10, `Left(`RadioButton(`id(a), a, a == preselected)))); + } + + col1num = col1num - 1; + } + ); + + term content = `MarginBox(1, 0.5, + `VBox( + `Label(label), + `VSpacing(1), + `Frame(_("Target Architecture"), + `RadioButtonGroup(`id(`rb), + `HBox( + `Top(widget1), + `HStretch(), + `Top(widget2), + `HStretch() + ) + ) + ), + `VSpacing(1), + `HBox( + `HSpacing(`opt(`hstretch), 2), + `HWeight(1, `PushButton(`id(`ok), Label::OKButton())), + `HSpacing(2), + `HWeight(1, `PushButton(`id(`cancel), Label::CancelButton())), + `HSpacing(`opt(`hstretch), 2) + ) + ) + ); + + UI::OpenDialog(content); + + any ui = UI::UserInput(); + string ret = (string)UI::QueryWidget(`id(`rb), `CurrentButton); + + UI::CloseDialog(); + + if (ui == `cancel || ui == `close) + { + // canceled + return nil; + } + else if (ui == `ok) + { + y2milestone("Selected architecture: %1", ret); + return ret; + } + else + { + y2error("Unhandled user input %1", ui); + return nil; + } +} + + +boolean CheckArchitecture(integer SrcID) +{ + map general_info = Pkg::SourceGeneralData(SrcID); + boolean found_architecture = false; + list<string> found_archs = []; + + string arch = ProductCreator::GetArch(); + if (arch == "s390_64") arch = "s390x"; + + // architecture check is possible only for YaST sources + if (general_info["type"]:"" == "YaST") + { + // Check architecture + map<string,string> read_content = ProductCreator::ReadContentFile(SrcID); + y2milestone("content file: %1", read_content); + + foreach(string key, string value, read_content, + { + if (key == "ARCH." + arch) + { + found_architecture = true; + break; + } + else + { + string found_arch = regexpsub(key, "ARCH\.(.*)", "\1"); + + if (found_arch != nil) + { + found_archs = add(found_archs, found_arch); + } + } + } + ); + } + else + { + y2milestone("Not a YaST source, cannot verify the architecture"); + found_architecture = true; + } + + y2milestone("Architecture %1 is supported: %2", arch, found_architecture); + + if (found_architecture) + { + return true; + } + else + { + y2milestone("Supported architectures: %1", found_archs); + + if (size(found_archs) == 0) + { + y2milestone("The repository does not provide architecture data, assuming it is compatible"); + return true; + } + + // the architecture is different, ask to switch it + // %1 is URL of the repository + // %2 is name of the architecture (like i386, x86_64, ppc...) + string new_arch = AskArch( + sformat(_("Source %1 +does not support the current target architecture (%2). +Change the target architecture? +"), general_info["url"]:"", ProductCreator::GetArch()), + found_archs, found_archs[0]:""); + + // nil == switch has been canceled + if (new_arch != nil) + { + // change the architecture + ProductCreator::SetPackageArch(new_arch); + return true; + } + } + + return false; +} + + /** * Dialog for selecting the sources * @return symbol @@ -440,12 +611,22 @@ term buttons = - `HBox( - `PushButton(`id(`select), Label::SelectButton() ), - `PushButton(`id(`remove), Label::RemoveButton() ), - // push button label - `PushButton(`id(`create), _("Cr&eate New...")) - ); + `VBox( + `HBox( + `ReplacePoint(`id(`rp), + `Label(sformat(_("Target architecture: %1"), ProductCreator::GetArch())) + ), + `HSpacing(2), + `PushButton(`id(`arch), Label::EditButton()) + ), + `VSpacing(0.3), + `HBox( + `PushButton(`id(`select), Label::SelectButton() ), + `PushButton(`id(`remove), Label::RemoveButton() ), + // push button label + `PushButton(`id(`create), _("Cr&eate New...")) + ) + ); term contents = @@ -489,43 +670,17 @@ else if (ret == `select) { integer SrcID = (integer)UI::QueryWidget(`id(`table), `CurrentItem); - map general_info = Pkg::SourceGeneralData(SrcID); - boolean found_architecture = false; - string arch = Arch::architecture (); - if (arch == "s390_64") arch = "s390x"; + boolean repo_ok = CheckArchitecture(SrcID); - // architecture check is possible only for YaST sources - if (general_info["type"]:"" == "YaST") - { - // Check architecture - map<string,string> read_content = ProductCreator::ReadContentFile(SrcID); - y2milestone("content file: %1", read_content); - - foreach(string key, string value, read_content, - { - if (key == "ARCH." + arch) - { - found_architecture = true; - break; - } - } - ); - } - else - { - y2milestone("Not a YaST source, cannot verify the architecture"); - found_architecture = true; - } - - y2milestone("Architecture %1 is supported: %2", arch, found_architecture); - - if (found_architecture) + if (repo_ok) { if (!contains(selected_items, SrcID)) { selected_items = add (selected_items, SrcID ); + map general_info = Pkg::SourceGeneralData(SrcID); + // enable the source if (general_info["enabled"]:false) { @@ -534,12 +689,14 @@ } UI::ChangeWidget(`id(`table), `Item(SrcID, 0) , _("X")); - } - else - { - Report::Error(sformat(_("The source does not support the architecture of this machine (%1). -Select another source. -"), arch)); + + // refresh the target architecture if it has been changed + if (ProductCreator::GetPackageArch() != nil) + { + UI::ReplaceWidget(`rp, + `Label(sformat(_("Target Architecture: %1"), ProductCreator::GetPackageArch())) + ); + } } } else if (ret == `remove) @@ -597,6 +754,68 @@ continue; } + string arch = ProductCreator::GetPackageArch() ; + + if (arch != nil) + { + y2milestone("Target architecture has been changed"); + ProductCreator::Config["arch"] = arch; + + boolean check_ok = true; + boolean arch_changed = false; + + do + { + string ar = ProductCreator::GetPackageArch(); + check_ok = true; + arch_changed = false; + + // all selected sources should be refreshed + // check archs onece again (needed after switching architecture multiple times) + foreach(integer src, selected_items, + { + if (!CheckArchitecture(src)) + { + check_ok = false; + break; + } + + arch_changed = arch_changed || (ar != ProductCreator::GetPackageArch()); + } + ); + } + while(arch_changed); + + if (!check_ok) + { + // error message + Report::Error(_("There is a mismatch between the selected +repositories and the machine architecture. + +Either select another repositories or +change the target architecture.")); + + // don't leave the dialog + continue; + } + + // temporarily initialize the target, read trusted GPG keys (needed for refresh) + Pkg::TargetInit("/", false); + + foreach(integer src, selected_items, + { + Pkg::SourceForceRefreshNow(src); + } + ); + + // reload repositories + Pkg::SourceFinishAll(); + Pkg::SourceStartManager(false); + + // finish the target + Pkg::TargetFinish(); + } + going_back = false; break; @@ -604,6 +823,34 @@ else if( ret == `back) { break; } + else if (ret == `arch) + { + // ask for the target architecture + string pkg_arch = ProductCreator::GetPackageArch(); + + if (pkg_arch == nil) + { + pkg_arch = Pkg::SystemArchitecture(); + } + + string new_arch = AskArch( + _("Select the new target architecture."), + // sort the list according to the current locale + lsort(["i386", "i486", "i586", "i686", "sparc", "sparc64", "mips", "mips64", "ppc", "ppc64", "alpha", + "s390", "s390x", "ia64", "x86_64"]), + pkg_arch); + + // nil == switch has been canceled + if (new_arch != nil && new_arch != "" && new_arch != pkg_arch) + { + // change the architecture + ProductCreator::SetPackageArch(new_arch); + + UI::ReplaceWidget(`rp, + `Label(sformat(_("Target Architecture: %1"), ProductCreator::GetPackageArch())) + ); + } + } else { y2error("unexpected retcode: %1", ret); continue; @@ -851,8 +1098,8 @@ // while the package manager is initialized UI::ReplaceWidget(`rep, mode == nil ? - `PackageSelector(`id(`packages )) : - `PackageSelector(`id(`packages ), `opt(mode)) + `PackageSelector(`id(`packages)) : + `PackageSelector(`id(`packages), `opt(mode)) ); symbol result = (symbol) UI::RunPkgSelection(`id(`packages ) ); @@ -1262,19 +1509,33 @@ */ define symbol packageSelector() { - string base_pattern = ProductCreator::Config["base"]:""; - list<string> patterns = ProductCreator::Config["addons"]:[]; - list<string> packages = ProductCreator::Config["packages"]:[]; - list<string> taboo = ProductCreator::Config["taboo"]:[]; - - map<string,any> result = runPackageSelector(base_pattern, patterns, packages, taboo, `patterns); - - ProductCreator::Config["base"] = result["base"]:""; - ProductCreator::Config["addons"] = result["addons"]:[]; - ProductCreator::Config["packages"] = result["packages"]:[]; - ProductCreator::Config["taboo"] = result["taboo"]:[]; - ProductCreator::Config["code10"] = result["code10"]:true; - ProductCreator::Config["type"] = result["type"]:`patterns; + map<string,any> result = $[]; + + do + { + string base_pattern = ProductCreator::Config["base"]:""; + list<string> patterns = ProductCreator::Config["addons"]:[]; + list<string> packages = ProductCreator::Config["packages"]:[]; + list<string> taboo = ProductCreator::Config["taboo"]:[]; + + result = runPackageSelector(base_pattern, patterns, packages, taboo, `patterns); + + y2debug("Package selector result: %1", result); + + ProductCreator::Config["base"] = result["base"]:""; + ProductCreator::Config["addons"] = result["addons"]:[]; + ProductCreator::Config["packages"] = result["packages"]:[]; + ProductCreator::Config["taboo"] = result["taboo"]:[]; + ProductCreator::Config["code10"] = result["code10"]:true; + ProductCreator::Config["type"] = result["type"]:`patterns; + } + while(result["ui"]:`next == `cancel && !ProductCreator::ReallyAbort()); + + // the package selector returns `cancel when pressing [Abort] + if (result["ui"]:`next == `cancel) + { + return `abort; + } return result["ui"]:`next; } @@ -1361,15 +1622,21 @@ GPGWidgets::SetSelectedPrivateKey(ProductCreator::Config["gpg_key"]:""); } - symbol ret = CWM::ShowAndRun ($[ - "widget_names" : ["sign_checkbox", "select_private_key", "create_new_key"], - "widget_descr" : union(GPGWidgets::Widgets(), sign_checkbox_widget()), - "contents" : GpgDialogContent(), - "caption" : caption, - "back_button" : Label::BackButton (), - "next_button" : Label::NextButton (), - "fallback_functions" : $[] - ]); + symbol ret = nil; + + do + { + ret = CWM::ShowAndRun ($[ + "widget_names" : ["sign_checkbox", "select_private_key", "create_new_key"], + "widget_descr" : union(GPGWidgets::Widgets(), sign_checkbox_widget()), + "contents" : GpgDialogContent(), + "caption" : caption, + "back_button" : Label::BackButton (), + "next_button" : Label::NextButton (), + "fallback_functions" : $[] + ]); + } + while(ret == `abort && !ProductCreator::ReallyAbort()); boolean sign = (boolean)UI::QueryWidget(`id("sign_checkbox"), `Value); y2milestone("Sign the medium: %1", sign); @@ -1417,6 +1684,16 @@ summary = Summary::AddLine(summary, sformat(_("Selected %1 packages"), size(Pkg::GetPackages(`selected, true)))); + string arch = ProductCreator::Config["arch"]:""; + // display the architecture in the summary if it has been changed + if (arch != nil && arch != "" && arch != Arch::architecture()) + { + summary = Summary::AddHeader(summary, _("Architecture") ); + + // summary line, %1 is e.g. i386, x86_64, ppc... + summary = Summary::AddLine(summary, sformat(_("Target architectrure: %1"), arch)); + } + // summary caption summary = Summary::AddHeader(summary,_("Output Directory")); @@ -1488,6 +1765,12 @@ repeat { ret = UI::UserInput(); + + if (ret == `abort && !ProductCreator::ReallyAbort()) + { + // abort canceled + ret = `dummy; + } } until (ret == `next || ret == `back || ret == `abort); Wizard::CloseDialog(); Modified: trunk/product-creator/src/helps.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/src/helps.ycp?rev... ============================================================================== --- trunk/product-creator/src/helps.ycp (original) +++ trunk/product-creator/src/helps.ycp Mon Aug 11 12:02:47 2008 @@ -91,10 +91,18 @@ </p> "), - /* Configure2 dialog help 1/2 */ + /* Source selection help 1/2 */ "sourceDialog" : _("<p><b><big>Select Package Sources</big></b><br> Select at least one package source.<br></p> -"), +") + /* Source selection help 2/2 */ + + _("<p><b><big>Target Architecture</big></b><br> +It is possible to create a product for different architecture than the architecture of this machine. +All selected repositories must support the target architecture.<br> +<b>Note:</b> KIWI does not support different architectures yet, do not change the +architecture if you intend to create a KIWI image from the current configuration.</p> +") + , /* Configure2 dialog help 1/2 */ "dest" : _("<p><b><big>ISO Directory and Image</big></b><br> Modified: trunk/product-creator/src/wizards.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/product-creator/src/wizards.ycp?r... ============================================================================== --- trunk/product-creator/src/wizards.ycp (original) +++ trunk/product-creator/src/wizards.ycp Mon Aug 11 12:02:47 2008 @@ -303,7 +303,7 @@ list<string> required_packages = ["inst-source-utils", "mkisofs", "createrepo"]; // add PPC specific packages - if (Arch::architecture() == "ppc" || Arch::architecture() == "ppc64") + if (ProductCreator::GetArch() == "ppc" || ProductCreator::GetArch() == "ppc64") { // /bin/objcopy - binutils // /bin/mkzimage - lilo -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org