/**
 * File:
 *   modules/NfsServer.ycp
 *
 * Module:
 *   Configuration of nfs_server
 *
 * Summary:
 *   NFS server configuration data, I/O functions.
 *
 * Authors:
 *   Martin Vidner <mvidner@suse.cz>
 *
 * $Id: NfsServer.ycp 20276 2004-11-10 12:09:38Z mvidner $
 *
 */

{
    module "NfsServer";
    textdomain "nfs_server";

    import "Progress";
    import "Report";
    import "Service";
    import "Summary";
    import "SuSEFirewall";
    import "Wizard";


    /* default value of settings modified */
    global boolean modified = false;


    /**
     * Function sets internal variable, which indicates, that any
     * settings were modified, to "true"
     */
    global define void SetModified () {
        modified = true;
    }

    /**
     * Functions which returns if the settings were modified
     * @return boolean  settings were modified
     */
    global define boolean GetModified () {
        return modified;
    }


    global define void Set (map settings);

    /**
     * Required packages for this module to operate
     *
     */
    global list<string> required_packages = ["nfs-utils"];


    /**
     * Write only, used during autoinstallation.
     * Don't run services and SuSEconfig, it's all done at one place.
     */
    global boolean write_only = false;


    /**
     * Should the server be started?
     * New since 9.0: Exports are independent of this setting.
     */
    global boolean start = false;

    /**
     * @example
     * [
     *   $[
     *     "mountpoint": "/projects",
     *     "allowed": [ "*.local.domain(ro)", "@trusted(rw)"]
     *   ],
     *   $[ ... ],
     *   ...
     * ]
     *
     */
    global list<map<string,any> > exports = [];

    /**
     * Do we have nfslock? (nfs-utils: yes, nfs-server: no)
     */
    boolean have_nfslock = true;

    /**
     * Get all NFS server configuration from a map.
     * When called by nfs_server_auto (preparing autoinstallation data)
     * the map may be empty.
     * @param settings	$["start": "exports":]
     * @return	success
     * @see	exports
     */
    global define boolean Import (map settings) ``{
	/*
	if (size (settings) == 0)
	{
	    // Reset - just continue with Set (#24544).
	}*/

	// To avoid enabling nfslock if it does not exist during autoinstall
	have_nfslock = (boolean) SCR::Read (.init.scripts.exists, "nfslock");
	Set (settings);
	return true;
    }

    /**
     * Set the variables just as is and without complaining
     * @param  settings
     * @return void
     */
    global define void Set (map settings)
	``{
	start = settings["start_nfsserver"]:false;
	exports = settings["nfs_exports"]:[];
	return;
    }


    /**
     * Dump the NFS settings to a map, for autoinstallation use.
     * @return	$["start": "exports":]
     * @see	exports
     */
    global define map Export () ``{
	return $[
	    "start_nfsserver": start,
	    "nfs_exports": exports,
	    ];
    }

    /**
     * Reads NFS settings from the SCR (.etc.exports)
     * @return true on success
     */
    global define boolean Read () ``{
	start = Service::Enabled("nfsserver");
	exports = (list<map<string,any> >) SCR::Read (.etc.exports);
	have_nfslock = (boolean) SCR::Read (.init.scripts.exists, "nfslock");

	SuSEFirewall::Read ();

	return exports != nil;
    }


    /**
     * Saves /etc/exports and creates missing directories.
     * @return true on success
     */
    global define boolean WriteExports () ``{
	    // create missing directories.
	    foreach (map<string, any> entry, exports, ``{
		string directory = (string) (entry["mountpoint"]:nil);
		if (SCR::Read (.target.dir, directory) == nil)
		{
		    if (! (boolean) SCR::Execute (.target.mkdir, directory))
		    {
			// not fatal - write other dirs.
			Report::Warning (sformat(_("Unable to create a missing directory:\n%1"), directory));
		    }
		}
	    });

	    // (the backup is now done by the agent)
	    if (! SCR::Write(.etc.exports, exports))
	    {
		// error popup message
		Report::Error (_("Unable to write to /etc/exports.
No changes will be made to the
exported directories.\n"));
		return false;
	    }

	    return true;
    }

    /**
     * Saves NFS server configuration. (exports(5))
     * Creates any missing directories.
     * @return true on success
     */
    global define boolean Write () ``{
	// if there is still work to do, don't return false immediately
	// but remember the error
	boolean ok = true;

	// dialog label
	Progress::New (_("Writing NFS Server Configuration..."), " ", 2, [
	    // progress stage label
	    _("Save /etc/exports"),
	    // progress stage label
	    _("Restart services"),
	   ], [
	    // progress step label
	    _("Saving /etc/exports..."),
	    // progress step label
	    _("Restarting services..."),
	    // final progress step label
	    _("Finished") ],
	    "" );

	// help text
	if (!write_only)
		Wizard::RestoreHelp(_("Writing NFS server settings"));

	Progress::NextStage ();

	// Independent of @ref start because of Heartbeat (#27001).
	if (! WriteExports ())
	{
	    Progress::Finish ();
	    return false;
	}

	Progress::NextStage ();

	if (!start)
	{
	    if (!write_only)
		Service::Stop ("nfsserver");

	    if (! Service::Disable("nfsserver"))
	    {
		Report::Error(Service::Error());
		ok = false;
	    }
	    if (have_nfslock)
	    {
		if (!write_only)
		    Service::Stop("nfslock");
		if (! Service::Disable("nfslock"))
		{
		    Report::Error(Service::Error());
		    ok = false;
		}
	    }
	}
	else
	{
	    if (! Service::Enable("portmap"))
	    {
		Report::Error (Service::Error());
		ok = false;
	    }
	    if (have_nfslock)
	    {
		if (! Service::Enable("nfslock"))
		{
		    Report::Error(Service::Error());
		    ok = false;
		}
	    }
	    if (! Service::Enable("nfsserver"))
	    {
		Report::Error(Service::Error());
		ok = false;
	    }

	    if (!write_only)
	    {
		if (Service::Status("portmap") != 0 )
		{
		    // portmap must not be started if it is running already (see bug # 9999)
		    Service::Start("portmap");
		}

		Service::Stop("nfsserver");
		if (have_nfslock)
		{
		    Service::Restart("nfslock");
		}
		Service::Start("nfsserver");

		if (Service::Status("nfsserver") != 0)
		{
		    // error popup message
		    Report::Error (_("Unable to restart the NFS server.
Your changes will be active after reboot.
"));
		    ok = false;
		}
	    }
	}

	SuSEFirewall::WriteOnly ();
	if (!write_only)
	{
	    SuSEFirewall::ActivateConfiguration ();
	}

	Progress::NextStage ();

	return ok;
    }

    /**
     * @return A summary for autoyast
     */
    global define string Summary() ``{
	string summary = "";
	// summary header; directories exported by NFS
	summary = Summary::AddHeader (summary, _("NFS Exports"));
	if (size (exports) > 0)
	{
	    foreach(map e, exports, ``{
		summary = Summary::OpenList (summary);
		summary = Summary::AddListItem (summary, e["mountpoint"]:"");
		summary = Summary::CloseList (summary);
	    });
	}
	else
	{
	    summary = Summary::AddLine (summary, Summary::NotConfigured ());
	}
	return summary;
    }


	/**
	* Return required packages for auto-installation
	* @return map of packages to be installed and to be removed
	*/
	global define map AutoPackages() ``{
		return ($["install": required_packages, "remove": []]);
	}



  /* The end of the definitions */

}
