Skip to content

Commit

Permalink
fixed bugs in systemd service registration, updated release v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
i2cy committed Sep 22, 2022
1 parent 219c58f commit 4a7693c
Show file tree
Hide file tree
Showing 18 changed files with 155 additions and 42 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

This repo is the server part of LockingLock project.

Project is still under development.

[Github Link](https://github.com/i2cy/LockingLock_Python)

# Installation
Expand All @@ -14,3 +12,19 @@ Project is still under development.

This command will help you to edit a configuration file and
add startup scripts on boot in systemd

# Auto-Startup on Linux
By running `i2llsrv setup` command, setup wizard will ask you in the end
of setup sequence for choosing whether should it register a systemd
service. Choose yes to generate service file and register which requires
root permission or sudo permission.

However, if the setup wizard failed to register startup service, it will generate
a one-script-done shell script at your home directory which named as:

`enable_auto-startup_for_i2ll.sh`

By executing this shell scripts by root or sudo, the automatic startup
service will be registered which named as `i2llserver.service`

Use `service i2llserver start|stop|restart` to control server
6 changes: 3 additions & 3 deletions build/lib/I2LLService/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __str__(self):
return "<LL device, index: {}, topic: {}>".format(self.device_index, self.root_topic)

def saveConfig(self):
self.__file_io = open(self.__file_io.name, "r+")
self.__file_io = open(self.__file_io.name, "r")
json_dict = json.load(self.__file_io)
self.__file_io.close()

Expand All @@ -54,7 +54,7 @@ def __init__(self, filename):
super(Config, self).__init__([])

if os.path.exists(filename) and os.path.isfile(filename):
self.__file_io = open(filename, "r+")
self.__file_io = open(filename, "r")
json_dict = json.load(self.__file_io)

self.mqtt_host = json_dict["mqtt_host"]
Expand Down Expand Up @@ -154,7 +154,7 @@ def saveConfig(self, new=False):
if new:
json_dict = {}
else:
self.__file_io = open(self.__file_io.name, "r+")
self.__file_io = open(self.__file_io.name, "r")
json_dict = json.load(self.__file_io)
self.__file_io.close()

Expand Down
113 changes: 94 additions & 19 deletions build/lib/I2LLService/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from i2cylib.crypto import DynKey16
from paho.mqtt import client
from pathlib import Path
from i2cylib.network.I2TCP import Server, Handler
from i2cylib.utils import Logger, get_args, DirTree, i2TecHome
import json
Expand All @@ -25,6 +26,8 @@
CMD_TOPIC = "request"

SYSTEMD_PATH = "/etc/systemd/system/i2llserver.service"
NON_ROOT_SYSTEMD_PATH = DirTree(Path.home(), "i2llserver.service")
NON_ROOT_AUTOINIT_PATH = DirTree(Path.home(), "enable_auto-startup_for_i2ll.sh")


class PahoMqttSessionFlags(object):
Expand Down Expand Up @@ -246,12 +249,12 @@ class LLServer(Server):
def __init__(self, config,
max_connections=20,
secured_connection=True, max_buffer_size=50,
watchdog_timeout=20):
watchdog_timeout=20, verbose=True):
assert isinstance(config, Config)

self.config = config
self.__mqtt_flag_dict = PahoMqttSessionFlags()
logger = Logger(config.log_file, level=config.log_level)
logger = Logger(config.log_file, level=config.log_level, echo=verbose)

