Friday, October 28, 2011

NFS shares

Show NFS shares exported from a host (can also point to localhost):
showmount -e 192.168.1.1
/etc/exports line on linux (share /blah with 192.168.1.2)
/blah               192.168.1.2(ro)
On the mac the options format is different. As with linux, root_squash to nobody is the default.
/blah -ro 192.168.1.2

Tuesday, October 25, 2011

Installing pip and virtualenv on OS X

Download and install the appropriate easy_install egg.
sudo sh setuptools-0.6c11-py2.X.egg
and from then on it is the same as for linux
sudo easy_install pip
sudo pip install virtualenv
Create a virtualenv instance:
virtualenv ENV
and you'll get something like:
Could not call install_name_tool -- you must have Apple's development tools installed
So you need to go off and install XCode, which will probably take a while (4.2 is 1.7 G).

Once you have Xcode, things should be good:
$ virtualenv ENV
New python executable in ENV/bin/python
Installing setuptools............done.
Installing pip...............done.
$ source ENV/bin/activate

Thursday, October 20, 2011

OSX launchd and inetd services

Apple has an epic writeup of how daemons should be written for OS X, Mach execution contexts, IPC and more in TN2083. This post is just some quick summary notes.

launchd is roughly equivalent to cron, init.d, and xinetd all rolled into one. Use it by dropping a plist into one of these directories:

  • /Library/LaunchDaemons runs as root on system startup
  • /Library/LaunchAgents runs as the user on login
  • ~/Library/LaunchAgents runs as the user for the specific user login

There is also /System/Library/Launch{Agents,Daemons} which is for the jobs installed by the OS. Use the directories above for any custom jobs.

List launchd jobs with
launchctl list
Start:
sudo launchctl load /Library/LaunchDaemons/com.myorg.somejob.plist
Stop:
sudo launchctl unload /Library/LaunchDaemons/com.myorg.somejob.plist

There are many different options for jobs, see the launchd.plist man page for a complete list. A simple inetd service might look something like this:
<dict>
 <key>Disabled</key>
 <false/>
 <key>Label</key>
 <string>com.myorg.somejob</string>
 <key>Program</key>
 <string>/usr/local/sbin/somejob</string>
 <key>Sockets</key>
 <dict>
  <key>Listeners</key>
  <dict>
   <key>SockServiceName</key>
   <string>9999</string>
  </dict>
 </dict>
 <key>inetdCompatibility</key>
 <dict>
  <key>Wait</key>
  <false/>
 </dict>
</dict>

/usr/local/sbin/somejob will be called whenever there is a connection on port 9999, and you can interact with the socket by reading and writing STDIN/STDOUT as normal for inetd.

Wednesday, October 19, 2011

Force MCX refresh - apply policy without a logout/reboot

If you are managing settings with MCX (e.g. like this), you want your MCX settings to apply as soon as they are pushed to the machine. Unfortunately this doesn't happen automatically. They get stored in the local directory services node, which you can see here:
dscl . -mcxread /Computers/local_computer
But they don't get propagated to the relevant plists under managed preferences until a logout or reboot happens. You can check the managed preferences plists like this:
defaults read /Library/Managed\ Preferences/com.apple.loginwindow
Fortunately on 10.6 and later, you can run mcxrefresh to force this propagation without a reboot:
sudo mcxrefresh -n myusername

Puppet expansion of facts inside command strings requires double quoted string

Small gotcha for puppet facts. If you want a puppet fact to be expanded inside a quoted string you need to use double quotes (i.e. a ruby-style format string).
  exec { 'something':
    # This has to be a double quote for the fact to get expanded
    command     => "/usr/bin/something ${my_custom_fact}",
    refreshonly => 'true',
  }

Wednesday, October 12, 2011

Chrome Extensions vs. Apps vs. Themes and what it looks like in your extensions directory

