Merge lp://qastaging/~mikemc/ubuntuone-control-panel/launchdaemon into lp://qastaging/ubuntuone-control-panel

Proposed by Mike McCracken
Status: Merged
Approved by: Mike McCracken
Approved revision: 361
Merged at revision: 360
Proposed branch: lp://qastaging/~mikemc/ubuntuone-control-panel/launchdaemon
Merge into: lp://qastaging/ubuntuone-control-panel
Diff against target: 663 lines (+601/-0)
2 files modified
ubuntuone/controlpanel/utils/darwin.py (+375/-0)
ubuntuone/controlpanel/utils/tests/test_darwin.py (+226/-0)
To merge this branch: bzr merge lp://qastaging/~mikemc/ubuntuone-control-panel/launchdaemon
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+124847@code.qastaging.launchpad.net

Commit message

- Darwin: use ServiceManagement API to securely install, check versions, and upgrade root fsevents daemon.

Description of the change

- Darwin: use ServiceManagement API to securely install, check versions, and upgrade root fsevents daemon.

** NOTES ABOUT WHAT IS GOING ON HERE **

This calls a bunch of CoreFoundation APIs using ctypes so the first 140 lines or so of the diff are ctypes boilerplate that sets up the types for the CF functions.

start reading at check_and_install_fsevents_daemon().
This function compares the version of the daemon that's packaged in the app's bundle (at daemon_path) to the version that's installed, if it exists.

If the installed one is the same, we're done. If it's newer, we raise an exception.
If it's older, we remove it. Then we install the new one.

The twist in this method is that we have to get authorization (show a dialog box) once to remove the old job, and then kill that authorization (calling AuthorizationFree with the kAuthorizationFlagDestroyRights flag, to remove it from the cache as well as freeing the authref's memory) before we can get the **same** authorization again to install the new job. This is annoying and I only figured it out via trial and error, one Apple dev rep said it shouldn't be necessary, but it's the only way I could get it to work.

Nothing else is all that tricky, the other functions are just wrapping a CoreFoundation call and checking the error message.

-- about CFShow: I had half a day of unicode annoyance trying to get the error description copied into a printable python string, and gave up and used CFShow. It just prints the description to stdout. It's the CF equivalent of NSLog or 'print'. It's sufficient to get the error messages somewhere readable.

-- About CFRelease(): the rule is that if you call a function that has "create" or "copy" in its name, then you'll need to release its return value. If you call a function that has "get", you don't own it and shouldn't release it.

-- about get_authorization(): the name of the right we request here and the flags we pass are from apple's sample code. If you check their docs, you might notice that SMJobRemove should require a different right. The docs are wrong or at least incomplete. We only need kSMRightBlessPrivilegedHelper.

** notes on testing **

This includes new tests in ubuntuone/controlpanel/utils/tests/test_darwin.py.
Those tests pass for me, but trunk still has some failing tests in share_links.py, which are unrelated.
pylint doesn't work right for me on darwin, but this branch adds no new pyflakes errors.

To IRL-test, talk to mmcc on IRC, or use the bundles I've built.
Building the bundle correctly with code signing - but not using my cert - will require changing the cert CN in the code for the daemon (in a branch not in trunk there) as well as the setup-mac script.

Using my bundles, here's how to test:
(Note that you need to have the line saying 'fs_monitor.default' end with 'daemon' not 'default' in syncdaemon.conf for the code to run the monitor. It'll still try to install either way.)

Test that running the app installs a daemon using this:
% sudo launchctl list com.ubuntu.one.fsevents

remove it with
% sudo launchctl remove com.ubuntu.one.fsevents

then install an old version of the daemon by running an old build of the app. Not the alpha 1, it didn't have this branch. -- Again, talk to me, I have an old one laying around.

Then run the new one again, with U1_DEBUG=1 and look at the log, does it say it found 1.0 and replaced it with 1.1? Then it worked.

Also, does the file sync work? Only version 1.1 of the fsevents daemon correctly sends events to the client.

To post a comment you must log in.
Revision history for this message
Mike McCracken (mikemc) wrote :

If you want to review this before I wake up, here's a signed build with this branch that just uploaded itself: http://ubuntuone.com/4KKHgfhAK46ABkOuvrdZci

Revision history for this message
Roberto Alsina (ralsina) wrote :

Tested IRL and read the code. AFAICS it looks good.

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

In the following code:

354 + try:
355 + remove_fsevents_daemon(authRef)
356 + except Exception, e:
357 + logger.exception("Problem removing running daemon: %r" % e)
358 +
359 + AuthorizationFree(authRef, kAuthorizationFlagDestroyRights)

shouldn't the Free be called in a finally clause?

In the InstallDaemonTestCase you can move the following to the setup instead of calling it in each of the tests:

469 + self._patch_and_track(utils.darwin,
470 + [('get_authorization', 'Fake AuthRef'),
471 + ('remove_fsevents_daemon', None),
472 + ('install_fsevents_daemon', None),
473 + ('AuthorizationFree', None)])

review: Needs Fixing
Revision history for this message
Mike McCracken (mikemc) wrote :

We just log that exception and don't re-raise it, so no - we will always call that AuthorizationFree.

The repeated patch call is now in setup.

Revision history for this message
Manuel de la Peña (mandel) :
review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (163.0 KiB)

The attempt to merge lp:~mikemc/ubuntuone-control-panel/launchdaemon into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running DBus test suite ***
ubuntuone.controlpanel.dbustests.test_dbus_service
  BaseTestCase
    runTest ... [OK]
  DBusServiceMainTestCase
    test_dbus_service_cant_register ... Control panel backend already running.
                                   [OK]
    test_dbus_service_main ... [OK]
  DBusServiceTestCase
    test_cant_register_twice ... [SKIPPED]
    test_dbus_busname_created ... [OK]
    test_error_handler_default ... [OK]
    test_error_handler_with_exception ... [OK]
    test_error_handler_with_failure ... [OK]
    test_error_handler_with_non_string_dict ... [OK]
    test_error_handler_with_string_dict ... [OK]
    test_register_service ... [OK]
  FileSyncTestCase
    test_file_sync_status_changed ... [OK]
    test_file_sync_status_disabled ... [OK]
    test_file_sync_status_disconnected ... [OK]
    test_file_sync_status_error ... [OK]
    test_file_sync_status_idle ... [OK]
    test_file_sync_status_starting ... [OK]
    test_file_sync_status_stopped ... [OK]
    test_file_sync_status_syncing ... [OK]
    test_file_sync_status_unknown ... [OK]
    test_status_changed_handler ... [OK]
    test_status_changed_handler_after_status_requested ... [OK]
    test_status_changed_handler_after_status_requested_twice ... [OK]
  OperationsAuthErrorTestCase
    test_account_info_returned ... [OK]
    test_change_device_settings ... [OK]
    test_change_replication_settings ... [OK]
    test_change_volume_settings ... [OK]
    test_connect_files ... [OK]
    test_devices_info_returned ... [OK]
    test_disable_files ... [OK]
    test_disconnect_files ... [OK]
    test_enable_files ... [OK]
    test_remove_device ... [OK]
    test_replications_info ... [OK]
    test_restart_files ... [OK]
    test_star...

361. By Mike McCracken

fix lint errors

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches