[wpkg-users] [Bug 175] Test return value of removeSettingsNode function

Rainer Meier r.meier at wpkg.org
Sun Oct 4 23:36:42 CEST 2009


Hi Simon,

simplesi wrote:
> Starting from the beginning again :)
> 
> I adminster several small school networks and use wpkg to deploy packages to
> several machines if it is quicker to use wpkg than to go around all
> computers and do a manual install.

Same here. Well, that's what WPKG was designed for.


> I want to be able to test a new package out or a modified one on an existing
> live system.
> I do this by trying to allocate/modify a package on one computer.


The way I would do it is to duplicate the WPKG share and let your test machines
using this specific installation.
In fact that's the only clean way to do it since WPKG does not support multiple
times the same package (same ID) with different revisions. So If you use only
one installation even if you change the profile of the "test" machine only the
others will perform an upgrade too.
Therefore a second instance of your WPKG share easily allows you to copy back
and forth your package definitions. Even moving a system from the "WPKG test" to
"WPKG production" environment is no problem since WPKG does not care about
profiles, it just cares about the packages assigned.

Another way using one single installation would be to create a completely new
package. E.g.
Having package "firefox" assigned to all machines and create a completely new
package called "firefox-test" and assign it (in addition to the "firefox"
package) to the test node. But this way it will always execute the "install"
command of the "firefox-test" package. You might specify the same commands as
for upgrade in the install command too. After successful testing you would have
to replace "firefox" by "firefox-test" package which will make the other
machines upgrading. This will also make your test node to remove the
firefox-test package and install the upgrade of "firefox". This should not be a
problem since you said "firefox-test" would not include a remove command. So
WPKG would just remove the package without leaving any trace.




> In practice, I have found this difficult to achieve this cleanly without
> breaking something sometimes :(

As I said, the best approach seems to be to dedicate a few (or one) machine for
testing and point them to another WPKG instance.


> Currently, WPKG will remove a package entry from WPKG.xml if it decides that
> the package is no longer required for that computer.

This is true.


> Even with the two exisiting flags (noremove and noforced remove) WPKG will
> still remove the package entry from WPKG.xml under certain circumstances.

Could you explain this "certain circumstances" in a bit more detail because it
might be a bug. I've checked the code and wpkg.xml entries are only removed in
the removePackage function. And all of them are completely skipped if the
/noremove flag (or noremove config) is set. In this case no remove commands are
executed at all and wpkg.xml is not touched at all.
The only way to touch wpkg.xml while the /noremove flag is set is to add a new
entry (or replace an existing one). But as you said you don't want to keep a
history but just don't want wpkg.xml to be modified if a package is removed but
no command is executed.

Exactly this should be achieved by the /noremove flag - the removePackage
function is invoked by the whole removal processing is skipped (including the
modification of wpkg.xml).

The drawback of this is of course, that you disable ALL remove commands for all
packages. But as I understood from your information NONE of your packages use
remove commands - so you can use /noremove permanently.
If not then setting /noremove during your test phase might be OK because I
understood that you're just afraid that packages are removed from wpkg.xml when
you do a mistake and the "problem" seems to be that WPKG has to re-install these
packages after you fixed your configuration.

So please try again the /noremove flag and report exactly in which case it
removes entries from wpkg.xml.


> If a mistake is made, and then later rectified, then WPKG thinks it hasn't
> installed a package and attempts re-install.

Yes true. This is what WPKG is used for - it fixes your mistakes too making sure
exactly the packages you assign are installed on the node. But I agree it might
trigger another update - which is in fact only done because you made a mistake
before.
In addition most installers terminate quite quickly (MSI...) if the application
is already installed. So usually this re-install is not an issue at all.
If it is because you use custom scripts/installers which take lots of resources
and therefore are a real issue to re-install you might extend these packages by
a check which allows WPKG to detect if the software is installed already.
This will make WPKG think this package is "new" to the host and it first checks
if the software is alredy there. If it is (checks are true) then no install
command is executed and you're done. That's what checks are there for.

You could also add checks to your installer scripts (install command) which will
make it terminate immediately if it has been applied already.

All in all re-installing of software has never been a problem to me and anybody
else I know. In addition WPKG already supports mechanisms (checks) to prevent
unnecessary re-installs - in addition checks would allow WPKG to verify on every
run that the package is still in place and fix it if it's not.


> IF I programmed a package with checks - I could probably work around this
> but I don't. I don't use checks and I dont use remove commands. I just have
> an install command to install and an update command to update -very simple
> :)

