Skip to content

Commit 776fddf

Browse files
[sonic-package-manager] code style fixes and enhancements (#1802)
Highlights: * Don't use f-strings where it is not needed * Indentation fixes in comprehension expressions * Created containers removal method in DockerApi * Fixed a debug message where dependency instead of conflict variable was displayed * Return value type annotations for some functions * Docstrings fixes & removed trailing spaces. Signed-off-by: Stepan Blyschak <[email protected]>
1 parent f53baac commit 776fddf

File tree

10 files changed

+115
-87
lines changed

10 files changed

+115
-87
lines changed

sonic_package_manager/constraint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def parse(constraints: Dict) -> 'ComponentConstraints':
9595
"""
9696

9797
components = {component: VersionConstraint.parse(version)
98-
for component, version in constraints.items()}
98+
for component, version in constraints.items()}
9999
return ComponentConstraints(components)
100100

101101
def deparse(self) -> Dict[str, str]:

sonic_package_manager/dockerapi.py

+9
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ def rm(self, container: str, **kwargs):
186186
self.client.containers.get(container).remove(**kwargs)
187187
log.debug(f'removed container {container}')
188188

189+
def rm_by_ancestor(self, image_id: str, **kwargs):
190+
""" Docker 'rm' command for running containers instantiated
191+
from image passed to this function. """
192+
193+
# Clean containers based on the old image
194+
containers = self.ps(filters={'ancestor': image_id}, all=True)
195+
for container in containers:
196+
self.rm(container.id, **kwargs)
197+
189198
def ps(self, **kwargs):
190199
""" Docker 'ps' command. """
191200

sonic_package_manager/errors.py

-1
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,3 @@ class PackageComponentConflictError(PackageInstallationError):
143143
def __str__(self):
144144
return (f'Package {self.name} conflicts with {self.component} {self.constraint} '
145145
f'in package {self.dependency} but version {self.installed_ver} is installed')
146-

sonic_package_manager/main.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ def install(ctx,
361361

362362
package_source = package_expr or from_repository or from_tarball
363363
if not package_source:
364-
exit_cli(f'Package source is not specified', fg='red')
364+
exit_cli('Package source is not specified', fg='red')
365365

366366
if not yes and not force:
367367
click.confirm(f'{package_source} is going to be installed, '
@@ -386,7 +386,7 @@ def install(ctx,
386386
except Exception as err:
387387
exit_cli(f'Failed to install {package_source}: {err}', fg='red')
388388
except KeyboardInterrupt:
389-
exit_cli(f'Operation canceled by user', fg='red')
389+
exit_cli('Operation canceled by user', fg='red')
390390

391391

392392
@cli.command()
@@ -409,7 +409,7 @@ def reset(ctx, name, force, yes, skip_host_plugins):
409409
except Exception as err:
410410
exit_cli(f'Failed to reset package {name}: {err}', fg='red')
411411
except KeyboardInterrupt:
412-
exit_cli(f'Operation canceled by user', fg='red')
412+
exit_cli('Operation canceled by user', fg='red')
413413

414414

415415
@cli.command()
@@ -426,12 +426,16 @@ def uninstall(ctx, name, force, yes):
426426
click.confirm(f'Package {name} is going to be uninstalled, '
427427
f'continue?', abort=True, show_default=True)
428428

429+
uninstall_opts = {
430+
'force': force,
431+
}
432+
429433
try:
430-
manager.uninstall(name, force)
434+
manager.uninstall(name, **uninstall_opts)
431435
except Exception as err:
432436
exit_cli(f'Failed to uninstall package {name}: {err}', fg='red')
433437
except KeyboardInterrupt:
434-
exit_cli(f'Operation canceled by user', fg='red')
438+
exit_cli('Operation canceled by user', fg='red')
435439

436440

437441
@cli.command()
@@ -453,7 +457,7 @@ def migrate(ctx, database, force, yes, dockerd_socket):
453457
except Exception as err:
454458
exit_cli(f'Failed to migrate packages {err}', fg='red')
455459
except KeyboardInterrupt:
456-
exit_cli(f'Operation canceled by user', fg='red')
460+
exit_cli('Operation canceled by user', fg='red')
457461

458462

459463
if __name__ == "__main__":

sonic_package_manager/manager.py

+48-41
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from sonic_package_manager.progress import ProgressManager
4040
from sonic_package_manager.reference import PackageReference
4141
from sonic_package_manager.registry import RegistryResolver
42+
from sonic_package_manager.service_creator import SONIC_CLI_COMMANDS
4243
from sonic_package_manager.service_creator.creator import (
4344
ServiceCreator,
4445
run_command
@@ -52,7 +53,6 @@
5253
RegistrySource,
5354
TarballSource
5455
)
55-
from sonic_package_manager.utils import DockerReference
5656
from sonic_package_manager.version import (
5757
Version,
5858
version_to_tag,
@@ -101,7 +101,7 @@ def wrapped_function(*args, **kwargs):
101101
return wrapped_function
102102

103103

104-
def rollback(func, *args, **kwargs):
104+
def rollback(func, *args, **kwargs) -> Callable:
105105
""" Used in rollback callbacks to ignore failure
106106
but proceed with rollback. Error will be printed
107107
but not fail the whole procedure of rollback. """
@@ -131,7 +131,7 @@ def package_constraint_to_reference(constraint: PackageConstraint) -> PackageRef
131131
return PackageReference(package_name, version_to_tag(version))
132132

133133

134-
def parse_reference_expression(expression):
134+
def parse_reference_expression(expression) -> PackageReference:
135135
try:
136136
return package_constraint_to_reference(PackageConstraint.parse(expression))
137137
except ValueError:
@@ -247,7 +247,7 @@ def validate_package_tree(packages: Dict[str, Package]):
247247
continue
248248

249249
component_version = conflicting_package.components[component]
250-
log.debug(f'conflicting package {dependency.name}: '
250+
log.debug(f'conflicting package {conflict.name}: '
251251
f'component {component} version is {component_version}')
252252

253253
if constraint.allows(component_version):
@@ -397,12 +397,17 @@ def install_from_source(self,
397397
if not self.database.has_package(package.name):
398398
self.database.add_package(package.name, package.repository)
399399

400+
service_create_opts = {
401+
'state': feature_state,
402+
'owner': default_owner,
403+
}
404+
400405
try:
401406
with contextlib.ExitStack() as exits:
402407
source.install(package)
403408
exits.callback(rollback(source.uninstall, package))
404409

405-
self.service_creator.create(package, state=feature_state, owner=default_owner)
410+
self.service_creator.create(package, **service_create_opts)
406411
exits.callback(rollback(self.service_creator.remove, package))
407412

408413
self.service_creator.generate_shutdown_sequence_files(
@@ -481,13 +486,7 @@ def uninstall(self, name: str, force=False):
481486
self.service_creator.generate_shutdown_sequence_files(
482487
self._get_installed_packages_except(package)
483488
)
484-
485-
# Clean containers based on this image
486-
containers = self.docker.ps(filters={'ancestor': package.image_id},
487-
all=True)
488-
for container in containers:
489-
self.docker.rm(container.id, force=True)
490-
489+
self.docker.rm_by_ancestor(package.image_id, force=True)
491490
self.docker.rmi(package.image_id, force=True)
492491
package.entry.image_id = None
493492
except Exception as err:
@@ -563,6 +562,13 @@ def upgrade_from_source(self,
563562

564563
# After all checks are passed we proceed to actual upgrade
565564

565+
service_create_opts = {
566+
'register_feature': False,
567+
}
568+
service_remove_opts = {
569+
'deregister_feature': False,
570+
}
571+
566572
try:
567573
with contextlib.ExitStack() as exits:
568574
self._uninstall_cli_plugins(old_package)
@@ -576,19 +582,15 @@ def upgrade_from_source(self,
576582
exits.callback(rollback(self._systemctl_action,
577583
old_package, 'start'))
578584

579-
self.service_creator.remove(old_package, deregister_feature=False)
585+
self.service_creator.remove(old_package, **service_remove_opts)
580586
exits.callback(rollback(self.service_creator.create, old_package,
581-
register_feature=False))
587+
**service_create_opts))
582588

583-
# Clean containers based on the old image
584-
containers = self.docker.ps(filters={'ancestor': old_package.image_id},
585-
all=True)
586-
for container in containers:
587-
self.docker.rm(container.id, force=True)
589+
self.docker.rm_by_ancestor(old_package.image_id, force=True)
588590

589-
self.service_creator.create(new_package, register_feature=False)
591+
self.service_creator.create(new_package, **service_create_opts)
590592
exits.callback(rollback(self.service_creator.remove, new_package,
591-
register_feature=False))
593+
**service_remove_opts))
592594

593595
self.service_creator.generate_shutdown_sequence_files(
594596
self._get_installed_packages_and(new_package)
@@ -654,16 +656,16 @@ def migrate_packages(self,
654656
old_package_database: PackageDatabase,
655657
dockerd_sock: Optional[str] = None):
656658
"""
657-
Migrate packages from old database. This function can do a comparison between
658-
current database and the database passed in as argument. If the package is
659-
missing in the current database it will be added. If the package is installed
660-
in the passed database and in the current it is not installed it will be
661-
installed with a passed database package version. If the package is installed
662-
in the passed database and it is installed in the current database but with
663-
older version the package will be upgraded to the never version. If the package
664-
is installed in the passed database and in the current it is installed but with
665-
never version - no actions are taken. If dockerd_sock parameter is passed, the
666-
migration process will use loaded images from docker library of the currently
659+
Migrate packages from old database. This function can do a comparison between
660+
current database and the database passed in as argument. If the package is
661+
missing in the current database it will be added. If the package is installed
662+
in the passed database and in the current it is not installed it will be
663+
installed with a passed database package version. If the package is installed
664+
in the passed database and it is installed in the current database but with
665+
older version the package will be upgraded to the never version. If the package
666+
is installed in the passed database and in the current it is installed but with
667+
never version - no actions are taken. If dockerd_sock parameter is passed, the
668+
migration process will use loaded images from docker library of the currently
667669
installed image.
668670
669671
Args:
@@ -784,7 +786,7 @@ def get_package_source(self,
784786
ref = parse_reference_expression(package_expression)
785787
return self.get_package_source(package_ref=ref)
786788
elif repository_reference:
787-
repo_ref = DockerReference.parse(repository_reference)
789+
repo_ref = utils.DockerReference.parse(repository_reference)
788790
repository = repo_ref['name']
789791
reference = repo_ref['tag'] or repo_ref['digest']
790792
reference = reference or 'latest'
@@ -815,8 +817,8 @@ def get_package_source(self,
815817
if package_entry.default_reference is not None:
816818
package_ref.reference = package_entry.default_reference
817819
else:
818-
raise PackageManagerError(f'No default reference tag. '
819-
f'Please specify the version or tag explicitly')
820+
raise PackageManagerError('No default reference tag. '
821+
'Please specify the version or tag explicitly')
820822

821823
return RegistrySource(package_entry.repository,
822824
package_ref.reference,
@@ -888,7 +890,7 @@ def get_installed_packages_list(self) -> List[Package]:
888890
Installed packages dictionary.
889891
"""
890892

891-
return [self.get_installed_package(entry.name)
893+
return [self.get_installed_package(entry.name)
892894
for entry in self.database if entry.installed]
893895

894896
def _migrate_package_database(self, old_package_database: PackageDatabase):
@@ -948,11 +950,11 @@ def _systemctl_action(self, package: Package, action: str):
948950
run_command(f'systemctl {action} {name}@{npu}')
949951

950952
def _install_cli_plugins(self, package: Package):
951-
for command in ('show', 'config', 'clear'):
953+
for command in SONIC_CLI_COMMANDS:
952954
self._install_cli_plugin(package, command)
953955

954956
def _uninstall_cli_plugins(self, package: Package):
955-
for command in ('show', 'config', 'clear'):
957+
for command in SONIC_CLI_COMMANDS:
956958
self._uninstall_cli_plugin(package, command)
957959

958960
def _install_cli_plugin(self, package: Package, command: str):
@@ -978,12 +980,17 @@ def get_manager() -> 'PackageManager':
978980
PackageManager
979981
"""
980982

981-
docker_api = DockerApi(docker.from_env())
983+
docker_api = DockerApi(docker.from_env(), ProgressManager())
982984
registry_resolver = RegistryResolver()
983-
return PackageManager(DockerApi(docker.from_env(), ProgressManager()),
985+
metadata_resolver = MetadataResolver(docker_api, registry_resolver)
986+
feature_registry = FeatureRegistry(SonicDB)
987+
service_creator = ServiceCreator(feature_registry,
988+
SonicDB)
989+
990+
return PackageManager(docker_api,
984991
registry_resolver,
985992
PackageDatabase.from_file(),
986-
MetadataResolver(docker_api, registry_resolver),
987-
ServiceCreator(FeatureRegistry(SonicDB), SonicDB),
993+
metadata_resolver,
994+
service_creator,
988995
device_info,
989996
filelock.FileLock(PACKAGE_MANAGER_LOCK_FILE, timeout=0))

sonic_package_manager/metadata.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ def deep_update(dst: Dict, src: Dict) -> Dict:
2424

2525
for key, value in src.items():
2626
if isinstance(value, dict):
27-
node = dst.setdefault(key, {})
28-
deep_update(node, value)
27+
node = dst.setdefault(key, {})
28+
deep_update(node, value)
2929
else:
30-
dst[key] = value
30+
dst[key] = value
3131
return dst
3232

3333

@@ -183,3 +183,4 @@ def from_labels(cls, labels: Dict[str, str]) -> Metadata:
183183
raise MetadataError(f'Failed to parse component version: {err}')
184184

185185
return Metadata(Manifest.marshal(manifest_dict), components)
186+

sonic_package_manager/registry.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def get_token(realm, service, scope) -> str:
3838

3939
response = requests.get(f'{realm}?scope={scope}&service={service}')
4040
if response.status_code != requests.codes.ok:
41-
raise AuthenticationServiceError(f'Failed to retrieve token')
41+
raise AuthenticationServiceError('Failed to retrieve token')
4242

4343
content = json.loads(response.content)
4444
token = content['token']
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
#!/usr/bin/env python
22

33
ETC_SONIC_PATH = '/etc/sonic'
4+
SONIC_CLI_COMMANDS = ('show', 'config', 'clear')

0 commit comments

Comments
 (0)