home *** CD-ROM | disk | FTP | other *** search
- /**
- * File: modules/SourceManagerSLP.ycp
- * Package: SLP Source Management
- * Summary: SLP-related SourceManager settings
- * Authors: Lukas Ocilka <locilka@suse.cz>
- * Status: Work in Progress
- *
- * $Id:$
- *
- * This module provides a complete set of functions that allows you to search
- * and select a new SLP source.
- */
- {
- import "SLP";
- import "Wizard";
- import "Directory";
- import "Stage";
- import "SuSEFirewall";
- import "Report";
- import "Label";
- // import "IP";
- // import "String";
- // import "FileUtils";
-
- textdomain "packager";
- module "SourceManagerSLP";
-
- term Icon (string icon_name) {
- map ui_info = UI::GetDisplayInfo();
- if ((boolean) ui_info["HasLocalImageSupport"]:false == false) return `Empty();
-
- return `Image (
- sformat (
- "%1/current/icons/22x22/apps/%2.png",
- Directory::themedir,
- icon_name
- ),
- "[x]"
- );
- }
-
- void CreateSearchUI () {
- UI::OpenDialog (
- `VBox (
- `HBox (
- `HSquash (`MarginBox (0.5, 0.2, Icon ("yast-you_server"))),
- // translators: popup heading (progress popup)
- `Left (`Heading(`id(`search_heading), _("SLP Search")))
- ),
- `Left (
- `ReplacePoint(`id(`search_rp), `Empty())
- )
- )
- );
- }
-
- void CloseSearchUI () {
- UI::CloseDialog ();
- }
-
- void SetSearchUI (term content) {
- UI::ReplaceWidget(`id(`search_rp), content);
- }
-
- void SearchForSLPServices (list <map> & services) {
- // progress information
- SetSearchUI (`Label (_("Scanning network for installation services...")));
- y2milestone("scanning network: SLP::FindSrvs(\"install.suse\", \"\")");
- services = SLP::FindSrvs ("install.suse", "");
- y2milestone("Done, found %1 sources", size(services));
- }
-
- void CreateSLPListFoundDialog (list <map> & services) {
- term filter_dialog = `Empty();
- boolean show_filter = false;
-
- // Show filter only for bigger amount of services
- if (size(services) > 15) {
- show_filter = true;
- filter_dialog = `MarginBox (0.5, 0.5, `Frame (
- // frame label
- _("Filter Form"),
- `VSquash (`HBox (
- // Only some characters are valid 'A-Z a-z 0-9 .*-'
- `HSquash(`TextEntry (`id (`filter_text), "")),
- // push button
- `PushButton(`id(`filter), `opt(`default), _("&Filter")),
- `HStretch()
- ))
- ));
- }
-
- // bugzilla #209426
- // window size (in ncurses) based on currently available space
- map display_info = UI::GetDisplayInfo();
- integer min_size_x = 76;
- integer min_size_y = 19;
- if (display_info["TextMode"]:true) {
- min_size_x = tointeger(display_info["Width"]:80) * 3 / 4;
- min_size_y = tointeger(display_info["Height"]:25) * 2 / 3 - 5;
- if (min_size_x < 76) min_size_x = 76;
- if (min_size_y < 18) min_size_y = 18;
- y2milestone("X/x Y/y %1/%2 %3/%4",
- display_info["Width"]:80, min_size_x,
- display_info["Height"]:25, min_size_y);
- }
-
- UI::OpenDialog (
- `VBox (
- `HBox (
- `HSquash (`MarginBox (0.5, 0.2, Icon ("yast-you_server"))),
- // translators: popup heading
- `Left (`Heading(`id(`search_heading), _("Choose SLP Catalog")))
- ),
- filter_dialog,
- `MarginBox (0.5, 0, `MinSize(
- min_size_x, min_size_y,
- `Tree (
- `id (`tree_of_services),
- `opt (`notify),
- // tree label (tree of available products)
- _("Available Installation Products"),
- []
- )
- )),
- `PushButton(`id(`details), _("Details...")),
- `VSpacing (1),
- `HBox (
- `PushButton (`id (`ok), `opt(`default), Label::SelectButton ()),
- `VSpacing (1),
- `PushButton (`id (`cancel), Label::CancelButton ())
- )
- )
- );
-
- if (show_filter) {
- UI::SetFocus(`filter_text);
- }
- }
-
- void InitDetailsButton () {
- integer current = (integer) UI::QueryWidget(`id(`tree_of_services), `CurrentItem);
- if (current == nil || current < 0) {
- UI::ChangeWidget(`id(`details), `Enabled, false);
- } else {
- UI::ChangeWidget(`id(`details), `Enabled, true);
- }
- }
-
- void ShowDetailsDialog (list <map> & services) {
- integer current = (integer) UI::QueryWidget(`id(`tree_of_services), `CurrentItem);
- if (current == nil || current < 0) {
- y2error("No service selected, no details");
- // error popup
- Report::Error(_("No details are available."));
- } else {
- map service_details = services[current]:$[];
-
- if (service_details == $[]) {
- // message popup
- Report::Message(_("No details are available."));
- } else {
- list <term> details = [];
- foreach (any key, any value, service_details, {
- details = add (details, `item (`id(nil), tostring (key), tostring (value)));
- });
-
- UI::OpenDialog (
- `VBox (
- `Left (`Heading(`id(`details_heading), _("Catalog Details"))),
- `MinSize (
- 60, 16,
- `Table (
- `header(
- // table header item
- _("Key"),
- // table header item
- _("Value")
- ),
- details
- )
- ),
- `VSpacing (1),
- `PushButton (`id(`ok), Label::OKButton())
- )
- );
- UI::UserInput();
- UI::CloseDialog();
- }
- }
- }
-
- /**
- * Initializes the listed SLP services.
- *
- * @param list <map> services (reference)
- * @param string regexp for services that should be visible (nil or "" for all)
- */
- void InitSLPListFoundDialog (list <map> & services, string regexp_string) {
- if (regexp_string == "") regexp_string = nil;
-
- map <string, list <integer> > inst_products = $[];
- string service_label = nil;
-
- // index in the list of 'services'
- integer service_counter = -1;
-
- foreach (map one_service, services, {
- // always increase the service ID, must be consistent for all turns
- service_counter = service_counter + 1;
-
- service_label = one_service["label"]:"";
-
- // bugzilla #219759
- // service label can be empty (not defined)
- if (service_label == "") {
- if (one_service["srvurl"]:"" != "") {
- service_label = sformat (
- "%1: %2",
- _("Catalog URL"),
- substring (one_service["srvurl"]:"", 21)
- );
- } else {
- y2error ("Wrong service definition: %1, key \"srvurl\" must not be empty.", one_service);
- }
- }
-
- // search works in "label" or in "srvurl" as a fallback
- if (regexp_string != nil) {
- // filter out all services that don't match the regexp
- if (! regexpmatch (service_label, regexp_string)) return;
- }
-
- // define an empty list if it is not defined at all
- if (inst_products[service_label]:nil == nil) inst_products[service_label] = [];
- inst_products[service_label] = add (inst_products[service_label]:[], service_counter);
- });
-
- list <term> tree_of_services = [];
- list <term> urls_for_product = nil;
- integer product_counter = -1;
- string service_url = nil;
-
- // "SUSE Linux 10.2 x86_64":[10, 195]
- foreach (string one_product, list <integer> service_ids, inst_products, {
- product_counter = product_counter + 1;
-
- if (size(service_ids) == 1) {
- integer service_id = service_ids[0]:nil;
- tree_of_services[product_counter] = `item (`id(service_id), one_product);
- } else {
- urls_for_product = [];
- foreach (integer service_id, service_ids, {
- // removing "install.suse..."
- service_url = substring(services[service_id, "srvurl"]:"", 21);
-
- urls_for_product = add (
- urls_for_product,
- `item (`id (service_id), service_url)
- );
- });
- // -1 for a product name without url (URLs are hidden below)
- tree_of_services[product_counter] = `item (`id (-1), one_product, urls_for_product);
- }
- });
-
- UI::ChangeWidget (`id(`tree_of_services), `Items, tree_of_services);
- InitDetailsButton ();
- }
-
- string GetCurrentlySelectedURL (list <map> & services) {
- integer current = (integer) UI::QueryWidget(`id(`tree_of_services), `CurrentItem);
-
- if (current == nil || current < 0) {
- // message popup
- Report::Message (_("Please, select one of offered options.
- This product has more installation sources available."));
-
- return nil;
- } else {
- string service_url = substring (services[current, "srvurl"]:"", 21);
-
- if (service_url == nil || service_url == "") {
- y2error(
- "An internal error occurred, service ID %1, %2 has no URL!",
- current, services[current]:$[]
- );
- // popup error
- Report::Error (_("An internal error occurred.
- The selected source has no URL."));
- return nil;
- } else {
- return service_url;
- }
- }
- }
-
- string EscapeChars(string input, string escape)
- {
- string ret = input;
-
- if (escape != nil && size(escape) > 0)
- {
- integer i = 0;
- integer sz = size(escape);
-
- while(i < sz)
- {
- string ch = substring(escape, i, 1);
- y2debug("Escaping %1", ch);
- ret = mergestring(splitstring(ret, ch), "\\" + ch);
- i = i + 1;
- };
- }
-
- return ret;
- }
-
- string HandleSLPListDialog (list <map> & services) {
- InitSLPListFoundDialog (services, nil);
-
- string dialog_ret = nil;
- any ret = nil;
-
- while (true) {
- ret = UI::UserInput();
-
- if (ret == `cancel) {
- dialog_ret = nil;
- break;
-
- } else if (ret == `ok) {
- dialog_ret = GetCurrentlySelectedURL (services);
- y2milestone("Selected URL: '%1'", dialog_ret);
- if (dialog_ret != "" && dialog_ret != nil) {
- break;
- }
-
- } else if (ret == `tree_of_services) {
- InitDetailsButton();
-
- } else if (ret == `filter) {
- string regexp_string = (string) UI::QueryWidget (`id(`filter_text), `Value);
- y2milestone("original regexp_string: %1", regexp_string);
- // escape special character in the input string
- // \ must be the first character!
- regexp_string = EscapeChars(regexp_string, "\\(){}[]+^$|");
- y2milestone("escaped regexp_string: %1", regexp_string);
-
- InitSLPListFoundDialog (services, regexp_string);
- } else if (ret == `details) {
- ShowDetailsDialog (services);
-
- } else {
- y2error("Unknown ret: %1", ret);
- }
- }
-
- return dialog_ret;
- }
-
- void CloseSLPListFoundDialog () {
- UI::CloseDialog();
- }
-
- void SearchForSLPServicesInfo (list <map> & services) {
- integer number_of_services = size (services);
-
- SetSearchUI (`Label (sformat (
- // progress information, %1 stands for number of services
- _("Collecting information of %1 services found..."),
- number_of_services
- )));
-
- y2milestone("Collecting data about %1 services", number_of_services);
-
- list <map> new_services = [];
-
- map<string,string> dns_cache = $[];
-
- integer counter = -1;
- foreach (map slp_service, services, {
- counter = counter + 1;
- string server_ip = slp_service["ip"]:"";
- string service_url = slp_service["srvurl"]:"";
-
- // bugzilla #219759
- // /usr/bin/host not in inst-sys
- // Anyway, it's not needed - key "ip" defines the server which has sent this reply
- //
- // if (!IP::Check4(server_ip))
- // {
- // if (haskey(dns_cache, server_ip))
- // {
- // server_ip = dns_cache[server_ip]:"";
- // }
- // else if (FileUtils::Exists ("/usr/bin/host"))
- // {
- // string server_ip_quoted = "'" + String::Quote (server_ip) + "'";
- // y2milestone ("Resolving host %1...", server_ip_quoted);
- // map m = (map)SCR::Execute (.target.bash_output, sformat ("/usr/bin/host %1 | /bin/grep address", server_ip_quoted));
- //
- // if (m["exit"]:0 == 0)
- // {
- // string out = m["stdout"]:"";
- // string ip = regexpsub (out, "has address (.*)$", "\\1");
- // if (ip != nil)
- // {
- // y2milestone("...resolved to %1", ip);
- // // cache the IP address
- // dns_cache[server_ip] = ip;
- //
- // server_ip = ip;
- // }
- // }
- // }
- // }
-
- // empty server_ip
- if (service_url != "" && server_ip != "") {
- map attrs = SLP::GetUnicastAttrMap (service_url, server_ip);
-
- if (attrs != nil && attrs != $[]) {
- slp_service = union (slp_service, attrs);
- }
- }
-
- new_services[counter] = slp_service;
- });
-
- y2milestone("Done");
-
- services = new_services;
- }
-
- /**
- * Function searches the SLP services on the current network.
- * If there are some SLP services, opens up a dialog containing
- * them and user has to select one or cancel the operation.
- * Selected URL is returned as string, otherwise a nil is returned.
- *
- * @return string service_URL
- */
- global string SelectOneSLPService () {
-
- CreateSearchUI();
- list <map> slp_services_found = [];
- SearchForSLPServices (slp_services_found);
-
- if (slp_services_found == nil || size(slp_services_found) == 0) {
- y2warning("No SLP catalogs found");
- } else {
- SearchForSLPServicesInfo(slp_services_found);
- }
- CloseSearchUI();
-
- // no servers found
- if (slp_services_found == nil || size(slp_services_found) == 0) {
- y2warning ("No SLP catalogs were found");
- if ((! Stage::initial ()) && SuSEFirewall::IsStarted ()) {
- Report::Message (
- // error popup
- _("No SLP catalogs have been found on your network.
- This could be caused by a running SuSEfirewall2,
- which probably blocks the network scanning.")
- );
- } else {
- Report::Message (
- // error popup
- _("No SLP catalogs have been found on your network.")
- );
- }
- return nil;
- }
-
- CreateSLPListFoundDialog (slp_services_found);
- string selected_service = HandleSLPListDialog (slp_services_found);
- CloseSLPListFoundDialog ();
-
- return selected_service;
- }
-
- /* EOF */
- }
-