Hello community, here is the log from the commit of package zmd-inventory checked in at Thu Jun 1 00:39:50 CEST 2006. -------- --- zmd-inventory/zmd-inventory.changes 2006-04-07 16:19:01.000000000 +0200 +++ zmd-inventory/zmd-inventory.changes 2006-06-01 00:15:53.000000000 +0200 @@ -1,0 +2,6 @@ +Thu Jun 1 00:15:30 CEST 2006 - maw@suse.de + +- New source drop (r29477) which: +- Implements software inventory for Novell Update services. + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ zmd-inventory.spec ++++++ --- /var/tmp/diff_new_pack.PkkjgR/_old 2006-06-01 00:39:42.000000000 +0200 +++ /var/tmp/diff_new_pack.PkkjgR/_new 2006-06-01 00:39:42.000000000 +0200 @@ -14,7 +14,7 @@ BuildRequires: hwinfo-devel log4net mono-basic mono-data-sqlite mono-devel update-desktop-files zmd-devel URL: http://www.novell.com Version: 7.1.1.0 -Release: 1 +Release: 8 License: LGPL BuildRoot: %{_tmppath}/%{name}-%{version}-build Source0: %name-%version.tar.bz2 @@ -59,6 +59,9 @@ %{_prefix}/lib/zmd/modules/* %changelog -n zmd-inventory +* Thu Jun 01 2006 - maw@suse.de +- New source drop (r29477) which: +- Implements software inventory for Novell Update services. * Fri Apr 07 2006 - thunder@suse.de - New source drop (svn r26837): - Fix so it builds with latest zmd. ++++++ zmd-inventory-7.1.1.0.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/zmd-inventory-7.1.1.0/src/ChangeLog new/zmd-inventory-7.1.1.0/src/ChangeLog --- old/zmd-inventory-7.1.1.0/src/ChangeLog 2006-04-07 16:09:22.000000000 +0200 +++ new/zmd-inventory-7.1.1.0/src/ChangeLog 2006-05-31 19:43:07.000000000 +0200 @@ -1,3 +1,16 @@ +2006-05-30 Dan Mills <thunder@ximian.com> + + * Makefile.am: Link with CookComputing.XmlRpc.dll (from the zmd + module directory), and add NUXmlRpcClient.cs. + + * NUInventory.cs: Flesh out software inventory. Should be pretty + much complete now; except for some severity strings that need to + be added to the comparison function. Hardware inventory still + MIA. + + * NUXmlRpcClient.cs: Interface and static class for talking to the + Novell Update XML-RPC inventory service. + 2006-04-07 Dan Mills <thunder@ximian.com> * SoftwareInventory.cs: PackageCollection -> ResolvableCatalog. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/zmd-inventory-7.1.1.0/src/Makefile.am new/zmd-inventory-7.1.1.0/src/Makefile.am --- old/zmd-inventory-7.1.1.0/src/Makefile.am 2006-03-30 06:26:25.000000000 +0200 +++ new/zmd-inventory-7.1.1.0/src/Makefile.am 2006-05-31 19:43:07.000000000 +0200 @@ -10,6 +10,7 @@ ASSEMBLIES = \ -r:System.Web.Services \ + -r:${zmdmoduledir}/CookComputing.XmlRpc.dll \ -pkg:zmd,zmd-package-management INVENTORY_SOURCES = \ @@ -21,7 +22,8 @@ Scanner.cs \ SoftwareInventory.cs \ Util.cs \ - NUInventory.cs + NUInventory.cs \ + NUXmlRpcClient.cs Novell.Zenworks.Zmd.Inventory.dll: $(INVENTORY_SOURCES) $(MCS) -target:library $(ASSEMBLIES) $(INVENTORY_SOURCES) -out:$@ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/zmd-inventory-7.1.1.0/src/Makefile.in new/zmd-inventory-7.1.1.0/src/Makefile.in --- old/zmd-inventory-7.1.1.0/src/Makefile.in 2006-04-07 16:10:16.000000000 +0200 +++ new/zmd-inventory-7.1.1.0/src/Makefile.in 2006-05-31 20:15:19.000000000 +0200 @@ -195,6 +195,7 @@ netadapter_bindir = ${libder}/zmd ASSEMBLIES = \ -r:System.Web.Services \ + -r:${zmdmoduledir}/CookComputing.XmlRpc.dll \ -pkg:zmd,zmd-package-management INVENTORY_SOURCES = \ @@ -206,7 +207,8 @@ Scanner.cs \ SoftwareInventory.cs \ Util.cs \ - NUInventory.cs + NUInventory.cs \ + NUXmlRpcClient.cs CLEANFILES = $(zmdmodule_DATA) netadapter-mapping-glue EXTRA_DIST = \ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/zmd-inventory-7.1.1.0/src/NUInventory.cs new/zmd-inventory-7.1.1.0/src/NUInventory.cs --- old/zmd-inventory-7.1.1.0/src/NUInventory.cs 2006-03-30 06:26:25.000000000 +0200 +++ new/zmd-inventory-7.1.1.0/src/NUInventory.cs 2006-05-31 19:43:07.000000000 +0200 @@ -1,5 +1,8 @@ using System; +using System.IO; +using System.Text; using System.Collections; +using System.Security.Cryptography; using System.Threading; using Novell.Zenworks.Utility; using Novell.Zenworks.Zmd; @@ -7,6 +10,7 @@ using Novell.Zenworks.Zmd.Scheduling; using Novell.Zenworks.Zmd.Packaging; using log4net; +using CookComputing.XmlRpc; using ZENInventory; namespace Novell.Zenworks.Zmd.Inventory { @@ -22,7 +26,7 @@ public static void ServiceAddedHandler (Service svc) { if (svc.ServiceType.Alias.Equals ("nu")) { log.Debug ("Novell Update Service added to inventory list"); - Uris.Add (svc.Uri); + Uris.Add (svc.Uri + ((svc.Uri.EndsWith ("/"))? "" : "/") + "data/RPC2/redcarpet-client.php"); // TODO: we may want to move these somewhere else, but // it doesn't currently matter too much, because there @@ -61,6 +65,7 @@ public class NUSoftwareInventory : InventoryRefresh { private static readonly ILog log = LogManager.GetLogger (typeof (NUSoftwareInventory)); + private static readonly string ChecksumFile = BuildConfig.LOCALSTATEDIR + "/lib/zmd/nu-software-inventory-checksum"; public NUSoftwareInventory () : base () { this.name = "Novell Update Service software inventory"; @@ -68,49 +73,185 @@ } protected override bool SendInventory () { - PatchInfo[] patches = MakePatchInfo (Patch.GetAll ()); - ProductInfo[] products = MakeProductInfo (Product.GetAll ()); + string deviceid = PreferenceManager.GetDeviceID (); + string secret = NUUtil.GetMD5 (deviceid + ":Express:" + PreferenceManager.GetSecret ()); + string target = DaemonProperties.Target.Name; + + ArrayList inventory = new ArrayList (); + inventory.AddRange (MakeXmlRpcResolvable (PackageManager.InstalledPackages.ToResolvables (), "package")); + inventory.AddRange (MakeXmlRpcResolvable (Patch.GetAll (), "patch")); + inventory.AddRange (MakeXmlRpcResolvable (Product.GetAll (), "product")); + + string checksum = NeedUpdate ((XmlRpcResolvable[]) inventory.ToArray (typeof (XmlRpcResolvable))); + if (checksum == null) { + log.Info ("Software inventory has not changed since last inventory refresh; sending updates only."); + inventory.Clear (); + } + + ArrayList updates = new ArrayList (); + updates.AddRange (MakeXmlRpcResolvable (Patch.GetUpdates (), "patch")); + + string maxSeverity = FindMaxSeverity ((XmlRpcResolvable[]) updates.ToArray (typeof (XmlRpcResolvable))); + + bool error = false; foreach (string uri in (string[]) NUInventoryManager.Uris.ToArray (typeof (string))) { - log.Debug (uri); - log.Debug ("FIXME: We don't do anything yet"); + log.Debug (String.Format ("Sending software inventory to NU server '{0}'", uri)); + + try { + INUXmlRpcService nuServer = NUXmlRpcService.Create (uri); + + log.Info (String.Format ("Sending {0} resolvables and {1} resolvable updates. Args:", inventory.Count, updates.Count)); + log.Debug (String.Format ("\tDevice ID: {0}", deviceid)); + log.Debug (String.Format ("\tSecret: {0}", secret)); + log.Debug (String.Format ("\tTarget: {0}", target)); + log.Debug (String.Format ("\tMax Severity: {0}", maxSeverity)); + + if (inventory.Count >= 1) + nuServer.SetResolvables (deviceid, secret, target, (XmlRpcResolvable[]) inventory.ToArray (typeof (XmlRpcResolvable))); + + nuServer.SetResolvableUpdates (deviceid, secret, target, maxSeverity, (XmlRpcResolvable[]) updates.ToArray (typeof (XmlRpcResolvable))); + + } catch (XmlRpcFaultException e) { + log.Error (String.Format ("Error sending software inventory to NU server '{0}': {1} (code {2})", uri, e.FaultString, e.FaultCode), e); + error = true; + return false; + } catch (Exception e) { + log.Error (String.Format ("Error sending software inventory to NU server '{0}'", uri), e); + error = true; + return false; + } finally { + if (!error && checksum != null) { + using (StreamWriter sw = new StreamWriter (ChecksumFile)) { + sw.Write (checksum); + sw.Write ("\n"); + } + } + } } return true; } - private static PatchInfo[] MakePatchInfo (Patch[] patches) { - ArrayList infos = new ArrayList (); - foreach (Patch p in patches) { - infos.Add (MakePatchInfo (p)); + // returns the new checksum that will have to be saved to the + // file if the inventory is successfully sent, or null + // otherwise. + + private static string NeedUpdate (XmlRpcResolvable[] resolvables) { + string newChecksum = GetResolvablesChecksum (resolvables); + + if (!File.Exists (ChecksumFile)) + return newChecksum; + + string oldChecksum; + using (StreamReader sr = new StreamReader (ChecksumFile)) { + oldChecksum = sr.ReadLine (); } - return (PatchInfo[]) infos.ToArray (typeof (PatchInfo)); - } - private static PatchInfo MakePatchInfo (Patch patch) { - PatchInfo p = new PatchInfo (); - return p; + if (oldChecksum == newChecksum) + return null; + + return newChecksum; } - private static ProductInfo[] MakeProductInfo (Product[] products) { - ArrayList infos = new ArrayList (); - foreach (Product p in products) { - infos.Add (MakeProductInfo (p)); + private static string GetResolvablesChecksum (XmlRpcResolvable[] resolvables) { + StringBuilder sb = new StringBuilder (); + + foreach (XmlRpcResolvable r in resolvables) { + sb.Append (r.name); + sb.Append (r.epoch); + sb.Append (r.version); + sb.Append (r.release); + sb.Append (r.arch); + sb.Append (r.type); } - return (ProductInfo[]) infos.ToArray (typeof (ProductInfo)); + + return NUUtil.GetMD5 (sb.ToString ()); } - private static ProductInfo MakeProductInfo (Product product) { - ProductInfo p = new ProductInfo (); - return p; + private static string FindMaxSeverity (XmlRpcResolvable[] resolvables) { + string max = ""; + + foreach (XmlRpcResolvable r in resolvables) { + if (CompareSeverity (r.severity, max) == 1) + max = r.severity; + } + + return max; } - private class PatchInfo { - public PatchInfo () { + // wow, this sucks so hard. + + private static int CompareSeverity (string a, string b) { + string foo = (a == null)? "" : a.ToLower (); + string bar = (b == null)? "" : b.ToLower (); + + if (foo == "" && bar == "") + return 0; + if (foo != "" && bar == "") + return 1; + if (foo == "" && bar != "") + return -1; + + switch (foo) { + case "recommended": + switch (bar) { + case "recommended": + return 0; + case "security": + return -1; + } + break; + case "security": + switch (bar) { + case "recommended": + return 1; + case "security": + return 0; + } + break; } + + log.Error (String.Format ("Unknown severity strings '{0}' / '{1}'", foo, bar)); + return 0; // fixme ? } - private class ProductInfo { - public ProductInfo () { + private static XmlRpcResolvable[] MakeXmlRpcResolvable (IResolvable[] resolvables, string type) { + ArrayList structs = new ArrayList (); + foreach (IResolvable r in resolvables) { + structs.Add (MakeXmlRpcResolvable (r, type)); } + return (XmlRpcResolvable[]) structs.ToArray (typeof (XmlRpcResolvable)); + } + + private static XmlRpcResolvable MakeXmlRpcResolvable (IResolvable resolvable, string type) { + XmlRpcResolvable r = new XmlRpcResolvable (); + r.name = resolvable.Name; + r.epoch = resolvable.Epoch; + r.version = resolvable.Version; + r.release = resolvable.Release; + r.arch = ArchUtility.ToString (resolvable.Arch); + r.type = type; + if (resolvable.Category != null) + r.severity = resolvable.Category; + else + r.severity = ""; + return r; + } + } + + public class NUUtil { + public static string GetMD5 (string input) { + UTF8Encoding encoder = new UTF8Encoding (); + Byte[] bytes = new Byte[input.Length]; + int count = encoder.GetBytes (input, 0, input.Length, bytes, 0); + + HashAlgorithm digest = HashAlgorithm.Create ("MD5"); + byte[] byteHash = digest.ComputeHash (bytes, 0, count); + + string result = ""; + foreach (Byte b in byteHash) + result += b.ToString("x02"); + + return result; } } } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/zmd-inventory-7.1.1.0/src/NUXmlRpcClient.cs new/zmd-inventory-7.1.1.0/src/NUXmlRpcClient.cs --- old/zmd-inventory-7.1.1.0/src/NUXmlRpcClient.cs 1970-01-01 01:00:00.000000000 +0100 +++ new/zmd-inventory-7.1.1.0/src/NUXmlRpcClient.cs 2006-05-31 19:43:07.000000000 +0200 @@ -0,0 +1,31 @@ +using CookComputing.XmlRpc; + +namespace Novell.Zenworks.Zmd.Inventory { + + public struct XmlRpcResolvable { + public string name; + public int epoch; + public string version; + public string release; + public string arch; + public string type; + public string severity; + } + + public interface INUXmlRpcService { + [XmlRpcMethod ("rcserver.machine.setResolvableUpdates")] + void SetResolvableUpdates (string user, string pass, string distro, string maxSeverity, XmlRpcResolvable[] updates); + + [XmlRpcMethod ("rcserver.machine.setResolvables")] + void SetResolvables (string user, string pass, string distro, XmlRpcResolvable[] inventory); + } + + public class NUXmlRpcService { + static public INUXmlRpcService Create (string url) { + XmlRpcClientProtocol proxy = (XmlRpcClientProtocol) XmlRpcProxyGen.Create (typeof (INUXmlRpcService)); + proxy.Url = url; + return (INUXmlRpcService) proxy; + } + } +} + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit-unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit-help@opensuse.org
participants (1)
-
root@suse.de