If you look in your chrome extensions directory on disk, things are a little confusing.

  1. There are extensions, which you can see listed at about:extensions.
  2. There are apps, which can be either packaged or hosted and will contain an app launch stanza like this in the manifest.json
       "app": {
          "launch": {
             "web_url": "https://mail.google.com/mail/mu/?mui=ca"
          },
          "urls": [ "https://mail.google.com/mail/mu/" ]
       },
    
    These don't seem to appear anywhere in the UI apart from when you open a new tab (there is no about:apps, see about:about for a full list of what is available).
  3. Themes, which are packaged in a similar way, but don't contain javascript or HTML. The manifest.json will have entries like this:
       "theme": {
          "colors": {
             "bookmark_text": [ 105, 96, 87 ],
             "frame": [ 92, 82, 73 ],
             "ntp_background": [ 235, 234, 211 ],
             "ntp_link": [ 105, 96, 87 ],
             "ntp_section": [ 158, 163, 139, 1 ],
             "ntp_section_link": [ 105, 96, 87 ],
             "ntp_section_text": [ 105, 96, 87 ],
             "ntp_text": [ 105, 96, 87 ],
             "tab_background_text": [ 255, 255, 255 ],
             "tab_text": [ 255, 255, 255 ],
             "toolbar": [ 158, 163, 139 ]
          },
    
Also, just figuring out the name of extensions can be confusing. In the manifest.json you will often see:
"name": "__MSG_some_name__",
Which means you need to go look in the relevant locale file like _locales/en/messages.json to find the actual name, it will look like this (note MSG and underscores stripped):
{
   "some_name": {
      "message": "My Rad Extension"
   }
}
The exception is if it is a theme, the messages.json file will look like:
{"themeName": {"message": "Earthy", "description": "theme name"}}
Except it also has a UTF-8 Byte Order Mark prepended to the start of the file, which is the three bytes 'ef bb bf'. If you're trying to parse it with an external JSON parser, those bytes might cause it to fail.

Friday, October 7, 2011

Using OS X directory services (dscl, dseditgroup) in single user mode

To access directory services you first need a writable root:
mount -uw /
Then you need the daemon loaded. On snow leopard:
launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServices.plist
And on Lion:
launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist

On lion you might see an error about DirectoryServices.plist not existing when you connect with dscl, it can be ignored.

Thursday, October 6, 2011

Transparent screen lock for monitoring displays

There are situations where a transparent screen lock is useful: i.e. monitoring displays, build status etc. On ubuntu I have used xtrlock, and I'm looking for something similar for OS X.

Tuesday, October 4, 2011

OS X and DNS

If you look at /etc/resolv.conf on a mac and expect to see the definitive DNS config, you are being misled. While some tools might use this config, most applications will use the mDNSResponder (the name is confusing, it is also used for unicast DNS) config maintained by configd. You can see this with:
scutil --dns
You can check out the mDNSReponder config with:
defaults read /System/Library/LaunchDaemons/com.apple.mDNSResponder
Which, incidentally, is the place to add -NoMulticastAdvertisements to disable bonjour.

You can make a query through mDNSResponder with:
$ dscacheutil -q host -a name slashdot.org
name: slashdot.org
ip_address: 216.34.181.45

$ dscacheutil -q host -a ip_address 216.34.181.45
name: slashdot.org
alias: 45.181.34.216.in-addr.arpa 
ip_address: 216.34.181.45

To see the DNS cache, dump the state of mDNSResponder into system.log with:
sudo killall -INFO mDNSResponder
You can also turn on (very verbose) DNS logging into system.log:
sudo killall -USR1 mDNSResponder
Or even turn on packet capture with:
sudo killall -USR2 mDNSResponder
You can see the other (non-DNS) caching in the local directory service with:
dscacheutil -statistics
dscacheutil -cachedump -entries

Monday, October 3, 2011

Automount and directory service search paths on OS X

The OS X directory service uses the search path to retrieve owner, group, and automount information. A config looks like this:
$ dscl localhost -read /Search
CSPSearchPath: /Local/Default /BSD/local /LDAPv3/main.ldap.example.com
DHCPLDAPDefault: off
LSPSearchPath: /Local/Default /BSD/local
NSPSearchPath: /Local/Default /BSD/local
ReadOnlyNode: ReadOnly
SearchPath: /Local/Default /BSD/local /LDAPv3/main.ldap.example.com
SearchPolicy: dsAttrTypeStandard:CSPSearchPath
The SearchPolicy tells you which one will be used - in this case the Custom Search Path or CSPSearchPath (LSPSearchPath and NSPSearchPath are read-only), which will look in /Local/Default then /BSD/local then in the LDAP server main.ldap.example.com. This is roughly the equivalent of nsswitch.conf on linux. You can also see the same information in Directory Utility:
"/System/Library/CoreServices/Directory Utility.app/Contents/MacOS/Directory Utility"
This app is used to configure the services that the mac will talk to for authentication (LDAP, NIS, Local, AD etc.), you can access that config on the command line with:
sudo defaults read /Library/Preferences/DirectoryService/DirectoryService
Automounts are kept in /etc/auto_master and you can get it to look in LDAP for the mounting info by adding '+auto_master' to the config. It will look for an automount map (see /etc/autofs.conf for more configuration options):
dn: ou=auto.master,ou=automount,ou=admin,dc=example,dc=com
ou: auto.master
objectClass: top
objectClass: automountMap
And shares identified by cn:
dn: cn=/home,ou=auto.master,ou=automount,ou=admin,dc=example,dc=com
cn: /home
objectClass: top
objectClass: automount
automountInformation: -nosuid home.nfs:/home
You can dump a full list of shares with a LDAP search like this:
ldapsearch -LLLx -b ou=auto.master,ou=automount,ou=admin,dc=example,dc=com
or via dscl like this:
dscl localhost -readall /LDAPv3/main.ldap.example.com/Automount