def test_manifest_v1_invalid_version(): with pytest.raises(ManifestError): Manifest.marshal({ 'package': { 'version': 'abc', 'name': 'test' }, 'service': { 'name': 'test' } })
def test_manifest_v1_invalid_package_constraint(): with pytest.raises(ManifestError): Manifest.marshal({ 'package': { 'name': 'test', 'version': '1.0.0', 'depends': ['swss>a'] }, 'service': { 'name': 'test' } })
def test_manifest_invalid_root_type(): manifest_json_input = { 'package': { 'name': 'test', 'version': '1.0.0' }, 'service': { 'name': 'test' }, 'container': 'abc' } with pytest.raises(ManifestError): Manifest.marshal(manifest_json_input)
def test_manifest_invalid_array_type(): manifest_json_input = { 'package': { 'name': 'test', 'version': '1.0.0' }, 'service': { 'name': 'test', 'warm-shutdown': { 'after': 'bgp' } } } with pytest.raises(ManifestError): Manifest.marshal(manifest_json_input)
def from_local(self, image: str): ref = Reference.parse(image) manifest = Manifest.marshal( self.metadata_store[ref['name']][ref['tag']]['manifest']) components = self.metadata_store[ref['name']][ ref['tag']]['components'] return Metadata(manifest, components)
def from_tarball(self, filepath: str) -> Manifest: path, ref = filepath.split(':') manifest = Manifest.marshal( self.metadata_store[path][ref]['manifest']) components = self.metadata_store[path][ref]['components'] yang = self.metadata_store[path][ref]['yang'] return Metadata(manifest, components, yang)
def from_registry(self, repository: str, reference: str): manifest = Manifest.marshal( self.metadata_store[repository][reference]['manifest']) components = self.metadata_store[repository][reference][ 'components'] yang = self.metadata_store[repository][reference]['yang'] return Metadata(manifest, components, yang)
def test_manifest_v1_defaults(): manifest = Manifest.marshal({'package': {'name': 'test', 'version': '1.0.0'}, 'service': {'name': 'test'}}) assert manifest['package']['depends'] == [] assert manifest['package']['breaks'] == [] assert manifest['package']['base-os'] == ComponentConstraints() assert not manifest['service']['asic-service'] assert manifest['service']['host-service']
def test_manifest_v1_mounts(): manifest = Manifest.marshal({'version': '1.0.0', 'package': {'name': 'test', 'version': '1.0.0'}, 'service': {'name': 'cpu-report'}, 'container': {'privileged': True, 'mounts': [{'source': 'a', 'target': 'b', 'type': 'bind'}]}}) assert manifest['container']['mounts'][0]['source'] == 'a' assert manifest['container']['mounts'][0]['target'] == 'b' assert manifest['container']['mounts'][0]['type'] == 'bind'
def test_manifest_v1_mounts_invalid(): with pytest.raises(ManifestError): Manifest.marshal({ 'version': '1.0.0', 'package': { 'name': 'test', 'version': '1.0.0' }, 'service': { 'name': 'cpu-report' }, 'container': { 'privileged': True, 'mounts': [{ 'not-source': 'a', 'target': 'b', 'type': 'bind' }] } })
def test_manifest_v1_service_spec(): manifest = Manifest.marshal({ 'package': { 'name': 'test', 'version': '1.0.0' }, 'service': { 'name': 'test', 'asic-service': True } }) assert manifest['service']['asic-service']
def test_manifest_v1_unmarshal(): manifest_json_input = {'package': {'name': 'test', 'version': '1.0.0', 'depends': [ { 'name': 'swss', 'version': '>1.0.0', 'components': {}, } ]}, 'service': {'name': 'test'}} manifest = Manifest.marshal(manifest_json_input) manifest_json = manifest.unmarshal() for key, section in manifest_json_input.items(): for field, value in section.items(): assert manifest_json[key][field] == value
def manifest(): return Manifest.marshal({ 'package': { 'name': 'test', 'version': '1.0.0', }, 'service': { 'name': 'test', 'requires': ['database'], 'after': ['database', 'swss', 'syncd'], 'before': ['ntp-config'], 'dependent-of': ['swss'], 'asic-service': False, 'host-service': True, 'warm-shutdown': { 'before': ['syncd'], 'after': ['swss'], }, 'fast-shutdown': { 'before': ['swss'], }, }, 'container': { 'privileged': True, 'volumes': [ '/etc/sonic:/etc/sonic:ro' ] }, 'processes': [ { 'name': 'test-process', 'reconciles': True, }, { 'name': 'test-process-2', 'reconciles': False, }, { 'name': 'test-process-3', 'reconciles': True, }, ] })
def from_labels(cls, labels: Dict[str, str]) -> Metadata: """ Get manifest from image labels. Args: labels: key, value string pairs Returns: Metadata Raises: MetadataError """ metadata_dict = translate_plain_to_tree(labels) try: sonic_metadata = metadata_dict['com']['azure']['sonic'] except KeyError: raise MetadataError('No metadata found in image labels') try: manifest_string = sonic_metadata['manifest'] except KeyError: raise MetadataError('No manifest found in image labels') try: manifest_dict = json.loads(manifest_string) except (ValueError, TypeError) as err: raise MetadataError(f'Failed to parse manifest JSON: {err}') components = {} if 'versions' in sonic_metadata: for component, version in sonic_metadata['versions'].items(): try: components[component] = Version.parse(version) except ValueError as err: raise MetadataError( f'Failed to parse component version: {err}') yang_module_str = sonic_metadata.get('yang-module') return Metadata(Manifest.marshal(manifest_dict), components, yang_module_str)