What does you provent inserting one single line into the package - a check?
One main purpose of checks are exactly what you describe: Prevent mistakes.

If you really don't want it - then try the /noremove flag again.


> If I could have a flag to stop WPKG from removing package entries, then when
> my mistake is rectified, wpkg would not attempt a re-install.

Actually it sounds to me that you just want to prevent WPKG from removing
anything during this test phase - no matter which mistake you do on the
profiles. The /noremove flag should do this. If not I am really open to get a
debug log from you which shows what happens.


> Its that simple :)

As I said it's supposed to support your use case already - even you can enable
it on temporary base using noremove in config.xml.
In fact your description contains quite a lot of "if I do this mistake, then do
this mistake... WPKG should still do this..." which I really don't like because
the Administrator has some responsability and the know-how to administrate this
tools. WPKG has to assume that the input data contains what the administrator
intends to do. So if a package is removed it has to assume the administrator
wants it to be removed from the client.



> function removeSettingsNodeSW(packageNode, saveImmediately) {
> // sw modified to stop removal if no remove instructions found
> 	if (getPackageCmdRemove(packageNode).length > 0) {

Here you have to be very careful. During package installation "packageNode" will
be a reference to the _new_ node read from packages.xml.
During package removal this will be the _old_ node read from wpkg.xml.
The remove commands might be different for new/old package.

> 		// make sure the settigngs node is selected
> 		var packageID = getPackageID(packageNode);
> 		dinfo("Removing package id '" + packageID + "' from settings.");
> 		var settingsNode = getSettingNode(packageID);
> 		var success = false;
> 		if(settingsNode != null) {
> 			success = removeNode(getSettings(), settingsNode);
> 		}
> 		// save settings if remove was successful
> 		if (success && saveImmediately) {
> 			saveSettings();
> 		}
> 		return success;
> 	} else {
> 		var packageID = getPackageID(packageNode);
> 		dinfo("package id '" + packageID + "' not removed as no remove
> instructions found.");
> 		var success = false;
> 		return success;
> 	}
> 	
> }
> 
> and then the calling code should check the return success value

Actually if you really do not succeed using /noremove you might try the
following easy change on your local machine:

1. use your removeSettingsNode; You might just have a single-liner in your case
since you never want to remove any settings node as far as I understood:
function removeSettingsNodeSW(packageNode, saveImmediately) {
	return false;
}


2. Modify addSettingsNode in order to work without using removeSettingsNode:
function addSettingsNode(packageNode, saveImmediately) {
	// first remove entry if one already exists

	// get current settings node
	var packageID = getPackageID(packageNode);
	var settingsNode = getSettingNode(packageID);

	if (settingsNode != null) {
		dinfo("Removing currently existing settings node first: '" +
				getPackageName(settingsNode) + "' (" + getPackageID(settingsNode) +
				"), Revision " + getPackageRevision(settingsNode));
		removeNode(getSettings(), settingsNode);
	}

	dinfo("Adding settings node: '" +
			 getPackageName(packageNode) + "' (" + getPackageID(packageNode) +
			 "), Revision " + getPackageRevision(packageNode));

	var success = addNode(getSettings(), packageNode);
	// save settings if remove was successful
	if (success && saveImmediately) {
		saveSettings();
	}
	return success;
}


Actually you should only have to change line 614 from
removeSettingsNode(settingsNode, false);
to
removeNode(getSettings(), settingsNode);


Completely untested of course. But this would prevent WPKG to remove any
wpkg.xml entry at any stage while it still allows to insert entires into wpkg.xml.

br,
Rainer



More information about the wpkg-users mailing list