From 15ffe1a2581be72300127c5eb0c61d201f27e062 Mon Sep 17 00:00:00 2001 From: Sergio <77530549+sergi0g@users.noreply.github.com> Date: Wed, 13 Aug 2025 11:59:48 +0300 Subject: [PATCH] wip --- Cargo.lock | 1343 ++++++++++++++++++++++++++++++++++ cup/Cargo.toml | 1 + cup/src/auth.rs | 51 ++ cup/src/docker.rs | 10 + cup/src/image_config.rs | 13 + cup/src/image_to_check.rs | 3 + cup/src/lib.rs | 111 ++- cup/src/reference.rs | 5 + cup/src/reference_matcher.rs | 38 + cup/src/registry.rs | 49 ++ cup/src/registry_config.rs | 9 + cup/src/socket.rs | 7 + cup/src/version/digest.rs | 1 + cup/src/version/extended.rs | 68 +- cup/src/version/mod.rs | 13 + cup/src/version/standard.rs | 51 +- 16 files changed, 1717 insertions(+), 56 deletions(-) create mode 100644 cup/src/auth.rs create mode 100644 cup/src/docker.rs create mode 100644 cup/src/image_config.rs create mode 100644 cup/src/image_to_check.rs create mode 100644 cup/src/reference.rs create mode 100644 cup/src/reference_matcher.rs create mode 100644 cup/src/registry.rs create mode 100644 cup/src/registry_config.rs create mode 100644 cup/src/socket.rs create mode 100644 cup/src/version/digest.rs diff --git a/Cargo.lock b/Cargo.lock index 811927e..98007e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -11,10 +26,150 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bollard" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8796b390a5b4c86f9f2e8173a68c2791f4fa6b038b84e96dbc01c016d1e6722c" +dependencies = [ + "base64", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "http", + "http-body-util", + "hyper", + "hyper-named-pipe", + "hyper-util", + "hyperlocal", + "log", + "pin-project-lite", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-stubs" +version = "1.49.0-rc.28.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7814991259013d5a5bee4ae28657dae0747d843cf06c40f7fc0c2894d6fa38" +dependencies = [ + "serde", + "serde_json", + "serde_repr", + "serde_with", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cup" version = "4.0.0" dependencies = [ + "bollard", "regex", "rustc-hash", ] @@ -27,12 +182,572 @@ version = "4.0.0" name = "cup_server" version = "4.0.0" +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", + "serde", +] + +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + [[package]] name = "memchr" version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.11.1" @@ -62,8 +777,636 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", + "serde", + "serde_derive", + "serde_json", + "time", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc3fcb250e53458e712715cf74285c1f889686520d79294a9ef3bd7aa1fc619" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "windows-sys", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/cup/Cargo.toml b/cup/Cargo.toml index e031966..56c5e0d 100644 --- a/cup/Cargo.toml +++ b/cup/Cargo.toml @@ -6,5 +6,6 @@ edition = "2024" [lib] [dependencies] +bollard = "0.19.2" regex = "1.11.1" rustc-hash = "2.1.1" diff --git a/cup/src/auth.rs b/cup/src/auth.rs new file mode 100644 index 0000000..8ae55da --- /dev/null +++ b/cup/src/auth.rs @@ -0,0 +1,51 @@ +use std::{fmt::Display, str::FromStr}; + +pub struct AuthToken { + token_type: TokenType, + value: String, +} + +enum TokenType { + Basic, + Bearer, +} + +impl Display for TokenType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Basic => "Basic", + Self::Bearer => "Bearer", + } + ) + } +} + +impl AuthToken { + pub fn from_basic(token: &str) -> Self { + Self { + token_type: TokenType::Basic, + value: token.to_string() + } + } + + pub fn from_bearer(token: &str) -> Self { + Self { + token_type: TokenType::Bearer, + value: token.to_string() + } + } + + pub fn get_type(&self) -> &'static str { + match &self.token_type { + TokenType::Basic => "Basic", + TokenType::Bearer => "Bearer" + } + } + + pub fn get_value(&self) -> &str { + &self.value + } +} \ No newline at end of file diff --git a/cup/src/docker.rs b/cup/src/docker.rs new file mode 100644 index 0000000..f1e3bc2 --- /dev/null +++ b/cup/src/docker.rs @@ -0,0 +1,10 @@ +use crate::socket::Socket; + +/// Wraps a Docker client and provides useful functions get data from it. +pub struct Docker { + socket: Socket, + client: bollard::Docker +} + +impl Docker { +} diff --git a/cup/src/image_config.rs b/cup/src/image_config.rs new file mode 100644 index 0000000..3bf770b --- /dev/null +++ b/cup/src/image_config.rs @@ -0,0 +1,13 @@ +use crate::version::{VersionType, standard::StandardUpdateType}; + +pub struct ImageConfig { + version_type: VersionType, + // Will only be read if update type is standard + ignored_update_types: Vec, + /// Whether to skip checking the image (default is false) + ignore: bool +} + +impl ImageConfig { + +} \ No newline at end of file diff --git a/cup/src/image_to_check.rs b/cup/src/image_to_check.rs new file mode 100644 index 0000000..7ad1b93 --- /dev/null +++ b/cup/src/image_to_check.rs @@ -0,0 +1,3 @@ +pub struct ImageToCheck { + +} \ No newline at end of file diff --git a/cup/src/lib.rs b/cup/src/lib.rs index 63e99ab..c4a11f8 100644 --- a/cup/src/lib.rs +++ b/cup/src/lib.rs @@ -1 +1,110 @@ -pub mod version; \ No newline at end of file +use rustc_hash::FxHashMap; + +use crate::{ + auth::AuthToken, image_config::ImageConfig, image_to_check::ImageToCheck, reference::Reference, + reference_matcher::ReferenceMatcher, registry::Registry, registry_config::RegistryConfig, + socket::Socket, +}; + +pub mod auth; +pub mod image_config; +pub mod image_to_check; +pub mod reference; +pub mod reference_matcher; +pub mod registry; +pub mod registry_config; +pub mod socket; +pub mod version; +pub mod docker; + +/// This struct is the main interface to Cup's functions. +/// Any useful user-provided or generated data is stored here for reuse during the lifetime of the struct. +#[derive(Default)] +pub struct Cup { + images: Vec, + socket: Socket, +} + +impl<'a> Cup { + /// Returns a new empty instance with all values initialized to their defaults. + pub fn new() -> Self { + Self::default() + } + + pub fn builder() -> CupBuilder { + CupBuilder::default() + } + + /// Check for updates to the images provided (and any images configured through options) + pub async fn check(images: &[&Reference]) -> Vec> { + todo!() + } +} + +#[derive(Default)] +pub struct CupBuilder { + /// Whether or not to check for updates to local images in addition to the other images. + check_local_images: bool, + /// Whether or not to check for updates to images used in the swarm in addition to the other images. If the host is not a manager node this will only check the locally running swarm images. + check_swarm_images: bool, + registry_config: FxHashMap, + overrides: FxHashMap, + socket: Socket, +} + +impl CupBuilder { + pub fn with_local_images(&mut self) { + self.check_local_images = true + } + + pub fn with_swarm_images(&mut self) { + self.check_swarm_images = true + } + + pub fn with_registry_auth(&mut self, registry: Registry, token: AuthToken) { + match self.registry_config.get_mut(®istry) { + Some(registry_config) => registry_config.auth = Some(token), + None => { + self.registry_config.insert( + registry, + RegistryConfig { + auth: Some(token), + ..Default::default() + }, + ); + } + } + } + + pub fn with_insecure_registry(&mut self, registry: Registry) { + match self.registry_config.get_mut(®istry) { + Some(registry_config) => registry_config.insecure = true, + None => { + self.registry_config.insert( + registry, + RegistryConfig { + insecure: true, + ..Default::default() + }, + ); + } + } + } + + pub fn with_image_config(&mut self, reference: ReferenceMatcher, config: ImageConfig) { + self.overrides.insert(reference, config); + } + + pub fn with_socket(&mut self, socket: Socket) { + self.socket = socket + } + + pub fn build(&self) -> Cup { + + + todo!() + } +} + +pub struct CheckResult {} +pub struct CheckError {} diff --git a/cup/src/reference.rs b/cup/src/reference.rs new file mode 100644 index 0000000..ca21079 --- /dev/null +++ b/cup/src/reference.rs @@ -0,0 +1,5 @@ +pub struct Reference(String); + +impl Reference { + +} \ No newline at end of file diff --git a/cup/src/reference_matcher.rs b/cup/src/reference_matcher.rs new file mode 100644 index 0000000..9394f68 --- /dev/null +++ b/cup/src/reference_matcher.rs @@ -0,0 +1,38 @@ +use regex::Regex; +use std::hash::Hash; + +/// When customizing image configuration, there may be a need to operate on a batch of images. The ReferenceMatcher describes which references the configuration should apply to. +pub enum ReferenceMatcher { + /// The reference is exactly equal to the string provided + ExactMatch(String), + /// The reference starts with the string provided, useful for configuring based on a registry or repository + PrefixMatch(String), + /// The reference ends with the string provided, useful for configuring based on a tag + SuffixMatch(String), + /// The reference contains the string provided + Contains(String), + /// For more complicated matching logic a regular expression can be used. + Custom(Regex), +} + +impl PartialEq for ReferenceMatcher { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (ReferenceMatcher::Custom(a), ReferenceMatcher::Custom(b)) => a.as_str() == b.as_str(), + (a, b) => a.eq(b), + } + } +} + +impl Eq for ReferenceMatcher {} + +impl Hash for ReferenceMatcher { + fn hash(&self, state: &mut H) { + match self { + Self::Custom(r) => r.as_str().hash(state), + o => o.hash(state), + } + } +} + +impl ReferenceMatcher {} diff --git a/cup/src/registry.rs b/cup/src/registry.rs new file mode 100644 index 0000000..2461114 --- /dev/null +++ b/cup/src/registry.rs @@ -0,0 +1,49 @@ +use std::{error::Error, fmt::Display, str::FromStr, sync::OnceLock}; + +use regex::Regex; + +#[derive(PartialEq, Eq, Hash)] +pub struct Registry { + value: String, +} + +/// Regex representing the value of `domainAndPort` from https://github.com/distribution/reference/blob/727f80d42224f6696b8e1ad16b06aadf2c6b833b/regexp.go#L108 +/// Used to verify whether a string is a registry hostname +const REGISTRY_REGEX: &str = r"^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\[(?:[a-fA-F0-9:]+)\])(?::[0-9]+)?$"; +static REGISTRY: OnceLock = OnceLock::new(); + +impl FromStr for Registry { + type Err = ParseRegistryError; + + fn from_str(s: &str) -> Result { + let regex = REGISTRY.get_or_init(|| Regex::new(REGISTRY_REGEX).unwrap()); + if s.is_empty() { + Ok(Self { + value: String::from("registry-1.docker.io"), + }) + } else if regex.is_match(s) { + Ok(Self { + value: s.to_string(), + }) + } else { + Err(ParseRegistryError { + registry: s.to_string(), + }) + } + } +} + +#[derive(Debug)] +pub struct ParseRegistryError { + pub registry: String, +} + +impl Display for ParseRegistryError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "`{}` is not a valid registry hostname", self.registry) + } +} + +impl Error for ParseRegistryError {} + +// TODO: Add tests \ No newline at end of file diff --git a/cup/src/registry_config.rs b/cup/src/registry_config.rs new file mode 100644 index 0000000..8a76e7b --- /dev/null +++ b/cup/src/registry_config.rs @@ -0,0 +1,9 @@ +use crate::auth::AuthToken; + +#[derive(Default)] +pub struct RegistryConfig { + /// An optional authentication token to use when making requests to this registry + pub(super) auth: Option, + /// Whether or not to connect to the registry over unencrypted HTTP + pub(super) insecure: bool +} \ No newline at end of file diff --git a/cup/src/socket.rs b/cup/src/socket.rs new file mode 100644 index 0000000..88b3fac --- /dev/null +++ b/cup/src/socket.rs @@ -0,0 +1,7 @@ +#[derive(Default)] +pub enum Socket { + #[default] + Default, + Unix(String), + Tcp(String) +} \ No newline at end of file diff --git a/cup/src/version/digest.rs b/cup/src/version/digest.rs new file mode 100644 index 0000000..7673ac1 --- /dev/null +++ b/cup/src/version/digest.rs @@ -0,0 +1 @@ +pub struct DigestVersion {} \ No newline at end of file diff --git a/cup/src/version/extended.rs b/cup/src/version/extended.rs index 3c6da17..2e7492f 100644 --- a/cup/src/version/extended.rs +++ b/cup/src/version/extended.rs @@ -15,10 +15,10 @@ pub struct ExtendedVersion { } impl ExtendedVersion { - pub fn parse(version_string: &str, regex: &str) -> Result { - let regex = Regex::new(regex).map_err(|e| VersionParseError { + pub fn parse(version_string: &str, regex: &str) -> Result { + let regex = Regex::new(regex).map_err(|e| ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::InvalidRegex(e), + kind: ParseVersionErrorKind::InvalidRegex(e), })?; // Check if all capture groups are named or anonymous @@ -29,9 +29,9 @@ impl ExtendedVersion { match prev_state { None => Ok(Some(name)), // First iteration Some(prev_state) => match (prev_state, name) { - (Some(_), None) | (None, Some(_)) => Err(VersionParseError { + (Some(_), None) | (None, Some(_)) => Err(ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::NonUniformCaptureGroups, + kind: ParseVersionErrorKind::NonUniformCaptureGroups, }), _ => Ok(Some(name)), }, @@ -51,22 +51,22 @@ impl ExtendedVersion { .capture_names() .flatten() .map(|name| { - let capture = captures.name(name).ok_or_else(|| VersionParseError { + let capture = captures.name(name).ok_or_else(|| ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::GroupDidNotMatch(name.to_string()), + kind: ParseVersionErrorKind::GroupDidNotMatch(name.to_string()), })?; let component = VersionComponent::from_str(capture.as_str()).map_err(|_| { - VersionParseError { + ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::GroupDidNotMatch( + kind: ParseVersionErrorKind::GroupDidNotMatch( name.to_string(), ), } })?; Ok((name.to_string(), component)) }) - .collect::, VersionParseError>>( + .collect::, ParseVersionError>>( )? } else { captures @@ -77,20 +77,20 @@ impl ExtendedVersion { .map(|(i, m)| { VersionComponent::from_str(m.as_str()) .map(|comp| (i, comp)) - .map_err(|e| VersionParseError { + .map_err(|e| ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::ParseComponent(e), + kind: ParseVersionErrorKind::ParseComponent(e), }) }) - .collect::, VersionParseError>>( + .collect::, ParseVersionError>>( )? }; Self { components } } None => { - return Err(VersionParseError { + return Err(ParseVersionError { version_string: version_string.to_string(), - kind: VersionParseErrorKind::NoMatch, + kind: ParseVersionErrorKind::NoMatch, }); } }) @@ -100,12 +100,12 @@ impl ExtendedVersion { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] #[non_exhaustive] -pub struct VersionParseError { +pub struct ParseVersionError { version_string: String, - kind: VersionParseErrorKind, + kind: ParseVersionErrorKind, } -impl Display for VersionParseError { +impl Display for ParseVersionError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, @@ -115,7 +115,7 @@ impl Display for VersionParseError { } } -impl Error for VersionParseError { +impl Error for ParseVersionError { fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.kind) } @@ -123,7 +123,7 @@ impl Error for VersionParseError { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -pub enum VersionParseErrorKind { +pub enum ParseVersionErrorKind { /// The regex supplied could not be compiled InvalidRegex(regex::Error), /// The regex supplied has both named and anonymous capture groups @@ -136,7 +136,7 @@ pub enum VersionParseErrorKind { ParseComponent(ParseIntError), } -impl Display for VersionParseErrorKind { +impl Display for ParseVersionErrorKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::InvalidRegex(_) => write!(f, "invalid regex"), @@ -152,7 +152,7 @@ impl Display for VersionParseErrorKind { } } -impl Error for VersionParseErrorKind { +impl Error for ParseVersionErrorKind { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { Self::InvalidRegex(e) => Some(e), @@ -172,8 +172,8 @@ mod tests { use crate::version::version_component::VersionComponent; use super::ExtendedVersion; - use super::VersionParseError; - use super::VersionParseErrorKind; + use super::ParseVersionError; + use super::ParseVersionErrorKind; #[test] fn parse_with_anonymous() { @@ -274,9 +274,9 @@ mod tests { "1.0.0-test2", r"(\d+)\.(\d+))\.(\d+)-test(\d+)" // Whoops, someone left an extra ) somewhere... ), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("1.0.0-test2"), - kind: VersionParseErrorKind::InvalidRegex( + kind: ParseVersionErrorKind::InvalidRegex( Regex::new(r"(\d+)\.(\d+))\.(\d+)-test(\d+)").unwrap_err() ) }) @@ -287,9 +287,9 @@ mod tests { fn invalid_component() { assert_eq!( ExtendedVersion::parse("50h+2-3_40", r"([a-z0-9]+)\+(\d+)-(\d+)_(\d+)"), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("50h+2-3_40"), - kind: VersionParseErrorKind::ParseComponent("50h".parse::().unwrap_err()) + kind: ParseVersionErrorKind::ParseComponent("50h".parse::().unwrap_err()) }) ) } @@ -301,9 +301,9 @@ mod tests { "4.1.2.5", r"(?\d+)\.(?\d+)\.(?\d+)\.(\d+)" ), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("4.1.2.5"), - kind: VersionParseErrorKind::NonUniformCaptureGroups + kind: ParseVersionErrorKind::NonUniformCaptureGroups }) ) } @@ -315,9 +315,9 @@ mod tests { "1-sometool-0.2.5-alpine", r"(?:\d+)-somet0ol-(\d+)\.(\d+)\.(\d+)-alpine" ), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("1-sometool-0.2.5-alpine"), - kind: VersionParseErrorKind::NoMatch + kind: ParseVersionErrorKind::NoMatch }) ) } @@ -329,9 +329,9 @@ mod tests { "2.0.5-alpine", r"(?\d+)\.(?\d+)\.(?\d+)|(?moe)-alpine" ), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("2.0.5-alpine"), - kind: VersionParseErrorKind::GroupDidNotMatch(String::from("Moe")) + kind: ParseVersionErrorKind::GroupDidNotMatch(String::from("Moe")) }) ) } diff --git a/cup/src/version/mod.rs b/cup/src/version/mod.rs index 4615ccc..bbf5dd3 100644 --- a/cup/src/version/mod.rs +++ b/cup/src/version/mod.rs @@ -1,8 +1,10 @@ use crate::version::date::DateVersion; +use crate::version::digest::DigestVersion; use crate::version::extended::ExtendedVersion; use crate::version::standard::StandardVersion; pub mod date; +pub mod digest; pub mod extended; pub mod standard; @@ -17,6 +19,17 @@ pub enum Version { Extended(ExtendedVersion), /// The "Date" versioning schema is for images which are versioned based on date and or time and come with their own quirky rules to compare them. Refer to `DateVersion` for more info. Date(DateVersion), + /// Version checking based on local and remote image digests + Digest(DigestVersion) +} + +pub enum VersionType { + /// Tries to automatically infer the version type. + Auto, + Standard, + Extended, + Date, + Digest } mod version_component { diff --git a/cup/src/version/standard.rs b/cup/src/version/standard.rs index b5f7830..9a54b8f 100644 --- a/cup/src/version/standard.rs +++ b/cup/src/version/standard.rs @@ -1,5 +1,7 @@ use std::{error::Error, fmt::Display, num::ParseIntError, str::FromStr}; +use rustc_hash::FxHashSet; + use super::version_component::VersionComponent; /// A versioning scheme I'd call SemVer-inspired. The main difference from [SemVer](https://semver.org) is that the minor and patch versions are optional. @@ -13,28 +15,28 @@ pub struct StandardVersion { } impl FromStr for StandardVersion { - type Err = VersionParseError; + type Err = ParseVersionError; fn from_str(s: &str) -> Result { let splits = s.split('.'); if splits.clone().any(|split| split.is_empty()) { - return Err(VersionParseError { + return Err(ParseVersionError { version_string: s.to_string(), - kind: VersionParseErrorKind::IncorrectFormat, + kind: ParseVersionErrorKind::IncorrectFormat, }); } let mut component_iter = splits.map(|component| { - VersionComponent::from_str(component).map_err(|e| VersionParseError { + VersionComponent::from_str(component).map_err(|e| ParseVersionError { version_string: s.to_string(), - kind: VersionParseErrorKind::ParseComponent(e), + kind: ParseVersionErrorKind::ParseComponent(e), }) }); let major = component_iter.next().transpose()?.unwrap(); let minor = component_iter.next().transpose()?; let patch = component_iter.next().transpose()?; if component_iter.next().is_some() { - return Err(VersionParseError { + return Err(ParseVersionError { version_string: s.to_string(), - kind: VersionParseErrorKind::TooManyComponents(4 + component_iter.count()), + kind: ParseVersionErrorKind::TooManyComponents(4 + component_iter.count()), }); } Ok(Self { @@ -45,15 +47,22 @@ impl FromStr for StandardVersion { } } +#[derive(PartialEq, Eq, Hash)] +pub enum StandardUpdateType { + Major, + Minor, + Patch +} + #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] #[non_exhaustive] -pub struct VersionParseError { +pub struct ParseVersionError { pub version_string: String, - pub kind: VersionParseErrorKind, + pub kind: ParseVersionErrorKind, } -impl Display for VersionParseError { +impl Display for ParseVersionError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, @@ -63,7 +72,7 @@ impl Display for VersionParseError { } } -impl Error for VersionParseError { +impl Error for ParseVersionError { fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.kind) } @@ -71,7 +80,7 @@ impl Error for VersionParseError { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -pub enum VersionParseErrorKind { +pub enum ParseVersionErrorKind { /// A version component could not be parsed ParseComponent(ParseIntError), /// The version string is not in the format expected by `StandardVersion` @@ -80,7 +89,7 @@ pub enum VersionParseErrorKind { TooManyComponents(usize), } -impl Display for VersionParseErrorKind { +impl Display for ParseVersionErrorKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self { Self::IncorrectFormat => write!(f, "version string is incorrectly formatted"), @@ -94,7 +103,7 @@ impl Display for VersionParseErrorKind { } } -impl Error for VersionParseErrorKind { +impl Error for ParseVersionErrorKind { fn source(&self) -> Option<&(dyn Error + 'static)> { match &self { Self::ParseComponent(e) => Some(e), @@ -108,7 +117,7 @@ impl Error for VersionParseErrorKind { mod tests { use std::str::FromStr; - use super::{StandardVersion, VersionParseError, VersionParseErrorKind}; + use super::{StandardVersion, ParseVersionError, ParseVersionErrorKind}; use super::super::version_component::VersionComponent; #[test] @@ -190,9 +199,9 @@ mod tests { fn parse_invalid_string() { assert_eq!( StandardVersion::from_str(".1.0"), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from(".1.0"), - kind: VersionParseErrorKind::IncorrectFormat + kind: ParseVersionErrorKind::IncorrectFormat }) ) } @@ -201,9 +210,9 @@ mod tests { fn parse_invalid_component() { assert_eq!( StandardVersion::from_str("0.1.O"), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("0.1.O"), - kind: VersionParseErrorKind::ParseComponent( + kind: ParseVersionErrorKind::ParseComponent( "O".parse::().unwrap_err() ) }) @@ -214,9 +223,9 @@ mod tests { fn parse_four_components() { assert_eq!( StandardVersion::from_str("1.2.4.0"), - Err(VersionParseError { + Err(ParseVersionError { version_string: String::from("1.2.4.0"), - kind: VersionParseErrorKind::TooManyComponents(4) + kind: ParseVersionErrorKind::TooManyComponents(4) }) ) }