ACC SHELL
/**
* File: packager/repositories_include.ycp
*
* Author: Cornelius Schumacher <cschum@suse.de>
* Ladislav Slezak <lslezak@suse.cz>
* Lukas Ocilka <locilka@suse.cz>
*
* Purpose: Include file to be shared by yast2-packager and yast2-add-on
*
* $Id: repositories_include.ycp 59098 2009-10-19 14:32:55Z lslezak $
*
*/
{
import "Stage";
import "Wizard";
import "AddOnProduct";
import "URL";
import "PackageSystem";
import "Popup";
import "Label";
import "SourceDialogs";
import "Report";
import "Progress";
textdomain "packager";
list<map<string,any> > sourceStatesIn = [];
list<map<string,any> > sourceStatesOut = [];
list<map<string,any> > serviceStatesIn = [];
list<map<string,any> > serviceStatesOut = [];
// constant Plaindir
const string plaindir_type = "Plaindir";
boolean download_meta = true;
boolean LicenseAccepted (integer id) {
boolean ret = AddOnProduct::AcceptedLicenseAndInfoFile (id);
return ret;
}
define symbol createSourceImpl(string url, boolean plaindir, boolean download, string preffered_name)
{
y2milestone("createSource: %1, plaindir: %2, download: %3, name: %4", URL::HidePassword(url), plaindir, download, preffered_name);
if ( url != "" )
{
// for Plaindir repository we have to use SourceCreateType() binding
map parsed = URL::Parse(url);
string scheme = parsed["scheme"]:"";
if (plaindir == true)
{
y2milestone("Using PlainDir repository type");
}
// check if SMB/CIFS share can be mounted
if (scheme == "smb" && SCR::Read(.target.size, "/sbin/mount.cifs") < 0)
{
y2milestone("SMB/CIFS share cannot be mounted, installing missing 'cifs-mount' package...");
// install cifs-mount package
PackageSystem::CheckAndInstallPackages(["cifs-mount"]);
}
Progress::New (
// TRANSLATORS: dialog caption
_("Adding a New Repository"),
" ",
3,
[ _("Check Repository Type"), _("Add Repository"), _("Read Repository License") ],
[ _("Checking Repository Type"), _("Adding Repository"), _("Reading Repository License") ],
// TRANSLATORS: dialog help
_("<p>Please wait while the repository manager downloads the repository details...</p>")
);
Progress::NextStage();
string service_type = Pkg::ServiceProbe(url);
y2milestone("Probed service type: %1", service_type);
if (service_type != nil && service_type != "NONE")
{
y2milestone("Adding a service of type %1...", service_type);
string alias = "service";
// all current aliases
list<string> aliases = maplist(map<string,any> s, serviceStatesOut,
{
return s["alias"]:"";
}
);
// service alias must be unique
// if it already exists add "_<number>" suffix to it
integer idx = 1;
while (contains(aliases, alias))
{
alias = sformat("service_%1", idx);
idx = idx + 1;
}
boolean autorefresh = true;
string schema = tolower(substring(url, 0, 3));
if (schema == "cd:" || schema == "dvd")
{
autorefresh = false;
y2milestone("Disabling autorefresh for a CD/DVD service");
}
// use alias as the name if it's missing
if (preffered_name == nil || preffered_name == "")
{
preffered_name = alias;
}
map<string,any> new_service = $["alias":alias, "autorefresh":autorefresh,
"enabled":true, "name":preffered_name, "url":url];
y2milestone("Added new service: %1", new_service);
serviceStatesOut = add(serviceStatesOut, new_service);
return `ok;
}
list<list<string> > new_repos = Pkg::RepositoryScan(url);
y2milestone("new_repos: %1", new_repos);
// add at least one product if the scan result is empty (no product info available)
if (size(new_repos) == 0)
{
string url_path = URL::Parse(url)["path"]:"";
list<string> p_elems = splitstring(url_path, "/");
const string fallback = _("Repository");
if (size(p_elems) > 1)
{
url_path = p_elems[size(p_elems) - 1]:fallback;
if (url_path == nil || url_path == "" )
{
url_path = p_elems[size(p_elems) - 2]:fallback;
if (url_path == nil || url_path == "" )
{
url_path = fallback;
}
}
}
new_repos = [ [ url_path, "/" ] ];
}
list<integer> newSources = [];
boolean auto_refresh = true;
// disable autorefresh for ISO images
const string iso_prefix = "iso:";
if (substring(url, 0, size(iso_prefix)) == iso_prefix)
{
y2milestone("ISO image detected, disabling autorefresh (%1)", URL::HidePassword(url));
auto_refresh = false;
}
// CD or DVD repository?
boolean cd_scheme = contains(["cd", "dvd"], tolower(URL::Parse(url)["scheme"]:""));
if (cd_scheme)
{
y2milestone("CD/DVD repository detected, disabling autorefresh (%1)", URL::HidePassword(url));
auto_refresh = false;
}
boolean enter_again = false;
foreach(list<string> repo, new_repos,
{
if (enter_again)
continue;
string name = repo[0]:"";
if (preffered_name != nil && preffered_name != "")
name = preffered_name;
string prod_dir = repo[1]:"/";
// probe repository type (do not probe plaindir repo)
string repo_type = (plaindir) ? plaindir_type : Pkg::RepositoryProbe(url, prod_dir);
y2milestone("Repository type (%1,%2): %3", URL::HidePassword(url), prod_dir, repo_type);
// the probing has failed
if (repo_type == nil || repo_type == "NONE")
{
if (scheme == "dir")
{
if (! Popup::AnyQuestion (
Popup::NoHeadline (),
// continue-back popup
_("There is no product information available at the given location.
If you expected to address a product, return back and enter
the correct location.
To make rpm packages located at the specified location available
in the packages selection, continue."),
Label::ContinueButton (),
Label::BackButton (),
`focus_no))
{
enter_again = true;
continue;
}
repo_type = plaindir_type;
y2warning("Probing has failed, using Plaindir repository type.");
}
else
{
continue;
}
}
string alias = name;
// replace " " -> "_" (avoid spaces in .repo file name)
alias = mergestring(splitstring(alias, " "), "_");
string alias_orig = alias;
// all current aliases
list<string> aliases = maplist(integer i, Pkg::SourceGetCurrent(false),
{
map info = Pkg::SourceGeneralData(i);
return info["alias"]:"";
}
);
// repository alias must be unique
// if it already exists add "_<number>" suffix to it
integer idx = 1;
while (contains(aliases, alias))
{
alias = sformat("%1_%2", alias_orig, idx);
idx = idx + 1;
}
// map with repository parameters: $[ "enabled" : boolean,
// "autorefresh" : boolean, "name" : string, "alias" : string,
// "base_urls" : list<string>, "prod_dir" : string, "type" : string ]
map<string,any> repo_prop = $[];
repo_prop["enabled"] = true;
repo_prop["autorefresh"] = auto_refresh;
repo_prop["name"] = name;
repo_prop["prod_dir"] = repo[1]:"/";
repo_prop["alias"] = alias;
repo_prop["base_urls"] = [ url ];
repo_prop["type"] = repo_type;
Progress::NextStage();
integer new_repo_id = Pkg::RepositoryAdd(repo_prop);
map<string,any> repo_prop_log = repo_prop;
repo_prop_log["base_urls"] = [ URL::HidePassword(url) ];
y2milestone("Added repository: %1: %2", new_repo_id, repo_prop_log);
newSources = add(newSources, new_repo_id);
if (cd_scheme)
{
// for CD/DVD repo download the metadata immediately,
// the medium is in the drive right now, it can be changed later
// and accidentaly added a different repository
y2milestone("Adding a CD or DVD repository, refreshing now...");
Pkg::SourceRefreshNow(new_repo_id);
}
}
);
// broken repository or wrong URL - enter the URL again
if (enter_again)
{
Pkg::SourceReleaseAll();
return `again;
}
if ( size( newSources ) == 0 )
{
y2error("Cannot add the repository");
// popup message part 1
string msg = sformat( _("Unable to create repository
from URL '%1'."), URL::HidePassword(url) );
if (regexpmatch(url, "\\.iso$"))
{
map parsed_url = URL::Parse(url);
string scheme = tolower(parsed_url["scheme"]:"");
if (contains(["ftp", "sftp", "http", "https"], scheme))
{
// error message
msg = msg + "\n\n" + _("Using an ISO image over ftp or http protocol is not possible.
Change the protocol or unpack the ISO image on the server side.");
}
}
// popup message part 2
msg = msg + "\n\n" + _("Change the URL and try again?");
boolean tryagain = Popup::YesNo(msg);
if (tryagain) return `again;
return `cancel;
}
else
{
Progress::NextStage();
foreach( integer id, newSources, ``{
if (! LicenseAccepted (id))
{
Pkg::SourceDelete (id);
}
else
{
map src_data = Pkg::SourceGeneralData (id);
y2milestone("Addded repository: %1", src_data);
map<string, any> sourceState = $[ "SrcId": id, "enabled": src_data["enabled"]:true, "autorefresh" : src_data["autorefresh"]:true, "name" : src_data["name"]:"", "do_refresh" : download ];
sourceStatesOut = add( sourceStatesOut, sourceState );
}
} );
// relese (unmount) the medium
Pkg::SourceReleaseAll();
return `ok;
}
}
else
{
y2error(-1, "Empty URL! Backtrace:");
return `again;
}
}
// start createSource() function in extra wizard dialog
symbol createSource(string url, boolean plaindir, boolean download, string preffered_name)
{
Wizard::CreateDialog();
symbol ret = createSourceImpl(url, plaindir, download, preffered_name);
Wizard::CloseDialog();
return ret;
}
symbol StoreSource () {
string url = SourceDialogs::GetURL ();
string name = SourceDialogs::GetRepoName ();
boolean plaindir = SourceDialogs::IsPlainDir();
// special case, bugzilla #238680
if (url == "slp://")
{
string required_package = "yast2-slp";
boolean installed_before = PackageSystem::Installed (required_package);
if (! Stage::initial() && ! installed_before) {
// Tries to Check and Install packages
if (
! PackageSystem::CheckAndInstallPackagesInteractive ([required_package]) ||
! PackageSystem::Installed (required_package)
) {
Report::Error (sformat (
// popup error message, %1 is the package name
_("Cannot search for SLP repositories
without having %1 package installed"),
required_package
));
y2warning ("Not searching for SLP repositories");
return `back;
// New .slp agent has been added
// FIXME: lazy loading of agents will make this obsolete
} else {
SCR::RegisterAgent(.slp, `ag_slp(`SlpAgent()));
}
}
string service = (string) WFM::call("select_slp_source");
if (service == nil) {
y2milestone("No SLP service selected, returning back...");
return `back;
}
else
{
url = service;
}
}
else if (url == "commrepos://")
{
any commrepos = WFM::call ("inst_productsources", [$["skip_already_used_repos":true]]);
y2milestone ("Community Repositories returned: %1", commrepos);
if (commrepos == `abort || commrepos == `cancel) {
y2milestone ("Using CR have been canceled");
return `back;
} else {
return `next;
}
}
if (createSource(url, plaindir, download_meta, name) == `again)
return `back;
return `next;
}
symbol TypeDialogOpts(boolean download, string url)
{
SourceDialogs::SetDownloadOption(download);
SourceDialogs::SetURL(url);
map<string,any> td = SourceDialogs::TypeDialogDownloadOpt();
symbol ret = td["ui"]:`next;
download_meta = td["download"]:true;
return ret;
}
symbol TypeDialog()
{
// download metadata, reset the stored URL
return TypeDialogOpts(true, "");
}
symbol EditDialog()
{
symbol ret = SourceDialogs::EditDialog ();
return ret;
}
} // EOF
ACC SHELL 2018