Skip to content

Commit

Permalink
Merge pull request #74 from lbr38/devel
Browse files Browse the repository at this point in the history
3.3.0
  • Loading branch information
lbr38 authored Sep 23, 2024
2 parents 19ef489 + 3c95f0d commit 688beb4
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 122 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/build-and-test-deb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ jobs:
- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,apache2 --assume-yes

- name: "Run test: list available modules"
run: python3 /opt/linupdate/linupdate.py --mod-list

Expand Down Expand Up @@ -255,6 +258,9 @@ jobs:
- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,apache2 --assume-yes

- name: "Run test: list available modules"
run: python3 /opt/linupdate/linupdate.py --mod-list

Expand Down Expand Up @@ -343,6 +349,9 @@ jobs:
- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,apache2 --assume-yes

- name: "Run test: list available modules"
run: python3 /opt/linupdate/linupdate.py --mod-list

Expand Down Expand Up @@ -428,6 +437,9 @@ jobs:
- name: "Run test: check updates"
run: sudo python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: sudo python3 /opt/linupdate/linupdate.py --update curl,wget,apache2 --assume-yes

- name: "Run test: list available modules"
run: sudo python3 /opt/linupdate/linupdate.py --mod-list

Expand Down Expand Up @@ -535,6 +547,9 @@ jobs:
- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,apache2 --assume-yes

- name: "Run test: print raw configuration"
run: python3 /opt/linupdate/linupdate.py --show-config

Expand Down
22 changes: 14 additions & 8 deletions .github/workflows/build-and-test-rpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ jobs:
- name: Install package
run: dnf --nogpgcheck localinstall -y ./linupdate-test-build-${{ env.VERSION }}.noarch.rpm

- name: Launch linupdate
run: python3 /opt/linupdate/linupdate.py --check-updates
# - name: Launch linupdate
# run: python3 /opt/linupdate/linupdate.py --check-updates

# Tests some params
- name: "Run test: print help"
Expand Down Expand Up @@ -184,20 +184,23 @@ jobs:
run: python3 /opt/linupdate/linupdate.py --get-exclude

- name: "Run test: set package exclusions on major update"
run: python3 /opt/linupdate/linupdate.py --exclude-major "apache2,mysql.*"
run: python3 /opt/linupdate/linupdate.py --exclude-major "httpd,mysql.*"

- name: "Run test: get package exclusions on major update"
run: python3 /opt/linupdate/linupdate.py --get-exclude-major

- name: "Run test: set services to restart after update"
run: python3 /opt/linupdate/linupdate.py --service-restart "apache2,mysql"
run: python3 /opt/linupdate/linupdate.py --service-restart "httpd,mysql"

- name: "Run test: get services to restart after update"
run: python3 /opt/linupdate/linupdate.py --get-service-restart

- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,httpd --assume-yes

- name: "Run test: list available modules"
run: python3 /opt/linupdate/linupdate.py --mod-list

Expand Down Expand Up @@ -247,8 +250,8 @@ jobs:
- name: Install package
run: dnf --nogpgcheck localinstall -y ./linupdate-test-build-${{ env.VERSION }}.noarch.rpm

- name: Launch linupdate
run: python3 /opt/linupdate/linupdate.py --check-updates
# - name: Launch linupdate
# run: python3 /opt/linupdate/linupdate.py --check-updates

# Tests some params
- name: "Run test: print help"
Expand Down Expand Up @@ -279,20 +282,23 @@ jobs:
run: python3 /opt/linupdate/linupdate.py --get-exclude

- name: "Run test: set package exclusions on major update"
run: python3 /opt/linupdate/linupdate.py --exclude-major "apache2,mysql.*"
run: python3 /opt/linupdate/linupdate.py --exclude-major "httpd,mysql.*"

- name: "Run test: get package exclusions on major update"
run: python3 /opt/linupdate/linupdate.py --get-exclude-major

- name: "Run test: set services to restart after update"
run: python3 /opt/linupdate/linupdate.py --service-restart "apache2,mysql"
run: python3 /opt/linupdate/linupdate.py --service-restart "httpd,mysql"

