1+ #!/usr/bin/env nu
2+ # Illumos media writer
3+
4+ # Downloads an OpenIndiana (OI) or OmniOS image, verifies SHA-256, and prints
5+ # the filename.
6+ # Defaults: os=OpenIndiana, release=stable, has_gui=false. Uses wget2 for large
7+ # downloads.
8+ # TODO: enable tilda expansion
9+
10+ def build_url [os_name : string , channel : string , version : string , has_gui : bool ] {
11+ let os = ($os_name | str downcase )
12+ if $os in [" openindiana" , " oi" ] {
13+ let edition = (if $has_gui { " gui" } else { " text" })
14+ if $channel == " stable" {
15+ $" https://dlc.openindiana.org/isos/hipster/($version )/OI-hipster-($edition )-($version ).usb"
16+ } else {
17+ $" https://dlc.openindiana.org/isos/hipster/test/OI-hipster-($edition )-($version ).usb"
18+ }
19+ } else if $os == " omnios" {
20+ if $channel == " stable" {
21+ $" https://downloads.omnios.org/media/stable/omnios-($version ).usb-dd"
22+ } else {
23+ $" https://downloads.omnios.org/media/bloody/omnios-bloody-($version ).usb-dd"
24+ }
25+ } else {
26+ error make { msg : $" Unknown os_name: ($os_name ). Use OI/OpenIndiana or OmniOS." }
27+ }
28+ }
29+
30+ def sha_url [image_url : string , os_name : string ] {
31+ let os = ($os_name | str downcase )
32+ if $os in [" openindiana" , " oi" ] {
33+ $" ($image_url ).sha256sum"
34+ } else {
35+ $" ($image_url ).sha256"
36+ }
37+ }
38+
39+ def main [
40+ output_dir : string , # mandatory
41+ os_name : string , # strictly: "OI", "OpenIndiana", "openindiana",
42+ # "OmniOS", or "omnios"
43+ release : string , # "stable" or "beta"
44+ -- version : string = " " , # flag with default: --version "20250914"
45+ -- gui # flag: --has-gui
46+ ] {
47+ # Strict validation for os_name
48+ let os_type = (if $os_name == " OI" {
49+ " OpenIndiana"
50+ } else if $os_name in [" OpenIndiana" , " openindiana" ] {
51+ " OpenIndiana"
52+ } else if $os_name in [" OmniOS" , " omnios" ] {
53+ " OmniOS"
54+ } else {
55+ error make { msg : $" Invalid os_name: ($os_name ). Use OI, OpenIndiana, openindiana, OmniOS, or omnios." }
56+ })
57+
58+ # Validate release using 'in' operator
59+ if $release not-in [" stable" , " beta" ] {
60+ error make { msg : $" Invalid release: ($release ). Valid values: stable, beta." }
61+ }
62+
63+ # Set default version if blank
64+ let latest = " 20251011"
65+ let version_default = (if $release == " stable" {
66+ if $os_type == " OpenIndiana" {
67+ " 20250606"
68+ } else {
69+ " r151054r"
70+ }
71+ } else {
72+ $latest
73+ })
74+ let version = (if $version == " " { $version_default } else { $version })
75+
76+ # Check if directory exists, exit with error if it doesn't
77+ if not ($output_dir | path exists ) {
78+ error make { msg : $" Directory ($output_dir ) does not exist." }
79+ }
80+
81+ # GUI only applies to OpenIndiana, use $gui flag directly
82+ let request_gui = (if $os_type == " OpenIndiana" { $gui } else { false })
83+
84+ # Convert to lowercase for URL building
85+ let os_for_url = (if $os_type == " OpenIndiana" { " openindiana" } else { " omnios" })
86+
87+ let image_url = (build_url $os_for_url $release $version $request_gui )
88+ let checksum_url = sha_url $image_url $os_for_url
89+
90+ let filename = ($image_url | split row " /" | last )
91+ let filepath = ($output_dir | path join $filename )
92+
93+ # Download only if file doesn't exist
94+ if ($filepath | path exists ) {
95+ print $" File ($filename ) already exists, skipping download."
96+ # resume download if previous one was interrupted
97+ # wget2 --continue --directory-prefix $output_dir $image_url
98+ } else {
99+ print $" Downloading ($filename ).."
100+ # gotta add parenthesis if this syntax is used: `--directory-prefix=$output_dir`
101+ wget2 -- directory-prefix $output_dir $image_url
102+ }
103+
104+ # Fetch checksum text without saving a file
105+ let checksum_text = (http get -- raw $checksum_url ) | decode utf-8
106+
107+ # Compute sha256 of downloaded file and compare to first token in checksum
108+ # file
109+ let file_hash = (open $filepath | hash sha256 )
110+ let expected = ($checksum_text | lines | first | split row " " | first )
111+
112+ if $file_hash == $expected {
113+ print $" [OK] sha256 verified for ($filename )"
114+ } else {
115+ error make { msg : (" sha256 mismatch: " + " \' " + $file_hash + " \' vs \' " + $expected + " \' " ) }
116+ }
117+
118+ # write image
119+ # for Omni change bs to 1M
120+ # OI example:
121+ # sudo dd bs=4M if=$filepath of=[TODO]/dev/sda status=progress conv=fsync
122+ # actual cmd example
123+ # sudo dd bs=4M if=($env.Home)/soft/images/OI/OI-hipster-text-20250914.usb of=/dev/sda status=progress conv=fsync
124+
125+ # warning all data will be destroyed..
126+ #
127+ }
0 commit comments