Skip to content

Commit 5c2256c

Browse files
committed
Feature: ChainIds computing was not pure + Max docker layers was 1000\nSolution: Use function rather than class method depending on self + use iteration rather than recursion
1 parent 7e9d67b commit 5c2256c

File tree

1 file changed

+28
-48
lines changed
  • src/aleph_client/commands/container

1 file changed

+28
-48
lines changed

src/aleph_client/commands/container/image.py

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@
88
Command = NewType('Command', Dict[str, str])
99
ConfigValue = NewType('ConfigValue', Union[str, bool, None, Command])
1010

11+
12+
def compute_chain_ids(diff_ids: List[str], layers_ids: List[str]) -> List[str]:
13+
# diff_ids are stored sequentially, from parent to child.
14+
# If the file has been tempered, this method cannot work.
15+
# ChainID(A) = DiffID(A)
16+
# ChainID(A|B) = Digest(ChainID(A) + " " + DiffID(B))
17+
# ChainID(A|B|C) = Digest(ChainID(A|B) + " " + DiffID(C))
18+
# https://github.com/opencontainers/image-spec/blob/main/config.md
19+
index = 0
20+
chain_ids = []
21+
diff_id = diff_ids[index]
22+
chain_ids.append(diff_id)
23+
index += 1
24+
while index < len(layers_ids):
25+
chain_id = "sha256:" + sha256(
26+
chain_ids[index - 1].encode()
27+
+ " ".encode()
28+
+ diff_ids[index].encode()
29+
).hexdigest()
30+
chain_ids.append(chain_id)
31+
index += 1
32+
return chain_ids
33+
34+
1135
class Image:
1236
config: Dict[str, ConfigValue]
1337
image_digest: str
@@ -42,55 +66,11 @@ def __init__(self, path: str):
4266
manifest = self.__load_metadata(tar, "manifest.json")
4367
self.repositories = self.__load_metadata(tar, "repositories")
4468
self.image_digest = manifest[0]["Config"].split(".")[0]
45-
self.config = self.__load_metadata(tar, f"{self.image_digest}.json")
69+
self.config = self.__load_metadata(
70+
tar, f"{self.image_digest}.json")
4671
self.layers_ids = list(map(
4772
lambda name: name.split('/')[0],
4873
manifest[0]["Layers"]
49-
)) # Only keep the Layer id, not the file path
74+
)) # Only keep the Layer id, not the file path
5075
self.diff_ids = self.config["rootfs"]["diff_ids"]
51-
self.chain_ids = self.__compute_chain_ids()
52-
53-
def __compute_chain_ids(self) -> List[str]:
54-
chain_ids = []
55-
# diff_ids are stored sequentially, from parent to child.
56-
# If the file has been tempered, this method cannot work.
57-
58-
# I used recursion because it was simpler to execute, not because it's better
59-
# cause it's not. TODO: use iteration
60-
def recursive_compute_chain_id(index: int) -> str:
61-
# ChainID(A) = DiffID(A)
62-
# ChainID(A|B) = Digest(ChainID(A) + " " + DiffID(B))
63-
# ChainID(A|B|C) = Digest(ChainID(A|B) + " " + DiffID(C))
64-
# https://github.com/opencontainers/image-spec/blob/main/config.md
65-
if index == 0:
66-
diff_id = self.diff_ids[index]
67-
chain_ids.append(diff_id)
68-
return diff_id
69-
chain_id = "sha256:" + sha256(
70-
recursive_compute_chain_id(index - 1).encode()
71-
+ " ".encode()
72-
+ self.diff_ids[index].encode()
73-
).hexdigest()
74-
chain_ids.append(chain_id)
75-
return chain_id
76-
77-
78-
79-
# TODO: test this iterative version
80-
iterative_chain_ids = []
81-
def iterative_compute_chain_id(index: int) -> str:
82-
diff_id = self.diff_ids[0]
83-
iterative_chain_ids.append(diff_id)
84-
i = 1
85-
while i < index:
86-
chain_id = "sha256:" + sha256(
87-
iterative_chain_ids[i - 1].encode()
88-
+ " ".encode()
89-
+ self.diff_ids[i].encode()
90-
).hexdigest()
91-
iterative_chain_ids.append(chain_id)
92-
return
93-
94-
recursive_compute_chain_id(len(self.layers_ids) - 1)
95-
96-
return chain_ids
76+
self.chain_ids = compute_chain_ids(self.diff_ids, self.layers_ids)

0 commit comments

Comments
 (0)