super(LLServer, self).__init__(config.i2tcp_psk.encode("utf-8"), config.i2tcp_port,
max_connections, logger, secured_connection,
Expand Down Expand Up @@ -452,11 +455,13 @@ def getDeviceClient(self, root_topic):
def manual():
print("""ESP32-S3 Locking Lock Cloud Service
i2llserver [setup/config/init] [-c] [-h]
i2llserver [setup/config/init] [-c] [-v] [-h]
Usage:
-c --config - set config path
-v --verbose - print log in stdio
-h --help - show this page
setup config init - initiate server with guidance
Expand All @@ -474,6 +479,7 @@ def main():
root.fixPath(False)
config = root.join("config.json")
init = False
verb = False

for opt in args:
if opt in ("-c", "--config"):
Expand All @@ -487,6 +493,9 @@ def main():
manual()
return

if opt in ("-v", "--verbose"):
verb = True

if opt == 0:
argv = args[opt]
if argv in ("init", "setup", "config"):
Expand All @@ -499,19 +508,6 @@ def main():
init = True

if init:
create_new_config = True
if config.exists():
try:
Config(config)
create_new_config = False
except Exception as err:
print("warning: config file corrupted, {}, should we replace it with a new one instead?".format(err))
choice = input("(input Y for yes, others for No): ").upper()
if choice in ("Y", "YES"):
create_new_config = True
else:
print("setup wizard will now exit, please edit the target config file to make it right")
return

def edit_device(conf_obj: Config):

Expand Down Expand Up @@ -678,9 +674,83 @@ def edit_globals(conf_obj: Config):
fail = True

def add_systemd(config_path: DirTree):

if os.name != "posix":
print("error: sorry, we are currently not supported for auto startup on other OS than Linux")
return
if DirTree("/usr/local/bin/i2llsrv").exists():
locate_executable = "/usr/local/bin/i2llsrv"
else:
locate_executable = Path(Path.home(), ".local/bin/i2llsrv").as_posix()

print("registering auto-startup for I2llServer")

payload = ("[Unit]\n"
"Description=Locking Lock Cloud Service\n"
"After=network.target\n"
"\n"
"[Service]\n"
"User={}"
"Group={}"
"Type=simple\n"
"Restart=on-failure\n"
"ExecStart={} -c \"{}\"\n"
"KillSignal=SIGINT\n"
"TimeoutStopSec=15s\n"
"RestartSec=15s\n"
"\n"
"[Install]\n"
"WantedBy=multi-user.target\n"
"Alias=i2llserver.service\n".format(os.popen("whoami").read(),
os.popen("whoami").read(),
locate_executable,
config_path.asPosix()))

print(" -> generating systemd file...")
with open(NON_ROOT_SYSTEMD_PATH, "w") as f:
f.write(payload)
f.close()
print(" systemd service file generated to \"{}\"".format(NON_ROOT_SYSTEMD_PATH))

print(" actions from now on require sudo permission, you may need to enter your user password")

print(" -> moving file to \"/etc/systemd/system/i2llserver.service\"")
rc = os.system("mv \"{}\" /etc/systemd/system >/dev/null 2>/dev/null".format(NON_ROOT_SYSTEMD_PATH))
if rc:
rc = os.system(
"sudo mv \"{}\" /etc/systemd/system >/dev/null 2>/dev/null".format(NON_ROOT_SYSTEMD_PATH))
if rc:
print(" warning: failed to move service file to /etc/systemd/system,"
" permission denied or file already exists")
print(" -> generating setup script for sudoer to run")
with open(NON_ROOT_AUTOINIT_PATH, "w") as f:
f.write("#!/bin/bash\n"
"mv \"{}\" /etc/systemd/system\n"
"systemctl enable i2llserver\n".format(NON_ROOT_SYSTEMD_PATH))
f.close()

print(" one-shot script generated at \"{}\", "
"run as root to finish auto-startup registration".format(NON_ROOT_AUTOINIT_PATH))
else:
print(" -> finishing registration")
rc = os.system("systemctl enable i2llserver >/dev/null 2>/dev/null")
if rc:
os.system("sudo systemctl enable i2llserver >/dev/null 2>/dev/null")
print(" service registered, use \"service i2llserver start\" to start service")

create_new_config = True
if config.exists():
try:
Config(config)
create_new_config = False
except Exception as err:
print("warning: config file corrupted, {}, should we replace it with a new one instead?".format(err))
choice = input("(input Y for yes, others for No): ").upper()
if choice in ("Y", "YES"):
create_new_config = True
else:
print("setup wizard will now exit, please edit the target config file to make it right")
return

if create_new_config:
if config.exists():
Expand Down Expand Up @@ -712,13 +782,18 @@ def add_systemd(config_path: DirTree):
return

else:
ll_srv = LLServer(Config(config))
conf = Config(config)
if not verb:
print("server starting, log file is located in \"{}\", use Ctrl+C to stop".format(conf.log_file))
ll_srv = LLServer(conf, verbose=verb)
ll_srv.start()

try:
input("")
while True:
time.sleep(10)
except KeyboardInterrupt:
pass

ll_srv.kill()


Expand Down
File renamed without changes.
File renamed without changes.
Binary file added history/i2llserver-0.0.4-py3-none-any.whl
Binary file not shown.
Binary file added history/i2llserver-0.0.4.tar.gz
Binary file not shown.
Binary file added history/i2llserver-0.0.5-py3-none-any.whl
Binary file not shown.
Binary file added history/i2llserver-0.0.5.tar.gz
Binary file not shown.
Binary file added history/i2llserver-0.0.6-py3-none-any.whl
Binary file not shown.
Binary file added history/i2llserver-0.0.6.tar.gz
Binary file not shown.
20 changes: 17 additions & 3 deletions i2llserver.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: i2llserver
Version: 0.0.3
Version: 1.0.0
Summary: Server of LockingLock project
Home-page: https://github.com/i2cy/LockingLock_Python
Author: I2cy Cloud
Expand All @@ -18,8 +18,6 @@ Description-Content-Type: text/markdown

This repo is the server part of LockingLock project.

Project is still under development.

[Github Link](https://github.com/i2cy/LockingLock_Python)

# Installation
Expand All @@ -30,3 +28,19 @@ Project is still under development.

This command will help you to edit a configuration file and
add startup scripts on boot in systemd

# Auto-Startup on Linux
By running `i2llsrv setup` command, setup wizard will ask you in the end
of setup sequence for choosing whether should it register a systemd
service. Choose yes to generate service file and register which requires
root permission or sudo permission.

However, if the setup wizard failed to register startup service, it will generate
a one-script-done shell script at your home directory which named as:

`enable_auto-startup_for_i2ll.sh`

By executing this shell scripts by root or sudo, the automatic startup
service will be registered which named as `i2llserver.service`

Use `service i2llserver start|stop|restart` to control server
1 change: 0 additions & 1 deletion i2llserver.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ i2llserver.egg-info/top_level.txt
i2llservice/__init__.py
i2llservice/client.py
i2llservice/config.py
i2llservice/main.py
i2llservice/server.py
1 change: 1 addition & 0 deletions i2llservice/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,4 @@ def getDeviceClient(self, root_topic):
assert isinstance(con, DeviceClient)
if con.root_topic in root_topic:
return con

6 changes: 3 additions & 3 deletions i2llservice/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __str__(self):
return "<LL device, index: {}, topic: {}>".format(self.device_index, self.root_topic)

def saveConfig(self):
self.__file_io = open(self.__file_io.name, "r+")
self.__file_io = open(self.__file_io.name, "r")
json_dict = json.load(self.__file_io)
self.__file_io.close()

Expand All @@ -54,7 +54,7 @@ def __init__(self, filename):
super(Config, self).__init__([])

if os.path.exists(filename) and os.path.isfile(filename):
self.__file_io = open(filename, "r+")
self.__file_io = open(filename, "r")
json_dict = json.load(self.__file_io)

self.mqtt_host = json_dict["mqtt_host"]
Expand Down Expand Up @@ -154,7 +154,7 @@ def saveConfig(self, new=False):
if new:
json_dict = {}
else:
self.__file_io = open(self.__file_io.name, "r+")
self.__file_io = open(self.__file_io.name, "r")
json_dict = json.load(self.__file_io)
self.__file_io.close()

Expand Down
Loading

0 comments on commit 4a7693c

Please sign in to comment.