Skip to content

Commit 5f7f304

Browse files
committed
Thrid Party Container Management using Sonic Package Manager - followup2
1 parent f5b85dd commit 5f7f304

File tree

4 files changed

+29
-134
lines changed

4 files changed

+29
-134
lines changed

sonic_package_manager/manager.py

+10-30
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
import paramiko
7474
import urllib.parse
7575
from scp import SCPClient
76-
from sonic_package_manager.manifest import Manifest, DEFAULT_MANIFEST, MANIFESTS_LOCATION, DEFAULT_MANIFEST_FILE
76+
from sonic_package_manager.manifest import Manifest, MANIFESTS_LOCATION, DEFAULT_MANIFEST_FILE
7777
LOCAL_JSON="/tmp/local_json"
7878

7979
@contextlib.contextmanager
@@ -813,14 +813,16 @@ def migrate_package(old_package_entry,
813813
package_source = self.get_package_source(package_ref=new_package_ref)
814814
package = package_source.get_package()
815815
new_package_default_version = package.manifest['package']['version']
816-
if old_package.version >= new_package_default_version:
816+
if old_package.version > new_package_default_version:
817817
log.info(f'{old_package.name} package version is lower '
818-
f'then or equal to the default in new image: '
819-
f'{old_package.version} >= {new_package_default_version}')
818+
f'then the default in new image: '
819+
f'{old_package.version} > {new_package_default_version}')
820820
new_package.version = old_package.version
821821
migrate_package(old_package, new_package)
822822
else:
823-
self.install(f'{new_package.name}={new_package_default_version}')
823+
#self.install(f'{new_package.name}={new_package_default_version}')
824+
repo_tag_formed="{}:{}".format(new_package.repository, new_package.default_reference)
825+
self.install(None,repo_tag_formed,name=new_package.name)
824826
else:
825827
# No default version and package is not installed.
826828
# Migrate old package same version.
@@ -870,7 +872,7 @@ def get_package_source(self,
870872

871873
if package_expression:
872874
ref = parse_reference_expression(package_expression)
873-
return self.get_package_source(package_ref=ref)
875+
return self.get_package_source(package_ref=ref, name=name)
874876
elif repository_reference:
875877
repo_ref = utils.DockerReference.parse(repository_reference)
876878
repository = repo_ref['name']
@@ -1189,12 +1191,6 @@ def create_package_manifest(self, name, from_json):
11891191
click.echo("Error: Manifest file '{}' already exists.".format(name))
11901192
return
11911193

1192-
#Creation of default manifest file in case the file does not exist
1193-
if not os.path.exists(MANIFESTS_LOCATION):
1194-
os.mkdir(MANIFESTS_LOCATION)
1195-
if not os.path.exists(DEFAULT_MANIFEST_FILE):
1196-
with open(DEFAULT_MANIFEST_FILE, 'w') as file:
1197-
json.dump(DEFAULT_MANIFEST, file, indent=4)
11981194

11991195
if from_json:
12001196
ret = self.download_file(from_json, LOCAL_JSON)
@@ -1217,19 +1213,12 @@ def create_package_manifest(self, name, from_json):
12171213
json.dump(data, file, indent=4)
12181214
click.echo(f"Manifest '{name}' created successfully.")
12191215

1220-
def check_manifests_directory_existence(self):
1221-
if not os.path.exists(MANIFESTS_LOCATION):
1222-
click.echo("Manifests files directory empty")
1223-
return False
12241216

12251217
def update_package_manifest(self, name, from_json):
12261218
if name == "default_manifest":
12271219
click.echo("Default Manifest updation is not allowed")
12281220
return
12291221

1230-
ret = self.check_manifests_directory_existence()
1231-
if ret is False:
1232-
return
12331222
original_file = os.path.join(MANIFESTS_LOCATION, name)
12341223
if not os.path.exists(original_file):
12351224
click.echo(f'Local Manifest file for {name} does not exists to update')
@@ -1267,11 +1256,8 @@ def delete_package_manifest(self, name):
12671256
if name == "default_manifest":
12681257
click.echo("Default Manifest deletion is not allowed")
12691258
return
1270-
ret = self.check_manifests_directory_existence()
1271-
if ret is False:
1272-
return
12731259
# Check if the manifest file exists
1274-
mfile_name = "{}{}".format(MANIFESTS_LOCATION, name)
1260+
mfile_name = "{}/{}".format(MANIFESTS_LOCATION, name)
12751261
if not os.path.exists(mfile_name):
12761262
click.echo("Error: Manifest file '{}' not found.".format(name))
12771263
return
@@ -1285,10 +1271,7 @@ def delete_package_manifest(self, name):
12851271
return
12861272

12871273
def show_package_manifest(self, name):
1288-
ret = self.check_manifests_directory_existence()
1289-
if ret is False:
1290-
return
1291-
mfile_name = "{}{}".format(MANIFESTS_LOCATION, name)
1274+
mfile_name = "{}/{}".format(MANIFESTS_LOCATION, name)
12921275
edit_file_name = "{}.edit".format(mfile_name)
12931276
if os.path.exists(edit_file_name):
12941277
mfile_name = edit_file_name
@@ -1298,9 +1281,6 @@ def show_package_manifest(self, name):
12981281
click.echo(json.dumps(data, indent=4))
12991282

13001283
def list_package_manifest(self):
1301-
ret = self.check_manifests_directory_existence()
1302-
if ret is False:
1303-
return
13041284
# Get all files in the manifest location
13051285
manifest_files = os.listdir(MANIFESTS_LOCATION)
13061286
if not manifest_files:

sonic_package_manager/manifest.py

+4-71
Original file line numberDiff line numberDiff line change
@@ -10,73 +10,12 @@
1010
)
1111
from sonic_package_manager.errors import ManifestError
1212
from sonic_package_manager.version import Version
13-
13+
from sonic_package_manager.database import BASE_LIBRARY_PATH
1414
import os
1515
import json
1616

