ACC SHELL

Path : /usr/share/YaST2/include/partitioning/
File Upload :
Current File : //usr/share/YaST2/include/partitioning/ep-import.ycp

/**
 * File:	ep-import.ycp
 * Package:	yast2-storage
 * Summary:	Expert Partitioner
 * Authors:	Michael Hager <mike@suse.de>
 *		Johannes Buchhold <jbuch@suse.de>
 *		Arvin Schnell <aschnell@suse.de>
 *
 * This file must only be included in other Expert Partitioner files ("ep-*.ycp").
 */
{
    textdomain "storage";


    string MountVar(map var, map root, string rdev, string mp, map<string, map> target_map)
    {
    string ret = "";
    boolean mount_success = false;
    y2milestone("MountVar rdev:%1 mp:%2 var:%3 root:%4", rdev, mp, var, root);
    if( var["size_k"]:0>0 )
	{
	ret = var["device"]:"";
	}
    else
	{
	list<string> ds = maplist( string d, map disk, target_map, ``(d));
	y2milestone("MountVar ds:%1", ds);
	ds = filter( string d, ds, ``(target_map[d,"type"]:`CT_UNKNOWN==`CT_DISK));
	y2milestone("MountVar ds:%1", ds);
	map rootm = Storage::GetDiskPartition( rdev );
	map rootf = Storage::GetDiskPartition( root["device"]:"" );
	map varf = Storage::GetDiskPartition( var["device"]:"" );
	if( rootf["disk"]:""==varf["disk"]:"" )
	    {
	    ret = Storage::GetDeviceName( rootm["disk"]:"", varf["nr"]:(any)0 );
	    }
	else if( size(ds)==1 )
	    {
	    ret = Storage::GetDeviceName( ds[0]:"", varf["nr"]:(any)0 );
	    }
	else if( size(ds)>1 )
	    {
	    integer i = 0;
	    while( i<size(ds) && isempty(ret) )
		{
		ret = Storage::GetDeviceName( ds[i]:"", varf["nr"]:(any)0 );
		if( !isempty(Storage::GetPartition( target_map, ret )) &&
		    Storage::Mount( ret, mp ) )
		    {
		    map d = (map)SCR::Read( .target.stat, mp+"/lib/hardware" );
		    y2milestone("MountVar d:%1", d);
		    if( !d["isdir"]:false )
			ret = "";
		    Storage::Umount( ret );
		    }
		else
		    ret = "";
		i = i+1;
		}
	    }
	}
    if( !isempty(ret) && !Storage::Mount( ret, mp ))
	ret = "";
    y2milestone("MountVar ret:%1", ret);
    return ret;
    }


    /**
     * Find and read fstab by installation. Scan existing partitions.
     * @parm target_map all targets
     * @parm search_point mount point where partitions can be mounted
     * @return map<string, list> map with device and fstab data found
     */
    map<string, list> FindExistingFstabs(map<string, map> target_map, string search_point)
    {
	map<string, list> fstabs = $[];

    foreach( string disk_device, map disk, target_map, {

	list<map> partitions = filter(map part, disk["partitions"]:[], {
	    return contains(FileSystems::possible_root_fs, part["detected_fs"]:`unknown);
	});

	foreach(map part, partitions, {

	    string part_device = part["device"]:"";

	    // try to mount
	    boolean mount_success = Storage::Mount(part_device, search_point);

	    if( mount_success &&
		SCR::Read(.target.size, search_point+"/etc/fstab") > 0 )
		{
		list<map> fstab = Storage::ReadFstab( search_point+"/etc" );
		y2milestone("FindExistingFstabs fstab:%1", fstab);
		if (!isempty(fstab))
		    {
		    if( find( map p, fstab, ``(p["size_k"]:0==0 ))!=nil )
			{
			string vardev = "";
			map var = find( map p, fstab, ``(p["mount"]:""=="/var"));
			map root = find( map p, fstab, ``(p["mount"]:""=="/"));
			y2milestone("FindExistingFstabs var:%1", var);
			if( var != nil )
			    {
			    vardev = MountVar( var, root, part_device,
			                       search_point+"/var", target_map );
			    y2milestone("FindExistingFstabs vardev:%1", vardev);
			    }
			map dmap = Storage::BuildDiskmap( $[] );
			if (!isempty(dmap))
			    {
			    y2milestone("FindExistingFstabs dmap:%1", dmap);
			    y2milestone("FindExistingFstabs fstab:%1", fstab);
			    fstab = maplist( map p, fstab, {
				if( p["size_k"]:0 == 0 )
				    p["device"] = Storage::HdDiskMap( p["device"]:"", dmap );
				return( p );
				});
			    y2milestone("FindExistingFstabs fstab:%1", fstab);
			    }
			integer s = size(fstab);
			fstab = filter( map p, fstab, ``(Storage::CanEdit(p,false)));
			if (s != size(fstab))
			    y2milestone("FindExistingFstabs fstab:%1", fstab);
			if (!isempty(vardev))
			    Storage::Umount( vardev );
			}

		    if (!isempty(fstab))
			fstabs[part_device] = fstab;
		    }
		}

	    // unmount
	    if( mount_success )
		Storage::Umount(part_device);
	    });
	});
    y2milestone("FindExistingFstabs size(fstabs):%1", size(fstabs));
    y2milestone("FindExistingFstabs fstabs:%1", fstabs);
    return fstabs;
    }


    /**
     * Scan and Read and return fstabs.
     * @parm target_map all targets
     * @return map<string, list> map with device and fstab data found
     */
    map<string, list> ScanAndReadExistingFstabs(map<string, map> target_map)
    {
	string search_point = Directory::tmpdir + "/tmp-mp";

	if (!((map) SCR::Read(.target.stat, search_point))["isdir"]:false)
	    SCR::Execute(.target.mkdir, search_point);

	map<string, list> fstabs = FindExistingFstabs(target_map, search_point);

	return fstabs;
    }


    /**
     * Merge fstab with target_map.
     */
    map<string, map> AddFstabToTargetMap(map<string, map> target_map, list<map> fstab, boolean format_sys)
    {
	y2milestone("AddFstabToTargetMap fstab:%1", fstab);

	map<string, map> new_target_map = mapmap(string disk_device, map disk, target_map, {

	    disk["partitions"] = maplist(map partition, disk["partitions"]:[], {

		string part_device = partition["device"]:"";

		if (!Storage::IsInstallationSource(part_device))
		{
		    foreach(map fstab_entry, fstab, {

			string dev_fstab = fstab_entry["device"]:"";
			string mount_fstab = fstab_entry["mount"]:"";

			if (dev_fstab == part_device)
			{
			    partition["mount"] = mount_fstab;
			    if (format_sys && FileSystems::IsSystemMp(mount_fstab, false))
				partition["format"] = true;
			    if (!isempty(fstab_entry["fstopt"]:"") && fstab_entry["fstopt"]:"" != "default")
				partition["fstopt"] = fstab_entry["fstopt"]:"";
			    if (fstab_entry["mountby"]:`device != `device)
				partition["mountby"] = fstab_entry["mountby"]:`device;
			    if (fstab_entry["enc_type"]:`none != `none)
				partition["enc_type"] = fstab_entry["enc_type"]:`none;
			}
		    });
		}

		return partition;
	    });

	    return $[ disk_device : disk ];
	});

	y2milestone("AddFstabToTargetMap new_target_map:%1", new_target_map);

	return new_target_map;
    }


    /**
     * Scan exiting partitions for fstab files and if one found read the mountpoints
     * from the fstab file and build a new target_map.
     * Ask the user if he like to use the new or old target_map
     * (with or without found mountpoints)
     */
    string FstabAddDialog(map<string, map> target_map, map<string, list> fstabs, boolean& format_sys)
    {
	y2milestone("FstabAddDialog target_map:%1", target_map);
	y2milestone("FstabAddDialog fstabs:%1", fstabs);

	if (isempty(fstabs))
	{
	    // popup text
	    Popup::Message(_("No previous system with mount points was detected."));
	    return "";
	}

	list<string> devices = maplist(string device, list fstab, fstabs, { return device; });

	list<symbol> fields = StorageSettings::FilterTable([ `device, `size, `type, `fs_type,
							     `label, `mount_point ]);

	term table_header = StorageFields::TableHeader(fields);

    // help text, richtext format
    string help_text = _("<P><B><BIG>Attention:</BIG></B><BR>YaST2 has scanned your hard disks and found an old Linux system
with mount points. On the right, see a list with the mount points found. </P>
")+
    // help text, richtext format
_("<P>To use these mount points, <BR>press <B>Yes</B>.</P>")+
    // help text, richtext format
_("<P>To ignore these mount points, <BR> press <B>No</B>.</P>");

	term navigate_buttons = `Empty();
	if (size(fstabs) > 1)
	{
	    navigate_buttons = `HBox(
		`PushButton(`id(`show_prev), _("Show &Previous")),
		`PushButton(`id(`show_next), _("Show &Next"))
	    );
	}

    UI::OpenDialog(
	`opt(`decorated),
	    `VBox( `VSpacing(0.45),
		   `ReplacePoint( `id(`heading), `Empty() ),
		   `MarginBox(2, 1,
			      `VBox(
				  `MinSize(60, 8, `Table(`id(`table), `opt(`keepSorting), table_header, [])),
				  `VSpacing(0.45),
				  navigate_buttons,
				  `VSpacing(0.45),
				  `Left(`CheckBox(`id(`format_sys), _("Format system volumes"), true))
				  )
		       ),
		   // popup text
		   `Heading(_("Would you like to use these mount points
for your new installation?")),
		   `VSpacing(0.45),
		   `ButtonBox(
		       `PushButton(`id(`help), `opt(`helpButton), Label::HelpButton()),
		       `PushButton(`id(`ok), `opt(`default), Label::YesButton()),
		       `PushButton(`id(`cancel), Label::NoButton())
		       )
		 )
	     );

    UI::ChangeWidget(`help, `HelpText, help_text);

    symbol userinput = `none;
    integer idx = 0;

    repeat
    {
	string device = devices[idx]:"";

	list<map> fstab = (list<map>) fstabs[device]:[];

	map<string, map> new_target_map = AddFstabToTargetMap(target_map, fstab, format_sys);

	// popup text %1 is replaced by a device name (e.g. /dev/hda1)
	string str = sformat(
_("A previous system with the following mount points was detected:
/etc/fstab found on %1"), device);
	UI::ReplaceWidget( `id(`heading), `Heading( str ) );

	list<term> table_contents = StorageFields::TableContents(fields, new_target_map,
								 StorageFields::PredicateMountpoint);
	UI::ChangeWidget(`id(`table), `Items, table_contents);
	UI::ChangeWidget(`id(`table), `CurrentItem, nil);

	if (size(fstabs) > 1)
	{
	    UI::ChangeWidget(`id(`show_prev), `Enabled, idx > 0);
	    UI::ChangeWidget(`id(`show_next), `Enabled, idx < size(fstabs) - 1);
	}

	userinput = (symbol) UI::UserInput();
	y2milestone("userinput %1", userinput);

	switch (userinput)
	{
	    case `show_next:
		idx = idx + 1;
		break;

	    case `show_prev:
		idx = idx - 1;
		break;
	}
	y2milestone( "idx %1", idx );
	}
    until( userinput == `ok || userinput == `cancel );

    format_sys = (boolean) UI::QueryWidget(`id(`format_sys), `Value);

    UI::CloseDialog();

    string device = userinput == `ok ? devices[idx]:"" : "";
    y2milestone("FstabAddDialog device:%1", device);
    return device;
    }


    void ImportMountPoints()
    {
	Storage::CreateTargetBackup("import");
	Storage::ResetOndiskTarget();

	map<string, map> target_map = Storage::GetOndiskTarget();

	map<string, list> fstabs = ScanAndReadExistingFstabs(target_map);
	y2milestone("ImportMountPoints fstabs:%1", fstabs);

	boolean format_sys = true;
	string device = FstabAddDialog(target_map, fstabs, format_sys);
	if (!isempty(device))
	{
	    y2milestone("ImportMountPoints device:%1", device);
	    list<map> fstab = (list<map>) fstabs[device]:[];

	    map<string, map> new_target_map = AddFstabToTargetMap(target_map, fstab, format_sys);

	    foreach(string d, map disk, new_target_map, {
		foreach(map p, disk["partitions"]:[], {
		    if (!isempty(p["mount"]:"") && p["enc_type"]:`none!=`none &&
			!p["tmpcrypt"]:false)
		    {
			string pwd = DlgCreateCryptFs( p["device"]:"", 1, false, false );
			if( pwd != nil && !isempty(pwd) )
			    Storage::SetCryptPwd( p["device"]:"", pwd );
		    }
		});
	    });

	    Storage::SetTargetMap(new_target_map);
	}
	else
	{
	    Storage::RestoreTargetBackup("import");
	}

	Storage::DisposeTargetBackup("import");
    }

}

ACC SHELL 2018