Skip to content

Commit

Permalink
patch
Browse files Browse the repository at this point in the history
  • Loading branch information
lbr38 committed Jul 19, 2024
1 parent 8a43161 commit 3ce518a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 92 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build-rpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ jobs:
python3 /opt/linupdate/linupdate.py --profile container
python3 /opt/linupdate/linupdate.py --env test
# Try to install package on latest Fedora
install-fedora:
name: Install on latest Fedora
Expand Down
10 changes: 8 additions & 2 deletions linupdate-agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@

# Import libraries
import time
import sys

# Import classes
from src.controllers.App.Service import Service

# Leave some time for the system to boot
# TODO
# time.sleep(60)
# time.sleep(30)

# Instantiate Service class
my_service = Service()

# Execute main function
# If an argument is passed, execute the corresponding module agent
if len(sys.argv) > 1:
my_service.run_agent(sys.argv[1])
exit(0)

# Else, execute main function
my_service.main()

exit(0)
2 changes: 1 addition & 1 deletion service/linupdate.systemd.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Description=linupdate-agent

[Service]
Type=simple
ExecStart=/opt/linupdate/service/linupdate-agent.py
ExecStart=/opt/linupdate/linupdate-agent.py

[Install]
WantedBy=multi-user.target
166 changes: 92 additions & 74 deletions src/controllers/App/Service.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,80 +6,97 @@
import sys
import importlib
import subprocess
import time
from pathlib import Path

# Import classes
from src.controllers.Module.Module import Module

class Service:
def __init__(self):
# Register signal handlers
signal.signal(signal.SIGTERM, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler)

self.child_processes = []
self.moduleController = Module()


#-------------------------------------------------------------------------------------------------------------------
#
# Check if a restart of this service is needed, and restart it if needed
# Service main function
#
#-------------------------------------------------------------------------------------------------------------------
def restart_self_if_needed(self):
if Path('/tmp/linupdate-service.restart').is_file():
# Only restart the service if linupdate is not running otherwise it could cut off a running update...
if Path('/tmp/linupdate.lock').is_file():
return

print('A restart of this service is required. Restarting...')
Path('/tmp/linupdate-service.restart').unlink()
subprocess.run(["systemctl", "restart", "linupdate.service"])

result = subprocess.run(
["systemctl", "--quiet", "restart", "linupdate.service"],
capture_output = True,
text = True
)

# If service could not be restarted, print error and exit
if result.returncode != 0:
print('Error: could not restart linupdate service: ' + result.stderr)
exit(1)
def main(self):
try:
while True:
# Retrieve enabled modules
enabled_modules = self.moduleController.getEnabled()

# For each enabled module, check if its agent is enabled
for module in enabled_modules:
# Convert module name to uppercase first letter
module_capitalize = module.capitalize()

# Import python module config class
module_import_path = importlib.import_module('src.controllers.Module.' + module_capitalize + '.Config')
module_class = getattr(module_import_path, 'Config')

# Instantiate module and get module configuration
my_module = module_class()
module_configuration = my_module.getConf()

# Check if module agent is enabled. If not, skip to next module
if not module_configuration['agent']['enabled']:
continue

# Check if module agent process is already running, if so, skip to next module
if any(agent['agent'] == module for agent in self.child_processes):
print('Module ' + module + ' agent is already running')
continue

# Start module agent
print('Starting ' + module + ' module agent')

# Start module agent as a child process
process = subprocess.Popen(
['/opt/linupdate/linupdate-agent.py', module],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)

# Add child process to list
self.child_processes.append({
'agent': module,
'process': process
})

print("I'm linupdate service")
time.sleep(5)

except Exception as e:
print('Linupdate service error:' + str(e))
exit(1)


#-------------------------------------------------------------------------------------------------------------------
#
# Service main function
# Run a module agent as a child process
#
#-------------------------------------------------------------------------------------------------------------------
def main(self):
def run_agent(self, module_name):
try:
# Check if a restart of this service is needed
self.restart_self_if_needed()

