Archive for the ‘macosx’ Category

Using crankd to run Puppet on network events

Sunday, October 17th, 2010

Gary Larizza has put together a great article that covers setting up crankd and Puppet to automatically apply system updates to Mac laptops when they appear on the corporate network.

http://glarizza.posterous.com/using-crankd-to-react-to-network-events

This is exactly what Chris and I wrote it for initially, so it’s great to see this info out there.

Now I have somewhere to point Greg if he bugs me about it again. :)

pymacds – managing DirectoryServices with Python

Wednesday, October 13th, 2010

[updated - 0.3 out with more useful wrapper methods]

I just added the pymacds module to the pymacadmin project.

To install the eggs for Python2.5 (OS X 10.5 only comes with 2.5) or Python2.6 (OS X 10.6 comes with both), run something like:


curl -O http://pymacadmin.googlecode.com/files/pymacds-0.3-py2.5.egg
sudo easy_install-2.5 pymacds-0.3-py2.5.egg

or


curl -O http://pymacadmin.googlecode.com/files/pymacds-0.3-py2.6.egg
sudo easy_install-2.6 pymacds-0.3-py2.6.egg

Once you’ve done this, you can use it like:


nigelk$ python2.5
Python 2.5.4 (r254:67916, Feb 11 2010, 00:50:55)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pymacds
>>> pymacds.UserAttribute('nigelk', 'NFSHomeDirectory')
[u'/Users/nigelk']
>>> pymacds.GetSearchNodes()
['/Local/Default', '/BSD/local', '/LDAPv3/my.ldap.node']
>>> pymacds.GetContactsNodes()
['/LDAPv3/my.ldap.node']
>>>

There are a few other useful methods, listing them here rather than going through them one by one. We’re particularly fond of the Ensure* methods for triggering DirectoryService node addition/removal on network events via crankd.


FlushCache():
GetSearchNodes():
GetContactsNodes():
AddNodeToSearchPath(node):
AddNodeToContactsPath(node):
DeleteNodeFromSearchPath(node):
DeleteNodeFromContactsPath(node):
EnsureSearchNodePresent(node):
EnsureSearchNodeAbsent(node):
EnsureContactsNodePresent(node):
EnsureContactsNodeAbsent(node):
DSQuery(dstype, objectname, attribute=None):
DSSet(dstype, objectname, attribute=None, value=None):
DSDelete(dstype, objectname, attribute=None, value=None):
UserAttribute(username, attribute):
GroupAttribute(groupname, attribute):
AddUserToLocalGroup(username, group):
RemoveUserFromLocalGroup(username, group):

Code contributions welcome.

Seeking input for possible Mac IT Conference

Sunday, May 2nd, 2010

The MacEnterprise steering committee has been talking about doing this
for way too long, but the recent lack of significant IT tracks at WWDC
has spurred us into action.

MacEnterprise is planning to partner with various other groups to get
a Mac IT focused conference started.

This is all very much up in the air, and at this stage we’re seeking
input as to how the community would like this conference to be
organized.

At this stage, we would like you to provide input on Google Moderator
as to ideas for the conference. You can submit ideas as well as vote
on other ideas here:

http://goo.gl/mod/4COQ

Additionally, there is some discussion going on on Twitter, under the
#MacITConference hashtag.

http://twitter.com/#search?q=%23MacITConference

Once we get a little bit better idea of the structure, we’ll be
calling for speakers and looking for sponsorship partners.

Finally… a sanctioned way of activating the screen saver.

Wednesday, November 25th, 2009

Ever since I started managing Macs in a corporate environment, I’ve been annoyed that Apple has failed to offer a sanctioned way of locking the screen via a keyboard command. This is a reasonably common requirement in a lot of corporate deployments. Sure we can use hot corners etc, or we can use one of the sanctioned methods to activate the loginwindow via Fast User Switching, but the former isn’t for everyone, and the latter sucks because it will tear down userspace VPN/802.1x connections.

We have reasonable MCX controls to require a password for the screensaver, but nothing to actually activate it. There are a bunch of private API calls you can use to achieve this, but using private APIs makes me feel dirty.

When I first started poking at Automator again in 10.6, I was pleased to notice that we have a “Start Screen Saver” action. This means that we can save such an Automator workflow as a Service, and then assign a keyboard command to it such that we can activate it from any application.

