-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OSMorphing] Check installed packages before installing packages #337
[OSMorphing] Check installed packages before installing packages #337
Conversation
coriolis/osmorphing/debian.py
Outdated
@@ -122,6 +122,14 @@ def set_net_config(self, nics_info, dhcp): | |||
cfg_name = "%s/coriolis_netplan.yaml" % netplan_base | |||
self._write_file_sudo(cfg_name, new_cfg) | |||
|
|||
def check_installed_package(self, package_name): | |||
cmd = 'dpkg-query -W %s' % ("".join(package_name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to just send a single command that lists all the packages installed on the migrated system. Parse that list and save it on the tools object. Then when you need to check a package, you just do a if package in self.installed_packages: return
or do a set difference like below to get the list of packages that need to be installed.
The point of this is to send a minimum amount of SSH commands, instead of sending N+1commands for each package we want to install. For Debian-based, you can use apt list --installed
, please check a command for the others too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also don't need to "".join(package_name)
here, you can simply pass the string value to the string format.
fc8e18b
to
b234a6f
Compare
coriolis/osmorphing/debian.py
Outdated
@@ -122,6 +122,13 @@ def set_net_config(self, nics_info, dhcp): | |||
cfg_name = "%s/coriolis_netplan.yaml" % netplan_base | |||
self._write_file_sudo(cfg_name, new_cfg) | |||
|
|||
def get_installed_packages(self): | |||
cmd = 'apt list --installed' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method has incomplete parsing in my opinion. I expected a list of package names, you returned a list of package names plus some other information. Please properly parse that list before returning it. Therefore please try the following:
All apt list --installed
lists packages in this format:
package_name/repo,version,etc
You could split this and only get the package name:
apt_list_output = self._exec_cmd_chroot(cmd).splitlines() # and maybe also a .decode(), not 100% sure
for line in apt_list_output:
package_name, _ = line.split('/', 1)
self.installed_packages.append(package_name)
# you don't need to return anything, I'd much rather do a set difference between installed_packages and
# packages_add inside (or before) install_packages. The upside to this is that you can switfly check packages
# in other places too (ex. if 'grubby' not in self.installed_packages: self._install(['grubby']).
coriolis/osmorphing/manager.py
Outdated
@@ -239,6 +239,10 @@ def morph_image(origin_provider, destination_provider, connection_info, | |||
LOG.info("Post packages uninstall") | |||
export_os_morphing_tools.post_packages_uninstall(packages_remove) | |||
|
|||
LOG.info("Checking for packages already installed") | |||
packages_add = import_os_morphing_tools.check_installed_packages( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can replace this with calling get_installed_packages
, and then only install the set difference
coriolis/osmorphing/redhat.py
Outdated
def _has_package_installed(self, package_name): | ||
cmd = 'rpm -q %s' % ("".join(package_name)) | ||
def get_installed_packages(self): | ||
cmd = 'rpm -qa' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can finetune this command also to only get the list of package names:
rpm -qa --qf '%{NAME}\n'
coriolis/osmorphing/redhat.py
Outdated
@@ -295,7 +294,7 @@ def pre_packages_install(self, package_names): | |||
super(BaseRedHatMorphingTools, self).pre_packages_install( | |||
package_names) | |||
self._yum_clean_all() | |||
if not self._has_package_installed('grubby'): | |||
if not any('grubby' in package for package in self.installed_packages): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned above, you can just check if 'grubbyis in
self.installed_packages`. Do please check the package name string as a whole, as this could have buggy results. Let's say your list has a package called 'grubby-somethhing', but you need 'grubby' package instead, this code would skip that install.
coriolis/osmorphing/suse.py
Outdated
@@ -65,6 +65,15 @@ def set_net_config(self, nics_info, dhcp): | |||
# TODO(alexpilotti): add networking support | |||
pass | |||
|
|||
def get_installed_packages(self): | |||
cmd = 'rpm -qa' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this the same as redhat please.
91b2075
to
2ca7cb4
Compare
coriolis/osmorphing/redhat.py
Outdated
def _has_package_installed(self, package_name): | ||
cmd = 'rpm -q %s' % ("".join(package_name)) | ||
def get_installed_packages(self): | ||
cmd = 'rpm -qa --qf \'%{NAME}\n\'' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is most probably going to fail. If it does, please try:
cmd = 'rpm -qa --qf "%{NAME}\\n"'
e290ed8
to
96f506b
Compare
coriolis/osmorphing/debian.py
Outdated
@@ -122,6 +122,17 @@ def set_net_config(self, nics_info, dhcp): | |||
cfg_name = "%s/coriolis_netplan.yaml" % netplan_base | |||
self._write_file_sudo(cfg_name, new_cfg) | |||
|
|||
def get_installed_packages(self): | |||
cmd = "apt list --installed 2>/dev/null | awk -F/ '{print $1}'" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove the 2>/dev/null
as stderr
is returned elsewhere, and will not be included in apt_list_output
coriolis/osmorphing/debian.py
Outdated
def get_installed_packages(self): | ||
cmd = "dpkg-query -f '${binary:Package}\n' -W" | ||
try: | ||
apt_list_output = self._exec_cmd_chroot( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, could you please check whether you could do the following:
apt_list_output = self._exec_cmd_chroot(cmd).decode().splitlines()
This way, you only call for decode()
once.
coriolis/osmorphing/manager.py
Outdated
@@ -239,6 +239,13 @@ def morph_image(origin_provider, destination_provider, connection_info, | |||
LOG.info("Post packages uninstall") | |||
export_os_morphing_tools.post_packages_uninstall(packages_remove) | |||
|
|||
LOG.info("Checking for packages already installed") | |||
import_os_morphing_tools.get_installed_packages() | |||
LOG.info("Packages already installed: %s" % |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a big list, please remove it.
coriolis/osmorphing/redhat.py
Outdated
self._exec_cmd_chroot(cmd) | ||
return True | ||
apt_list_output = self._exec_cmd_chroot( | ||
cmd).splitlines() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above about the decode()
coriolis/osmorphing/suse.py
Outdated
cmd = 'rpm -qa --qf \'%{NAME}\n\'' | ||
try: | ||
apt_list_output = self._exec_cmd_chroot( | ||
cmd).splitlines() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above about the decode()
1619902
to
4bea23c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. If your testing also looks good, please go ahead and update the unit tests also.
4bea23c
to
c264810
Compare
c264810
to
e96a52c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you!
This PR adds check_installed_package for Redhat, Debian and SUSE.