Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: [NODE-1577] add a file size check for ic-os upgrade images #4453

Merged
merged 3 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bazel/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ exports_files(
"prost_generator.sh",
"generic_rust_bench.sh",
"canbench.sh",
"file_size_test.sh",
],
visibility = ["//visibility:public"],
)
Expand Down
20 changes: 20 additions & 0 deletions bazel/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,23 @@ write_info_file_var = rule(
"varname": attr.string(mandatory = True),
},
)

def file_size_check(
name,
max_file_size):
"""
A check to make sure the given file is below the specified size.

Args:
name: Name of the file.
max_file_size: Max accepted size in bytes.
"""
native.sh_test(
name = "%s_size_test" % name,
srcs = ["//bazel:file_size_test.sh"],
data = [name],
env = {
"FILE": "$(rootpath %s)" % name,
"MAX_SIZE": str(max_file_size),
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail

file_size=$(wc -c <"$FILE")

if [ "$file_size" -ge "$MAX_SIZE" ]; then
if [ "$file_size" -gt "$MAX_SIZE" ]; then
echo "'$FILE', '$file_size' bytes exceeds the allowed maximum size '$MAX_SIZE'" >&2
exit 1
else
Expand Down
25 changes: 24 additions & 1 deletion ic-os/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This macro defines the overall build process for ICOS images, including:
"""

load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("//bazel:defs.bzl", "gzip_compress", "zstd_compress")
load("//bazel:defs.bzl", "file_size_check", "gzip_compress", "zstd_compress")
load("//ci/src/artifacts:upload.bzl", "upload_artifacts")
load("//ic-os/bootloader:defs.bzl", "build_grub_partition")
load("//ic-os/components:boundary-guestos.bzl", boundary_component_files = "component_files")
Expand All @@ -23,6 +23,7 @@ def icos_build(
image_deps_func,
mode = None,
malicious = False,
max_file_sizes = None,
upgrades = True,
vuln_scan = True,
visibility = None,
Expand All @@ -39,6 +40,7 @@ def icos_build(
image_deps_func: Function to be used to generate image manifest
mode: dev or prod. If not specified, will use the value of `name`
malicious: if True, bundle the `malicious_replica`
max_file_sizes: mapping of output file to max allowed size
upgrades: if True, build upgrade images as well
vuln_scan: if True, create targets for vulnerability scanning
visibility: See Bazel documentation
Expand All @@ -51,6 +53,9 @@ def icos_build(
if mode == None:
mode = name

if max_file_sizes == None:
max_file_sizes = {}

image_deps = image_deps_func(mode, malicious)

# -------------------- Version management --------------------
Expand Down Expand Up @@ -337,6 +342,12 @@ def icos_build(
tags = ["manual"],
)

if "disk-img.tar.zst" in max_file_sizes:
file_size_check(
name = "disk-img.tar.zst",
max_file_size = max_file_sizes["disk-img.tar.zst"],
)

# -------------------- Assemble upgrade image --------------------

if upgrades:
Expand All @@ -358,6 +369,12 @@ def icos_build(
tags = ["manual"],
)

if "update-img.tar.zst" in max_file_sizes:
file_size_check(
name = "update-img.tar.zst",
max_file_size = max_file_sizes["update-img.tar.zst"],
)

upgrade_image(
name = "update-img-test.tar",
boot_partition = ":partition-boot-test.tzst",
Expand All @@ -376,6 +393,12 @@ def icos_build(
tags = ["manual"],
)

if "update-img-test.tar.zst" in max_file_sizes:
file_size_check(
name = "update-img-test.tar.zst",
max_file_size = max_file_sizes["update-img-test.tar.zst"],
)

# -------------------- Upload artifacts --------------------

upload_suffix = ""
Expand Down
5 changes: 5 additions & 0 deletions ic-os/guestos/envs/prod/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ load("//publish:defs.bzl", "checksum_rule")
icos_build(
name = "prod",
image_deps_func = image_deps,
max_file_sizes = {
"disk-img.tar.zst": 450 * 1000 * 1000, # 419 MB on 2025-03-21
"update-img.tar.zst": 450 * 1000 * 1000, # 416 MB on 2025-03-21
"update-img-test.tar.zst": 450 * 1000 * 1000, # 416 MB on 2025-03-21
},
upload_prefix = "guest-os",
visibility = [
"//rs:ic-os-pkg",
Expand Down
5 changes: 5 additions & 0 deletions ic-os/hostos/envs/prod/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ load("//publish:defs.bzl", "checksum_rule")
icos_build(
name = "prod",
image_deps_func = image_deps,
max_file_sizes = {
"disk-img.tar.zst": 900 * 1000 * 1000, # 837 MB on 2025-03-21
"update-img.tar.zst": 900 * 1000 * 1000, # 835 MB on 2025-03-21
"update-img-test.tar.zst": 900 * 1000 * 1000, # 835 MB on 2025-03-21
},
upload_prefix = "host-os",
visibility = ["//rs:ic-os-pkg"],
vuln_scan = False,
Expand Down
3 changes: 3 additions & 0 deletions ic-os/setupos/envs/prod/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ load("//publish:defs.bzl", "checksum_rule")
icos_build(
name = "prod",
image_deps_func = image_deps,
max_file_sizes = {
"disk-img.tar.zst": 2100 * 1000 * 1000, # 2.1 GB on 2025-03-21
},
upgrades = False,
upload_prefix = "setup-os",
vuln_scan = False,
Expand Down
40 changes: 18 additions & 22 deletions publish/canisters/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("//bazel:defs.bzl", "file_size_check")
load("//ci/src/artifacts:upload.bzl", "upload_artifacts")
load("//publish:defs.bzl", "checksum_rule")
load("//rs/nns:nns.bzl", NNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES = "CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES")
Expand Down Expand Up @@ -62,57 +63,52 @@ COMPRESSED_CANISTERS = {
"ledger-archive-node-canister.wasm.gz": "//rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm.wasm.gz",
}

DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES = "21"
DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES = 21

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES = {
# -- FI team --
# The compressed version of these two canisters should be ~600kb,
# we are setting the check to 7 to leave some space for growth
# but enough to get an alert in case of a spike in size.
"ic-icrc1-ledger.wasm.gz": "7",
"ic-icrc1-ledger.wasm.gz": 7,
# The size is currently at 704585 bytes.
"ic-icrc1-ledger-u256.wasm.gz": "8",
"ic-icrc1-ledger-u256.wasm.gz": 8,
# Size when constraint addded: 841_234 bytes
"ledger-canister.wasm.gz": "9",
"ledger-canister.wasm.gz": 9,
# Size when constraint addded: 906_940 bytes
"ledger-canister_notify-method.wasm.gz": "10",
"ledger-canister_notify-method.wasm.gz": 10,

# -- XC team --
# Size when constraint addded: 447_593 bytes
"ic-btc-checker.wasm.gz": "6",
"ic-btc-checker.wasm.gz": 6,
# Size when constraint addded: 696_633 bytes
"ic-ckbtc-minter.wasm.gz": "8",
"ic-ckbtc-minter.wasm.gz": 8,
# Size when constraint addded: 1_230_630 bytes
"ic-cketh-minter.wasm.gz": "13",
"ic-cketh-minter.wasm.gz": 13,
# The orchestrator needs to embed 3 wasms at compile time
# (ICRC1 index, ICRC1 ledger, and ICRC1 archive) and size is
# therefore strictly controlled.
# Size when constraint addded: 1_704_979 bytes
"ic-ledger-suite-orchestrator-canister.wasm.gz": "18",
"ic-ledger-suite-orchestrator-canister.wasm.gz": 18,

# -- BN team --
# Size when constraint addded: 540_349 bytes
"rate-limit-canister.wasm.gz": "7",
"rate-limit-canister.wasm.gz": 7,
# Size when constraint addded: 452_227 bytes
"salt-sharing-canister.wasm.gz": "6",
"salt-sharing-canister.wasm.gz": 6,
}

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.update(NNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES)

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.update(SNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES)

[
sh_test(
name = name + "_compressed_size_test",
srcs = ["file_size_test.sh"],
data = [name],
env = {
"FILE": "$(rootpath " + name + ")",
"MAX_SIZE": CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.get(
name,
DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES,
) + "0" * 5,
},
file_size_check(
name = name,
max_file_size = CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.get(
name,
DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES,
) * 100000,
)
for (name, size) in CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.items()
]
Expand Down
12 changes: 6 additions & 6 deletions rs/nns/nns.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ but other things could be added here later.
# amount of growth happens.

CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES = {
"cycles-minting-canister.wasm.gz": "6",
"genesis-token-canister.wasm.gz": "3",
"governance-canister.wasm.gz": "17",
"governance-canister_test.wasm.gz": "17",
"registry-canister.wasm.gz": "14",
"root-canister.wasm.gz": "4",
"cycles-minting-canister.wasm.gz": 6,
"genesis-token-canister.wasm.gz": 3,
"governance-canister.wasm.gz": 17,
"governance-canister_test.wasm.gz": 17,
"registry-canister.wasm.gz": 14,
"root-canister.wasm.gz": 4,
}
8 changes: 4 additions & 4 deletions rs/sns/sns.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ but other things could be added here later.
# amount of growth happens.

CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES = {
"sns-governance-canister.wasm.gz": "14",
"sns-governance-canister_test.wasm.gz": "14",
"sns-root-canister.wasm.gz": "5",
"sns-swap-canister.wasm.gz": "7",
"sns-governance-canister.wasm.gz": 14,
"sns-governance-canister_test.wasm.gz": 14,
"sns-root-canister.wasm.gz": 5,
"sns-swap-canister.wasm.gz": 7,
}