aboutsummaryrefslogtreecommitdiff
path: root/automation/server/server.py
blob: c8f225217f7b5cb70a01984f2a1aa20720d6e69f (plain)
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
#!/usr/bin/python2
#
# Copyright 2010 Google Inc. All Rights Reserved.

import logging
import optparse
import pickle
import signal
from SimpleXMLRPCServer import SimpleXMLRPCServer
import sys

from automation.common import logger
from automation.common.command_executer import CommandExecuter
from automation.server import machine_manager
from automation.server.job_group_manager import JobGroupManager
from automation.server.job_manager import JobManager


class Server(object):
  """Plays a role of external interface accessible over XMLRPC."""

  def __init__(self, machines_file=None, dry_run=False):
    """Default constructor.

    Args:
      machines_file: Path to file storing a list of machines.
      dry_run: If True, the server only simulates command execution.
    """
    CommandExecuter.Configure(dry_run)

    self.job_manager = JobManager(
        machine_manager.MachineManager.FromMachineListFile(
            machines_file or machine_manager.DEFAULT_MACHINES_FILE))

    self.job_group_manager = JobGroupManager(self.job_manager)

    self._logger = logging.getLogger(self.__class__.__name__)

  def ExecuteJobGroup(self, job_group, dry_run=False):
    job_group = pickle.loads(job_group)
    self._logger.info('Received ExecuteJobGroup(%r, dry_run=%s) request.',
                      job_group, dry_run)

    for job in job_group.jobs:
      job.dry_run = dry_run
    return self.job_group_manager.AddJobGroup(job_group)

  def GetAllJobGroups(self):
    self._logger.info('Received GetAllJobGroups() request.')
    return pickle.dumps(self.job_group_manager.GetAllJobGroups())

  def KillJobGroup(self, job_group_id):
    self._logger.info('Received KillJobGroup(%d) request.', job_group_id)
    self.job_group_manager.KillJobGroup(pickle.loads(job_group_id))

  def GetJobGroup(self, job_group_id):
    self._logger.info('Received GetJobGroup(%d) request.', job_group_id)

    return pickle.dumps(self.job_group_manager.GetJobGroup(job_group_id))

  def GetJob(self, job_id):
    self._logger.info('Received GetJob(%d) request.', job_id)

    return pickle.dumps(self.job_manager.GetJob(job_id))

  def GetMachineList(self):
    self._logger.info('Received GetMachineList() request.')

    return pickle.dumps(self.job_manager.machine_manager.GetMachineList())

  def StartServer(self):
    self.job_manager.StartJobManager()

  def StopServer(self):
    self.job_manager.StopJobManager()
    self.job_manager.join()


def GetServerOptions():
  """Get server's settings from command line options."""
  parser = optparse.OptionParser()
  parser.add_option('-m',
                    '--machines-file',
                    dest='machines_file',
                    help='The location of the file '
                    'containing the machines database',
                    default=machine_manager.DEFAULT_MACHINES_FILE)
  parser.add_option('-n',
                    '--dry-run',
                    dest='dry_run',
                    help='Start the server in dry-run mode, where jobs will '
                    'not actually be executed.',
                    action='store_true',
                    default=False)
  return parser.parse_args()[0]


def Main():
  logger.SetUpRootLogger(filename='server.log', level=logging.DEBUG)

  options = GetServerOptions()
  server = Server(options.machines_file, options.dry_run)
  server.StartServer()

  def _HandleKeyboardInterrupt(*_):
    server.StopServer()
    sys.exit(1)

  signal.signal(signal.SIGINT, _HandleKeyboardInterrupt)

  try:
    xmlserver = SimpleXMLRPCServer(
        ('localhost', 8000),
        allow_none=True,
        logRequests=False)
    xmlserver.register_instance(server)
    xmlserver.serve_forever()
  except Exception as ex:
    logging.error(ex)
    server.StopServer()
    sys.exit(1)


if __name__ == '__main__':
  Main()