ScriptCollection 4.2.59__py3-none-any.whl → 4.2.60__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ScriptCollection/GeneralUtilities.py +36 -36
- ScriptCollection/ScriptCollectionCore.py +41 -14
- ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +18 -7
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +77 -40
- {scriptcollection-4.2.59.dist-info → scriptcollection-4.2.60.dist-info}/METADATA +1 -1
- {scriptcollection-4.2.59.dist-info → scriptcollection-4.2.60.dist-info}/RECORD +9 -9
- {scriptcollection-4.2.59.dist-info → scriptcollection-4.2.60.dist-info}/WHEEL +0 -0
- {scriptcollection-4.2.59.dist-info → scriptcollection-4.2.60.dist-info}/entry_points.txt +0 -0
- {scriptcollection-4.2.59.dist-info → scriptcollection-4.2.60.dist-info}/top_level.txt +0 -0
|
@@ -36,10 +36,10 @@ class VersionEcholon(Enum):
|
|
|
36
36
|
LatestVersion = 3
|
|
37
37
|
|
|
38
38
|
class Platform(Enum):
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
Windows_AMD64 = 0
|
|
40
|
+
Linux_AMD64 = 1
|
|
41
|
+
Linux_ARM64 = 2
|
|
42
|
+
MacOS_ARM64 = 3
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class Dependency:
|
|
@@ -1444,13 +1444,13 @@ class GeneralUtilities:
|
|
|
1444
1444
|
machine = platform.machine().lower()
|
|
1445
1445
|
|
|
1446
1446
|
if system == "windows" and machine in ("x86_64", "amd64"):
|
|
1447
|
-
return Platform.
|
|
1447
|
+
return Platform.Windows_AMD64
|
|
1448
1448
|
elif system == "linux" and machine in ("x86_64", "amd64"):
|
|
1449
|
-
return Platform.
|
|
1449
|
+
return Platform.Linux_AMD64
|
|
1450
1450
|
elif system == "linux" and machine in ("arm64", "aarch64"):
|
|
1451
|
-
return Platform.
|
|
1451
|
+
return Platform.Linux_ARM64
|
|
1452
1452
|
elif system == "darwin" and machine in ("x86_64", "amd64"):
|
|
1453
|
-
return Platform.
|
|
1453
|
+
return Platform.MacOS_ARM64
|
|
1454
1454
|
else:
|
|
1455
1455
|
raise ValueError(f"Unsupported platform: {system}/{machine}")
|
|
1456
1456
|
|
|
@@ -1458,10 +1458,10 @@ class GeneralUtilities:
|
|
|
1458
1458
|
@check_arguments
|
|
1459
1459
|
def platform_to_short_str(platform_value: Platform) -> str:
|
|
1460
1460
|
mapping = {
|
|
1461
|
-
Platform.
|
|
1462
|
-
Platform.
|
|
1463
|
-
Platform.
|
|
1464
|
-
Platform.
|
|
1461
|
+
Platform.Windows_AMD64: "win-x64",
|
|
1462
|
+
Platform.Linux_AMD64: "linux-x64",
|
|
1463
|
+
Platform.Linux_ARM64: "linux-arm64",
|
|
1464
|
+
Platform.MacOS_ARM64: "osx-arm64",
|
|
1465
1465
|
}
|
|
1466
1466
|
return mapping[platform_value]
|
|
1467
1467
|
|
|
@@ -1469,10 +1469,10 @@ class GeneralUtilities:
|
|
|
1469
1469
|
@check_arguments
|
|
1470
1470
|
def platform_from_short_str(platform_str: str) -> Platform:
|
|
1471
1471
|
mapping = {
|
|
1472
|
-
"win-x64": Platform.
|
|
1473
|
-
"linux-x64": Platform.
|
|
1474
|
-
"linux-arm64": Platform.
|
|
1475
|
-
"osx-arm64": Platform.
|
|
1472
|
+
"win-x64": Platform.Windows_AMD64,
|
|
1473
|
+
"linux-x64": Platform.Linux_AMD64,
|
|
1474
|
+
"linux-arm64": Platform.Linux_ARM64,
|
|
1475
|
+
"osx-arm64": Platform.MacOS_ARM64,
|
|
1476
1476
|
}
|
|
1477
1477
|
if platform_str not in mapping:
|
|
1478
1478
|
raise ValueError(f"Unsupported platform string: {platform_str}")
|
|
@@ -1482,10 +1482,10 @@ class GeneralUtilities:
|
|
|
1482
1482
|
@check_arguments
|
|
1483
1483
|
def platform_to_dash_str(platform_value: Platform) -> str:
|
|
1484
1484
|
mapping = {
|
|
1485
|
-
Platform.
|
|
1486
|
-
Platform.
|
|
1487
|
-
Platform.
|
|
1488
|
-
Platform.
|
|
1485
|
+
Platform.Windows_AMD64: "Windows-x64",
|
|
1486
|
+
Platform.Linux_AMD64: "Linux-x64",
|
|
1487
|
+
Platform.Linux_ARM64: "Linux-arm64",
|
|
1488
|
+
Platform.MacOS_ARM64: "MacOS-arm64",
|
|
1489
1489
|
}
|
|
1490
1490
|
return mapping[platform_value]
|
|
1491
1491
|
|
|
@@ -1493,10 +1493,10 @@ class GeneralUtilities:
|
|
|
1493
1493
|
@check_arguments
|
|
1494
1494
|
def platform_from_dash_str(platform_str: str) -> Platform:
|
|
1495
1495
|
mapping = {
|
|
1496
|
-
"Windows-x64": Platform.
|
|
1497
|
-
"Linux-x64": Platform.
|
|
1498
|
-
"Linux-arm64": Platform.
|
|
1499
|
-
"MacOS-arm64": Platform.
|
|
1496
|
+
"Windows-x64": Platform.Windows_AMD64,
|
|
1497
|
+
"Linux-x64": Platform.Linux_AMD64,
|
|
1498
|
+
"Linux-arm64": Platform.Linux_ARM64,
|
|
1499
|
+
"MacOS-arm64": Platform.MacOS_ARM64,
|
|
1500
1500
|
}
|
|
1501
1501
|
if platform_str not in mapping:
|
|
1502
1502
|
raise ValueError(f"Unsupported platform string: {platform_str}")
|
|
@@ -1506,10 +1506,10 @@ class GeneralUtilities:
|
|
|
1506
1506
|
@check_arguments
|
|
1507
1507
|
def platform_to_docker_platform_str(platform_value: Platform) -> str:
|
|
1508
1508
|
mapping = {
|
|
1509
|
-
Platform.
|
|
1510
|
-
Platform.
|
|
1511
|
-
Platform.
|
|
1512
|
-
Platform.
|
|
1509
|
+
Platform.Windows_AMD64: "windows/amd64",
|
|
1510
|
+
Platform.Linux_AMD64: "linux/amd64",
|
|
1511
|
+
Platform.Linux_ARM64: "linux/arm64",
|
|
1512
|
+
Platform.MacOS_ARM64: "linux/arm64", # macOS → linux container
|
|
1513
1513
|
}
|
|
1514
1514
|
return mapping[platform_value]
|
|
1515
1515
|
|
|
@@ -1517,10 +1517,10 @@ class GeneralUtilities:
|
|
|
1517
1517
|
@check_arguments
|
|
1518
1518
|
def platform_to_dotnet_runtime_identifier(platform_value: Platform) -> str:
|
|
1519
1519
|
mapping = {
|
|
1520
|
-
Platform.
|
|
1521
|
-
Platform.
|
|
1522
|
-
Platform.
|
|
1523
|
-
Platform.
|
|
1520
|
+
Platform.Windows_AMD64: "win-x64",
|
|
1521
|
+
Platform.Linux_AMD64: "linux-x64",
|
|
1522
|
+
Platform.Linux_ARM64: "linux-arm64",
|
|
1523
|
+
Platform.MacOS_ARM64: "osx-arm64",
|
|
1524
1524
|
}
|
|
1525
1525
|
return mapping[platform_value]
|
|
1526
1526
|
|
|
@@ -1528,9 +1528,9 @@ class GeneralUtilities:
|
|
|
1528
1528
|
@check_arguments
|
|
1529
1529
|
def get_all_platforms() -> list[Platform]:
|
|
1530
1530
|
return [
|
|
1531
|
-
Platform.
|
|
1532
|
-
Platform.
|
|
1533
|
-
Platform.
|
|
1534
|
-
Platform.
|
|
1531
|
+
Platform.Windows_AMD64,
|
|
1532
|
+
Platform.Linux_AMD64,
|
|
1533
|
+
Platform.Linux_ARM64,
|
|
1534
|
+
Platform.MacOS_ARM64,
|
|
1535
1535
|
]
|
|
1536
1536
|
|
|
@@ -36,7 +36,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
|
|
|
36
36
|
from .ProgramRunnerPopen import ProgramRunnerPopen
|
|
37
37
|
from .SCLog import SCLog, LogLevel
|
|
38
38
|
|
|
39
|
-
version = "4.2.
|
|
39
|
+
version = "4.2.60"
|
|
40
40
|
__version__ = version
|
|
41
41
|
|
|
42
42
|
class VSCodeWorkspaceShellTask:
|
|
@@ -215,22 +215,30 @@ class ScriptCollectionCore:
|
|
|
215
215
|
|
|
216
216
|
def registry_contains_image(self,registry_url:str,image:str,registry_username:str,registry_password:str)->bool:
|
|
217
217
|
"""This function assumes that the registry is a custom deployed docker-registry (see https://hub.docker.com/_/registry )"""
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
218
|
+
try:
|
|
219
|
+
if "/" in image:
|
|
220
|
+
image=image.rsplit("/", 1)[-1]
|
|
221
|
+
registry_username,registry_password=self.__load_credentials_if_required_and_available(registry_url,registry_username,registry_password)
|
|
222
|
+
catalog_url = f"{registry_url}/v2/_catalog"
|
|
223
|
+
response = requests.get(catalog_url, auth=(registry_username, registry_password),timeout=20)
|
|
224
|
+
response.raise_for_status() # check if statuscode = 200
|
|
225
|
+
data = response.json()
|
|
226
|
+
# expected: {"repositories": ["nginx", "myapp"]}
|
|
227
|
+
images = data.get("repositories", [])
|
|
228
|
+
if not (image in images):
|
|
229
|
+
return False
|
|
230
|
+
|
|
231
|
+
if self.get_tags_of_images_from_registry(registry_url,image,registry_username,registry_password)<1:
|
|
232
|
+
return False
|
|
233
|
+
|
|
234
|
+
return True
|
|
235
|
+
except Exception:
|
|
236
|
+
return False
|
|
229
237
|
|
|
230
238
|
def docker_platform_to_slug(self,platform_value: Platform) -> str:
|
|
231
|
-
if platform_value == Platform.
|
|
239
|
+
if platform_value == Platform.Linux_AMD64:
|
|
232
240
|
return "linux-amd64"
|
|
233
|
-
elif platform_value == Platform.
|
|
241
|
+
elif platform_value == Platform.Linux_ARM64:
|
|
234
242
|
return "linux-arm64"
|
|
235
243
|
raise ValueError(f"Unsupported platform: {platform_value}")
|
|
236
244
|
|
|
@@ -3234,3 +3242,22 @@ OCR-content:
|
|
|
3234
3242
|
files=self.get_all_files_in_git_repository(repository_folder,ignore_ignored_files,include_submodules)
|
|
3235
3243
|
GeneralUtilities.ensure_file_exists(target_file)
|
|
3236
3244
|
GeneralUtilities.write_lines_to_file(target_file, files)
|
|
3245
|
+
|
|
3246
|
+
@GeneralUtilities.check_arguments
|
|
3247
|
+
def get_all_commits_in_git_repository(self,repository_folder:str,include_all_heads:bool=False) -> list[str]:
|
|
3248
|
+
"""Returns a textual visualization of all commits in a git-repository."""
|
|
3249
|
+
#do 'git log --reverse --all --pretty=format:"%ci | %H | %cn <%ce> | %s"'
|
|
3250
|
+
args = ["log", "--reverse", "--pretty=format:%ci | %H | %cn <%ce> | %s"]
|
|
3251
|
+
if include_all_heads:
|
|
3252
|
+
args.append("--all")
|
|
3253
|
+
result=self.run_program_argsasarray("git", args, repository_folder, throw_exception_if_exitcode_is_not_zero=True)
|
|
3254
|
+
return result[1]
|
|
3255
|
+
|
|
3256
|
+
@GeneralUtilities.check_arguments
|
|
3257
|
+
def write_commit_list_for_repository(self,repository_folder:str,target_file:str,include_all_heads:bool=False) -> None:
|
|
3258
|
+
if os.path.isabs(target_file):
|
|
3259
|
+
target_file=GeneralUtilities.resolve_relative_path(target_file,repository_folder)
|
|
3260
|
+
target_file=GeneralUtilities.normalize_path(target_file)
|
|
3261
|
+
commits=self.get_all_commits_in_git_repository(repository_folder, include_all_heads)
|
|
3262
|
+
GeneralUtilities.ensure_file_exists(target_file)
|
|
3263
|
+
GeneralUtilities.write_lines_to_file(target_file, commits)
|
|
@@ -23,22 +23,22 @@ class TFCPS_CodeUnitSpecific_Docker_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
|
23
23
|
codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(codeunit_file)
|
|
24
24
|
if custom_arguments is None:
|
|
25
25
|
custom_arguments=dict[str,str]()
|
|
26
|
+
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
|
27
|
+
app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
|
|
28
|
+
GeneralUtilities.ensure_folder_exists_and_is_empty(app_artifacts_folder)
|
|
26
29
|
for platform in platforms:
|
|
27
30
|
#builder must be created once before with "docker buildx create --use"
|
|
28
|
-
args = ["buildx","build", "--platform",GeneralUtilities.platform_to_docker_platform_str(platform), "--pull", "--force-rm", "--progress=plain", "--build-arg", f"TargetEnvironmentType={self.get_target_environment_type()}", "--build-arg", f"CodeUnitName={codeunitname}", "--build-arg", f"CodeUnitVersion={codeunitversion}", "--build-arg", f"CodeUnitOwnerName={self.tfcps_Tools_General.get_codeunit_owner_name(self.get_codeunit_file())}", "--build-arg", f"CodeUnitOwnerEMailAddress={self.tfcps_Tools_General.get_codeunit_owner_emailaddress(self.get_codeunit_file())}"]
|
|
31
|
+
args = ["buildx","build", "--platform",GeneralUtilities.platform_to_docker_platform_str(platform), "--pull", "--force-rm", "--progress=plain", "--build-arg", f"TargetEnvironmentType={self.get_target_environment_type()}", "--build-arg", f"CodeUnitName={codeunitname}", "--build-arg", f"CodeUnitVersion={codeunitversion}", "--build-arg", f"CodeUnitOwnerName={self.tfcps_Tools_General.get_codeunit_owner_name(self.get_codeunit_file())}", "--build-arg", f"CodeUnitOwnerEMailAddress={self.tfcps_Tools_General.get_codeunit_owner_emailaddress(self.get_codeunit_file())}", "--build-arg", f"Platform={GeneralUtilities.platform_to_dash_str(platform)}", "--build-arg", f"DotNetRuntime={GeneralUtilities.platform_to_dotnet_runtime_identifier(platform)}"]
|
|
29
32
|
for custom_argument_key, custom_argument_value in custom_arguments.items():
|
|
30
33
|
args.append("--build-arg")
|
|
31
34
|
args.append(f"{custom_argument_key}={custom_argument_value}")
|
|
32
35
|
args = args+["--tag", f"{codeunitname_lower}:latest", "--tag", f"{codeunitname_lower}:{codeunitversion}", "--file", f"{codeunitname}/Dockerfile"]
|
|
33
36
|
if not self.use_cache():
|
|
34
37
|
args.append("--no-cache")
|
|
38
|
+
args.append("--load")
|
|
35
39
|
args.append(".")
|
|
36
|
-
codeunit_content_folder =
|
|
40
|
+
codeunit_content_folder = codeunit_folder
|
|
37
41
|
GeneralUtilities.retry_action(lambda a=args, f=codeunit_content_folder: self._protected_sc.run_program_argsasarray("docker", a, f, print_errors_as_information=True), 3)
|
|
38
|
-
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
|
39
|
-
app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
|
|
40
|
-
GeneralUtilities.ensure_directory_does_not_exist(app_artifacts_folder)
|
|
41
|
-
GeneralUtilities.ensure_directory_exists(app_artifacts_folder)
|
|
42
42
|
|
|
43
43
|
self._protected_sc.run_program_argsasarray("docker", ["save", "--output", f"{codeunitname}_v{codeunitversion}_{GeneralUtilities.platform_to_dash_str(platform)}.tar", f"{codeunitname_lower}:{codeunitversion}"], app_artifacts_folder, print_errors_as_information=True)
|
|
44
44
|
self.__generate_sbom_for_docker_image()
|
|
@@ -98,10 +98,21 @@ class TFCPS_CodeUnitSpecific_Docker_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
|
98
98
|
if environment_variables is None:
|
|
99
99
|
environment_variables={}
|
|
100
100
|
current_platform = GeneralUtilities.get_current_platform()
|
|
101
|
+
platform_for_test:Platform=None
|
|
102
|
+
if current_platform == Platform.Windows_AMD64:
|
|
103
|
+
platform_for_test=Platform.Linux_AMD64
|
|
104
|
+
elif current_platform == Platform.Linux_AMD64:
|
|
105
|
+
platform_for_test=Platform.Linux_AMD64
|
|
106
|
+
elif current_platform == Platform.Linux_ARM64:
|
|
107
|
+
platform_for_test=Platform.Linux_ARM64
|
|
108
|
+
elif current_platform == Platform.MacOS_ARM64:
|
|
109
|
+
platform_for_test=Platform.Linux_ARM64
|
|
110
|
+
else:
|
|
111
|
+
raise ValueError(f"Current platform {current_platform} is not supported for testing.")
|
|
101
112
|
oci_image_artifacts_folder :str= GeneralUtilities.resolve_relative_path("Other/Artifacts/BuildResult_OCIImage", self.get_codeunit_folder())
|
|
102
113
|
container_name:str=f"{self.get_codeunit_name()}finaltest".lower()
|
|
103
114
|
self.tfcps_Tools_General.ensure_containers_are_not_running([container_name])
|
|
104
|
-
self.tfcps_Tools_General.load_docker_image(oci_image_artifacts_folder,
|
|
115
|
+
self.tfcps_Tools_General.load_docker_image(oci_image_artifacts_folder,platform_for_test)
|
|
105
116
|
codeunit_file:str=os.path.join(self.get_codeunit_folder(),f"{self.get_codeunit_name()}.codeunit.xml")
|
|
106
117
|
image=f"{self.get_codeunit_name()}:{self.tfcps_Tools_General.get_version_of_codeunit(codeunit_file)}".lower()
|
|
107
118
|
argument=f"run -d --name {container_name}"
|
|
@@ -650,13 +650,13 @@ class TFCPS_Tools_General:
|
|
|
650
650
|
if update:
|
|
651
651
|
platform_str:str=None
|
|
652
652
|
match architecture:
|
|
653
|
-
case Platform.
|
|
653
|
+
case Platform.Windows_AMD64:
|
|
654
654
|
platform_str = "windows_amd64"
|
|
655
|
-
case Platform.
|
|
655
|
+
case Platform.Linux_ARM64:
|
|
656
656
|
platform_str = "linux_arm64"
|
|
657
|
-
case Platform.
|
|
657
|
+
case Platform.Linux_AMD64:
|
|
658
658
|
platform_str = "linux_amd64"
|
|
659
|
-
case Platform.
|
|
659
|
+
case Platform.MacOS_ARM64:
|
|
660
660
|
platform_str = "darwin_arm64"
|
|
661
661
|
case _:
|
|
662
662
|
raise ValueError(f"Unknown platform: {str(architecture)}")
|
|
@@ -678,10 +678,10 @@ class TFCPS_Tools_General:
|
|
|
678
678
|
else:
|
|
679
679
|
raise ValueError(f"Unknown extension: \"{extension}\"")
|
|
680
680
|
|
|
681
|
-
download_and_extract("Windows", "windows", "zip",Platform.
|
|
682
|
-
download_and_extract("Linux", "linux", "tar.gz",Platform.
|
|
683
|
-
download_and_extract("Linux", "linux", "tar.gz",Platform.
|
|
684
|
-
download_and_extract("MacOS", "darwin", "tar.gz",Platform.
|
|
681
|
+
download_and_extract("Windows", "windows", "zip",Platform.Windows_AMD64)
|
|
682
|
+
download_and_extract("Linux", "linux", "tar.gz",Platform.Linux_AMD64)
|
|
683
|
+
download_and_extract("Linux", "linux", "tar.gz",Platform.Linux_ARM64)
|
|
684
|
+
download_and_extract("MacOS", "darwin", "tar.gz",Platform.MacOS_ARM64)
|
|
685
685
|
|
|
686
686
|
@GeneralUtilities.check_arguments
|
|
687
687
|
def clone_repository_as_resource(self, local_repository_folder: str, remote_repository_link: str, resource_name: str, repository_subname: str = None,use_cache:bool=True) -> None:
|
|
@@ -1161,7 +1161,7 @@ class TFCPS_Tools_General:
|
|
|
1161
1161
|
GeneralUtilities.write_text_to_file(version_file, latest_version_function)
|
|
1162
1162
|
|
|
1163
1163
|
@GeneralUtilities.check_arguments
|
|
1164
|
-
def push_docker_build_artifact(self, push_artifacts_file: str, registry: str, push_readme: bool, repository_folder_name: str, remote_image_name: str = None
|
|
1164
|
+
def push_docker_build_artifact(self, push_artifacts_file: str, registry: str, push_readme: bool, repository_folder_name: str, remote_image_name: str = None) -> None:
|
|
1165
1165
|
folder_of_this_file = os.path.dirname(push_artifacts_file)
|
|
1166
1166
|
filename = os.path.basename(push_artifacts_file)
|
|
1167
1167
|
codeunitname_regex: str = "([a-zA-Z0-9]+)"
|
|
@@ -1169,8 +1169,7 @@ class TFCPS_Tools_General:
|
|
|
1169
1169
|
if match := re.search(filename_regex, filename, re.IGNORECASE):
|
|
1170
1170
|
codeunitname = match.group(1)
|
|
1171
1171
|
else:
|
|
1172
|
-
raise ValueError(f"Expected push-artifacts-file to match the regex \"{filename_regex}\" where \"{codeunitname_regex}\" represents the codeunit-name.")
|
|
1173
|
-
|
|
1172
|
+
raise ValueError(f"Expected push-artifacts-file to match the regex \"{filename_regex}\" where \"{codeunitname_regex}\" represents the codeunit-name.")
|
|
1174
1173
|
repository_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}..{os.path.sep}Submodules{os.path.sep}{repository_folder_name}", folder_of_this_file)
|
|
1175
1174
|
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
|
1176
1175
|
artifacts_folder = os.path.join(repository_folder,codeunitname, "Other", "Artifacts")
|
|
@@ -1178,40 +1177,78 @@ class TFCPS_Tools_General:
|
|
|
1178
1177
|
codeunit_version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
1179
1178
|
if remote_image_name is None:
|
|
1180
1179
|
remote_image_name = codeunitname
|
|
1180
|
+
tar_files=[f for f in GeneralUtilities.get_direct_files_of_folder(applicationimage_folder) if f.endswith(".tar")]
|
|
1181
|
+
target_image_address=f"{registry}/{remote_image_name}"
|
|
1182
|
+
tar_files_with_platforms: list[tuple[str, str, str]] = []
|
|
1183
|
+
for tar_file in tar_files:
|
|
1184
|
+
filename=os.path.basename(tar_file)#filename looks like "{codeunitname}_v{codeunitversion}_{GeneralUtilities.platform_to_dash_str(platform)}.tar"
|
|
1185
|
+
platform:Platform=self.platform_from_filename(filename)#GeneralUtilities.platform_from_dash_str( filename.split("_")[-1].split(".")[0])
|
|
1186
|
+
platform_os_in_docker_format :str = None
|
|
1187
|
+
platform_arch_in_docker_format :str = None
|
|
1188
|
+
if platform==Platform.Windows_AMD64:
|
|
1189
|
+
raise NotImplementedError("Building docker images for Windows is not implemented yet.")
|
|
1190
|
+
elif platform==Platform.Linux_AMD64:
|
|
1191
|
+
platform_os_in_docker_format = "linux"
|
|
1192
|
+
platform_arch_in_docker_format = "amd64"
|
|
1193
|
+
elif platform==Platform.Linux_ARM64:
|
|
1194
|
+
platform_os_in_docker_format = "linux"
|
|
1195
|
+
platform_arch_in_docker_format = "arm64"
|
|
1196
|
+
elif platform==Platform.MacOS_ARM64:
|
|
1197
|
+
raise NotImplementedError("Building docker images for MacOS is not implemented yet.")
|
|
1198
|
+
else:
|
|
1199
|
+
raise ValueError(f"Unsupported platform {platform} extracted from filename {filename}.")
|
|
1200
|
+
tar_files_with_platforms.append((tar_file, platform_os_in_docker_format, platform_arch_in_docker_format))
|
|
1201
|
+
self.push_docker_build_artifact_as_multi_arch_artifact(tar_files_with_platforms,target_image_address, "v"+codeunit_version)
|
|
1202
|
+
self.push_docker_build_artifact_as_multi_arch_artifact(tar_files_with_platforms,target_image_address, "latest")
|
|
1203
|
+
if push_readme:
|
|
1204
|
+
self.__sc.run_program_with_retry("docker-pushrm", target_image_address, codeunit_folder)
|
|
1205
|
+
|
|
1206
|
+
def push_docker_build_artifact_as_multi_arch_artifact(self,tar_files: list[tuple[str, str, str]], image_address: str, tag: str):
|
|
1207
|
+
"""
|
|
1208
|
+
tar_files: list of (tar_path, os, arch) tuples
|
|
1209
|
+
for example [
|
|
1210
|
+
("MyApp.Linux.arm64.tar", "linux", "arm64"),
|
|
1211
|
+
("MyApp.Linux.amd64.tar", "linux", "amd64")
|
|
1212
|
+
]
|
|
1213
|
+
image_address for example: "myregistry.example.com/myapp"
|
|
1214
|
+
tag for example: "1.0.0"
|
|
1215
|
+
"""
|
|
1216
|
+
arch_tags = []
|
|
1217
|
+
|
|
1218
|
+
for tar_path, os_name, arch in tar_files:
|
|
1219
|
+
arch_tag = f"{image_address}:{tag}-{os_name}-{arch}"
|
|
1220
|
+
arch_tags.append(arch_tag)
|
|
1221
|
+
|
|
1222
|
+
# Load tar → local image
|
|
1223
|
+
print(f"Loading {tar_path}...")
|
|
1224
|
+
result = self.__sc.run_program_argsasarray("docker",[ "load", "-i", tar_path], capture_output=True)
|
|
1225
|
+
# docker load outputs: "Loaded image: sha256:abc123..." or "Loaded image ID: ..."
|
|
1226
|
+
# we need the loaded image ID
|
|
1227
|
+
loaded_id = None
|
|
1228
|
+
for line in GeneralUtilities.string_to_lines(result[1]):
|
|
1229
|
+
if "Loaded image" in line:
|
|
1230
|
+
loaded_id = line.split(":", 1)[1].strip()
|
|
1231
|
+
break
|
|
1232
|
+
|
|
1233
|
+
if not loaded_id:
|
|
1234
|
+
raise RuntimeError(f"Could not determine loaded image from output: \"{result[1]}\"")
|
|
1235
|
+
|
|
1236
|
+
# Retag + push
|
|
1237
|
+
self.__sc.run_program_argsasarray("docker",[ "tag", loaded_id, arch_tag])
|
|
1238
|
+
self.__sc.run_program_argsasarray("docker",[ "push", arch_tag])
|
|
1239
|
+
|
|
1240
|
+
# Create multi-arch manifest
|
|
1241
|
+
final_tag = f"{image_address}:{tag}"
|
|
1242
|
+
self.__sc.run_program_argsasarray("docker", [ "buildx", "imagetools", "create", "--tag", final_tag] + arch_tags)
|
|
1181
1243
|
|
|
1182
|
-
def push_image(tar_file:str,tag:str,remote_image_name:str):
|
|
1183
|
-
GeneralUtilities.assert_condition(tag==tag.lower(), f"Tag \"{tag}\" must be in lower-case.")
|
|
1184
|
-
remote_image_name = remote_image_name.lower()
|
|
1185
|
-
local_image_name = codeunitname.lower()
|
|
1186
|
-
remote_repo = f"{registry}/{remote_image_name}"
|
|
1187
|
-
remote_image_version = f"{remote_repo}:{tag}"
|
|
1188
|
-
self.__sc.log.log("Load image...")
|
|
1189
|
-
self.__sc.run_program("docker", f"load --input {tar_file}", applicationimage_folder)
|
|
1190
|
-
self.__sc.log.log("Tag image...")
|
|
1191
|
-
self.__sc.run_program_with_retry("docker", f"tag {local_image_name}:{tag} {remote_image_version}")
|
|
1192
|
-
self.__sc.log.log("Push image...")
|
|
1193
|
-
self.__sc.run_program_with_retry("docker", f"push {remote_image_version}")
|
|
1194
|
-
if push_readme:
|
|
1195
|
-
self.__sc.run_program_with_retry("docker-pushrm", f"{remote_repo}", codeunit_folder)
|
|
1196
|
-
|
|
1197
|
-
default_tar_image_file:str=None
|
|
1198
|
-
for image_file in GeneralUtilities.get_direct_files_of_folder(applicationimage_folder):
|
|
1199
|
-
image_filename = os.path.basename(image_file)
|
|
1200
|
-
platform:Platform=self.platform_from_filename(image_filename)
|
|
1201
|
-
tag=codeunit_version+"-"+GeneralUtilities.platform_to_short_str(platform).lower()
|
|
1202
|
-
if platform == default_platform:
|
|
1203
|
-
default_tar_image_file:str=image_file
|
|
1204
|
-
push_image(image_file,tag,remote_image_name)
|
|
1205
|
-
if default_tar_image_file is not None:
|
|
1206
|
-
push_image(default_tar_image_file,"latest",remote_image_name)
|
|
1207
|
-
push_image(default_tar_image_file,codeunit_version,remote_image_name)
|
|
1208
1244
|
|
|
1209
1245
|
@GeneralUtilities.check_arguments
|
|
1210
1246
|
def platform_from_filename(self,filename: str) -> Platform:
|
|
1211
1247
|
match = re.search(r'_([^_]+)\.tar', filename)
|
|
1212
|
-
if
|
|
1213
|
-
|
|
1214
|
-
|
|
1248
|
+
if match:
|
|
1249
|
+
return GeneralUtilities.platform_from_dash_str(match.group(1))
|
|
1250
|
+
else:
|
|
1251
|
+
raise ValueError(f"Cannot extract platform from filename: \"{filename}\"")
|
|
1215
1252
|
|
|
1216
1253
|
def prepare_building_codeunits(self,repository_folder:str,use_cache:bool,generate_development_certificate:bool):
|
|
1217
1254
|
if generate_development_certificate:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
ScriptCollection/AnionBuildPlatform.py,sha256=K-PHarX802A0PU8uRu0GNcEZiXujFoXHACe-X9YJsAQ,11711
|
|
2
2
|
ScriptCollection/CertificateUpdater.py,sha256=Pa6eyjQSx7IIvj4PQVMI0IwMs01KQrNSB7Qa-7lRfBs,9375
|
|
3
3
|
ScriptCollection/Executables.py,sha256=qpo0g5peWdlK5uLIUCyLDB9c3JCk0ETbtmOJXZwuHh4,44510
|
|
4
|
-
ScriptCollection/GeneralUtilities.py,sha256=
|
|
4
|
+
ScriptCollection/GeneralUtilities.py,sha256=FEjJEfA3riVT7G4sL8bzKPb7w0SN8YjONNWMtiBo_j8,64882
|
|
5
5
|
ScriptCollection/HTTPMaintenanceOverheadHelper.py,sha256=TToNtyO1XzsMbBsTBf3o0xgOK0v4Jf03qw2Z0xb2nCk,2007
|
|
6
6
|
ScriptCollection/ProcessesRunner.py,sha256=o5raxIt3lknNPoPrjNzJ2bprRPJ3SnL0rrR7crraD7E,1523
|
|
7
7
|
ScriptCollection/ProgramRunnerBase.py,sha256=4A2eQgSg_rRgQcgSi-LYtUlM-uSQEpS7qFWn0tWt4uo,2171
|
|
@@ -9,7 +9,7 @@ ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrR
|
|
|
9
9
|
ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
|
|
10
10
|
ScriptCollection/ProgramRunnerSudo.py,sha256=_khC3xuTdrPoLluBJZWfldltmmuKltABJPcbjZSFW-4,4835
|
|
11
11
|
ScriptCollection/SCLog.py,sha256=8TRy1LeYMsPOIuWUcnUNNbO5pd-cNBS-3cn-kdzP8FU,4768
|
|
12
|
-
ScriptCollection/ScriptCollectionCore.py,sha256=
|
|
12
|
+
ScriptCollection/ScriptCollectionCore.py,sha256=k9Jxim56NM5dr6wAZrITk-bxZhKKxeXi1gb1zkfcDUo,176930
|
|
13
13
|
ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
ScriptCollection/OCIImages/AbstractImageHandler.py,sha256=83qDMILwxhH9DbC0sb358Vu8PXEysmJJyap_6gECZqs,1627
|
|
15
15
|
ScriptCollection/OCIImages/OCIImageManager.py,sha256=aBogkSXNDyi8NO11N-s03nuFJEv7PyJ-wjHuYYeZfvs,6662
|
|
@@ -30,9 +30,9 @@ ScriptCollection/TFCPS/TFCPS_Generic.py,sha256=O-0guM_LJCcZmPZJhMgTvXD2RXUJEBWWv
|
|
|
30
30
|
ScriptCollection/TFCPS/TFCPS_MergeToMain.py,sha256=-Ev9D3bZDlUk2WFQhcmvzQ3FCS97OdsVUd0koAdmpZc,7474
|
|
31
31
|
ScriptCollection/TFCPS/TFCPS_MergeToStable.py,sha256=Ajfy2pLajTuU6UpwItHt4C2a-gLF3gPc4z6BktL3Cio,22163
|
|
32
32
|
ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py,sha256=f0Uq1cA_4LvmL72cal0crrbKF6PcxL13D9wBKuQ1YBw,2328
|
|
33
|
-
ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=
|
|
33
|
+
ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=RCwtEwuZUds-gyHa2qCitWZUgapM3-IZJKF9e5Zwxck,98000
|
|
34
34
|
ScriptCollection/TFCPS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=
|
|
35
|
+
ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=xMuj-GoEwDnmUWbmdF536dNQL7jnTaw9aQ-gcDqUkgQ,11743
|
|
36
36
|
ScriptCollection/TFCPS/Docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationBase.py,sha256=bT6Gd5pQpZCw4OQz6HWkPCSn5z__eUUEisABLDSxd0o,200
|
|
38
38
|
ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationGenerate.py,sha256=QyjOfMY22JWCvKjMelHiDWbJiWqotOfebpJpgDUaoO4,237
|
|
@@ -47,8 +47,8 @@ ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=kL37qJNwH6
|
|
|
47
47
|
ScriptCollection/TFCPS/NodeJS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py,sha256=KFKDdfV9DFHE5n7TI6m1Ra1Qw2JwL_JQjneBfqcRQ_w,13467
|
|
49
49
|
ScriptCollection/TFCPS/Python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
-
scriptcollection-4.2.
|
|
51
|
-
scriptcollection-4.2.
|
|
52
|
-
scriptcollection-4.2.
|
|
53
|
-
scriptcollection-4.2.
|
|
54
|
-
scriptcollection-4.2.
|
|
50
|
+
scriptcollection-4.2.60.dist-info/METADATA,sha256=dQYQcvTQgiDemUjezOsxBCyPOkzYt6DkBe7HSGQUxf4,7690
|
|
51
|
+
scriptcollection-4.2.60.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
52
|
+
scriptcollection-4.2.60.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
|
|
53
|
+
scriptcollection-4.2.60.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
|
|
54
|
+
scriptcollection-4.2.60.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|