mirror of
https://github.com/munki/munki.git
synced 2026-01-05 22:20:00 -06:00
162 lines
4.7 KiB
Python
162 lines
4.7 KiB
Python
# encoding: utf-8
|
|
#
|
|
# Copyright 2009-2020 Greg Neagle.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""
|
|
munkistatus.py
|
|
|
|
Created by Greg Neagle on 2009-09-24.
|
|
|
|
Utility functions for using MunkiStatus.app
|
|
to display status and progress.
|
|
"""
|
|
from __future__ import absolute_import, print_function
|
|
|
|
import os
|
|
import time
|
|
|
|
# PyLint cannot properly find names inside Cocoa libraries, so issues bogus
|
|
# No name 'Foo' in module 'Bar' warnings. Disable them.
|
|
# pylint: disable=E0611
|
|
from Foundation import NSDistributedNotificationCenter
|
|
from Foundation import NSNotificationDeliverImmediately
|
|
from Foundation import NSNotificationPostToAllSessions
|
|
# pylint: enable=E0611
|
|
|
|
# we use lots of camelCase-style names. Deal with it.
|
|
# pylint: disable=C0103
|
|
|
|
# our NSDistributedNotification identifier
|
|
NOTIFICATION_ID = 'com.googlecode.munki.managedsoftwareupdate.statusUpdate'
|
|
|
|
# keep our current status. We keep this so that notification clients
|
|
# that come "online" late can get current state
|
|
_currentStatus = {}
|
|
|
|
def initStatusDict():
|
|
'''Initialize our status dictionary'''
|
|
global _currentStatus
|
|
_currentStatus = {
|
|
'message': '',
|
|
'detail': '',
|
|
'percent': -1,
|
|
'stop_button_visible': True,
|
|
'stop_button_enabled': True,
|
|
'command': '',
|
|
'pid': os.getpid()
|
|
}
|
|
|
|
def launchMunkiStatus():
|
|
'''Uses launchd KeepAlive path so it launches from a launchd agent
|
|
in the correct context.
|
|
This is more complicated to set up, but makes Apple (and launchservices)
|
|
happier.
|
|
There needs to be a launch agent that is triggered when the launchfile
|
|
is created; and that launch agent then runs MunkiStatus.app.'''
|
|
initStatusDict()
|
|
|
|
launchfile = "/var/run/com.googlecode.munki.MunkiStatus"
|
|
try:
|
|
open(launchfile, 'w').close()
|
|
except (OSError, IOError):
|
|
pass
|
|
time.sleep(0.1)
|
|
if os.path.exists(launchfile):
|
|
os.unlink(launchfile)
|
|
|
|
|
|
def postStatusNotification():
|
|
'''Post a status notification'''
|
|
dnc = NSDistributedNotificationCenter.defaultCenter()
|
|
dnc.postNotificationName_object_userInfo_options_(
|
|
NOTIFICATION_ID,
|
|
None,
|
|
_currentStatus,
|
|
NSNotificationDeliverImmediately + NSNotificationPostToAllSessions)
|
|
|
|
|
|
def message(messageText):
|
|
'''Sets the status message.'''
|
|
_currentStatus['message'] = messageText
|
|
postStatusNotification()
|
|
|
|
|
|
def detail(detailsText):
|
|
'''Sets the detail text.'''
|
|
_currentStatus['detail'] = detailsText
|
|
postStatusNotification()
|
|
|
|
|
|
def percent(percentage):
|
|
'''Sets the progress indicator to 0-100 percent done.
|
|
If you pass a negative number, the progress indicator
|
|
is shown as an indeterminate indicator (barber pole).'''
|
|
_currentStatus['percent'] = percentage
|
|
postStatusNotification()
|
|
|
|
|
|
def hideStopButton():
|
|
'''Hides the stop button.'''
|
|
_currentStatus['stop_button_visible'] = False
|
|
postStatusNotification()
|
|
|
|
|
|
def showStopButton():
|
|
'''Shows the stop button.'''
|
|
_currentStatus['stop_button_visible'] = True
|
|
postStatusNotification()
|
|
|
|
|
|
def disableStopButton():
|
|
'''Disables (grays out) the stop button.'''
|
|
_currentStatus['stop_button_enabled'] = False
|
|
postStatusNotification()
|
|
|
|
|
|
def enableStopButton():
|
|
'''Enables the stop button.'''
|
|
_currentStatus['stop_button_enabled'] = True
|
|
postStatusNotification()
|
|
|
|
|
|
def activate():
|
|
'''Brings MunkiStatus window to the front.'''
|
|
_currentStatus['command'] = 'activate'
|
|
postStatusNotification()
|
|
# now clear the command; unlike the other fields, this
|
|
# should not persist between notifications
|
|
_currentStatus['command'] = ''
|
|
|
|
|
|
def quit_app():
|
|
'''Tells the status app that we're done.'''
|
|
_currentStatus['command'] = 'quit'
|
|
postStatusNotification()
|
|
# now clear the command; unlike the other fields, this
|
|
# should not persist between notifications
|
|
_currentStatus['command'] = ''
|
|
|
|
|
|
def restartAlert():
|
|
'''Tells MunkiStatus to display a restart alert.'''
|
|
_currentStatus['command'] = 'showRestartAlert'
|
|
postStatusNotification()
|
|
# now clear the command; unlike the other fields, this
|
|
# should not persist between notifications
|
|
_currentStatus['command'] = ''
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print('This is a library of support tools for the Munki Suite.')
|