예제 #1
0
파일: main.py 프로젝트: sycomix/unicron
    def populateList(self, sender):
        self.selected.clear()
        self.w.list._removeSelection()
        item = self.pathList.titleOfSelectedItem()

        for i in range(len(self.w.list)):
            del self.w.list[0]

        thisItem = {}
        image = None
        id = os.getuid()
        systemWarning = "You should not edit or remove existing system's daemons. These jobs are required for a working macOS system."

        if item != 'Active Daemons':
            if item == 'User Agents':
                homedir = os.path.expanduser('~')
                path = homedir + '/Library/LaunchAgents'
                # If the folder doesn't exist in the user folder, create it
                try:
                    os.listdir(path)
                except:
                    os.mkdir(path)
            elif item == 'Global Agents':
                path = '/Library/LaunchAgents'
            elif item == 'Global Daemons':
                path = '/Library/LaunchDaemons'
            elif item == 'System Agents':
                path = '/System/Library/LaunchAgents'
                self._warning(self, systemWarning, "showSystemWarning")
            elif item == 'System Daemons':
                path = '/System/Library/LaunchDaemons'
                self._warning(self, systemWarning, "showSystemWarning")

            items = []
            files = os.listdir(path)
            count = 0

            for file in files:
                if file.endswith('.plist'):
                    file = file.replace('.plist', '')
                    try:
                        pid = launchd.LaunchdJob(file).pid
                    except:
                        pid = False
                    if launchd.LaunchdJob(file).exists() and pid != None:
                        image = NSImage.imageNamed_(NSImageNameStatusAvailable)
                    elif launchd.LaunchdJob(file).exists() and pid == None:
                        image = NSImage.imageNamed_(
                            NSImageNameStatusPartiallyAvailable)
                    else:
                        image = NSImage.imageNamed_(NSImageNameStatusNone)
                    state = True
                    thisItem['image'] = image
                    thisItem['name'] = file
                    self.w.list.append(thisItem)
                    count += 1
            self.w.counter.set(str(count) + ' Jobs')
예제 #2
0
파일: main.py 프로젝트: sycomix/unicron
    def _loadUnloadDaemon(self, sender, command):
        self.w.list.scrollToSelection()
        name = self.selected['name']
        path = self.selected['file']

        if bool(launchd.LaunchdJob(name).exists()):
            try:
                subprocess.call(
                    ['launchctl', 'unload', '%s' % path],
                    cwd='/',
                    shell=False,
                    universal_newlines=False)
            except:
                return
        else:
            try:
                subprocess.call(
                    ['launchctl', 'load', '%s' % path],
                    cwd='/',
                    shell=False,
                    universal_newlines=False)
            except:
                return

        self.populateList(self)
예제 #3
0
def plist_launch_write(label, program_arguments, scope):
    plist = dict(
        Label=label,
        ProgramArguments=program_arguments.split(),
        RunAtLoad=True,
        KeepAlive=True,
    )
    job = launchd.LaunchdJob(label)
    fname = launchd.plist.write(label, plist, scope)
    launchd.load(fname)
예제 #4
0
def uninstall(label):
    '''
    Utility function to remove a .plist file and unload it

    :param label: job label
    '''
    if launchd.LaunchdJob(label).exists():
        fname = launchd.plist.discover_filename(label)
        launchd.unload(fname)
        os.unlink(fname)
예제 #5
0
def agent_to_menu_item(agent) -> rumps.MenuItem:
    ag = plistlib.readPlist(agent)
    label = ag['Label']
    ar = rumps.MenuItem("")
    aj = launchd.LaunchdJob(label)
    exist = aj.exists()
    if exist:
        pid = aj.pid
        status = aj.laststatus
        if pid == -1 and status == 0:
            ar_title = NSAttributedString.alloc().initWithString_attributes_(
                label, b_attr)
            ar._menuitem.setAttributedTitle_(ar_title)
            insert_unload_reload(ar, aj)
            ar.add(
                rumps.MenuItem("Start",
                               callback=lambda x: launchctl("start", label)))
            insert_log_menu_items(ar, ag)
            ar.add("Idle")
            ar.add("No Errors")
        elif pid > 0 and status == 0:
            ar_title = NSAttributedString.alloc().initWithString_attributes_(
                label, g_attr)
            ar._menuitem.setAttributedTitle_(ar_title)
            insert_unload_reload(ar, aj)
            ar.add(
                rumps.MenuItem("Stop",
                               callback=lambda x: launchctl("stop", label)))
            insert_log_menu_items(ar, ag)
            ar.add(f"Running ({pid})")
            ar.add("No Errors")
        elif status != 0:
            ar_title = NSAttributedString.alloc().initWithString_attributes_(
                label, r_attr)
            ar._menuitem.setAttributedTitle_(ar_title)
            insert_unload_reload(ar, aj)
            ar.add(
                rumps.MenuItem("Start",
                               callback=lambda x: launchctl("start", label)))
            insert_log_menu_items(ar, ag)
            ar.add("Stopped")
            ar.add(f"Error ({status})")
    else:
        ar.title = label
        sub_load = rumps.MenuItem(
            title="Load",
            callback=lambda x: launchd.load(f"{USER_AGENTS}/{label}.plist"))
        ar.add(sub_load)
        insert_log_menu_items(ar, ag)
        ar.add("Unloaded")
    return ar