17-
DEFAULT_MANIFEST = {
18-
"version": "1.0.0",
19-
"package": {
20-
"version": "1.0.0",
21-
"name": "default_manifest",
22-
"description": "",
23-
"base-os": {},
24-
"depends": [],
25-
"breaks": [],
26-
"init-cfg": {},
27-
"changelog": {},
28-
"debug-dump": ""
29-
},
30-
"service": {
31-
"name": "default_manifest",
32-
"requires": [],
33-
"requisite": [],
34-
"wanted-by": [],
35-
"after": [],
36-
"before": [],
37-
"dependent": [],
38-
"dependent-of": [],
39-
"post-start-action": "",
40-
"pre-shutdown-action": "",
41-
"asic-service": False,
42-
"host-service": True,
43-
"delayed": False,
44-
"check_up_status": False,
45-
"warm-shutdown": {
46-
"after": [],
47-
"before": []
48-
},
49-
"fast-shutdown": {
50-
"after": [],
51-
"before": []
52-
},
53-
"syslog": {
54-
"support-rate-limit": False
55-
}
56-
},
57-
"container": {
58-
"privileged": False,
59-
"entrypoint": "",
60-
"volumes": [],
61-
"mounts": [],
62-
"environment": {},
63-
"tmpfs": []
64-
},
65-
"processes": [],
66-
"cli": {
67-
"mandatory": False,
68-
"show": [],
69-
"config": [],
70-
"clear": [],
71-
"auto-generate-show": False,
72-
"auto-generate-config": False,
73-
"auto-generate-show-source-yang-modules": [],
74-
"auto-generate-config-source-yang-modules": []
75-
}
76-
}
77-
MANIFESTS_LOCATION = "/var/lib/sonic-package-manager/manifests/"
78-
DEFAULT_MANIFEST_NAME = "default_manifest"
79-
DEFAULT_MANIFEST_FILE = os.path.join(MANIFESTS_LOCATION, DEFAULT_MANIFEST_NAME)
17+
MANIFESTS_LOCATION = os.path.join(BASE_LIBRARY_PATH, "manifests")
18+
DEFAULT_MANIFEST_FILE = os.path.join(BASE_LIBRARY_PATH, "default_manifest")
8019

