Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
bce1ec14f1 | |||
57064a39b6 | |||
7c85855281 | |||
7325ee1c0c | |||
4a12e1ba8f | |||
2df68d3fca | |||
5fd3a9d925 |
@ -6,3 +6,4 @@ go.work.sum
|
||||
modd.*conf
|
||||
test-initrd*
|
||||
test-initrd/**/*
|
||||
target
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
||||
/tmp
|
||||
/go.work
|
||||
/go.work.sum
|
||||
/target
|
||||
|
576
Cargo.lock
generated
Normal file
576
Cargo.lock
generated
Normal file
@ -0,0 +1,576 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "init"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"shell-escape",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.199"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.199"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-escape"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "init"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
env_logger = "0.11.3"
|
||||
log = "0.4.21"
|
||||
serde = { version = "1.0.198", features = ["derive"] }
|
||||
serde_json = "1.0.116"
|
||||
serde_yaml = "0.9.34"
|
||||
shell-escape = "0.1.5"
|
||||
tokio = { version = "1.38.0", features = ["rt", "signal", "process", "macros"] }
|
30
Dockerfile
30
Dockerfile
@ -1,4 +1,18 @@
|
||||
from golang:1.21.6-alpine3.19 as build
|
||||
# ------------------------------------------------------------------------
|
||||
from rust:1.79.0-alpine3.20 as rust
|
||||
|
||||
run apk add --no-cache musl-dev # pkgconfig cryptsetup-dev lvm2-dev clang-dev clang-static
|
||||
|
||||
workdir /src
|
||||
copy Cargo.* .
|
||||
copy src src
|
||||
run --mount=type=cache,id=novit-rs,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,id=novit-rs-target,sharing=private,target=/src/target \
|
||||
cargo build --release && cp target/release/init / \
|
||||
&& strip /init
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
from golang:1.22.4-alpine3.20 as build
|
||||
|
||||
workdir /src
|
||||
|
||||
@ -11,24 +25,26 @@ run \
|
||||
&& go build -o /go/bin/init -trimpath .
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
from alpine:3.19.0 as initrd
|
||||
from alpine:3.20.0 as initrd
|
||||
|
||||
run apk add --no-cache xz
|
||||
|
||||
workdir /layer
|
||||
run wget -O- https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/x86_64/alpine-minirootfs-3.18.4-x86_64.tar.gz |tar zxv
|
||||
run . /etc/os-release \
|
||||
&& wget -O- https://dl-cdn.alpinelinux.org/alpine/v${VERSION_ID%.*}/releases/x86_64/alpine-minirootfs-${VERSION_ID}-x86_64.tar.gz |tar zxv
|
||||
|
||||
run apk add --no-cache -p . musl lvm2 lvm2-dmeventd udev cryptsetup e2fsprogs btrfs-progs lsblk
|
||||
run apk add --no-cache -p . musl coreutils lvm2 lvm2-extra lvm2-dmeventd udev cryptsetup e2fsprogs btrfs-progs lsblk
|
||||
run rm -rf usr/share/apk var/cache/apk
|
||||
|
||||
copy --from=build /go/bin/init .
|
||||
#copy --from=build /go/bin/init .
|
||||
copy --from=rust /init /layer/init
|
||||
|
||||
# check viability
|
||||
run chroot /layer /init hello
|
||||
run chroot . /init hello
|
||||
|
||||
run find |cpio -H newc -o >/initrd
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
from alpine:3.19.0
|
||||
from alpine:3.20.0
|
||||
copy --from=initrd /initrd /
|
||||
entrypoint ["base64","/initrd"]
|
||||
|
5
Dockerfile.build
Normal file
5
Dockerfile.build
Normal file
@ -0,0 +1,5 @@
|
||||
from rust:1.77.1-alpine as rust
|
||||
|
||||
run apk add --no-cache musl-dev
|
||||
run apk add --no-cache musl lvm2 lvm2-extra lvm2-dmeventd udev cryptsetup e2fsprogs btrfs-progs lsblk
|
||||
|
2
Dockerfile.test
Normal file
2
Dockerfile.test
Normal file
@ -0,0 +1,2 @@
|
||||
from alpine:3.19.0
|
||||
run apk add --no-cache musl lvm2 lvm2-extra lvm2-dmeventd udev cryptsetup e2fsprogs btrfs-progs lsblk
|
@ -12,52 +12,10 @@ import (
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"novit.tech/direktil/pkg/config/apply"
|
||||
"novit.tech/direktil/pkg/sysfs"
|
||||
)
|
||||
|
||||
var loopOffset = 0
|
||||
|
||||
func bootV1() {
|
||||
log.Info().Msg("-- boot v1 --")
|
||||
|
||||
// find and mount /boot
|
||||
bootMatch := param("boot", "")
|
||||
bootMounted := false
|
||||
if bootMatch != "" {
|
||||
bootFS := param("boot.fs", "vfat")
|
||||
for i := 0; ; i++ {
|
||||
devNames := sysfs.DeviceByProperty("block", bootMatch)
|
||||
|
||||
if len(devNames) == 0 {
|
||||
if i > 30 {
|
||||
fatal("boot partition not found after 30s")
|
||||
}
|
||||
log.Info().Msg("boot partition not found, retrying")
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
devFile := filepath.Join("/dev", devNames[0])
|
||||
|
||||
log.Info().Str("dev", devFile).Msg("boot partition found")
|
||||
|
||||
mount(devFile, "/boot", bootFS, bootMountFlags, "")
|
||||
bootMounted = true
|
||||
break
|
||||
}
|
||||
} else {
|
||||
log.Info().Msg("Assuming /boot is already populated.")
|
||||
}
|
||||
|
||||
// load config
|
||||
cfgPath := param("config", "/boot/config.yaml")
|
||||
|
||||
layersDir = filepath.Join("/boot", bootVersion, "layers")
|
||||
applyConfig(cfgPath, bootMounted)
|
||||
|
||||
finalizeBoot()
|
||||
}
|
||||
|
||||
func applyConfig(cfgPath string, bootMounted bool) (cfg *configV1) {
|
||||
cfgBytes, err := os.ReadFile(cfgPath)
|
||||
if err != nil {
|
||||
@ -139,12 +97,6 @@ func applyConfig(cfgPath string, bootMounted bool) (cfg *configV1) {
|
||||
}
|
||||
}
|
||||
|
||||
// - write configuration
|
||||
log.Info().Msg("writing /config.yaml")
|
||||
if err := os.WriteFile("/system/config.yaml", cfgBytes, 0600); err != nil {
|
||||
fatal("failed: ", err)
|
||||
}
|
||||
|
||||
// - write files
|
||||
apply.Files(cfg.Files, "/system")
|
||||
|
||||
@ -186,11 +138,3 @@ func applyConfig(cfgPath string, bootMounted bool) (cfg *configV1) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func finalizeBoot() {
|
||||
// switch root
|
||||
log.Info().Msg("switching root")
|
||||
err := syscall.Exec("/sbin/switch_root", []string{"switch_root",
|
||||
"-c", "/dev/console", "/system", "/sbin/init"}, os.Environ())
|
||||
fatal("switch_root failed: ", err)
|
||||
}
|
@ -6,41 +6,51 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
func askSecret(prompt string) []byte {
|
||||
stdinTTY.EchoOff()
|
||||
var (
|
||||
inputTTYs = new(sync.Map)
|
||||
askingSecret atomic.Bool
|
||||
)
|
||||
|
||||
var (
|
||||
in io.Reader = stdin
|
||||
out io.Writer = stdout
|
||||
)
|
||||
func registerInput(in *tty) { inputTTYs.Store(in, in) }
|
||||
func unregiterInput(in *tty) { inputTTYs.Delete(in) }
|
||||
|
||||
if stdin == nil {
|
||||
in = os.Stdin
|
||||
out = os.Stdout
|
||||
}
|
||||
func askSecret(prompt string) (s []byte) {
|
||||
err := func() (err error) {
|
||||
askingSecret.Store(true)
|
||||
defer askingSecret.Store(false)
|
||||
|
||||
out.Write([]byte(prompt + ": "))
|
||||
inputTTYs.Range(func(k, v any) (con bool) { v.(*tty).EchoOff(); return true })
|
||||
defer inputTTYs.Range(func(k, v any) (con bool) { v.(*tty).Restore(); return true })
|
||||
|
||||
if stdin != nil {
|
||||
stdout.HideInput()
|
||||
}
|
||||
var (
|
||||
in io.Reader = stdin
|
||||
out io.Writer = stdout
|
||||
)
|
||||
|
||||
s, err := bufio.NewReader(in).ReadBytes('\n')
|
||||
if stdin == nil {
|
||||
in = os.Stdin
|
||||
out = os.Stdout
|
||||
}
|
||||
|
||||
if stdin != nil {
|
||||
stdout.ShowInput()
|
||||
}
|
||||
out.Write([]byte(prompt + ": "))
|
||||
|
||||
stdinTTY.Restore()
|
||||
s, err = bufio.NewReader(in).ReadBytes('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
s = bytes.TrimRight(s, "\r\n")
|
||||
return
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
fatalf("failed to read from stdin: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
|
||||
s = bytes.TrimRight(s, "\r\n")
|
||||
return s
|
||||
return
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/yaml.v3"
|
||||
@ -99,3 +100,11 @@ func bootV2() {
|
||||
// finalize
|
||||
finalizeBoot()
|
||||
}
|
||||
|
||||
func finalizeBoot() {
|
||||
// switch root
|
||||
log.Info().Msg("switching root")
|
||||
err := syscall.Exec("/sbin/switch_root", []string{"switch_root",
|
||||
"-c", "/dev/console", "/system", "/sbin/init"}, os.Environ())
|
||||
fatal("switch_root failed: ", err)
|
||||
}
|
||||
|
@ -81,6 +81,13 @@ func bootstrap(cfg *config.Config) {
|
||||
layersOverride["modules"] = "/modules.sqfs"
|
||||
sysCfg := applyConfig(sysCfgPath, false)
|
||||
|
||||
// load requested modules
|
||||
for _, mod := range sysCfg.Modules {
|
||||
log.Info().Str("module", mod).Msg("loading module")
|
||||
run("modprobe", mod)
|
||||
}
|
||||
|
||||
// localy-generated assets dir
|
||||
localGenDir := filepath.Join(bsDir, "local-gen")
|
||||
|
||||
// vpns are v2+
|
||||
@ -118,7 +125,7 @@ func bootstrap(cfg *config.Config) {
|
||||
}
|
||||
|
||||
// update-ca-certificates
|
||||
log.Info().Msg("updating CA certifices")
|
||||
log.Info().Msg("updating CA certificates")
|
||||
run("chroot", "/system", "update-ca-certificates")
|
||||
}
|
||||
|
||||
|
27
build-init
Executable file
27
build-init
Executable file
@ -0,0 +1,27 @@
|
||||
set -ex
|
||||
|
||||
which podman &>/dev/null && docker=podman || docker=docker
|
||||
|
||||
mkdir -p empty
|
||||
$docker build -t nv-rs-build --network=host -f Dockerfile.build empty
|
||||
|
||||
case $1 in
|
||||
release)
|
||||
opts=--release
|
||||
bindir=target/release
|
||||
;;
|
||||
"")
|
||||
bindir=target/debug
|
||||
;;
|
||||
*)
|
||||
echo >&2 "invalid arg: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
$docker run --rm -i --net=host --user=$UID \
|
||||
nv-rs-build \
|
||||
cargo build $opts
|
||||
|
||||
mkdir -p dist
|
||||
cp $bindir/init dist/
|
5
go.mod
5
go.mod
@ -1,8 +1,8 @@
|
||||
module novit.tech/direktil/initrd
|
||||
|
||||
require (
|
||||
github.com/creack/pty v1.1.21
|
||||
github.com/freddierice/go-losetup/v2 v2.0.1
|
||||
github.com/kr/pty v1.1.8
|
||||
github.com/pkg/term v1.1.0
|
||||
github.com/rs/zerolog v1.31.0
|
||||
golang.org/x/crypto v0.18.0
|
||||
@ -11,12 +11,11 @@ require (
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
novit.tech/direktil/pkg v0.0.0-20240120153454-29595df7b8ff
|
||||
novit.tech/direktil/pkg v0.0.0-20240120172717-8498a102796f
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cavaliergopher/cpio v1.0.1 // indirect
|
||||
github.com/creack/pty v1.1.21 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
|
62
go.sum
62
go.sum
@ -1,44 +1,25 @@
|
||||
github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM=
|
||||
github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
|
||||
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/freddierice/go-losetup/v2 v2.0.1 h1:wPDx/Elu9nDV8y/CvIbEDz5Xi5Zo80y4h7MKbi3XaAI=
|
||||
github.com/freddierice/go-losetup/v2 v2.0.1/go.mod h1:TEyBrvlOelsPEhfWD5rutNXDmUszBXuFnwT1kIQF4J8=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mdlayher/genetlink v1.3.1 h1:roBiPnual+eqtRkKX2Jb8UQN5ZPWnhDCGj/wR6Jlz2w=
|
||||
github.com/mdlayher/genetlink v1.3.1/go.mod h1:uaIPxkWmGk753VVIzDtROxQ8+T+dkHqOI0vB1NA9S/Q=
|
||||
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
|
||||
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
|
||||
github.com/mdlayher/netlink v1.7.1 h1:FdUaT/e33HjEXagwELR8R3/KL1Fq5x3G5jgHLp/BTmg=
|
||||
github.com/mdlayher/netlink v1.7.1/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
|
||||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
|
||||
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
|
||||
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
|
||||
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||
@ -49,71 +30,47 @@ github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
@ -123,28 +80,15 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c h1:Okh6a1xpnJslG9Mn84pId1Mn+Q8cvpo4HCeeFWHo0cA=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb h1:c5tyN8sSp8jSDxdCCDXVOpJwYXXhmTkNMt+g0zTSOic=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb h1:9aqVcYEDHmSNb0uOWukxV5lHV09WqiSiCuhEgWNETLY=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb/go.mod h1:mQqgjkW8GQQcJQsbBvK890TKqUK1DfKWkuBGbOkuMHQ=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
novit.nc/direktil/pkg v0.0.0-20220221171542-fd3ce3a1491b/go.mod h1:zwTVO6U0tXFEaga73megQIBK7yVIKZJVePaIh/UtdfU=
|
||||
novit.tech/direktil/pkg v0.0.0-20230201224712-5e39572dc50e h1:eQFbzcuB4wOSrnOhkcN30hFDCIack40VkIoqVRbWnWc=
|
||||
novit.tech/direktil/pkg v0.0.0-20230201224712-5e39572dc50e/go.mod h1:2Mir5x1eT/e295WeFGzzXa4siunKX4z+rmNPfVsXS0k=
|
||||
novit.tech/direktil/pkg v0.0.0-20231217121409-827fa62f58aa h1:eBk9nQTxIJU5cT8aJVjfRWiUd4sv8YV0kXALbSFOKdI=
|
||||
novit.tech/direktil/pkg v0.0.0-20231217121409-827fa62f58aa/go.mod h1:AYEEjNi7ljJG+V4F4LzxWntfbSs+KnNPO3kqvcEzIU4=
|
||||
novit.tech/direktil/pkg v0.0.0-20240120153454-29595df7b8ff h1:GctOfnciAzBRoEOxFulavphO3vSVj1jR6DZVlyGueJU=
|
||||
novit.tech/direktil/pkg v0.0.0-20240120153454-29595df7b8ff/go.mod h1:zjezU6tELE880oYHs/WAauGBupKIEQQ7KqWTB69RW10=
|
||||
novit.tech/direktil/pkg v0.0.0-20240120172717-8498a102796f h1:7y11nLhChrrsLQwRaW7wn/9x+Xn2gEVtzj75VkOpJ+o=
|
||||
novit.tech/direktil/pkg v0.0.0-20240120172717-8498a102796f/go.mod h1:zjezU6tELE880oYHs/WAauGBupKIEQQ7KqWTB69RW10=
|
||||
|
9
main.go
9
main.go
@ -44,6 +44,8 @@ func newPipe() (io.ReadCloser, io.WriteCloser) {
|
||||
func main() {
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
|
||||
registerInput(newTTY(os.Stdin.Fd()))
|
||||
|
||||
switch baseName := filepath.Base(os.Args[0]); baseName {
|
||||
case "init":
|
||||
runInit()
|
||||
@ -88,11 +90,8 @@ func runInit() {
|
||||
|
||||
_, err := os.Stat("/config.yaml")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
bootV1()
|
||||
return
|
||||
}
|
||||
fatal("stat failed: ", err)
|
||||
log.Error().Err(err).Msg("config not found")
|
||||
fatal()
|
||||
}
|
||||
|
||||
bootV2()
|
||||
|
14
modd.conf
14
modd.conf
@ -7,8 +7,16 @@ go.??? **/*.go {
|
||||
prep: go build -o dist/ ./tools/...
|
||||
}
|
||||
|
||||
dist/init Dockerfile {
|
||||
prep: docker build -t novit-initrd-gen .
|
||||
prep: docker run novit-initrd-gen |base64 -d >dist/initrd.new
|
||||
**/*.rs Cargo.* {
|
||||
prep: cargo test
|
||||
#prep: cargo build
|
||||
prep: docker build --network host -t novit-initrd-gen .
|
||||
prep: docker run --net=host --rm novit-initrd-gen |base64 -d >dist/initrd.new
|
||||
prep: mv dist/initrd.new dist/initrd
|
||||
}
|
||||
|
||||
#dist/init Dockerfile {
|
||||
# prep: docker build --network host -t novit-initrd-gen .
|
||||
# prep: docker run --net=host --rm novit-initrd-gen |base64 -d >dist/initrd.new
|
||||
# prep: mv dist/initrd.new dist/initrd
|
||||
#}
|
||||
|
2
run-docker
Executable file
2
run-docker
Executable file
@ -0,0 +1,2 @@
|
||||
docker build -t nv-initrd-test -f Dockerfile.test empty
|
||||
docker run -d --name nv-initrd-test -it --privileged -v $PWD:/src --workdir /src/test-initrd nv-initrd-test
|
@ -10,7 +10,8 @@ if ! [ -e $disk2 ]; then
|
||||
qemu-img create -f qcow2 $disk2 10G
|
||||
fi
|
||||
|
||||
exec qemu-system-x86_64 -pidfile qemu.pid -kernel test-kernel -initrd test-initrd.cpio \
|
||||
exec qemu-system-x86_64 -pidfile qemu.pid \
|
||||
-kernel test-kernel -initrd test-initrd.cpio \
|
||||
-smp 2 -m 2048 \
|
||||
-netdev bridge,br=novit,id=eth0 -device virtio-net-pci,netdev=eth0 \
|
||||
-drive file=$disk1,if=virtio \
|
||||
|
1
src/bootstrap.rs
Normal file
1
src/bootstrap.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod config;
|
145
src/bootstrap/config.rs
Normal file
145
src/bootstrap/config.rs
Normal file
@ -0,0 +1,145 @@
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Config {
|
||||
anti_phishing_code: String,
|
||||
|
||||
keymap: Option<String>,
|
||||
modules: String,
|
||||
|
||||
auths: Vec<Auth>,
|
||||
|
||||
networks: Vec<Network>,
|
||||
|
||||
#[serde(default)]
|
||||
ssh: SSHServer,
|
||||
|
||||
#[serde(default)]
|
||||
pre_lvm_crypt: Vec<CryptDev>,
|
||||
#[serde(default)]
|
||||
lvm: Vec<LvmVG>,
|
||||
#[serde(default)]
|
||||
crypt: Vec<CryptDev>,
|
||||
|
||||
bootstrap: Bootstrap,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Auth {
|
||||
name: String,
|
||||
#[serde(rename = "sshKey")]
|
||||
ssh_key: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Network {
|
||||
name: String,
|
||||
interfaces: Vec<NetworkInterface>,
|
||||
script: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct NetworkInterface {
|
||||
pub var: String,
|
||||
pub n: i16,
|
||||
pub regexps: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct SSHServer {
|
||||
listen: String,
|
||||
keys: SSHKeys,
|
||||
}
|
||||
impl Default for SSHServer {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
listen: "[::]:22".to_string(),
|
||||
keys: SSHKeys::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct SSHKeys {
|
||||
dsa: String,
|
||||
rsa: String,
|
||||
ecdsa: String,
|
||||
ed25519: String,
|
||||
}
|
||||
impl Default for SSHKeys {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
dsa: "id_dsa".to_string(),
|
||||
rsa: "id_rsa".to_string(),
|
||||
ecdsa: "id_ecdsa".to_string(),
|
||||
ed25519: "id_ed25519".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LvmVG {
|
||||
vg: String,
|
||||
pvs: LvmPV,
|
||||
|
||||
#[serde(default)]
|
||||
defaults: LvmLVDefaults,
|
||||
|
||||
lvs: Vec<LvmLV>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LvmLVDefaults {
|
||||
#[serde(default = "default_fs")]
|
||||
fs: String,
|
||||
raid: Option<Raid>,
|
||||
}
|
||||
impl Default for LvmLVDefaults {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fs: default_fs(),
|
||||
raid: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_fs() -> String {
|
||||
"ext4".to_string()
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LvmLV {
|
||||
name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
fs: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
raid: Option<Raid>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
size: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
extents: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LvmPV {
|
||||
n: i16,
|
||||
regexps: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct CryptDev {
|
||||
name: String,
|
||||
dev: Option<String>,
|
||||
prefix: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Raid {
|
||||
mirrors: Option<u8>,
|
||||
stripes: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Bootstrap {
|
||||
dev: String,
|
||||
seed: String,
|
||||
}
|
27
src/lsblk.rs
Normal file
27
src/lsblk.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Report {
|
||||
pub blockdevices: Vec<BlockDev>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct BlockDev {
|
||||
pub name: String,
|
||||
#[serde(rename = "maj:min")]
|
||||
pub maj_min: String,
|
||||
pub rm: bool,
|
||||
pub size: String,
|
||||
pub ro: bool,
|
||||
#[serde(rename = "type")]
|
||||
pub dev_type: String,
|
||||
pub mountpoints: Vec<Option<String>>,
|
||||
#[serde(default)]
|
||||
pub children: Vec<BlockDev>,
|
||||
}
|
||||
|
||||
pub fn report() -> io::Result<Report> {
|
||||
let output = Command::new("lsblk").arg("--json").output()?;
|
||||
Ok(serde_json::from_slice(output.stdout.as_slice()).unwrap())
|
||||
}
|
84
src/lvm.rs
Normal file
84
src/lvm.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
struct Report {
|
||||
report: Vec<ReportObj>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
enum ReportObj {
|
||||
PV { pv: Vec<PV> },
|
||||
VG { vg: Vec<VG> },
|
||||
LV { lv: Vec<LV> },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct PV {
|
||||
pub pv_name: String,
|
||||
pub vg_name: String,
|
||||
pub pv_fmt: String,
|
||||
pub pv_attr: String,
|
||||
pub pv_size: String,
|
||||
pub pv_free: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VG {
|
||||
pub vg_name: String,
|
||||
pub pv_count: String,
|
||||
pub lv_count: String,
|
||||
pub snap_count: String,
|
||||
pub vg_attr: String,
|
||||
pub vg_size: String,
|
||||
pub vg_free: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LV {
|
||||
lv_name: String,
|
||||
vg_name: String,
|
||||
lv_attr: String,
|
||||
lv_size: String,
|
||||
pool_lv: String,
|
||||
origin: String,
|
||||
data_percent: String,
|
||||
metadata_percent: String,
|
||||
move_pv: String,
|
||||
mirror_log: String,
|
||||
copy_percent: String,
|
||||
convert_lv: String,
|
||||
}
|
||||
|
||||
pub fn pvs() -> io::Result<Vec<PV>> {
|
||||
report_cmd("pvs", |o| match o {
|
||||
ReportObj::PV { pv } => Some(pv),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn vgs() -> io::Result<Vec<VG>> {
|
||||
report_cmd("vgs", |o| match o {
|
||||
ReportObj::VG { vg } => Some(vg),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lvs() -> io::Result<Vec<LV>> {
|
||||
report_cmd("lvs", |o| match o {
|
||||
ReportObj::LV { lv } => Some(lv),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn report_cmd<T>(cmd: &str, find: fn(ReportObj) -> Option<Vec<T>>) -> io::Result<Vec<T>> {
|
||||
let output = Command::new(cmd).arg("--reportformat=json").output()?;
|
||||
let report: Report = serde_json::from_slice(output.stdout.as_slice()).unwrap();
|
||||
Ok(report
|
||||
.report
|
||||
.into_iter()
|
||||
.filter_map(find)
|
||||
.flatten()
|
||||
.collect())
|
||||
}
|
169
src/main.rs
Normal file
169
src/main.rs
Normal file
@ -0,0 +1,169 @@
|
||||
mod bootstrap;
|
||||
mod lsblk;
|
||||
mod lvm;
|
||||
|
||||
use anyhow::format_err;
|
||||
use log::error;
|
||||
use std::io;
|
||||
use std::process::{exit, Command};
|
||||
use std::{env, fs};
|
||||
|
||||
fn main() {
|
||||
if let None = env::var_os("RUST_LOG") {
|
||||
env::set_var("RUST_LOG", "info");
|
||||
}
|
||||
env_logger::init();
|
||||
|
||||
env::set_var("PATH", "/bin:/sbin");
|
||||
|
||||
if let Some(arg) = env::args().into_iter().nth(1) {
|
||||
match arg.as_str() {
|
||||
"hello" => println!("hello"),
|
||||
_ => {
|
||||
error!("invalid arg: {arg}");
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
exit(0);
|
||||
}
|
||||
|
||||
let cfg: bootstrap::config::Config = retry(|| {
|
||||
let cfg = fs::read("config.yaml").map_err(|e| format_err!("failed to read config: {e}"))?;
|
||||
serde_yaml::from_slice(cfg.as_slice())
|
||||
.map_err(|e| format_err!("failed to parse config: {e}"))
|
||||
});
|
||||
|
||||
serde_yaml::to_writer(io::stdout(), &cfg).unwrap();
|
||||
|
||||
mount("none", "/proc", "proc", None);
|
||||
mount("none", "/sys", "sysfs", None);
|
||||
mount("none", "/dev", "devtmpfs", None);
|
||||
mount("none", "/dev/pts", "devpts", Some("gid=5,mode=620"));
|
||||
|
||||
exec("ash", vec!["-c", "set -ex; pvs; false"]);
|
||||
|
||||
for pv in lvm::pvs().unwrap() {
|
||||
println!("pv: {pv:?}");
|
||||
}
|
||||
for vg in lvm::vgs().unwrap() {
|
||||
println!("vg: {vg:?}");
|
||||
}
|
||||
for lv in lvm::lvs().unwrap() {
|
||||
println!("lv: {lv:?}");
|
||||
}
|
||||
|
||||
println!("lsblk: {:?}", lsblk::report());
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn mount(src: &str, dst: &str, fstype: &str, opts: Option<&str>) {
|
||||
let _ = fs::create_dir_all(dst).inspect_err(|e| error!("failed to create dir {dst}: {e}"));
|
||||
|
||||
let mut args = vec![src, dst, "-t", fstype];
|
||||
if let Some(opts) = opts {
|
||||
args.extend(["-o", opts]);
|
||||
}
|
||||
exec("mount", args);
|
||||
}
|
||||
|
||||
fn exec(prog: &str, args: Vec<&str>) {
|
||||
let cmd_str = sh_str(prog, &args);
|
||||
retry_or_ignore(|| {
|
||||
println!("\x1b[34m# {cmd_str}\x1b[0m");
|
||||
let mut cmd = Command::new(prog);
|
||||
cmd.args(args.clone());
|
||||
let s = cmd.status()?;
|
||||
if s.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format_err!("command failed: {s}"))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn retry_or_ignore(action: impl Fn() -> anyhow::Result<()>) {
|
||||
loop {
|
||||
match action() {
|
||||
Ok(_) => return,
|
||||
Err(e) => {
|
||||
eprintln!("\x1b[31m{e}\x1b[0m");
|
||||
|
||||
loop {
|
||||
eprint!("[r]etry, [i]gnore, or [s]hell? ");
|
||||
|
||||
let mut line = String::new();
|
||||
io::stdin().read_line(&mut line).unwrap();
|
||||
|
||||
match line.trim() {
|
||||
"r" => break,
|
||||
"i" => return,
|
||||
"s" => {
|
||||
exec_shell();
|
||||
break;
|
||||
}
|
||||
v => {
|
||||
eprintln!("invalid choice: {v:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn retry<T>(action: impl Fn() -> anyhow::Result<T>) -> T {
|
||||
loop {
|
||||
match action() {
|
||||
Ok(v) => return v,
|
||||
Err(e) => {
|
||||
eprintln!("\x1b[31m{e}\x1b[0m");
|
||||
|
||||
loop {
|
||||
eprint!("[r]etry, or [s]hell? ");
|
||||
|
||||
let mut line = String::new();
|
||||
io::stdin().read_line(&mut line).unwrap();
|
||||
|
||||
match line.trim() {
|
||||
"r" => break,
|
||||
"s" => {
|
||||
exec_shell();
|
||||
break;
|
||||
}
|
||||
v => {
|
||||
eprintln!("invalid choice: {v:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_shell() {
|
||||
let mut child = match Command::new("ash").spawn() {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
error!("failed to exec shell: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let _ = child.wait();
|
||||
}
|
||||
|
||||
fn sh_str(prog: &str, args: &Vec<&str>) -> String {
|
||||
use std::borrow::Cow;
|
||||
|
||||
let mut buf = String::new();
|
||||
|
||||
buf.push_str(&shell_escape::escape(Cow::from(prog)));
|
||||
|
||||
for &arg in args {
|
||||
buf.push(' ');
|
||||
buf.push_str(&shell_escape::escape(Cow::from(arg)));
|
||||
}
|
||||
|
||||
buf
|
||||
}
|
58
ssh.go
58
ssh.go
@ -9,9 +9,10 @@ import (
|
||||
"os/exec"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/kr/pty"
|
||||
"github.com/creack/pty"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
@ -142,14 +143,35 @@ func sshHandleChannel(remoteAddr string, channel ssh.Channel, requests <-chan *s
|
||||
command := string(req.Payload[4 : req.Payload[3]+4])
|
||||
switch command {
|
||||
case "init":
|
||||
go func() {
|
||||
io.Copy(channel, stdout.NewReader())
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(stdinPipe, channel)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
if ptyF == nil {
|
||||
go func() {
|
||||
channel.Stderr().Write([]byte("\033[5m\033[31;1m\n\nWARNING: no TTY requested, passwords will be echoed!\n\n\033[0m"))
|
||||
time.Sleep(3 * time.Second)
|
||||
io.Copy(channel, stdout.NewReader())
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(stdinPipe, channel)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
|
||||
} else {
|
||||
stdinTTY := newTTY(ptyF.Fd())
|
||||
if askingSecret.Load() {
|
||||
stdinTTY.EchoOff()
|
||||
}
|
||||
registerInput(stdinTTY)
|
||||
defer unregiterInput(stdinTTY)
|
||||
|
||||
go func() {
|
||||
io.Copy(ttyF, stdout.NewReader())
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(stdinPipe, ttyF)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
}
|
||||
|
||||
req.Reply(true, nil)
|
||||
|
||||
@ -195,15 +217,6 @@ func sshHandleChannel(remoteAddr string, channel ssh.Channel, requests <-chan *s
|
||||
ttyF = nil
|
||||
}()
|
||||
|
||||
go func() {
|
||||
io.Copy(channel, ptyF)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(ptyF, channel)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
|
||||
req.Reply(true, nil)
|
||||
|
||||
case "pty-req":
|
||||
@ -227,6 +240,15 @@ func sshHandleChannel(remoteAddr string, channel ssh.Channel, requests <-chan *s
|
||||
|
||||
req.Reply(true, nil)
|
||||
|
||||
go func() {
|
||||
io.Copy(channel, ptyF)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(ptyF, channel)
|
||||
once.Do(closeCh)
|
||||
}()
|
||||
|
||||
case "window-change":
|
||||
w, h := sshParseDims(req.Payload)
|
||||
sshSetWinsize(ptyF.Fd(), w, h)
|
||||
|
@ -26,9 +26,9 @@ networks:
|
||||
- eno.*
|
||||
- enp.*
|
||||
script: |
|
||||
ip a add 2001:41d0:306:168f::1337:2eed/64 dev $iface
|
||||
ip li set $iface up
|
||||
#udhcpc $iface
|
||||
udhcpc -i $iface -b -t1 -T1 -A5 ||
|
||||
ip a add 2001:41d0:306:168f::1337:2eed/64 dev $iface
|
||||
|
||||
pre_lvm_crypt:
|
||||
- dev: /dev/vda
|
||||
|
Binary file not shown.
BIN
test-kernel
BIN
test-kernel
Binary file not shown.
25
tty.go
25
tty.go
@ -1,29 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
stdinTTY = &tty{int(os.Stdin.Fd()), nil}
|
||||
)
|
||||
|
||||
type tty struct {
|
||||
fd int
|
||||
termios *unix.Termios
|
||||
}
|
||||
|
||||
func newTTY(fd uintptr) *tty {
|
||||
termios, _ := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
||||
return &tty{int(fd), termios}
|
||||
}
|
||||
|
||||
func (t *tty) EchoOff() {
|
||||
termios, err := unix.IoctlGetTermios(t.fd, unix.TCGETS)
|
||||
if err != nil {
|
||||
if t.termios == nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.termios = termios
|
||||
|
||||
newState := *termios
|
||||
newState := *t.termios
|
||||
newState.Lflag &^= unix.ECHO
|
||||
newState.Lflag |= unix.ICANON | unix.ISIG
|
||||
newState.Iflag |= unix.ICRNL
|
||||
@ -31,8 +27,9 @@ func (t *tty) EchoOff() {
|
||||
}
|
||||
|
||||
func (t *tty) Restore() {
|
||||
if t.termios != nil {
|
||||
unix.IoctlSetTermios(t.fd, unix.TCSETS, t.termios)
|
||||
t.termios = nil
|
||||
if t.termios == nil {
|
||||
return
|
||||
}
|
||||
|
||||
unix.IoctlSetTermios(t.fd, unix.TCSETS, t.termios)
|
||||
}
|
||||
|
Reference in New Issue
Block a user