Unfortunately this action is buggy. If you activate the workflow and wiggle the mouse around, you’ll get an error dialog after unlocking the screen.

Luckily we have another way of achieving the same goal. The System Events AppleScript dictionary contains the same functionality.


tell application "System Events"
start current screen saver
end tell

So you can simply create an Automator “Service” workflow and add a “Run AppleScript” action with the following code snippet.


on run {input, parameters}

tell app "System Events"
start current screen saver
end tell

return input
end run

Save it, and assign a hot key, and you can finally activate the screensaver from the keyboard.

Apple have documented the binary plist format

Friday, October 30th, 2009

Thanks to Dave Dribin for pointing this out.

In http://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c

So really there’s no reason why we can’t have plistlib etc for Ruby/Python/whatever deal with binary plists on non-Mac platforms.

/*
HEADER
    magic number ("bplist")
    file format version

OBJECT TABLE
    variable-sized objects

    Object Formats (marker byte followed by additional info in some cases)
    null    0000 0000
    bool    0000 1000           // false
    bool    0000 1001           // true
    fill    0000 1111           // fill byte
    int 0001 nnnn   …     // # of bytes is 2^nnnn, big-endian bytes
    real    0010 nnnn   …     // # of bytes is 2^nnnn, big-endian bytes
    date    0011 0011   …     // 8 byte float follows, big-endian bytes
    data    0100 nnnn   [int]   … // nnnn is number of bytes unless 1111 then int count follows, followed by bytes
    string  0101 nnnn   [int]   … // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
    string  0110 nnnn   [int]   … // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t
        0111 xxxx           // unused
    uid 1000 nnnn   …     // nnnn+1 is # of bytes
        1001 xxxx           // unused
    array   1010 nnnn   [int]   objref* // nnnn is count, unless ’1111′, then int count follows
        1011 xxxx           // unused
    set 1100 nnnn   [int]   objref* // nnnn is count, unless ’1111′, then int count follows
    dict    1101 nnnn   [int]   keyref* objref* // nnnn is count, unless ’1111′, then int count follows
        1110 xxxx           // unused
        1111 xxxx           // unused

OFFSET TABLE
    list of ints, byte size of which is given in trailer
    — these are the byte offsets into the file
    — number of these is in the trailer

TRAILER
    byte size of offset ints in offset table
    byte size of object refs in arrays and dicts
    number of offsets in offset table (also is number of objects)
    element # in offset table which is top level object
    offset table offset

*/
 

Greg Neagle on Adobe Enterprise Toolkit/Munki/Puppet

Thursday, October 8th, 2009

If you’re a Mac IT person, and you don’t know about Greg Neagle’s Managing OS X blog, you need to fix that situation now.

One of the reasons Greg is so awesome in our field is that he’s eminently pragmatic, with enough hacker mentality to make sure he simply gets the job done with a minimum of fuss. His recent post on the trials and tribulations of working with the Adobe Enterprise Deployment Kit is a great example.

Not only is he trying to come up with something flexible enough to actually use efficiently, he’s dug into the innards and explained exactly what’s going on.

I talked to a few people at Puppet Camp last week about large scale Mac management, and everyone seemed really excited about the Munki Project, which is all Greg’s work so far. Basically the idea is to provide OS X with an actual repository for package management, using native Mac packages, and attempting to reuse vendor packages as much as is feasible.

If no-one else does it, I’ll end up putting together a munki type and provider for Puppet. I’m really looking forward to being able to simply do stuff like:

package { "iWork":
  ensure => latest,
}

just like other operating systems, letting the repository handle dependencies. The way it should be….

This really could be one of the most important community contributions to large scale Mac management in the history of OS X in my opinion.

Apple opens up dev forums for Snow Leopard discussions

Friday, April 24th, 2009

I have been waiting for this for a very long time…

One of the major problems with working in Mac IT has been the lack of a space to discuss pre-release seeds of major OS X versions, ie the current state of Snow Leopard 10.6.

Things change a lot between major releases. Seemingly small changes by Apple can have an enormous impact upon workflow, and when you couple this with the fact that new hardware will often only work correctly on the latest OS X release, you often end up being forced to support 10.x.0 releases that simply don’t work correctly.

