New config options for daemonization, configfile location and basedir location
Using --daemon {start|stop|restart} OctoPrint can now be daemonized/controlled in daemon mode. Via --pidfile it's possible to set the pidfile to use, --configfile allows specification of the config.yaml to use, --basedir specifies the location of the basedir from which to base off the upload, timelapse and log folders. I also updated the README to include some config file settings which were previously undocumented.master
parent
8570f73794
commit
363f00775b
69
README.md
69
README.md
|
@ -39,39 +39,39 @@ Usage
|
||||||
|
|
||||||
Just start the server via
|
Just start the server via
|
||||||
|
|
||||||
python -m octoprint.server
|
|
||||||
|
|
||||||
or alternatively
|
|
||||||
|
|
||||||
./run
|
./run
|
||||||
|
|
||||||
By default it binds to all interfaces on port 5000 (so pointing your browser to `http://127.0.0.1:5000`
|
By default it binds to all interfaces on port 5000 (so pointing your browser to `http://127.0.0.1:5000`
|
||||||
will do the trick). If you want to change that, use the additional command line parameters `host` and `port`,
|
will do the trick). If you want to change that, use the additional command line parameters `host` and `port`,
|
||||||
which accept the host ip to bind to and the numeric port number respectively. If for example you want to the server
|
which accept the host ip to bind to and the numeric port number respectively. If for example you want the server
|
||||||
to only listen on the local interface on port 8080, the command line would be
|
to only listen on the local interface on port 8080, the command line would be
|
||||||
|
|
||||||
python -m octoprint.server --host=127.0.0.1 --port=8080
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
./run --host=127.0.0.1 --port=8080
|
./run --host=127.0.0.1 --port=8080
|
||||||
|
|
||||||
Alternatively, the host and port on which to bind can be defined via the configuration.
|
Alternatively, the host and port on which to bind can be defined via the configuration.
|
||||||
|
|
||||||
If you want to run OctoPrint as a daemon, there's another script for that:
|
If you want to run OctoPrint as a daemon (only supported on Linux), use
|
||||||
|
|
||||||
./run-as-daemon [start|stop|restart]
|
./run --daemon {start|stop|restart} [--pidfile PIDFILE]
|
||||||
|
|
||||||
It will create a pid file at `/tmp/octoprint.pid` for now. Further commandline arguments will not be evaluated,
|
If you do not supply a custom pidfile location via `--pidfile PIDFILE`, it will be created at `/tmp/octoprint.pid`.
|
||||||
so you'll need to define host and port in the configuration file if you want something different there than the default.
|
|
||||||
|
You can also specify the configfile or the base directory (for basing off the `uploads`, `timelapse` and `logs` folders),
|
||||||
|
e.g.:
|
||||||
|
|
||||||
|
./run --config /path/to/another/config.yaml --basedir /path/to/my/basedir
|
||||||
|
|
||||||
|
See `run --help` for further information.
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The config-file `config.yaml` for OctoPrint is expected in its settings folder, which is located at `~/.octoprint`
|
If not specified via the commandline, the configfile `config.yaml` for OctoPrint is expected in its settings folder,
|
||||||
on Linux, at `%APPDATA%/OctoPrint` on Windows and at `~/Library/Application Support/OctoPrint` on MacOS.
|
which is located at `~/.octoprint` on Linux, at `%APPDATA%/OctoPrint` on Windows and at
|
||||||
|
`~/Library/Application Support/OctoPrint` on MacOS.
|
||||||
|
|
||||||
The following example config should explain the available options:
|
The following example config should explain the available options, most of which can also be configured via the
|
||||||
|
settings dialog within OctoPrint:
|
||||||
|
|
||||||
# Use the following settings to configure the serial connection to the printer
|
# Use the following settings to configure the serial connection to the printer
|
||||||
serial:
|
serial:
|
||||||
|
@ -111,6 +111,10 @@ The following example config should explain the available options:
|
||||||
# Whether to enable the gcode viewer in the UI or not
|
# Whether to enable the gcode viewer in the UI or not
|
||||||
gCodeVisualizer: true
|
gCodeVisualizer: true
|
||||||
|
|
||||||
|
# Specified whether OctoPrint should wait for the start response from the printer before trying to send commands
|
||||||
|
# during connect
|
||||||
|
waitForStartOnConnect: false
|
||||||
|
|
||||||
# Use the following settings to set custom paths for folders used by OctoPrint
|
# Use the following settings to set custom paths for folders used by OctoPrint
|
||||||
folder:
|
folder:
|
||||||
# Absolute path where to store gcode uploads. Defaults to the uploads folder in the OctoPrint settings folder
|
# Absolute path where to store gcode uploads. Defaults to the uploads folder in the OctoPrint settings folder
|
||||||
|
@ -122,7 +126,38 @@ The following example config should explain the available options:
|
||||||
|
|
||||||
# Absolute path where to store temporary timelapse files. Defaults to the timelapse/tmp folder in the OctoPrint
|
# Absolute path where to store temporary timelapse files. Defaults to the timelapse/tmp folder in the OctoPrint
|
||||||
# settings dir
|
# settings dir
|
||||||
timelapse_tmp: /path/timelapse/tmp/folder
|
timelapse_tmp: /path/to/timelapse/tmp/folder
|
||||||
|
|
||||||
|
# Absolute path where to store log files. Defaults to the logs folder in the OctoPrint settings dir
|
||||||
|
logs: /path/to/logs/folder
|
||||||
|
|
||||||
|
# Use the following settings to configure temperature profiles which will be displayed in the temperature tab.
|
||||||
|
temperature:
|
||||||
|
profiles:
|
||||||
|
- name: ABS
|
||||||
|
extruder: 210
|
||||||
|
bed: 100
|
||||||
|
- name: PLA
|
||||||
|
extruder: 180
|
||||||
|
bed: 60
|
||||||
|
|
||||||
|
# Use the following settings to configure printer parameters
|
||||||
|
printerParameters:
|
||||||
|
# Use this to define the movement speed on X, Y, Z and E to use for the controls on the controls tab
|
||||||
|
movementSpeed:
|
||||||
|
x: 6000
|
||||||
|
y: 6000
|
||||||
|
z: 200
|
||||||
|
e: 300
|
||||||
|
|
||||||
|
# Use the following settings to tweak OctoPrint's appearance a bit to better distinguish multiple instances/printers
|
||||||
|
appearance:
|
||||||
|
# Use this to give your printer a name. It will be displayed in the title bar (as "<Name> [OctoPrint]") and in the
|
||||||
|
# navigation bar (as "OctoPrint: <Name>")
|
||||||
|
name: My Printer Model
|
||||||
|
|
||||||
|
# Use this to color the navigation bar. Supported colors are red, orange, yellow, green, blue, violet and default.
|
||||||
|
color: blue
|
||||||
|
|
||||||
# Use the following settings to add custom controls to the "Controls" tab within OctoPrint
|
# Use the following settings to add custom controls to the "Controls" tab within OctoPrint
|
||||||
#
|
#
|
||||||
|
|
|
@ -18,7 +18,6 @@ import octoprint.gcodefiles as gcodefiles
|
||||||
import octoprint.util as util
|
import octoprint.util as util
|
||||||
|
|
||||||
SUCCESS = {}
|
SUCCESS = {}
|
||||||
UPLOAD_FOLDER = settings().getBaseFolder("uploads")
|
|
||||||
BASEURL = "/ajax/"
|
BASEURL = "/ajax/"
|
||||||
app = Flask("octoprint")
|
app = Flask("octoprint")
|
||||||
# Only instantiated by the Server().run() method
|
# Only instantiated by the Server().run() method
|
||||||
|
@ -249,7 +248,7 @@ def readGcodeFiles():
|
||||||
|
|
||||||
@app.route(BASEURL + "gcodefiles/<path:filename>", methods=["GET"])
|
@app.route(BASEURL + "gcodefiles/<path:filename>", methods=["GET"])
|
||||||
def readGcodeFile(filename):
|
def readGcodeFile(filename):
|
||||||
return send_from_directory(UPLOAD_FOLDER, filename, as_attachment=True)
|
return send_from_directory(settings().getBaseFolder("uploads"), filename, as_attachment=True)
|
||||||
|
|
||||||
@app.route(BASEURL + "gcodefiles/upload", methods=["POST"])
|
@app.route(BASEURL + "gcodefiles/upload", methods=["POST"])
|
||||||
def uploadGcodeFile():
|
def uploadGcodeFile():
|
||||||
|
@ -442,7 +441,14 @@ def performSystemAction():
|
||||||
|
|
||||||
#~~ startup code
|
#~~ startup code
|
||||||
class Server():
|
class Server():
|
||||||
def run(self, host = "0.0.0.0", port = 5000, debug = False):
|
def __init__(self, configfile=None, basedir=None, host="0.0.0.0", port=5000, debug=False):
|
||||||
|
self._configfile = configfile
|
||||||
|
self._basedir = basedir
|
||||||
|
self._host = host
|
||||||
|
self._port = port
|
||||||
|
self._debug = debug
|
||||||
|
|
||||||
|
def run(self):
|
||||||
# Global as I can't work out a way to get it into PrinterStateConnection
|
# Global as I can't work out a way to get it into PrinterStateConnection
|
||||||
global printer
|
global printer
|
||||||
global gcodeManager
|
global gcodeManager
|
||||||
|
@ -452,11 +458,22 @@ class Server():
|
||||||
from tornado.ioloop import IOLoop
|
from tornado.ioloop import IOLoop
|
||||||
from tornado.web import Application, FallbackHandler
|
from tornado.web import Application, FallbackHandler
|
||||||
|
|
||||||
|
# first initialize the settings singleton and make sure it uses given configfile and basedir if available
|
||||||
|
self._initSettings(self._configfile, self._basedir)
|
||||||
|
|
||||||
|
# then initialize logging
|
||||||
|
self._initLogging(self._debug)
|
||||||
|
|
||||||
gcodeManager = gcodefiles.GcodeManager()
|
gcodeManager = gcodefiles.GcodeManager()
|
||||||
printer = Printer(gcodeManager)
|
printer = Printer(gcodeManager)
|
||||||
|
|
||||||
logging.getLogger(__name__).info("Listening on http://%s:%d" % (host, port))
|
if self._host is None:
|
||||||
app.debug = debug
|
self._host = settings().get(["server", "host"])
|
||||||
|
if self._port is None:
|
||||||
|
self._port = settings().getInt(["server", "port"])
|
||||||
|
|
||||||
|
logging.getLogger(__name__).info("Listening on http://%s:%d" % (self._host, self._port))
|
||||||
|
app.debug = self._debug
|
||||||
|
|
||||||
self._router = tornadio2.TornadioRouter(PrinterStateConnection)
|
self._router = tornadio2.TornadioRouter(PrinterStateConnection)
|
||||||
|
|
||||||
|
@ -464,10 +481,13 @@ class Server():
|
||||||
(".*", FallbackHandler, {"fallback": WSGIContainer(app)})
|
(".*", FallbackHandler, {"fallback": WSGIContainer(app)})
|
||||||
])
|
])
|
||||||
self._server = HTTPServer(self._tornado_app)
|
self._server = HTTPServer(self._tornado_app)
|
||||||
self._server.listen(port, address=host)
|
self._server.listen(self._port, address=self._host)
|
||||||
IOLoop.instance().start()
|
IOLoop.instance().start()
|
||||||
|
|
||||||
def initLogging(self):
|
def _initSettings(self, configfile, basedir):
|
||||||
|
s = settings(init=True, basedir=basedir, configfile=configfile)
|
||||||
|
|
||||||
|
def _initLogging(self, debug):
|
||||||
self._config = {
|
self._config = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"formatters": {
|
"formatters": {
|
||||||
|
@ -503,24 +523,6 @@ class Server():
|
||||||
}
|
}
|
||||||
logging.config.dictConfig(self._config)
|
logging.config.dictConfig(self._config)
|
||||||
|
|
||||||
def start(self):
|
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
self._defaultHost = settings().get(["server", "host"])
|
|
||||||
self._defaultPort = settings().get(["server", "port"])
|
|
||||||
|
|
||||||
self._parser = OptionParser(usage="usage: %prog [options]")
|
|
||||||
self._parser.add_option("-d", "--debug", action="store_true", dest="debug",
|
|
||||||
help="Enable debug mode")
|
|
||||||
self._parser.add_option("--host", action="store", type="string", default=self._defaultHost, dest="host",
|
|
||||||
help="Specify the host on which to bind the server, defaults to %s if not set" % (self._defaultHost))
|
|
||||||
self._parser.add_option("--port", action="store", type="int", default=self._defaultPort, dest="port",
|
|
||||||
help="Specify the port on which to bind the server, defaults to %s if not set" % (self._defaultPort))
|
|
||||||
(options, args) = self._parser.parse_args()
|
|
||||||
|
|
||||||
self.initLogging()
|
|
||||||
self.run(host=options.host, port=options.port, debug=options.debug)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
octoprint = Server()
|
octoprint = Server()
|
||||||
octoprint.start()
|
octoprint.run()
|
||||||
|
|
|
@ -9,17 +9,19 @@ import yaml
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
APPNAME="OctoPrint"
|
APPNAME="OctoPrint"
|
||||||
OLD_APPNAME="PrinterWebUI"
|
|
||||||
|
|
||||||
instance = None
|
instance = None
|
||||||
|
|
||||||
def settings():
|
def settings(init=False, configfile=None, basedir=None):
|
||||||
global instance
|
global instance
|
||||||
if instance is None:
|
if instance is None:
|
||||||
instance = Settings()
|
if init:
|
||||||
|
instance = Settings(configfile, basedir)
|
||||||
|
else:
|
||||||
|
raise ValueError("Settings not initialized yet")
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
old_default_settings = {
|
default_settings = {
|
||||||
"serial": {
|
"serial": {
|
||||||
"port": None,
|
"port": None,
|
||||||
"baudrate": None
|
"baudrate": None
|
||||||
|
@ -35,33 +37,16 @@ old_default_settings = {
|
||||||
"bitrate": "5000k",
|
"bitrate": "5000k",
|
||||||
"watermark": True
|
"watermark": True
|
||||||
},
|
},
|
||||||
|
"feature": {
|
||||||
|
"gCodeVisualizer": True,
|
||||||
|
"waitForStartOnConnect": False
|
||||||
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
"uploads": None,
|
"uploads": None,
|
||||||
"timelapse": None,
|
"timelapse": None,
|
||||||
"timelapse_tmp": None,
|
"timelapse_tmp": None,
|
||||||
"logs": None
|
"logs": None
|
||||||
},
|
},
|
||||||
"feature": {
|
|
||||||
"gCodeVisualizer": True,
|
|
||||||
"waitForStartOnConnect": False
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
default_settings = old_default_settings.copy()
|
|
||||||
default_settings.update({
|
|
||||||
"appearance": {
|
|
||||||
"name": "",
|
|
||||||
"color": "default"
|
|
||||||
},
|
|
||||||
"controls": [],
|
|
||||||
"printerParameters": {
|
|
||||||
"movementSpeed": {
|
|
||||||
"x": 6000,
|
|
||||||
"y": 6000,
|
|
||||||
"z": 200,
|
|
||||||
"e": 300
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"temperature": {
|
"temperature": {
|
||||||
"profiles":
|
"profiles":
|
||||||
[
|
[
|
||||||
|
@ -69,16 +54,29 @@ default_settings.update({
|
||||||
{"name": "PLA", "extruder" : 180, "bed" : 60 }
|
{"name": "PLA", "extruder" : 180, "bed" : 60 }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"printerParameters": {
|
||||||
|
"movementSpeed": {
|
||||||
|
"x": 6000,
|
||||||
|
"y": 6000,
|
||||||
|
"z": 200,
|
||||||
|
"e": 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"appearance": {
|
||||||
|
"name": "",
|
||||||
|
"color": "default"
|
||||||
|
},
|
||||||
|
"controls": [],
|
||||||
"system": {
|
"system": {
|
||||||
"actions": []
|
"actions": []
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
valid_boolean_trues = ["true", "yes", "y", "1"]
|
valid_boolean_trues = ["true", "yes", "y", "1"]
|
||||||
|
|
||||||
class Settings(object):
|
class Settings(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, configfile=None, basedir=None):
|
||||||
self._logger = logging.getLogger(__name__)
|
self._logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
self.settings_dir = None
|
self.settings_dir = None
|
||||||
|
@ -86,17 +84,15 @@ class Settings(object):
|
||||||
self._config = None
|
self._config = None
|
||||||
self._dirty = False
|
self._dirty = False
|
||||||
|
|
||||||
self._init_settings_dir()
|
self._init_settings_dir(basedir)
|
||||||
self.load()
|
self.load(configfile)
|
||||||
|
|
||||||
def _init_settings_dir(self):
|
def _init_settings_dir(self, basedir):
|
||||||
|
if basedir is not None:
|
||||||
|
self.settings_dir = basedir
|
||||||
|
else:
|
||||||
self.settings_dir = _resolveSettingsDir(APPNAME)
|
self.settings_dir = _resolveSettingsDir(APPNAME)
|
||||||
|
|
||||||
# migration due to rename
|
|
||||||
old_settings_dir = _resolveSettingsDir(OLD_APPNAME)
|
|
||||||
if os.path.exists(old_settings_dir) and os.path.isdir(old_settings_dir) and not os.path.exists(self.settings_dir):
|
|
||||||
os.rename(old_settings_dir, self.settings_dir)
|
|
||||||
|
|
||||||
def _getDefaultFolder(self, type):
|
def _getDefaultFolder(self, type):
|
||||||
folder = default_settings["folder"][type]
|
folder = default_settings["folder"][type]
|
||||||
if folder is None:
|
if folder is None:
|
||||||
|
@ -105,29 +101,15 @@ class Settings(object):
|
||||||
|
|
||||||
#~~ load and save
|
#~~ load and save
|
||||||
|
|
||||||
def load(self):
|
def load(self, configfile):
|
||||||
|
if configfile is not None:
|
||||||
|
filename = configfile
|
||||||
|
else:
|
||||||
filename = os.path.join(self.settings_dir, "config.yaml")
|
filename = os.path.join(self.settings_dir, "config.yaml")
|
||||||
oldFilename = os.path.join(self.settings_dir, "config.ini")
|
|
||||||
if os.path.exists(filename) and os.path.isfile(filename):
|
if os.path.exists(filename) and os.path.isfile(filename):
|
||||||
with open(filename, "r") as f:
|
with open(filename, "r") as f:
|
||||||
self._config = yaml.safe_load(f)
|
self._config = yaml.safe_load(f)
|
||||||
elif os.path.exists(oldFilename) and os.path.isfile(oldFilename):
|
|
||||||
config = ConfigParser.ConfigParser(allow_no_value=True)
|
|
||||||
config.read(oldFilename)
|
|
||||||
self._config = {}
|
|
||||||
for section in old_default_settings.keys():
|
|
||||||
if not config.has_section(section):
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._config[section] = {}
|
|
||||||
for option in old_default_settings[section].keys():
|
|
||||||
if not config.has_option(section, option):
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._config[section][option] = config.get(section, option)
|
|
||||||
self._dirty = True
|
|
||||||
self.save(force=True)
|
|
||||||
os.rename(oldFilename, oldFilename + ".bck")
|
|
||||||
else:
|
else:
|
||||||
self._config = {}
|
self._config = {}
|
||||||
|
|
||||||
|
|
70
run
70
run
|
@ -1,14 +1,62 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/python
|
||||||
|
import sys
|
||||||
|
from octoprint.daemon import Daemon
|
||||||
|
from octoprint.server import Server
|
||||||
|
|
||||||
PYTHON=`which python`
|
class Main(Daemon):
|
||||||
|
def __init__(self, pidfile, configfile, basedir, host, port, debug):
|
||||||
|
Daemon.__init__(self, pidfile)
|
||||||
|
|
||||||
SOURCE="${BASH_SOURCE[0]}"
|
self._configfile = configfile
|
||||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
self._basedir = basedir
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
self._host = host
|
||||||
SOURCE="$(readlink "$SOURCE")"
|
self._port = port
|
||||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
self._debug = debug
|
||||||
done
|
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
|
||||||
|
|
||||||
cd $DIR
|
def run(self):
|
||||||
$PYTHON -m octoprint.server $@
|
octoprint = Server(self._configfile, self._basedir, self._host, self._port, self._debug)
|
||||||
|
octoprint.run()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(prog="run")
|
||||||
|
|
||||||
|
parser.add_argument("-d", "--debug", action="store_true", dest="debug",
|
||||||
|
help="Enable debug mode")
|
||||||
|
|
||||||
|
parser.add_argument("--host", action="store", type=str, dest="host",
|
||||||
|
help="Specify the host on which to bind the server")
|
||||||
|
parser.add_argument("--port", action="store", type=int, dest="port",
|
||||||
|
help="Specify the port on which to bind the server")
|
||||||
|
|
||||||
|
parser.add_argument("-c", "--config", action="store", dest="config",
|
||||||
|
help="Specify the config file to use. OctoPrint needs to have write access for the settings dialog to work. Defaults to ~/.octoprint/config.yaml")
|
||||||
|
parser.add_argument("-b", "--basedir", action="store", dest="basedir",
|
||||||
|
help="Specify the basedir to use for uploads, timelapses etc. OctoPrint needs to have write access. Defaults to ~/.octoprint")
|
||||||
|
|
||||||
|
parser.add_argument("--daemon", action="store", type=str, choices=["start", "stop", "restart"],
|
||||||
|
help="Daemonize/control daemonized OctoPrint instance (only supported under Linux right now)")
|
||||||
|
parser.add_argument("--pid", action="store", type=str, dest="pidfile", default="/tmp/octoprint.pid",
|
||||||
|
help="Pidfile to use for daemonizing, defaults to /tmp/octoprint.pid")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.daemon:
|
||||||
|
if sys.platform == "darwin" or sys.platform == "win32":
|
||||||
|
print >> sys.stderr, "Sorry, daemon mode is only supported under Linux right now"
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
daemon = Main(args.pidfile, args.config, args.basedir, args.host, args.port, args.debug)
|
||||||
|
if args.command is not None:
|
||||||
|
if "start" == args.command:
|
||||||
|
daemon.start()
|
||||||
|
elif "stop" == args.command:
|
||||||
|
daemon.stop()
|
||||||
|
elif "restart" == args.command:
|
||||||
|
daemon.restart()
|
||||||
|
else:
|
||||||
|
octoprint = Server(args.config, args.basedir, args.host, args.port, args.debug)
|
||||||
|
octoprint.run()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
import sys
|
|
||||||
from octoprint.daemon import Daemon
|
|
||||||
from octoprint.server import Server
|
|
||||||
|
|
||||||
class Main(Daemon):
|
|
||||||
def run(self):
|
|
||||||
octoprint = Server()
|
|
||||||
octoprint.start()
|
|
||||||
|
|
||||||
def main():
|
|
||||||
daemon = Main('/tmp/octoprint.pid')
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
if 'start' == sys.argv[1]:
|
|
||||||
daemon.start()
|
|
||||||
elif 'stop' == sys.argv[1]:
|
|
||||||
daemon.stop()
|
|
||||||
elif 'restart' == sys.argv[1]:
|
|
||||||
daemon.restart()
|
|
||||||
else:
|
|
||||||
print "Unknown command"
|
|
||||||
sys.exit(2)
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
print "usage: %s start|stop|restart" % sys.argv[0]
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
Loading…
Reference in New Issue