- name: "Run test: get services to restart after update"
run: python3 /opt/linupdate/linupdate.py --get-service-restart

- name: "Run test: check updates"
run: python3 /opt/linupdate/linupdate.py --check-updates

- name: "Run text: update specific packages"
run: python3 /opt/linupdate/linupdate.py --update curl,wget,httpd --assume-yes

- name: "Run test: list available modules"
run: python3 /opt/linupdate/linupdate.py --mod-list

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ jobs:
body: |
**Changes:**
- Reposerver module: sending more logs to the server when updating packages
- Fixed update process on RHEL based systems
- Added a new parameter to update only a list of packages
- Reposerver module: added the feature to receive a list of packages to update
draft: false
prerelease: false

Expand Down
3 changes: 2 additions & 1 deletion linupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ def main():
my_module.pre()

# Execute packages update
my_package.update(my_args.assume_yes,
my_package.update(my_args.packages_to_update,
my_args.assume_yes,
my_args.ignore_exclude,
my_args.check_updates,
my_args.dist_upgrade,
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/App/Service.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def main(self):
# If the process has terminated with an error (exit 1), print a message
if retcode != 0:
print('[' + child['agent'] + '-agent] Terminated with return code ' + str(retcode) + ' :(')
print("[" + child['agent'] + "-agent] I'm dead for now but I will be resurrected soon, please wait or restart main service")
print("[" + child['agent'] + "-agent] I'm dead for now but I will be resurrected soon, please wait or restart linupdate service")

# Remove child process from list
self.child_processes.remove(child)
Expand Down
22 changes: 22 additions & 0 deletions src/controllers/Args.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def parse(self):
Args.assume_yes = False
Args.check_updates = False
Args.ignore_exclude = False
Args.packages_to_update = []
Args.dist_upgrade = False
Args.keep_oldconf = True

Expand Down Expand Up @@ -72,6 +73,8 @@ def parse(self):
# Set mail recipient
parser.add_argument("--set-mail-recipient", action="store", nargs='?', default="null")

# Packages to update list
parser.add_argument("--update", "-u", action="store", nargs='?', default="null")
# Dist upgrade
parser.add_argument("--dist-upgrade", "-du", action="store_true", default="null")
# Keep oldconf
Expand Down Expand Up @@ -298,8 +301,19 @@ def parse(self):
except Exception as e:
raise ArgsException('Could not set mail recipient(s): ' + str(e))

#
# If --update param has been set
#
if args.update != "null":
try:
for package in args.update.split(','):
Args.packages_to_update.append({'name': package.strip()})
except Exception as e:
raise ArgsException('Could not parse update list: ' + str(e))

#
# If --ignore-exclude param has been set
#
if args.ignore_exclude != "null":
Args.ignore_exclude = True

Expand Down Expand Up @@ -629,6 +643,14 @@ def help(self):
{
'title': 'Update options'
},
{
'args': [
'--update',
'-u'
],
'option': 'PACKAGE',
'description': 'Update only the specified packages (separated by commas)'
},
{
'args': [
'--dist-upgrade',
Expand Down
45 changes: 44 additions & 1 deletion src/controllers/Module/Reposerver/Agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ def run_inotify_package_event(self):
self.inotify_exception = str(e)


#-----------------------------------------------------------------------------------------------
#
# Set request status
#
#-----------------------------------------------------------------------------------------------
def set_request_status(self, request_id, status):
json_data = {
'response-to-request': {
'request-id': request_id,
'status': status
}
}

# Send the response
self.websocket.send(json.dumps(json_data))


#-----------------------------------------------------------------------------------------------
#
# On message received from the websocket
Expand Down Expand Up @@ -175,19 +192,45 @@ def websocket_on_message(self, ws, message):
# Case the request is 'request-packages-infos', then send packages informations to the reposerver
elif message['request'] == 'request-packages-infos':
print('[reposerver-agent] Reposerver requested packages informations')

# Send a response to the reposerver to make the request as running
self.set_request_status(request_id, 'running')

# Log everything to the log file
with Log(log):
self.reposerverStatusController.send_packages_info()

# Case the request is 'update-all-packages', then update all packages
elif message['request'] == 'update-all-packages':
print('[reposerver-agent] Reposerver requested all packages update')

# Send a response to the reposerver to make the request as running
self.set_request_status(request_id, 'running')

# Log everything to the log file
with Log(log):
self.packageController.update(True)
self.packageController.update([], True)

# Send a summary to the reposerver, with the summary of the update (number of packages updated or failed)
summary = self.packageController.summary

# Case the request is 'request-specific-packages-installation', then update a list of packages
# A list of packages must be provided in the message
elif message['request'] == 'request-specific-packages-installation':
if 'data' in message:
if 'packages' in message['data'] and len(message['data']['packages']) > 0:
print('[reposerver-agent] Reposerver requested to update a list of packages')

# Send a response to the reposerver to make the request as running
self.set_request_status(request_id, 'running')

# Log everything to the log file
with Log(log):
self.packageController.update(message['data']['packages'], True)

# Send a summary to the reposerver, with the summary of the installation (number of packages installed or failed)
summary = self.packageController.summary

else:
raise Exception('unknown request sent by reposerver: ' + message['request'])

Expand Down
80 changes: 64 additions & 16 deletions src/controllers/Package/Apt.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,59 @@ def __init__(self):
# Create an instance of the apt cache
self.aptcache = apt.Cache()

# Total count of success and failed package updates
self.summary = {
'update': {
'success': {
'count': 0,
'packages': {}
},
'failed': {
'count': 0,
'packages': {}
}
}
}

# Define some default options
self.dist_upgrade = False
self.keep_oldconf = True


#-----------------------------------------------------------------------------------------------
#
# Return the current version of a package
#
#-----------------------------------------------------------------------------------------------
def get_current_version(self, package):
try:
# Open apt cache
self.aptcache.open(None)

# Get the package from the cache
pkg = self.aptcache[package]

# If the package is not installed, return an empty string
if not pkg.is_installed:
return ''

# Return the installed version of the package
return pkg.installed.version

except Exception as e:
raise Exception('could not get current version of package ' + package + ': ' + str(e))


#-----------------------------------------------------------------------------------------------
#
# Return the available version of a package
#
#-----------------------------------------------------------------------------------------------
def get_available_version(self, package):
try:
# Open apt cache
self.aptcache.open(None)

# Get the package from the cache
pkg = self.aptcache[package]

# If the package is not installed, return an empty string
if not pkg.is_installed:
return ''

# Return the available version of the package
return pkg.candidate.version

except Exception as e:
raise Exception('could not get available version of package ' + package + ': ' + str(e))


#-----------------------------------------------------------------------------------------------
#
# Return list of installed apt packages, sorted by name
Expand Down Expand Up @@ -208,6 +242,20 @@ def update(self, packagesList, update_method: str = 'one_by_one', exit_on_packag
# Log file to store each package update output (when 'one_by_one' method is used)
log = '/tmp/linupdate-update-package.log'

# Package update summary
self.summary = {
'update': {
'success': {
'count': 0,
'packages': {}
},
'failed': {
'count': 0,
'packages': {}
}
}
}

# If update_method is 'one_by_one', update packages one by one (one command per package)
if update_method == 'one_by_one':
# Loop through the list of packages to update
Expand Down Expand Up @@ -252,14 +300,14 @@ def update(self, packagesList, update_method: str = 'one_by_one', exit_on_packag
# If --keep-oldconf is True, then keep the old configuration file
if self.keep_oldconf:
cmd = [
'apt-get', 'install', pkg['name'], '-y',
'apt-get', 'install', pkg['name'] + '=' + pkg['available_version'], '-y',
# Debug only
# '--dry-run',
'-o', 'Dpkg::Options::=--force-confdef',
'-o', 'Dpkg::Options::=--force-confold'
]
else:
cmd = ['apt-get', 'install', pkg['name'], '-y']
cmd = ['apt-get', 'install', pkg['name'] + '=' + pkg['available_version'], '-y']

popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)

Expand Down
Loading

0 comments on commit 688beb4

Please sign in to comment.