To get around this you stagger bulk purchases to avoid the periods when new OS versions are released, and you pay for ADC accounts that give you access to the pre-release seeds.

The problem is that testing is time consuming, and good bug reporting is even more so.  There’s nothing more dispiriting than spending several hours putting together a good bug report for Apple, only to submit it and get it marked as a duplicate.

Sure, there were the AppleSeed forums, but they’ve never really taken off, which I can only assume means that there really aren’t that many Mac IT people on the AppleSeed program.

Ta-da! https://devforums.apple.com/community/mac

Now we have a space we can talk in that is sanctioned by Apple. If it turns out that something fundamental is broken or works completely differently in a pre-release seed, we can share this information with each other, leading to more discrete bug reports to Apple, and leading to an OS that upon release hopefully works better in all sorts of deployments.

Well done Apple.

dre on the LKDC

Wednesday, May 14th, 2008

So dre has done a great overview of the LKDC in Leopard, including a more detailed wiki page. There really isn’t enough info out there about the LKDC, and it’s quite awesome technology.

Querying hosts with DirectoryService

Sunday, March 23rd, 2008

So as host, ping, nslookup, dig etc don’t use the same resolver path as the rest of the OS, we used to always use lookupd for this.

It’s not exactly the most obvious solution in the world, but since lookupd, netinfod and memberd were all rolled into DirectoryService in 10.5, we now use dscacheutil to do this.


$ dscacheutil -q host -a name www.google.com
name: www.l.google.com
alias: www.google.com
ip_address: 74.125.19.104
ip_address: 74.125.19.147
ip_address: 74.125.19.99
ip_address: 74.125.19.103

This is a much more appropriate way of debugging host problems if the *nix tools aren’t showing any problems but OS X components are.

This will fetch the result from the cache, and if it’s not there, fetch it and place it in the cache. If you want to make sure this is a fresh request, do:

dscacheutil -flushcache

and you can always do this:

dscacheutil -cachedump -entries host

to inspect the cache for hosts.

I was actually debugging a Mobile Account problem the other day where the user agreed to create a mobile account at the loginwindow, and yet it kept logging them in with the network account.

Inspecting the DirectoryService cache with:

dscacheutil -cachedump -entries user

showed that the /Local/Default entry for that user was never retrieved. Flushing the cache fixed it.

Turns out the user said no to creating a Mobile Account once, and then logged out without rebooting (and didn’t tell us they’d said no ;-) ). OS X kept the cached entry around and failed to update when creating the Mobile Account as it should have.

Need to get that one into radar….

MacPort issue when using patch…

Sunday, March 23rd, 2008

After spending a little while banging my head against the wall over this one….

root@snicko [ ~ ]
# port install git-core +svn +bash_completion
---> Applying patches to perl5.8
Error: Target org.macports.patch returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_lang_perl5.8/work/perl-5.8.8" && patch -p0 < '/opt/local/var/macports/sources/rsync.macports.org/release/ports/lang/perl5.8/files/patch-makedepend.SH'" returned error 2
Command output: Get file makedepend.SH from Perforce with lock? [y]
Perforce client error:
Connect to server failed; check $P4PORT.
TCP connect to perforce failed.
perforce: host unknown.
patch: **** Can't get file makedepend.SH from Perforce

Error: The following dependencies failed to build: p5-error perl5.8 p5-libwww-perl p5-compress-zlib p5-compress-raw-zlib p5-io-compress-base p5-scalar-list-utils p5-io-compress-zlib p5-html-parser p5-html-tagset p5-uri p5-svn-simple subversion-perlbindings apr apr-util db44 sqlite3 gawk gmake readline neon subversion bash-completion p5-term-readkey rsync popt
Error: Status 1 encountered during processing.

I finally found Jack Palevich's post talking about exporting the POSIXLY_CORRECT environment variable as follows.


POSIXLY_CORRECT=1 port install git-core +svn +bash_completion

Of course now I’ve run into an issue with tcl…. *sigh*, but I’ve seen the patch issue above crop up a few times, and this certainly seems to be fixing it.

It’s bad enough that MacPorts and Fink can’t depend upon Apple to provide sane libraries and headers in OS X, and thus you end up with most of another whole freaking operating system in /opt/local or /sw, but I simply refuse to have both installed, no matter how frustrating it is that I can’t get all the software I need working via just one of them.