awlsim-server 4.95 KB
Newer Older
1 2 3 4 5
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# AWL simulator - Server interface
#
6
# Copyright 2013-2016 Michael Buesch <m@bues.ch>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#
# This program 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.
#
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

23 24
from __future__ import division, absolute_import, print_function, unicode_literals

25 26
import sys
import getopt
27
from socket import AF_INET, AF_INET6
28

29 30 31 32
from awlsim_loader.common import *
from awlsim_loader.core import *
from awlsim_loader.coreclient import *
from awlsim_loader.coreserver import *
33
import awlsim_loader.cython_helper as cython_helper
34 35 36


def usage():
37 38
	print("awlsim-server version %s" % VERSION_STRING)
	print("")
39 40 41 42
	print("Usage: awlsim-server [OPTIONS] <project.awlpro>")
	print("")
	print("<project.awlpro> is an optional project file that will be loaded.")
	print("If -w is also given, all project changes are written back to that file.")
43 44
	print("")
	print("Options:")
45
	print(" -l|--listen HOST[:PORT] Listen on the specified HOST:PORT")
46
	print("                         Defaults to %s:%d" %\
47
		  (AwlSimServer.DEFAULT_HOST, AwlSimServer.DEFAULT_PORT))
48 49
	print("                         The special values 'all', 'any' or an empty host")
	print("                         can be used to listen on any interface.")
50 51
	print(" -4|--force-ipv4         Force the use of IPv4.")
	print(" -6|--force-ipv6         Force the use of IPv6.")
52
	print(" -B|--background         Fork a background process")
53
	print(" -w|--rw-project         Enable project file writing")
54 55 56 57 58 59 60
	print(" -L|--loglevel LVL       Set the log level:")
	print("                         0: Log nothing")
	print("                         1: Log errors")
	print("                         2: Log errors and warnings")
	print("                         3: Log errors, warnings and info messages (default)")
	print("                         4: Verbose logging")
	print("                         5: Extremely verbose logging")
61 62 63 64 65

def main():
	global opt_listen
	global opt_background

66 67
	opt_project = None
	opt_rwProject = False
68
	opt_listen = (AwlSimServer.DEFAULT_HOST, AwlSimServer.DEFAULT_PORT)
69
	opt_family = None
70
	opt_background = False
71
	opt_loglevel = Logging.LOG_INFO
72 73 74

	try:
		(opts, args) = getopt.getopt(sys.argv[1:],
75 76 77
			"hl:46BwL:",
			[ "help", "listen=", "force-ipv4", "force-ipv6",
			  "background", "rw-project",
78
			  "loglevel=", ])
79 80 81
	except getopt.GetoptError as e:
		printError(str(e))
		usage()
Michael Büsch's avatar
Michael Büsch committed
82
		return ExitCodes.EXIT_ERR_CMDLINE
83 84 85
	for (o, v) in opts:
		if o in ("-h", "--help"):
			usage()
Michael Büsch's avatar
Michael Büsch committed
86
			return ExitCodes.EXIT_OK
87 88
		if o in ("-l", "--listen"):
			try:
89
				host, port = parseNetAddress(v)
90 91 92
				if not host.strip() or\
				   host in {"any", "all"}:
					host = ""
93 94 95 96 97
				if port is None:
					port = AwlSimServer.DEFAULT_PORT
				opt_listen = (host, port)
			except AwlSimError as e:
				printError("-l|--listen: %s" % e.message)
98
				sys.exit(1)
99 100 101 102
		if o in ("-4", "--force-ipv4"):
			opt_family = AF_INET
		if o in ("-6", "--force-ipv6"):
			opt_family = AF_INET6
103 104
		if o in ("-B", "--background"):
			opt_background = True
105 106
		if o in ("-w", "--rw-project"):
			opt_rwProject = True
107 108 109 110 111 112
		if o in ("-L", "--loglevel"):
			try:
				opt_loglevel = int(v)
			except ValueError:
				printError("-L|--loglevel: Invalid log level")
				sys.exit(1)
113
	if len(args) not in (0, 1):
114
		usage()
Michael Büsch's avatar
Michael Büsch committed
115
		return ExitCodes.EXIT_ERR_CMDLINE
116 117
	if args:
		opt_project = args[0]
118

Michael Büsch's avatar
Michael Büsch committed
119
	exitCode = ExitCodes.EXIT_OK
120
	try:
121
		Logging.setLoglevel(opt_loglevel)
122 123 124 125 126
		if opt_background:
			interpreter = sys.executable
			assert(interpreter)
			serverProcess = AwlSimServer.start(listenHost = opt_listen[0],
							   listenPort = opt_listen[1],
127
							   listenFamily = opt_family,
128
							   forkInterpreter = interpreter,
129 130 131
							   commandMask = 0,
							   projectFile = opt_project,
							   projectWriteBack = opt_rwProject)
132 133 134
			printInfo("Started awlsim server process (PID: %d)" %\
				  serverProcess.pid)
		else:
135
			if cython_helper.shouldUseCython():
Michael Büsch's avatar
Michael Büsch committed
136
				printInfo("*** Using accelerated CYTHON core "
137
					  "(AWLSIM_CYTHON environment variable is set)")
Michael Büsch's avatar
Michael Büsch committed
138

139 140
			exitCode = AwlSimServer.start(listenHost = opt_listen[0],
						      listenPort = opt_listen[1],
141
						      listenFamily = opt_family,
142
						      forkInterpreter = None,
143 144 145
						      commandMask = 0,
						      projectFile = opt_project,
						      projectWriteBack = opt_rwProject)
146 147
	except AwlSimError as e:
		printError(e.getReport())
Michael Büsch's avatar
Michael Büsch committed
148
		return ExitCodes.EXIT_ERR_SIM
149 150 151 152 153

	return exitCode

if __name__ == "__main__":
	sys.exit(main())