예제 #6
0
    def test_launchd_lazy_constructor(self):
        # we assume that com.apple.Finder always exists and that it is always
        # running and always has a laststatus. Hmmmm.
        label = "com.apple.Finder"
        job = launchd.LaunchdJob(label)
        self.assertTrue(job.exists())
        self.assertFalse(hasattr(job, '_pid'))
        self.assertFalse(hasattr(job, '_laststatus'))
        self.assertEqual(None, job._properties)
        job.refresh()
        self.assertNotEqual(None, job._pid)
        self.assertNotEqual(None, job._laststatus)
        self.assertNotEqual(None, job._properties)

        job = launchd.LaunchdJob(label)
        self.assertTrue(job.exists())
        self.assertNotEqual(None, job.pid)
        self.assertNotEqual(None, job.laststatus)
        self.assertNotEqual(None, job._properties)

        # let's do the same with something invalid:
        label = "com.apple.Nonexistant-bogus-entry"
        job = launchd.LaunchdJob(label, 1, 2)
        self.assertEqual(1, job.pid)
        self.assertEqual(2, job.laststatus)
        self.assertFalse(job.exists())
        self.assertRaises(ValueError, job.refresh)
        # even though refresh() was called, the object remains unchanged:
        self.assertEqual(1, job.pid)
        self.assertEqual(2, job.laststatus)
        self.assertFalse(job.exists())

        # also test "None":
        label = "com.apple.Nonexistant-bogus-entry2"
        job = launchd.LaunchdJob(label, None, None)
        self.assertEqual(None, job.pid)
        self.assertEqual(None, job.laststatus)
예제 #7
0
def main():
    myplist = dict(
        Disabled=False,
        Label="testlaunchdwrapper_python",
        Nice=-15,
        OnDemand=True,
        ProgramArguments=[
            "/bin/bash", "-c", "sleep 1 && echo 'Hello World' && exit 0"
        ],
        RunAtLoad=True,
        ServiceDescription="runs a sample command",
        ServiceIPC=False,
    )

    import time
    label = myplist['Label']
    job = launchd.LaunchdJob(label)
    if not job.exists():
        print("'%s' is not loaded in launchd. Installing..." % (label))
        install(label, myplist)
        while job.pid is not None:
            print("Alive! PID = %s" % job.pid)
            job.refresh()
            time.sleep(0.2)
    else:
        if job.pid is None:
            print("'%s' is loaded but not currently running" % (job.label))
        else:
            print("'%s' is loaded and currently running: PID = %s" %
                  (job.label, job.pid))
            while job.pid is not None:
                print("Alive! PID = %s" % job.pid)
                job.refresh()
                time.sleep(0.2)

    print("Uninstalling again...")
    uninstall(label)
    return 0
예제 #8
0
 def job(self):
     """The launchd.LaunchdJob for this LaunchAgent."""
     if self.is_loaded:
         return launchd.LaunchdJob(self.label)
     else:
         return None
예제 #9
0
 def is_loaded(self):
     """
     Boolean indicating whether the configuration file for this LaunchAgent
     has been loaded.
     """
     return launchd.LaunchdJob(self.label).exists()
예제 #10
0
    if launchd.LaunchdJob(label).exists():
        fname = launchd.plist.discover_filename(label)
        launchd.unload(fname)
        os.unlink(fname)


myplist = dict(Label="com.example.launched.datewriter",
               Disabled=False,
               KeepAlive=True,
               RunAtLoad=True,
               Program=__file__,
               ProgramArguments=["/bin/bash", "-c", "python3", __file__],
               ServiceDescription="Test for launchd",
               SartInterval=10)
label = myplist['Label']
job = launchd.LaunchdJob(label)
if not job.exists():
    print("'%s' is not loaded in launchd. Installing..." % (label))
    install(label, myplist)
else:
    if job.pid is None:
        print("'%s' is loaded but not currently running" % (job.label))
    else:
        print("'%s' is loaded and currently running: PID = %s" %
              (job.label, job.pid))
choice = input("Uninstall? [y/n]: ")
if choice == "y":
    print("Uninstalling...")
    uninstall(label)

#Reads back queued launchd jobs