# Retrieve enabled modules
enabled_modules = self.moduleController.getEnabled()

# For each enabled module, check if its agent is enabled
for module in enabled_modules:
# Convert module name to uppercase first letter
module_name = module.capitalize()
# Convert module name to uppercase first letter
module_name_capitalize = module_name.capitalize()

# Import python module config class
module_import_path = importlib.import_module('src.controllers.Module.' + module_name + '.Config')
module_class = getattr(module_import_path, 'Config')
while True:
print("I'm reposerver module agent")
time.sleep(5)

# Instantiate module and get module configuration
my_module = module_class()
module_configuration = my_module.getConf()

# Check if agent is enabled
if module_configuration['agent']['enabled']:
print('Executing agent for module ' + module_name)

# Import python module agent class
module_import_path = importlib.import_module('src.controllers.Module.' + module_name + '.Agent')
my_module_agent_class = getattr(module_import_path, 'Agent')()

# Instantiate module and call module agent main method in a child process
# process = subprocess.Popen(['python3', '-c', 'import src.controllers.Module.' + module_name + '.Agent; src.controllers.Module.' + module_name + '.Agent.main()'])
# self.child_processes.append(process)
# Import python module agent class
# module_import_path = importlib.import_module('src.controllers.Module.' + module_name + '.Agent')
# my_module_agent_class = getattr(module_import_path, 'Agent')()


except Exception as e:
print('Linupdate service error:' + str(e))
Expand All @@ -92,33 +109,34 @@ def main(self):
#
#-------------------------------------------------------------------------------------------------------------------
def stop_child_processes(self):
for process in self.child_processes:
if not self.child_processes:
print('No child processes')
return

# Stop all child processes
for child in self.child_processes:
# Retrieve agent name and process
agent = child['agent']
process = child['process']

print('Stopping ' + agent + ' module agent')

# Terminate process
process.terminate()

try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()


#-------------------------------------------------------------------------------------------------------------------
#
# Signal handler
# This function is called when the service receives a SIGTERM or SIGINT signal
#
#-------------------------------------------------------------------------------------------------------------------
def signal_handler(sig, frame):
print('Linupdate service received signal ' + str(sig) + '. Stopping all child processes')
service.stop_child_processes()
sys.exit(0)


#-------------------------------------------------------------------------------------------------------------------
#
# Main
#
#-------------------------------------------------------------------------------------------------------------------
if __name__ == "__main__":
service = Service()
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
service.main()
#-------------------------------------------------------------------------------------------------------------------
#
# Signal handler
# This function is called when the service receives a SIGTERM or SIGINT signal
#
#-------------------------------------------------------------------------------------------------------------------
def signal_handler(self, sig, frame):
print('Linupdate service received signal ' + str(sig) + '. Stopping all child processes...')
self.stop_child_processes()
sys.exit(0)
18 changes: 4 additions & 14 deletions src/controllers/Args.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ def parse(self):
myExit.cleanExit()
except Exception as e:
raise Exception('Could not enable module: ' + str(e))
else:
raise Exception('Module name is required')

#
# If --mod-disable param has been set
Expand All @@ -409,20 +411,8 @@ def parse(self):
myExit.cleanExit()
except Exception as e:
raise Exception('Could not disable module: ' + str(e))

#
# If --mod-configure param has been set
#
# if args.mod_configure != "null":
# print(args.mod_configure)
# # If module to configure is set (not 'None'), configure the module
# if args.mod_configure:
# try:
# # Configure module
# myModule.configure(args.mod_configure)
# myExit.cleanExit()
# except Exception as e:
# raise Exception('Could not configure ' + args.mod_configure + ' module: ' + str(e))
else:
raise Exception('Module name is required')

except Exception as e:
raise Exception(str(e))
Expand Down

0 comments on commit 3ce518a

Please sign in to comment.