8120
class ManifestSchema:
8221
""" ManifestSchema class describes and provides marshalling
@@ -318,12 +257,6 @@ def unmarshal(self) -> Dict:
318257

319258
def get_manifest_from_local_file(name):
320259

321-
if not os.path.exists(MANIFESTS_LOCATION):
322-
os.mkdir(MANIFESTS_LOCATION)
323-
if not os.path.exists(DEFAULT_MANIFEST_FILE):
324-
with open(DEFAULT_MANIFEST_FILE, 'w') as file:
325-
json.dump(DEFAULT_MANIFEST, file, indent=4)
326-
327260
if '.edit' in name:
328261
actual_name = name.split('.edit')[0]
329262
else:
@@ -351,9 +284,9 @@ def get_manifest_from_local_file(name):
351284
'azure': {
352285
'sonic': {
353286
'manifest': json_str
354-
}
355287
}
356288
}
357289
}
290+
}
358291
return desired_dict
359292

tests/sonic_package_manager/test_manager.py

+11-28
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,10 @@ def test_manager_migration(package_manager, fake_db_for_migration):
354354
call('test-package-3=1.6.0'),
355355
# test-package-4 was not present in DB at all, but it is present and installed in
356356
# fake_db_for_migration, thus asserting that it is going to be installed.
357-
call('test-package-4=1.5.0'),
357+
call(None, 'Azure/docker-test-4:1.5.0', name='test-package-4'),
358358
# test-package-5 1.5.0 was installed in fake_db_for_migration but the default
359359
# in current db is 1.9.0, assert that migration will install the newer version.
360-
call('test-package-5=1.9.0'),
360+
call(None, 'Azure/docker-test-5:1.9.0', name='test-package-5'),
361361
# test-package-6 2.0.0 was installed in fake_db_for_migration but the default
362362
# in current db is 1.5.0, assert that migration will install the newer version.
363363
call('test-package-6=2.0.0')],
@@ -385,12 +385,12 @@ def save(self, named):
385385
return DockerClient(dockerd_sock)
386386

387387

388-
#def test_manager_migration_dockerd(package_manager, fake_db_for_migration, mock_docker_api):
389-
#package_manager.install = Mock()
390-
#package_manager.get_docker_client = Mock(side_effect=mock_get_docker_client)
391-
#package_manager.migrate_packages(fake_db_for_migration, '/var/run/docker.sock')
392-
#package_manager.get_docker_client.assert_has_calls([
393-
#call('/var/run/docker.sock')], any_order=True)
388+
def test_manager_migration_dockerd(package_manager, fake_db_for_migration, mock_docker_api):
389+
package_manager.install = Mock()
390+
package_manager.get_docker_client = Mock(side_effect=mock_get_docker_client)
391+
package_manager.migrate_packages(fake_db_for_migration, '/var/run/docker.sock')
392+
package_manager.get_docker_client.assert_has_calls([
393+
call('/var/run/docker.sock')], any_order=True)
394394

395395

396396
def test_create_package_manifest_default_manifest(package_manager):
@@ -478,29 +478,18 @@ def test_manifests_update_command(package_manager):
478478
mock_echo.assert_called_with("Manifest 'test_manifest' updated successfully.")
479479

480480

481-
def test_check_manifests_directory_existence(package_manager):
482-
with patch('click.echo') as mock_echo, \
483-
patch('os.path.exists') as mock_exists:
484-
485-
mock_exists.return_value = False
486-
result = package_manager.check_manifests_directory_existence()
487-
mock_echo.assert_called_with("Manifests files directory empty")
488-
assert result == False
489481

490482
def test_delete_package_manifest(package_manager):
491483
with patch('click.echo') as mock_echo, \
492484
patch('click.prompt') as mock_prompt, \
493485
patch('os.path.exists') as mock_exists, \
494-
patch('os.remove') as mock_remove, \
495-
patch.object(package_manager, 'check_manifests_directory_existence') as mock_check_manifests:
496-
486+
patch('os.remove') as mock_remove:
497487

498488
# Test case 1: deleting default manifest
499489
package_manager.delete_package_manifest("default_manifest")
500490
mock_echo.assert_called_with("Default Manifest deletion is not allowed")
501491
mock_echo.reset_mock() # Reset the mock for the next test case
502492

503-
mock_check_manifests.return_value = True
504493
# Test case 2: manifest file doesn't exist
505494
mock_exists.return_value = True
506495
mock_exists.side_effect = lambda x: False if x.endswith("test_manifest") else True
@@ -526,7 +515,6 @@ def test_show_package_manifest(package_manager):
526515
with patch('click.echo') as mock_echo, \
527516
patch('os.path.exists') as mock_exists, \
528517
patch('builtins.open', unittest.mock.mock_open()) as mock_open, \
529-
patch.object(package_manager, 'check_manifests_directory_existence') as mock_check_manifests, \
530518
patch('json.load') as mock_json_load:
531519

532520
mock_exists.return_value = True
@@ -543,18 +531,13 @@ def test_list_package_manifest(package_manager):
543531
patch('os.path.exists') as mock_exists, \
544532
patch('os.listdir') as mock_listdir:
545533

546-
# Test case 1: manifest directory doesn't exist
547-
mock_exists.return_value = False
548-
package_manager.list_package_manifest()
549-
mock_echo.assert_called_with("Manifests files directory empty")
550-
551-
# Test case 2: no custom local manifest files found
534+
# Test case 1: no custom local manifest files found
552535
mock_exists.return_value = True
553536
mock_listdir.return_value = []
554537
package_manager.list_package_manifest()
555538
mock_echo.assert_called_with("No custom local manifest files found.")
556539

557-
# Test case 3: custom local manifest files found
540+
# Test case 2: custom local manifest files found
558541
mock_listdir.return_value = ["manifest1.json", "manifest2.json"]
559542
package_manager.list_package_manifest()
560543
mock_echo.assert_any_call("Custom Local Manifest files:")

tests/sonic_package_manager/test_metadata.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from sonic_package_manager.database import PackageEntry
1111
from sonic_package_manager.errors import MetadataError
12-
from sonic_package_manager.manifest import Manifest, MANIFESTS_LOCATION, DEFAULT_MANIFEST_NAME
12+
from sonic_package_manager.manifest import Manifest, MANIFESTS_LOCATION, DEFAULT_MANIFEST_FILE
1313
from sonic_package_manager.metadata import MetadataResolver
1414
from sonic_package_manager.version import Version
1515

@@ -157,8 +157,7 @@ def test_metadata_resolver_local_with_name_and_use_edit(mock_registry_resolver,
157157
mock_json_loads.side_effect = ValueError # Simulate ValueError when parsing JSON
158158

159159
# Create the default manifest file
160-
default_manifest_path = os.path.join(MANIFESTS_LOCATION, DEFAULT_MANIFEST_NAME)
161-
sonic_fs.create_file(default_manifest_path)
160+
sonic_fs.create_file(DEFAULT_MANIFEST_FILE)
162161
sonic_fs.create_file(os.path.join(MANIFESTS_LOCATION, "test_manifest.edit"))
163162

164163
metadata_resolver = MetadataResolver(mock_docker_api, mock_registry_resolver)
@@ -176,14 +175,14 @@ def test_metadata_resolver_local_with_name_and_default_manifest(mock_registry_re
176175
mock_json_loads.side_effect = ValueError # Simulate ValueError when parsing JSON
177176

178177
# Create the default manifest file
179-
default_manifest_path = os.path.join(MANIFESTS_LOCATION, DEFAULT_MANIFEST_NAME)
178+
sonic_fs.create_file(DEFAULT_MANIFEST_FILE)
180179
sonic_fs.create_file(default_manifest_path)
181180

182181
metadata_resolver = MetadataResolver(mock_docker_api, mock_registry_resolver)
183182
with pytest.raises(FileNotFoundError):
184183
metadata = metadata_resolver.from_local('image', use_local_manifest=False, name='test_manifest', use_edit=True)
185184

186-
mock_open.assert_called_with(os.path.join(MANIFESTS_LOCATION, DEFAULT_MANIFEST_NAME), 'r')
185+
mock_open.assert_called_with(DEFAULT_MANIFEST_FILE, 'r')
187186
mock_json_loads.assert_not_called() # Ensure json.loads is not called
188187

189188

0 commit comments

Comments
 (0)