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 / clients / inst_extrasources.ycp < prev    next >
Text File  |  2006-11-29  |  8KB  |  372 lines

  1. /**
  2.  * File:    clients/inst_extrasources.ycp
  3.  * Package:    yast2-installation
  4.  * Summary:    Add extra installation sources from content file
  5.  * Authors:    Ladislav Slez├ík <lslezak@suse.cz>
  6.  *
  7.  * Assumptions:
  8.  * - the sources have been initialized
  9.  * - the sources will be saved afterwards
  10.  * (this means that running this client alone will not work)
  11.  *
  12.  * $Id$
  13.  */
  14.  
  15. {
  16.  
  17. textdomain "installation";
  18.  
  19. import "GetInstArgs";
  20. import "Popup";
  21. import "SourceManager";
  22. import "Label";
  23. import "Mode";
  24. import "String";
  25. import "Internet";
  26.  
  27. // editUrl()
  28. include "packager/inst_source_dialogs.ycp";
  29.  
  30. // the tag providing location of the additional sources in content file
  31. string content_file_tag = "EXTRAURLS";
  32. string optional_tag = "OPTIONALURLS";
  33.  
  34. /**
  35.  * Show a confirmation dialog with list of the extra sources.
  36.  * @param urls list of URLs
  37.  * @return boolean true if the user wants to register the sources
  38.  */
  39. list<string> ConfirmExtraSources(map<string,boolean> urls)
  40. {
  41.     list<term> items = [];
  42.  
  43.     // display the enabled sources at the beginning of the list
  44.     foreach(string url, boolean deflt, urls,
  45.     {
  46.         if (deflt)
  47.         {
  48.         items = add(items, `item(`id(url), url, deflt));
  49.         }
  50.     }
  51.     );
  52.  
  53.     foreach(string url, boolean deflt, urls,
  54.     {
  55.         if (!deflt)
  56.         {
  57.         items = add(items, `item(`id(url), url, deflt));
  58.         }
  59.     }
  60.     );
  61.  
  62.     integer width = 76;
  63.     integer height = 8;
  64.  
  65.     term popup = `HBox(
  66.     `HSpacing(1),
  67.     `VBox(
  68.         `VSpacing(0.2),
  69.         // heading in a popup window
  70.         `Heading(_("Additional Installation Sources")),
  71.         `VSpacing(0.2),
  72.         `VBox(
  73.         `HSpacing(width),
  74.         `HBox(
  75.             `VSpacing(height),
  76.             // label
  77.             `MultiSelectionBox(`id(`multi), _("Sources to Register"), items)
  78.         )
  79.         ),
  80.         `VSpacing(0.2),
  81.         // label - use more lines for the translated message (no more than about 60 characters per line)
  82.         `Label(_("Later you can install additional software from these external sources.\nRegister the sources now?")),
  83.         `VSpacing(0.5),
  84.         `HBox(
  85.         `HStretch(),
  86.         `PushButton(`id(`yes), `opt(`default, `key_F10), Label::YesButton()),
  87.         `HSpacing(2),
  88.         `PushButton(`id(`no), `opt(`key_F9), Label::NoButton()),
  89.         `HStretch()
  90.         ),
  91.         `VSpacing(0.5)
  92.         ),
  93.     `HSpacing(1)
  94.     );
  95.  
  96.     UI::OpenDialog(`opt(`decorated), popup);
  97.  
  98.     symbol ui = (symbol)UI::UserInput();
  99.     y2milestone("Extra sources confirmed: %1", ui);
  100.  
  101.     list<string> selected_items = (list<string>) UI::QueryWidget(`id(`multi), `SelectedItems);
  102.     y2milestone("Selected items: %1", selected_items);
  103.  
  104.     UI::CloseDialog();
  105.  
  106.     return (ui == `yes) ? selected_items : [];
  107. }
  108.  
  109. /**
  110.  * Temporarily start the network
  111.  * @return map The network status before starting
  112.  */
  113. define map<string,boolean> NetworkStart()
  114. {
  115.     // network connection status
  116.     boolean already_up = false;
  117.  
  118.     // flag: demand has been changed
  119.     boolean i_set_demand = false;
  120.  
  121.     if (!Mode::test())
  122.         already_up = Internet::Status();
  123.  
  124.     if (!already_up)
  125.     {
  126.     // label - text in a popup window, progress indicator
  127.     UI::OpenDialog(`opt(`decorated), `Label(_("Testing the Internet Connection...")));
  128.  
  129.     // this code is from inst_you.ycp
  130.     if (!Internet::demand)
  131.     {
  132.         Internet::SetDemand (true);
  133.         i_set_demand = true;
  134.     }
  135.  
  136.     Internet::Start ("");
  137.  
  138.     integer i = 150;
  139.     while (i > 0)
  140.     {
  141.         if (!Internet::Status ())
  142.         break;
  143.  
  144.         if (Internet::Connected ())
  145.         break;
  146.  
  147.         // ping anything (www.suse.com) to trigger dod connections
  148.         //
  149.         // This ping should only set the network up,
  150.         // The IP now is different to the current www.suse.com's IP
  151.         // but it doesn't matter, what we need is just a network traffic.
  152.         SCR::Execute (.target.bash_background,
  153.               "/bin/ping -c 1 -w 1 213.95.15.200");
  154.  
  155.         sleep (1000);
  156.     }
  157.  
  158.     UI::CloseDialog();
  159.     }
  160.  
  161.     return $["already_up" : already_up, "i_set_demand" : i_set_demand];
  162. }
  163.  
  164. /**
  165.  * Restore the network status
  166.  * @param original_status original status before starting the network
  167.  */
  168. define void NetworkStop(map<string,boolean> original_status)
  169. {
  170.     if (!original_status["already_up"]:false)
  171.     {
  172.     Internet::Stop("");
  173.  
  174.     if (original_status["i_set_demand"]:false)
  175.     {
  176.         Internet::SetDemand(false);
  177.     }
  178.     }
  179. }
  180.  
  181. /**
  182.  * Dowload and parse content files from current installation sources
  183.  * @param registered
  184.  * @return map Extra URLs for each source:  $[ string source_url : list<string> extra_urls ]
  185.  */
  186. define map<string,boolean> GetExtraURLs(list<string> registered)
  187. {
  188.     map<string,boolean> extra_urls = $[];
  189.  
  190.     list<map> products = Pkg::ResolvableProperties("", `product, "");
  191.     y2milestone("Products: %1", products);
  192.  
  193.     foreach(map product, products,
  194.     {
  195.         // get the extra sources
  196.         list<string> extra = (list<string>)product["extra_urls"]:[];
  197.         list<string> optional = (list<string>)product["optional_urls"]:[];
  198.  
  199.         if (size(extra) > 0)
  200.         {
  201.         foreach(string url, extra,
  202.             {
  203.             // is the URL already registered?
  204.             if (!contains(registered, url))
  205.             {
  206.                 extra_urls = add(extra_urls, url, true);
  207.             }
  208.             else
  209.             {
  210.                 y2milestone("Source %1 is already registered", url);
  211.             }
  212.             }
  213.         );
  214.         }
  215.  
  216.         if (size(optional) > 0)
  217.         {
  218.         foreach(string url, optional,
  219.             {
  220.             // is the URL already registered?
  221.             if (!contains(registered, url))
  222.             {
  223.                 extra_urls = add(extra_urls, url, false);
  224.             }
  225.             else
  226.             {
  227.                 y2milestone("Source %1 is already registered", url);
  228.             }
  229.             }
  230.         );
  231.  
  232.         }
  233.     }
  234.     );
  235.  
  236.     y2milestone("Extra sources: %1", extra_urls);
  237.     return extra_urls;
  238. }
  239.  
  240. /**
  241.  * Register the installation sources
  242.  * @param url_list list of the sources to register
  243.  * @return list<integer> list of created source IDs
  244.  */
  245. define list<integer> RegisterSources(list<string> url_list)
  246. {
  247.     list<integer> ret = [];
  248.  
  249.     foreach(string new_url, url_list,
  250.     {
  251.         boolean again = true;
  252.         while (again)
  253.         {
  254.         integer srcid = Pkg::SourceCreate(new_url, "/");
  255.         y2milestone ("Created source %1: %2", srcid, new_url);
  256.  
  257.         if (srcid == -1)
  258.         {
  259.             // popup message
  260.             if (Popup::YesNo (_("An error occurred while creating the installation source.") + "\n"
  261.             // popup message
  262.             + _("Details:") + "\n" + Pkg::LastError() + "\n" + _("Try again?")))
  263.             {
  264.             new_url = editUrl (new_url);
  265.             }
  266.             else
  267.             {
  268.             again = false;
  269.             }
  270.         }
  271.         else
  272.         {
  273.             // disable the source
  274.             Pkg::SourceSetEnabled(srcid, false);
  275.  
  276.             // remember the ID
  277.             ret = add (ret, srcid);
  278.             again = false;
  279.         }
  280.         }
  281.     }
  282.     );
  283.  
  284.     return ret;
  285. }
  286.  
  287. list<string> RegisteredUrls()
  288. {
  289.     list<string> ret = [];
  290.     // get all registered installation sources
  291.     list<integer> srcs = Pkg::SourceGetCurrent(false);
  292.  
  293.     foreach(integer src, srcs,
  294.     {
  295.         map general = Pkg::SourceGeneralData(src);
  296.  
  297.         string url = general["url"]:"";
  298.  
  299.         if (url != nil && url != "")
  300.         {
  301.         ret = add(ret, url);
  302.         }
  303.     }
  304.     );
  305.  
  306.     // remove duplicates
  307.     ret = toset(ret);
  308.  
  309.     y2milestone("Registered sources: %1", ret);
  310.  
  311.     return ret;
  312. }
  313.  
  314. //////////////////////////////////////////
  315.  
  316. if ( GetInstArgs::going_back())     // going backwards?
  317. {
  318.     return `auto;                   // don't execute this once more
  319. }
  320.  
  321. // autoyast mode, user cannot be asked
  322. if (Mode::autoinst())
  323. {
  324.     y2milestone("Skipping extra source configuration in autoyast mode");
  325.     return `auto;
  326. }
  327.  
  328. // remember the original network status
  329. map<string,boolean> net_config = NetworkStart();
  330.  
  331. if (!Internet::Connected())
  332. {
  333.     y2warning("Cannot connect to the internet, skipping extra source configuration");
  334.     NetworkStop(net_config);
  335.     return `auto;
  336. }
  337.  
  338. list<string> already_registered = RegisteredUrls();
  339.  
  340. // $[ string url : boolean default ]
  341. map<string,boolean> register_url = GetExtraURLs(already_registered);
  342.  
  343.  
  344. // any confirmed source to register?
  345. if (size(register_url) > 0)
  346. {
  347.     list<string> confirmed_sources = ConfirmExtraSources(register_url);
  348.     {
  349.     // register (create) the sources
  350.     list<integer> added_ids = RegisterSources(confirmed_sources);
  351.  
  352.     // synchronize the sources if any source has been added
  353.     if (size(added_ids) > 0)
  354.     {
  355.         // reload (disable) the resolvables
  356.         Pkg::SourceLoad();
  357.  
  358.         y2milestone ("syncing to zmd");
  359.         boolean synced = SourceManager::SyncAddedAndDeleted (added_ids, []);
  360.         y2milestone ("sync status: %1", synced);
  361.     }
  362.     }
  363. }
  364.  
  365. // restore the network status
  366. NetworkStop(net_config);
  367.  
  368. return `auto;
  369.  
  370. /* EOF */
  371. }
  372.