This file is indexed.

/usr/share/pyshared/lunch/runner.py is in python-lunch 0.4.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Lunch
# Copyright (C) 2009 Société des arts technologiques (SAT)
# http://www.sat.qc.ca
# All rights reserved.
#
# This file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Lunch is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Lunch.  If not, see <http://www.gnu.org/licenses/>.

"""
Main entry point of the lunch master application.
"""
import os
import sys
import traceback
from optparse import OptionParser
from lunch import __version__

DESCRIPTION = "Lunch is a distributed process launcher for GNU/Linux. The Lunch master launches lunch-slave processes through an encrypted SSH session if on a remote host. Those slave processes can in turn launch the desired commands on-demand."

def run():
    """
    Runs the application.
    """
    parser = OptionParser(usage="%prog [config file] [options]", version="%prog " + __version__, description=DESCRIPTION)
    parser.add_option("-f", "--config-file", type="string", help="Specifies the python config file. You can also simply specify the config file as the first argument.")
    parser.add_option("-l", "--logging-directory", type="string", default="/var/tmp/lunch", help="Specifies the logging and pidfile directory for the master. Default is /var/tmp/lunch")
    parser.add_option("-q", "--log-to-file", action="store_true", help="Enables logging master infos to file and disables logging to standard output.")
    parser.add_option("-g", "--graphical", action="store_true", help="Enables the graphical user interface.")
    parser.add_option("-v", "--verbose", action="store_true", help="Makes the logging output verbose.")
    parser.add_option("-d", "--debug", action="store_true", help="Makes the logging output very verbose.")
    parser.add_option("-k", "--kill", action="store_true", help="Kills another lunch master that uses the same config file and logging directory. Exits once it's done.")
    (options, args) = parser.parse_args()
    # --------- set configuration file
    if options.config_file:
        config_file = options.config_file
    DEFAULT_CONFIG_FILE = os.path.expanduser("~/.lunchrc")
    if len(args) == 1 and not options.config_file: 
        #log.msg("DEBUG: overriding config_file with %s" % (args[0])) 
        config_file = args[0] 
    else:
        config_file = DEFAULT_CONFIG_FILE
    # --------- set if logging 
    if options.log_to_file:
        file_logging_enabled = True
    else:
        file_logging_enabled = False
    logging_dir = options.logging_directory
        
    # ---------- load the right reactor
    if options.graphical:
        try:
            from twisted.internet import gtk2reactor
            gtk2reactor.install() # has to be done before importing reactor
            import gtk # just for a test
            GUI_ENABLED = True
            #print("Successfully loaded the GTK+ graphical user interface.")
        except ImportError, e:
            print("Could not load the GTK+ graphical user interface. " + str(e))
            GUI_ENABLED = False
    else:
        # print("Using lunch master without the GUI.")
        GUI_ENABLED = False
    from twisted.internet import reactor
    from twisted.internet import defer
    # --------- load the module and run
    from lunch import master
    error_message = None
    if not os.path.exists(config_file):
        error_message = "No such file: %s" % (config_file)
    else:
        log_level = 'warning'
        if options.verbose:
            log_level = 'info'
        if options.debug:
            log_level = 'debug'
        if options.kill:
            def _killed_cb(result):
                #TODO: show a dialog to the user if --graphical is given.
                if reactor.running:
                    reactor.stop()
            master.start_stdout_logging(log_level=log_level) #FIXME: should be able to log to file too
            identifier = master.gen_id_from_config_file_name(config_file)
            master.log.info("Will check if lunch master %s is running and kill it if so." % (identifier))
            deferred = master.kill_master_if_running(identifier=identifier, directory=logging_dir)
            deferred.addCallback(_killed_cb)
            reactor.run()
            sys.exit(0)
        try:
            #print("DEBUG: using config_file %s" % (config_file))
            lunch_master = master.run_master(config_file, log_to_file=file_logging_enabled, log_dir=logging_dir, log_level=log_level)
        except master.FileNotFoundError, e:
            #print("Error starting lunch as master.")
            msg = "A configuration file is missing. Try the --help flag. "
            msg += str(e)
            error_message = msg
            #sys.exit(1)
        except RuntimeError, e:
            #print(str(e))
            error_message = str(e)
            #sys.exit(1)
        except Exception, e:
            error_message = "There is an error in your lunch file !\n"
            error_message += traceback.format_exc()
    if error_message is not None:
        print(error_message)
        if GUI_ENABLED:
            from lunch import dialogs
            def _cb(result):
                # stops reactor when the error dialog is closed
                reactor.stop()
            d = defer.Deferred()
            d.addCallback(_cb)
            error_dialog = dialogs.ErrorDialog(d, error_message)
            print("Running reactor to show error dialog.")
            reactor.run() # need it for the GTK error dialog
            print("Reactor stopped. Exiting.")
        sys.exit(1)
    if GUI_ENABLED:
        from lunch import gui
        app = gui.start_gui(lunch_master)
        #print("Done starting the app.")
    try:
        reactor.run()
    except KeyboardInterrupt:
        #log.msg("Ctrl-C in Master.", logging.INFO)
        #lunch_master.quit_master()
        reactor.stop()