In working on our upcoming Lion transition/roll-out, I've created a number of setup/configuration packages that are applicable to Lion machines only.
I want to be able to add them to common included manifests for all machines so that if/when they are upgraded to Lion, the machines will automatically have these packages installed without admin action at the time of the Lion upgrade. (I'd like users to be able to schedule/perform their own upgrade to Lion using InstallLion.pkg in optional_installs)
Munki currently has a mechanism (minimum_os_version/maximum_os_version) which causes it to install only the latest version of a package that declares support for a given OS version; I use this a lot, especially with items like Xcode, where a given version of Xcode requires a minimum OS version.
But this feature also issues warnings when it cannot find any version of a given package that is applicable for the current OS (or processor arch). In some cases, this is what you want -- as an admin you want to know that you forgot to add or need to add a version of package Foo that works with OS X 10.7.2.
But in other cases, you know full well that a given package is applicable only for, say, Lion, and you don't want Munki warning you that Snow Leopard machines can't find an applicable version.
A workaround for this issue is to create a dummy package that installs nothing that is applicable for the inverse case, but this is a pain to do if you have a large number of this type of package.
What is needed is a way to tell Munki: here's a package I'd like installed, but if it doesn't apply to the current OS or proc or ???, don't worry about it.
This information can't really be encoded in the pkginfo -- it needs to be one level higher. Foo-1.0 could be for Snow Leopard only, and Foo-2.0 could be for Lion only. Bar-1.0 could be for Lion only, and there is no version of Bar for Snow Leopard. There's currently no way, while looking through the individual versions, that Munki can know that it's OK that it can't find a version of Bar for a Snow Leopard machine. So the info probably needs to be in a manifest.
I just can't seem to wrap my head around a solution to this that is simple, understandable, and flexible.
The best I can come up with is something awfully complex along the lines of:
<key>os_arch_specific</key>
<array>
<dict>
<key>os_version_startswith<key>
<string>10.7</string>
<key>managed_installs</key>
<array>
<string>LionVPNpolicy</key>
<string>Lion802.1Xpolicy</key>
</array>
</dict>
<dict>
<key>os_version_startswith<key>
<string>10.6</string>
<key>managed_installs</key>
<array>
<string>CiscoVPNclient</key>
<string>Our802.1xSetupScript</key>
</array>
</dict>
</array>
The
<key>os_version_startswith<key>
<string>10.7</string>
part is really just a placeholder; we'd need to come up with a full syntax of comparison keys and expressions. I've started looking at the documentation for Cocoa's NSPredicate to see if that might be useable for this.
Any better (simpler!) ideas?
-Greg
Isn't that sufficient data for managedsoftwareupdate to know whether
to through up an error or not?
Let's say Munki is running on Leopard. It needs to install Foo.
Foo-2.0 might have exclude_os_version:{10.3,10.4,10.5}
So great, then Munki's done? That's what this pkginfo implies --- there is NO version of Foo for Leopard.
Whoops, there's a Foo-1.0 that has exclude_os_version:{10.6,10.7}
I just missed that and now the Munki admin posts to munki-dev wondering why Foo-1.0 wasn't installed on his/her Leopard machines.
-Greg
But what if the admin screws up when Foo-2.0 comes out and
That's a great solution and exactly why preflight scripts are useful; it enables munki admins to implement features without having to make changes to the core munki code.
But *I* can easily make changes to the core Munki code, and hopefully do it in a way that is useful to a large number of Munki admins, so they don't have to write and debug scripts.
-Greg
-Greg
#!/usr/bin/python
import sys
import os
from Foundation import NSPredicate
def doComparison(comp_string, obj):
print 'Comparison: %s' % comp_string
p = NSPredicate.predicateWithFormat_(comp_string)
print p.evaluateWithObject_(obj)
print
info = {}
info['os_vers'] = '10.7.2'
info['arch'] = 'x86_64'
print info
print
comparisonstring = 'os_vers MATCHES "10\.7.*"'
doComparison(comparisonstring, info)
-Greg
NSPredicate can do RegEx-style comparisons, too:
comparisonstring = 'os_vers MATCHES "10\.7.*"'
#!/usr/bin/python
import sys
import os
from Foundation import NSPredicate
def doComparison(comp_string, obj):
print 'Comparison: %s' % comp_string
p = NSPredicate.predicateWithFormat_(comp_string)
print p.evaluateWithObject_(obj)
info = {}
info['os_vers'] = '10.7.2'
info['arch'] = 'x86_64'
print info
doComparison(comparisonstring, info)
<key>conditional_items</key>
<array>
<dict>
<key>predicate<key>
<string>os_vers BEGINSWITH "10.7"</string>
<key>managed_installs</key>
<array>
<string>LionVPNpolicy</key>
<string>Lion802.1Xpolicy</key>
</array>
</dict>
<dict>
<key>predicate<key>
<string>os_vers BEGINSWITH "10.6"</string>
<key>managed_installs</key>
<array>
<string>CiscoVPNclient</key>
<string>Our802.1xSetupScript</key>
</array>
</dict>
<dict>
<key>predicate<key>
<string>arch == "powerpc"</string>
<key>managed_installs</key>
<array>
<string>OracleCalendar</key>
</array>
</dict>
</array>
Depending on what keys we define, we could do conditionals on more than OS version and processor architecture. Some possibilities:
Laptop vs Desktop - for example, make some packages automatically available only to laptops
Date (might be tricky since we have to coerce a string into an NSDate) -- this would cause items to be made available in a manifest after a certain date (or NOT after a certain date)
AvailableDiskSpace
ConsoleUser (that's a bit crazy...)
Amount of RAM
Etc....
-Greg
I really like the simplicity of the current manifest structure which
in short says "on this host install or uninstall this set of
packages", with some complexity to allow for optional installs and
updates. If munki were to include configuration options based upon OS
for a given package or set of packages it would be putting package
information in two places (manifests and pkgsinfo). Remember with
Lion, the OS version is just another package. We could extend this
logic to say "if Adobe CS 5 is installed, then install Plug-IN-X" etc
etc.
Whether a package should be ignored for a given OS is a package
quality, not a manifest quality. The place to add another layer is in
pkgsinfo.
In the interest of being solution oriented, I offer the following.
I don't know the best naming convention here, but let's start with
adding a new type of file in pkgsinfo, which I will call
foo-all_versions.plist for lack of a better name (please think of
something better). This file contains the next level of package
information for foo-1.0.plist and foo-2.0.plist. For example,
foo-all_versions.plist can have the configuration elements saying
which version of foo goes with which OS:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>foo</string>
<key>version</key>
<string>all</string>
<key>os_arch_specific</key>
<array>
<dict>
<key>os_version_startswith</key>
<string>10.7</string>
<key>version_works_with</key>
<array>
<string>7.0.1</string>
<string>7.5.*</string>
</array>
<key>os_version_startswith</key>
<string>10.6</string>
<key>version_works_with</key>
<array>
<string>6.*</string>
</array>
</dict>
</array>
</dict>
</plist>
In this, name:{foo} matches the name key in foo-1.0.plist and
foo-2.0.plist. It is the key that ties all the pkgsinfo files
together. The key-value version:{all} tells munki that this package
applies to all versions of name:{foo} and is what makes it at the next
level.
After that the key-values provides the configuration information
necessary for managessoftwareupdate to determine which version to
install. This level of pkgsinfo file is also a place redundant
information currently found in both foo-1.0.plist and foo-2.0.plist
(and not likely to change when foo-3.0.plist is released) could live.
It seems to me that putting pkgsinfo logic in manifests will subtract
from the munki's simplicity. Just look at
http://code.google.com/p/munki/wiki/Manifests to see how easy it is to
create a manifest.
Raúl
> There's currently no way, while looking through the individual versions, that Munki can know that it's OK that it can't find a version of Bar for a Snow Leopard machine.
Why can't there just be a boolean that says, in effect, imply a "null" package if min_os/max_os don't apply? That is, if no versions of this package match in the repo, and one of them had this flag to true, assume the package is installed/not installed.
--Jim
-Greg
> This makes perfect sense. I now understand why the exclude_os_version
> would have to live at another level than the existing pkgsinfo level.
>
> I really like the simplicity of the current manifest structure which
> in short says "on this host install or uninstall this set of
> packages", with some complexity to allow for optional installs and
> updates.
No-one would have to use the conditional items. That would be an "advanced" feature!
> If munki were to include configuration options based upon OS
> for a given package or set of packages it would be putting package
> information in two places (manifests and pkgsinfo). Remember with
> Lion, the OS version is just another package. We could extend this
> logic to say "if Adobe CS 5 is installed, then install Plug-IN-X" etc
> etc.
Munki already supports this using "update_for".
>
> Whether a package should be ignored for a given OS is a package
> quality, not a manifest quality.
When you phrase it that way.
But if you phrase it like this:
"Only install these items if the machine meets the following criteria: []"
then it makes sense to put it in a manifest, which determines what should be installed on a machine.
This seems more complex than my proposal.
Something I implied, but did not make explicit for my proposal, was that you could include more than managed_installs -- you could conditionally do managed_uninstalls and optional_installs:
<key>conditional_items</key>
<array>
<dict>
<key>predicate<key>
<string>os_vers BEGINSWITH "10.7"</string>
<key>managed_installs</key>
<array>
<string>LionVPNpolicy</key>
<string>Lion802.1Xpolicy</key>
</array>
<key>managed_uninstalls</key>
<array>
<string>CiscoVPNclient</key>
</array>
</dict>
<dict>
<key>predicate<key>
<string>arch == "x86_64"</string>
<key>optional_installs</key>
<array>
<string>Some64BitOnlyApplication</key>
</array>
</dict>
</array>
>
> In this, name:{foo} matches the name key in foo-1.0.plist and
> foo-2.0.plist. It is the key that ties all the pkgsinfo files
> together. The key-value version:{all} tells munki that this package
> applies to all versions of name:{foo} and is what makes it at the next
> level.
>
> After that the key-values provides the configuration information
> necessary for managessoftwareupdate to determine which version to
> install. This level of pkgsinfo file is also a place redundant
> information currently found in both foo-1.0.plist and foo-2.0.plist
> (and not likely to change when foo-3.0.plist is released) could live.
>
> It seems to me that putting pkgsinfo logic in manifests will subtract
> from the munki's simplicity. Just look at
> http://code.google.com/p/munki/wiki/Manifests to see how easy it is to
> create a manifest.
>
And that won't change for the simple case.
My reason for wanting it in the pkginfo is entirely selfish: I'm programmatically constructing manifests based on selections from a web ui (WUI?), and right now don't have any version matching, so I'd prefer it be pushed to the pkginfos. Eventually I'll code around this, but not quite done yet :)
On the side, it'd be awesome if Munki added a header that was the OS version :)
--Jim
> Definitely a concern. I'd say that once true it's always true.
>
> My reason for wanting it in the pkginfo is entirely selfish: I'm programmatically constructing manifests based on selections from a web ui (WUI?), and right now don't have any version matching, so I'd prefer it be pushed to the pkginfos. Eventually I'll code around this, but not quite done yet :)
>
> On the side, it'd be awesome if Munki added a header that was the OS version :)
What do you mean by this?
> Definitely a concern. I'd say that once true it's always true.
>
> My reason for wanting it in the pkginfo is entirely selfish: I'm programmatically constructing manifests based on selections from a web ui (WUI?), and right now don't have any version matching, so I'd prefer it be pushed to the pkginfos. Eventually I'll code around this, but not quite done yet :)
But if you are programmatically construction manifests, you can probably avoid the issue I'm working on entirely, by simply not adding non-applicable items to your generated manifest.
(similar to Heig's solution, and I think also how Simian handles things when it dynamically generates manifests for its clients)
-Greg
> I agree that there is room in manifest for advanced conditional information. "If laptop install X" would be simplier than the manifest_include method I'm using.
>
> I just think (at this point in the discussion) that conditional package info should be in the pkgsinfo directory. Isn't update_for a pkgsinfo key?
Yes.
And typically any item that has an "update_for" key is NOT explicitly added to any manifest.
Let's approach this another way:
managed_installs
This is a list of things that MUST be installed on the machine.
The admin should be warned if something has prevented these items from being installed.
managed_uninstalls
This is a list of things that MUST be removed if they are found on the machine.
The admin should be warned if something has prevented these items from being uninstalled.
managed_updates
This is a list of things that -- if some version is ALREADY installed -- should be updated if needed to the latest version Munki knows about, and should have any items that are marked as "update_for" this item installed.
The admin should be warned if something has prevented updates for these items from being installed.
optional_installs
This is a list of things that a user of the machine can choose to install or uninstall. Once chosen for install or uninstall, the admin should be warned if something has prevented the install/uninstall from happening.
But we've identified a class of items that should be conditionally installed (or uninstalled). That is, if the conditions are met, the items should be treated as if they are in one of the above lists (minus maybe managed_updates). If the conditions are not met, Munki should act as though these items are not in the manifest -- it should not search the catalogs at all for more info on these items.
That's my argument for why this info should be in a manifest and not in pkginfo.
-Greg
My simplest idea would be in a manifest:
managed_installs
managed_installs_if_possible
The second form would suppress this class of warnings further down the chain.
That said - the conditional in a manifest is powerful - the power only limited by what 'info' dictionary you make availalbe to it.
What I'd be more interested in is conditionals in the pkginfo:
- install "RemoveOldOffice&accessories"
- if: MSOffice2011 is installed AND not flag-keep-old-versions.
This would also allow setting conditions to allow a downgrade where an updated version has proved bad.
Much much more for the admin to debug when something doesn't work though.
Rob.
>> On the side, it'd be awesome if Munki added a header that was the OS version :)
>
> What do you mean by this?
That Munki would add an X-Mac-OS-Version header to the http request being sent, e.g., "X-Mac-OS-Version: 10.7.2 (11C74)".
>> I'm programmatically constructing manifests
> But if you are programmatically construction manifests, you can probably avoid the issue I'm working on entirely, by simply not adding non-applicable items to your generated manifest.
Absolutely, but I don't have information about what OS release is on a system before I'm asked for the manifest to construct. That is, when a client connects, I don't actually know if it has 10.6 or 10.7; in our wildly decentralized environment there's no way for me to control it either. So I have "dead" entries for Java for 10.6 so that the Adobe suites can depend on a Java package.
I could get the version info the report file, but that is generated and sent during the postflight stage, not before the manifest is requested.
So: if Munki sent the OS release as an additional header, I could programmatically write the manifest, and that would be perfect. I can submit a patch.
--Jim
On Nov 17, 2011, at 4:38 PM, Greg Neagle wrote:On Nov 17, 2011, at 1:37 PM, Zajkowski, James wrote:On the side, it'd be awesome if Munki added a header that was the OS version :)What do you mean by this?
That Munki would add an X-Mac-OS-Version header to the http request being sent, e.g., "X-Mac-OS-Version: 10.7.2 (11C74)".
I find this whole discussion very helpful and one of the reasons I am
happy we went with munki. That this thread also crashed my mobile when
I was trying to reply to it in the subway is just an added bonus.
I am going to restate my concerns as a customer of munki.
* As a SysAdmin, I need to be able to troubleshoot my repo quickly no
matter how many packages and hosts it manages.
Comment: New levels of tags within conditional tags, seems like it
will slow me down. Perhaps a tool that can run with command line or
config file inputs to see how a given host will react against a
manifest will be necessary. Or perhaps the times I have to use
conditions will be low enough that it will be manageable.
* As a SysAdmin, I need to be able to quickly create the plists used by munki.
Comment: makecatalogs makes it trivial to create catalogs. munkiimport
and makepkgsinfo do this for pkgs and pkgsinfo. Will manifestutil do
this for manifests? Right now all I need is vim to make manifests. If
certain packages require these conditions, then I will have no choice
but to use them to have a clean install. The alternative now is to
have different manifest files when a host is upgraded from one OS
version to the next, which is not scalable for large self-managed
population.
* As a SysAdmin, it would be very convenient to set up a manifest that
doesn't have to change as the clients that use it are upgraded to new
OS versions.
Comment: I think this is what you are trying to achieve with these new features.
Raul
The alternative now is to
have different manifest files when a host is upgraded from one OS
version to the next, which is not scalable for large self-managed
population.
* As a SysAdmin, it would be very convenient to set up a manifest that
doesn't have to change as the clients that use it are upgraded to new
OS versions.
Comment: I think this is what you are trying to achieve with these new features.
Have you looked at Simian as a server for Munki? It may largely answer your desire for deterministic management even as complexity is added.
Cheers,
Rob.
Most importantly this wouldn't break anything that already exists and would be optional like the other keys in manifest files. It would still be possible for new users to write simple manifests without having to touch predicates.
--
Hannes Juutilainen
Parent manifest:
<key>catalogs</key>
<array>
<string>testing</string>
<string>production</string>
</array>
<key>included_manifests</key>
<array>
<string>conditional/LionConfig</string>
<string>conditional/SnowLeopardConfig</string>
</array>
Manifest conditional/LionConfig:
<key>condition</key>
<string>os_vers BEGINSWITH "10.7"</string>
<key>managed_installs</key>
<array>
<string>Lion802.1XconfigProfile</string>
<string>LionVPNconfigProfile</string>
</array>
<key>managed_uninstalls</key>
<array>
<string>CiscoVPNClient</string>
</array>
Manifest conditional/SnowLeopardConfig:
<key>condition</key>
<string>os_vers BEGINSWITH "10.7"</string>
<key>managed_installs</key>
<array>
<string>CiscoVPNClient</string>
<string>SnowLeopard802.1XconfigScript</string>
</array>
So instead of a complicated new structure, we've just added a single new key. Admins would have to group their conditional items together in included manifests; but all the included manifests would be downloaded -- even the ones that ultimately won't be used.
This seems way less complicated to understand (and write), and ultimately would provide identical functionality. Downside are that it's less concise -- if you had lots of conditional predicates, each predicate would need its own manifest; with my original suggestion you could embed as many predicates as you'd like in a single manifest.
Rob M thinks there might be a performance hit if you had a lot of these conditional manifests -- especially ones that end up as not applicable for a given machine.
He's probably right, but I think we can mitigate much of that.
-Greg
<key>managed_installs</key>
<array>
<dict>
<key>name</key>
<string>FooApplication</string>
<key>version</key>
<string>1.15.0.1</string>
<key>condition</key>
<string>os_vers BEGINSWITH "10.7"</string>
</dict>
</array>
The at the same time we can start to phase out the use of placing
versions in the pkg name field separated by a dash, which has caused
problems for our admins in the past.
Although, I'm still not convinced that the condition data belongs in
the manifest in the first place. I think the original argument was
simply that catalogs are parsed and filtered before manifest items are
searched for, so if a condition is not met and an item is filtered out
then it throws a warning. This is an easy problem to solve in the
catalog filtering: keep track of names that were filtered out, and
don't throw a warning if it was not found purely because conditions
were not met. Splitting data about how and why a particular package
installs into two places seems wrong.
> If we're going to modify the way manifests are handled, why not make use of XML?
>
> <key>managed_installs</key>
> <array>
> <dict>
> <key>name</key>
> <string>FooApplication</string>
> <key>version</key>
> <string>1.15.0.1</string>
> <key>condition</key>
> <string>os_vers BEGINSWITH "10.7"</string>
> </dict>
> </array>
>
This change would break all existing Munki clients. You could not implement this for a given client until it had been updated with newer munki tools; if you rely on included manifests (as I do) you could not use the new format until every single client had the new tools.
The two proposals I made yesterday are backwards-compatible in that they would not break existing clients; but the two proposals would be handled quite differently by existing clients:
My original proposal wraps all conditional items inside a new key-value pair. Existing clients would ignore this key and value, and therefore would not install/remove any conditional items. Once they had the updated munki tools, they then would process the conditional items.
My revised/simpler proposal relies on a single new key that causes Munki to either use or ignore the entire manifest. Existing Munki clients would ignore the new key, and therefore install/remove ALL conditional items.
I think the first behavior is preferable -- that is, admins should be able to add new conditional items to a manifest and clients with out-of-date munki tools would simply ignore these items until they got the updated tools. So while I was leaning toward the revised/simpler proposal, I'm once again favoring my original proposal.
> The at the same time we can start to phase out the use of placing
> versions in the pkg name field separated by a dash, which has caused
> problems for our admins in the past.
Same problem with existing clients.
When I created the data formats for Munki, I was creating all manifests and pkginfo files BY HAND. So the formats had to strike a balance between machine-parsabilty and human readability and write-ability. That's perhaps less needed now that we have tools like makepkginfo and munkiimport, but hand-editing an array of strings is always going to be easier than hand-editing an array of dicts.
>
> Although, I'm still not convinced that the condition data belongs in
> the manifest in the first place. I think the original argument was
> simply that catalogs are parsed and filtered before manifest items are
> searched for, so if a condition is not met and an item is filtered out
> then it throws a warning. This is an easy problem to solve in the
> catalog filtering: keep track of names that were filtered out, and
> don't throw a warning if it was not found purely because conditions
> were not met.
But that could be warning they need -- they actually _want_ Xcode to install, but the only version in the Munki repo doesn't work on Lion. They need the warning so they'll go get a Lion-compatible version and import it into the repo.
Sometimes it's an error if a package isn't available to install because there is no version in the repo that matches the current OS or architecture. Sometime's it's not. Distinguishing the two is the trick.
> Splitting data about how and why a particular package
> installs into two places seems wrong.
pkginfo contains metadata about the _package_.
A manifest contains data about what should be installed or removed from a given machine.
Some of that data may be conditional, based on things like "what's the major OS release on this machine?" "Is it a laptop or desktop?" "Does it have 'testing' in its list of catalogs?" "Is it a 64-bit capable machine?" "Does it have over 100GB of available disk space?" I think this could be arbitrarily expanded -- the admin could create a special plist file (or a preflight script could) that defined any number of attributes to use for conditional installs: username, department, building location, group membership, etc.
I think you've met this need already with Simian -- it dynamically generates manifests for a client based on conditions you support. So you probably don't need and won't use this functionality. Those of use using dumb static web servers as our Munki servers are more likely to need and use it.
Hi Greg,I'm just getting started with munki and I want to say that I absolutely love the work you've done. Running InstallAppleSoftwareUpdates is a no-brainer that is saving me a lot of softwareupdate -i -a.Conditional items seem a nice addition, I would definitely make use of it. Would it be possible to piggyback group membership of the console user as attribute?e.g. <string>console_user_group_membership="adobe_cs4_users"</string>That way you can have group based installations
> On Dec 1, 2011, at 5:15 AM, Arjen van Bochoven wrote:
>
>> Conditional items seem a nice addition, I would definitely make use of it. Would it be possible to piggyback group membership of the console user as attribute?
>>
>> e.g. <string>console_user_group_membership="adobe_cs4_users"</string>
>>
>> That way you can have group based installations
>
> I understand the idea, but it would be hard to implement inside the current conditional framework, which can only compare against strings, integers, and other basic type.
In your example you have catalogs -- array of strings working, wouldn't it be possible to use that mechanism for group info?
>
>
> You'd need a way to generate a complete list of all groups the console user is a member of so you could say something like:
>
> console_user_groups CONTAINS "adobe_cs4_users"
Exactly
> Since OS X supports nested groups, that's trickier than it sounds.
AFAIK the output of `id -a username` expands all nested groups
> And what happens when Munki runs when no-one is logged in and there is no console user?
I figured this particular rule only applies to a logged in console user. I'm not sure how this pans out when a user chooses to 'log out and install'..
> I'm considering making this mechanism admin-extendable, where an admin could write a script (perhaps part of a Munki preflight) that populated a special file with key/value pairs. The conditional mechanism would then use the keys and values in this file in addition to keys and values that are internally generated.
> In this way, you could compare on any value you can generate from any mechanism.
Another idea might be to define shell command as condition, you could then use the exit status to determine if the condition passed. That way you don't need to make use of a preflight script.
Not sure if that has other (security) implications.
Arjen
>
> On 1 dec. 2011, at 16:49, Greg Neagle wrote:
>
>> On Dec 1, 2011, at 5:15 AM, Arjen van Bochoven wrote:
>>
>>> Conditional items seem a nice addition, I would definitely make use of it. Would it be possible to piggyback group membership of the console user as attribute?
>>>
>>> e.g. <string>console_user_group_membership="adobe_cs4_users"</string>
>>>
>>> That way you can have group based installations
>>
>> I understand the idea, but it would be hard to implement inside the current conditional framework, which can only compare against strings, integers, and other basic type.
>
> In your example you have catalogs -- array of strings working, wouldn't it be possible to use that mechanism for group info?
Sure, but you'd have to pre-populate the array with a list of group names.
>>
>>
>> You'd need a way to generate a complete list of all groups the console user is a member of so you could say something like:
>>
>> console_user_groups CONTAINS "adobe_cs4_users"
>
> Exactly
>
>> Since OS X supports nested groups, that's trickier than it sounds.
>
> AFAIK the output of `id -a username` expands all nested groups
Not for me:
gneagle@moss:~ % id
uid=4389(gneagle) gid=100(_lpoperator) groups=100(_lpoperator),801(fmpadmin),681(systems),512(Domain Admins),16(group),663(tech),869(VPN2Factor),756(SQL_RDC),12(everyone),62(netaccounts),833(Digidelivery),4124(ScroogeUsers)
Yet I know I am also a member of the 'www' group:
gneagle@moss:~ % dsmemberutil checkmembership -U gneagle -G www
user is a member of the group
I think there are other groups I am a member of that are not showing here.
>
>> And what happens when Munki runs when no-one is logged in and there is no console user?
>
> I figured this particular rule only applies to a logged in console user. I'm not sure how this pans out when a user chooses to 'log out and install'..
>
>> I'm considering making this mechanism admin-extendable, where an admin could write a script (perhaps part of a Munki preflight) that populated a special file with key/value pairs. The conditional mechanism would then use the keys and values in this file in addition to keys and values that are internally generated.
>
>> In this way, you could compare on any value you can generate from any mechanism.
>
> Another idea might be to define shell command as condition, you could then use the exit status to determine if the condition passed. That way you don't need to make use of a preflight script.
Again, the script would have to be run and its exit status stored before the comparison was done -- we're only doing comparisons against dictionary key/values.
Arjen
Having this admin extended would be fantastic also, something that you
can either manipulate locally or via MCX. For example at present in
our labs we have;
lees-mbp:~ lee$ cd /Volumes/munki/manifests/lab/labexample/
lees-mbp:labexample lee$ ls -1
labexample
lecturer
student
lecturer and student both nest "labexample", which pretty much all the
packages go in all, and we associate ARD, file maker and a few other
bits and bobs to the lecturer machine. This system irks me a bit, as
it's a bit unnecessary for 2-3 packages to have this complexity. If we
could put in a conditional that somewhere on the lecturers machine
there's a munki readable reference to "lecturer machine", that it
would install the lecturer "pack", it would just bring the
requirements for manifests right down.
I can see heaps of examples for scanners with funky drivers you don't
want everywhere and that sort of thing too.
Lee
> >http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptua...
> ...
>
> read more »
> We'll be associating a few packages with this shortly. We need a bunch
> of packages to go to everyone except laptop users, and were knocking
> our heads together with a clean way to implement it. It will certainly
> save a lot of effort nesting additional manifests and so on.
>
> Having this admin extended would be fantastic also, something that you
> can either manipulate locally or via MCX. For example at present in
> our labs we have;
>
> lees-mbp:~ lee$ cd /Volumes/munki/manifests/lab/labexample/
> lees-mbp:labexample lee$ ls -1
> labexample
> lecturer
> student
>
> lecturer and student both nest "labexample", which pretty much all the
> packages go in all, and we associate ARD, file maker and a few other
> bits and bobs to the lecturer machine. This system irks me a bit, as
> it's a bit unnecessary for 2-3 packages to have this complexity. If we
> could put in a conditional that somewhere on the lecturers machine
> there's a munki readable reference to "lecturer machine", that it
> would install the lecturer "pack", it would just bring the
> requirements for manifests right down.
You could easily accomplish what I think you're trying to do by using the "hostname" attribute for a conditional comparison. It would be really simply if the lecturer computers had something unique about their hostname, like a prefix or suffix.
Say, they all have a prefix of "LEC" so example hostnames for 3 lecturer machines might be:
LEC-ABC123
LEC-DEF456
LEC-XYZ789
Your conditional items might look like this:
<key>conditional_items</key>
<array>
<dict>
<key>condition</key>
<string>hostname BEGINSWITH "LEC"</string>
<key>managed_installs</key>
<array>
<string>lecturer_package_1</string>
<string>lecturer_package_2</string>
<string>lecturer_package_3</string>
</array>
</dict>
</array>
>I've gotten zero feedback on this.
>I know in the US, people were probably occupied with Thanksgiving and
>Black Friday shopping binges.
>
>I've rolled it out to a test group and it's working great -- exactly as
>I'd hoped. I'm deploying VPN and 802.1X configuration profiles to laptops
>but not desktops, deploying a new package only to machines that have
>"testing" in their list of catalogs, and deploying the CiscoVPNClient to
>Snow Leopard machines, but a VPN profile to Lion machines, all from a
>single included manifest that all machines get. (And the machines not yet
>running the updated munki tools just ignore the conditional_items.)
>
>I will probably merge this branch to master later this week.
>
>-Greg
Hi,
I'm keen to try this out, basically to restrict which machines will try to
install Lion based on hardware.
Couldn't find that 'branch' though to take a look through.
Or has it already been added and I've missed it and it's not in the
documentation?
Just getting to grips properly with Munki, testing it out so far on 20 of
200+ Mac's.
Adobe Reader, Office 2011 & patches, SPSS19, EndNote X5, Firefox, Adobe
Flash Plugin, and as of today thanks to the util(s) by Greg N: OS X Lion
:)
--
Andrew Rae
Senior Technician (IT and Computing Support)
LIMM, University of Leeds
ACSP | MCP | CCNA
<rest of conversation:>
> On 29/11/2011 22:39, "Greg Neagle" <gregn...@mac.com> wrote:
>
>
>> I've gotten zero feedback on this.
>> I know in the US, people were probably occupied with Thanksgiving and
>> Black Friday shopping binges.
>>
>> I've rolled it out to a test group and it's working great -- exactly as
>> I'd hoped. I'm deploying VPN and 802.1X configuration profiles to laptops
>> but not desktops, deploying a new package only to machines that have
>> "testing" in their list of catalogs, and deploying the CiscoVPNClient to
>> Snow Leopard machines, but a VPN profile to Lion machines, all from a
>> single included manifest that all machines get. (And the machines not yet
>> running the updated munki tools just ignore the conditional_items.)
>>
>> I will probably merge this branch to master later this week.
>>
>> -Greg
>
> Hi,
> I'm keen to try this out, basically to restrict which machines will try to
> install Lion based on hardware.
> Couldn't find that 'branch' though to take a look through.
The code has been merged into "master" and can be downloaded and built using the information here:
http://code.google.com/p/munki/wiki/BuildingMunki
> Or has it already been added and I've missed it and it's not in the
> documentation?
There hasn't been an official release with the new functionality.
Ah-ha! Excellent, will give that a bash and feed-back :)
Thanks again for all the hard-work!
Andrew
Greg,
This morning I built the current version "0.8.1 build 1373"
I've been trying it out this morning, seems to work very well!
Deploying Lion to machines that aren't iMac4,x: NOT(machine_model
BEGINSWITH "iMac4,")
Deploying Software pre-Lion: os_vers < "10.7"
Deploying software post-Lion: os_vers => "10.7"
Note to self and anyone else who tries to click the cut-down link on the
email copies:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Pred
icates/Articles/pSyntax.html
I couldn't find a better way to match a machine that wasn't Lion
compatible. Or should I say I couldn't think of a clever way to do it
based on the 'Currently available attributes' you listed. 'arch' is coming
from the current install of the OS & not based on hardware, at a guess?
Given that munki / Lion is only being currently installed & being tested
on iMacs and a few recent MacBook Pro's - it's not an urgent issue for me
- but would be good to hear what others think about testing for
compatibility before showing it in the list of 'optional updates' etc. or
maybe even 'managed_installs' in the future!
Thanks again,
Andrew
--
Andrew Rae
Senior Technician (IT and Computing Support)
LIMM
Office: (0113 34) 37881
For Support: https://limmhelp.leeds.ac.uk
ACSP | MCP | CCNA
I think this may have been incorrect worded when it was written?
I have some MacPro1,1 's ... They all run in EFI Mode 'EFI32' and the
Kernel Default Mode is '32-bit' although they will run 64 bit applications
as the CPU has 64 bit architecture.
Is there a way to determine if the machine is capable of running 64 bit
software, or is this not possible within the OS (for example) or is it
just with this current implementation of the munki code.
> os_vers -- string. Example: "10.7.2"
> Example comparison: 'os_vers BEGINSWITH "10.7"'
> os_vers_major -- integer: Example: 10
> os_vers_minor -- integer: Example: 7
> os_vers_patch -- integer: Example: 2
> Example comparison: 'os_vers_patch >= 2'
> machine_model -- string. Examples: 'Macmini1,1', 'iMac4,1',
>'MacBookPro8,2'
> machine_type -- string. Currently either 'laptop' or 'desktop'
> Example comparison: 'machine_type == "laptop"'
> catalogs -- array of strings. This contains the current catalog list for
>the manifest being processed.
> Example comparison: 'catalogs CONTAINS "testing"'
>
>Comparisons are implemented via Cocoa's NSPredicate objects.
>Predicate syntax documented here:
>http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Pre
>dicates/Articles/pSyntax.html
Sorry to be a pain!
Many Thanks,
Andrew
>> On Nov 18, 2011, at 3:42 PM, Greg Neagle wrote:
>> <SNIP>
>> The above conditional_items section will cause the CiscoVPNclient to be
>> installed on laptops running Snow Leopard. If such a laptop is later
>> upgraded to Lion, the CisocVPNclient will be removed and a Lion profile
>> that configures VPN will be installed.
>>
>> Currently available attributes for conditional comparison:
>> hostname -- string.
>> arch -- string. processor architecture. Examples: 'powerpc', 'i386',
>> 'x86_64'
>> Example comparison: 'arch == "x86_64"'
>
> I think this may have been incorrect worded when it was written?
>
> I have some MacPro1,1 's ... They all run in EFI Mode 'EFI32' and the
> Kernel Default Mode is '32-bit' although they will run 64 bit applications
> as the CPU has 64 bit architecture.
>
> Is there a way to determine if the machine is capable of running 64 bit
> software, or is this not possible within the OS (for example) or is it
> just with this current implementation of the munki code.
Can you provide a more specific example of a problem you are trying to solve?
-Greg
OsiriX 64 bit enabler installation, which we only want to install on
machines capable of running 64bit applications.
This code only installs on Mac's which have 64bit EFI, where the OS
actually boots into 64bit mode:
<key>conditional_items</key>
<array>
<dict>
<key>condition</key>
<string>arch == "x86_64"</string>
<key>managed_installs</key>
<array>
<string>osirix64-2011</string>
</array>
</dict>
</array>
There is some more information here:
http://www.macobserver.com/tmo/article/checking_32_or_64-bit_kernel_boot_mo
de_in_snow_leopard
Running
ioreg -l -p IODeviceTree | grep firmware-abi
returns 'EFI32', even though the OS is capable of running 64bit
applications it does not have a 64bit EFI firmware.
Also the 'System Profiler' shows '64-bit Kernel and Extensions: No'
It'd be good to be able to detect if the machine is running an OS capable
of 64bit applications, as an alternative to what the kernel on the machine
is running in. More useful info and an application to check what modes
machines are running in is here
http://www.ahatfullofsky.comuv.com/English/Programs/SMS/SMS.html
I have a feeling from what I've read, that even some of the MacBookPro's
etc will return a value of 32bit. Theory backed up by information from
Apple site: http://support.apple.com/kb/HT3770
This may help:
sysctl hw | grep 64bit
Which returns
hw.cpu64bit_capable: 1
On my MacPro1,1.
Hope that helps
Andrew
There weren't very many models of Intel Macs that were not capable of running 64bit apps -- only the models that shipped with the Intel Core (not Core 2) processors. You probably have only a subset of those models in your inventory. So you can use conditional_items to NOT install on those machine_models.
Something like:
<key>condition</key>
<string>arch IN { 'i386', 'x86_64' } AND NOT machine_model IN { 'iMac4,1', 'iMac4,2', 'Macmini1,1', 'MacBook1,1', 'MacBookPro1,1', 'MacBookPro1,2' }</string>
-Greg
On 13/01/2012 16:36, "Greg Neagle" <gregn...@mac.com> wrote:
>Munki does not currently track that information, and so can't do
>conditional_items based on it. But may I suggest a different approach?
>
>There weren't very many models of Intel Macs that were not capable of
>running 64bit apps -- only the models that shipped with the Intel Core
>(not Core 2) processors. You probably have only a subset of those models
>in your inventory. So you can use conditional_items to NOT install on
>those machine_models.
>
>Something like:
>
><key>condition</key>
><string>arch IN { 'i386', 'x86_64' } AND NOT machine_model IN {
>'iMac4,1', 'iMac4,2', 'Macmini1,1', 'MacBook1,1', 'MacBookPro1,1',
>'MacBookPro1,2' }</string>
>
>-Greg
I'd done a similar line for the Lion Installer for now Š We've not many
PPC but I think I might add that first 'arch' bit, just to be safe!
It's a good workaround, many thanks,
Andrew