ACC SHELL

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

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

    import "PackageCallbacks";
    import "PackageSystem";


    //boolean initialized = false;
    map <string, map> target_map = $[];
    boolean already_initialized = false;

    void CreateNfsMainPanel(any user_data)
    {
	list <map> nfs_list = [];
	symbol Predicate(map disk, map partition)
	{
	    return StorageFields::PredicateDiskType(disk, partition, [`CT_NFS]);
	}

	term CreateContent()
	{
	    boolean pkg_installed = false;
	    //fallback dialog content
	    term fallback_content = `VBox (
				`Left( `Label(_("NFS configuration is not available. Check yast2-nfs-client package installation.")) ),
				`VStretch(),
				`HStretch()
			    );

	    //Check if we have y2-nfs-client installed
	    if ( !Stage::initial() )
	    {
		list <string> pkgs = [ "yast2-nfs-client" ];
	        PackageCallbacks::RegisterEmptyProgressCallbacks();
	        pkg_installed = PackageSystem::CheckAndInstallPackages(pkgs);
	        PackageCallbacks::RestorePreviousProgressCallbacks();
	    }
	    //in inst-sys, have a look at nfs-client4part adapter client
	    else
	    {
		string filename = "nfs-client4part";
		pkg_installed = WFM::ClientExists(filename);
	    }

	    if ( pkg_installed )
	    {
	        term content = (term) WFM::CallFunction("nfs-client4part", ["CreateUI"]);
		if ( content != nil )
		    return content;
		else
		    y2error("Failed to retrieve dialog content from yast2-nfs-client");
	    }

	    //Obviously something went wrong - reset the help text and put a fallback content in
	    Wizard::SetHelpText(" ");
	    return fallback_content;
	}

        void Initialize()
	{
	    target_map = Storage::GetTargetMap();

	    //No NFS shares so far, set empty 'partitions' list
	    if( !haskey( target_map, "/dev/nfs" ) )
	        target_map["/dev/nfs"] = $[ "type" : `CT_NFS, "partitions" : [] ];
	    nfs_list = target_map["/dev/nfs", "partitions"]:[];

	    y2milestone("Found NFS shares: %1", nfs_list);

	    if( !Stage::initial() && !already_initialized )
	    {
		y2milestone("Reading NFS settings");
	        WFM::CallFunction("nfs-client4part", ["Read"]);
	        already_initialized = true;
	    }

	}



	UI::ReplaceWidget(`tree_panel,
			  Greasemonkey::Transform(
			      `VBox(
				  `HStretch(),
				  // heading
				  `IconAndHeading(_("Network File System (NFS)"), StorageIcons::nfs_icon),
			          CreateContent()
				  )
			      )
	    );

	Initialize();

	WFM::CallFunction("nfs-client4part", [ "FromStorage", $[ "shares" : nfs_list] ] );
    }


    void HandleNfsMainPanel(any user_data, map event)
    {

	void AddShare ( map <string, any> entry )
	{
	    y2milestone("Adding NFS share: %1 mountpoint: %2 options: %3",
                         entry["device"]:"", entry["mount"]:"", entry["fstopt"]:"");
            target_map = Storage::GetTargetMap();
	    list<map> nfs_list = target_map["/dev/nfs", "partitions"]:[];

	    string device = entry["device"]:"";
	    string mount = entry["mount"]:"";
	    string opts = entry["fstopt"]:"";
	    boolean nfs4 = entry["vfstype"]:"nfs" == "nfs4";

	    integer sizeK = Storage::CheckNfsVolume(device, opts, nfs4);
	    if (sizeK <= 0)
	    {
		//rollback only if user does not want to save (#450060)
		//the mount might fail later if the errors are not corrected, but the user has been warned
		if (  !Popup::YesNo( sformat( _("Test mount of NFS share '%1' failed.\nSave it anyway?"), entry["device"]:"")) )
		{
		    WFM::CallFunction("nfs-client4part", [ "FromStorage", $[ "shares" : nfs_list] ] );
		    return;
		}
		y2warning("Test mount of NFS share %1 failed, but user decided to save it anyway - this might not work.", entry["device"]:"");

		//this really sucks - but libstorage returns negative integers (error code) instead of
		//real size - Perl then wants to die in addNfsVolume call
		sizeK = 0;
	    }
	    Storage::AddNfsVolume(device, opts, sizeK, mount, nfs4);
        }

	void EditShare( map <string, any> entry )
	{
	    y2milestone("Changing NFS share: %1 mountpoint: %2 options: %3",
                         entry["device"]:"", entry["mount"]:"", entry["fstopt"]:"");

	    //device got renamed -
	    //delete the one with old name and create new
	    if (haskey(entry,"old_device"))
	    {
		Storage::DeleteDevice(entry["old_device"]:"");
		AddShare(entry);
	    }
	    else
	    {
	        string dev = entry["device"]:"";
                target_map = Storage::GetTargetMap();
	        list<map> nfs_list = target_map["/dev/nfs", "partitions"]:[];

	        nfs_list = maplist ( map m, nfs_list, {
		    if( m["device"]:"" == dev)
		    {
		        m["fstopt"] = entry["fstopt"]:"";
	                m["mount"] = entry["mount"]:"";
			m["vfstype"] = entry["used_fs"]:`nfs == `nfs ? "nfs" : "nfs4";
		    }
		    return m;
	        });
	        target_map["/dev/nfs", "partitions"] = nfs_list;
	        Storage::SetTargetMap( target_map );
	    }
	}

	void DeleteShare( map <string, any> entry )
	{
	    y2milestone("Deleting NFS share: %1 mountpoint: %2 options: %3",
                         entry["device"]:"", entry["mount"]:"", entry["fstopt"]:"");
	    string dev = entry["device"]:"";

	    Storage::DeleteDevice(dev);
	}

	map <string, any> line = ( map <string, any> ) WFM::CallFunction("nfs-client4part", [ "HandleEvent", $[ "widget_id" : Event::IsWidgetActivated(event) ] ]);

	//do something only if y2-nfs-client returns some reasonable data
	if ( line != $[] && line != nil)
	{
	    switch (Event::IsWidgetActivated(event))
	    {
	        case `newbut:
	        {
		    AddShare( line );
		    break;
	        }
	        case `editbut:
	        {
		    EditShare( line );
		    break;
	        }
	        case `delbut:
	        {
		    DeleteShare( line );
		    break;
	        }
	        default:
		    break;
	     }
	     UI::SetFocus(`id(`fstable));
	     UpdateMainStatus();
	}
	//FIXME: Take care that non-fstab settings of nfs-client
	//(firewall, sysconfig, idmapd) get written on closing partitioner
    }

    void CreateNfsPanel(any user_data)
    {
	//a hack - we don't have overviews for nfs dirs, so let's switch to the main panel ...
	CreateNfsMainPanel( user_data );
	UI::ChangeWidget(`tree, `CurrentItem, `nfs );
    }

}

ACC SHELL 2018