├── .gitignore ├── nix-modules ├── no-filesystem.nix ├── register-nix-store.nix ├── tmpfs-root.nix ├── swap-to-disk.nix └── nix-netboot-serve-service.nix ├── shell.nix ├── default.nix ├── src ├── files.rs ├── nix.rs ├── hydra.rs ├── webservercontext.rs ├── dispatch_profile.rs ├── nofiles.rs ├── options.rs ├── dispatch.rs ├── dispatch_hydra.rs ├── dispatch_configuration.rs ├── boot.rs └── main.rs ├── boot.sh ├── Cargo.toml ├── LICENSE ├── nixos-test.nix ├── flake.lock ├── flake.nix ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | gc-roots 3 | cpio-cache/ 4 | -------------------------------------------------------------------------------- /nix-modules/no-filesystem.nix: -------------------------------------------------------------------------------- 1 | { 2 | fileSystems."/" = { 3 | device = "/dev/bogus"; 4 | fsType = "ext4"; 5 | }; 6 | boot.loader.grub.enable = false; 7 | } 8 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | (import 2 | (fetchTarball { 3 | url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; 4 | sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; 5 | }) 6 | { src = ./.; }).shellNix 7 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | (import 2 | (fetchTarball { 3 | url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; 4 | sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; 5 | }) 6 | { src = ./.; }).defaultNix 7 | -------------------------------------------------------------------------------- /nix-modules/register-nix-store.nix: -------------------------------------------------------------------------------- 1 | # register-nix-store 2 | # 3 | # Register the store paths provided by nix-netboot-serve into the Nix 4 | # database. 5 | # 6 | # Makes it safe to call nix-collect-garbage. 7 | { pkgs, ... }: { 8 | boot.postBootCommands = '' 9 | PATH=${pkgs.nix}/bin /nix/.nix-netboot-serve-db/register 10 | ''; 11 | } 12 | -------------------------------------------------------------------------------- /src/files.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::path::Path; 3 | use tokio::fs::File; 4 | use tokio::io::BufReader; 5 | use tokio_stream::Stream; 6 | use tokio_util::io::ReaderStream; 7 | use warp::hyper::body::Bytes; 8 | 9 | pub async fn open_file_stream( 10 | path: &Path, 11 | ) -> std::io::Result>> { 12 | let file = File::open(path).await?; 13 | 14 | Ok(ReaderStream::new(BufReader::new(file))) 15 | } 16 | -------------------------------------------------------------------------------- /boot.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | #url=http://127.0.0.1:3030/boot/0m60ngchp6ki34jpwmpbdx3fby6ya0sf-nixos-system-nginx-21.11pre307912.fe01052444c/netboot.ipxe 4 | #url=http://127.0.0.1:3030/dispatch/profile/amazon-image 5 | url=http://127.0.0.1:3030/dispatch/configuration/m1.small 6 | 7 | qemu-kvm \ 8 | -enable-kvm \ 9 | -m 16G \ 10 | -cpu max \ 11 | -serial mon:stdio \ 12 | -net user,bootfile="$url" \ 13 | -net nic \ 14 | -msg timestamp=on \ 15 | -nographic 16 | -------------------------------------------------------------------------------- /src/nix.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::path::Path; 3 | 4 | use tokio::process::Command; 5 | 6 | pub async fn realize_path(name: String, path: &str, gc_root: &Path) -> io::Result { 7 | // FIXME: Two interleaving requests could make this gc root go away, letting the closure be 8 | // GC'd during the serve. 9 | let symlink = gc_root.join(&name); 10 | 11 | let realize = Command::new(env!("NIX_STORE_BIN")) 12 | .arg("--realise") 13 | .arg(path) 14 | .arg("--add-root") 15 | .arg(&symlink) 16 | .arg("--indirect") 17 | .status() 18 | .await?; 19 | 20 | return Ok(realize.success()); 21 | } 22 | -------------------------------------------------------------------------------- /src/hydra.rs: -------------------------------------------------------------------------------- 1 | use reqwest; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashMap; 4 | 5 | #[derive(Serialize, Deserialize, Debug)] 6 | pub struct Job { 7 | pub buildoutputs: HashMap, 8 | } 9 | 10 | #[derive(Serialize, Deserialize, Debug)] 11 | pub struct BuildOutput { 12 | pub path: String, 13 | } 14 | 15 | pub async fn get_latest_job( 16 | server: &str, 17 | project: &str, 18 | jobset: &str, 19 | job: &str, 20 | ) -> Result { 21 | reqwest::Client::new() 22 | .get(format!( 23 | "https://{}/job/{}/{}/{}/latest", 24 | server, project, jobset, job 25 | )) 26 | .header("Accept", "application/json") 27 | .send() 28 | .await? 29 | .json::() 30 | .await 31 | } 32 | -------------------------------------------------------------------------------- /src/webservercontext.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use warp::reject; 4 | use warp::{Filter, Rejection}; 5 | 6 | use nix_cpio_generator::cpio_cache::CpioCache; 7 | 8 | #[derive(Clone)] 9 | pub struct WebserverContext { 10 | pub profile_dir: Option, 11 | pub configuration_dir: Option, 12 | pub gc_root: PathBuf, 13 | pub cpio_cache: CpioCache, 14 | } 15 | 16 | pub fn with_context( 17 | context: WebserverContext, 18 | ) -> impl Filter + Clone { 19 | warp::any().map(move || context.clone()) 20 | } 21 | 22 | pub fn server_error() -> Rejection { 23 | reject::not_found() 24 | } 25 | 26 | pub fn feature_disabled(msg: &str) -> Rejection { 27 | warn!("Feature disabled: {}", msg); 28 | reject::not_found() 29 | } 30 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nix-netboot-serve" 3 | version = "0.1.0" 4 | edition = "2018" 5 | license = "mit" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | cpio = "0.2.2" 11 | nix-cpio-generator = "0.3.0" 12 | futures = "0.3.16" 13 | http = "0.2.4" 14 | lazy_static = "1.4.0" 15 | log = "0.4.14" 16 | pretty_env_logger = "0.4.0" 17 | reqwest = { version = "0.11.4", features = [ "json" ] } 18 | rlimit = "0.6.2" 19 | serde = { version = "1.0.130", features = ["derive"] } 20 | serde_urlencoded = "0.7.0" 21 | structopt = { version = "0.3" } 22 | tempfile = "3.2.0" 23 | tokio = { version = "1", features = ["full"] } 24 | tokio-stream = { version = "0.1.7", features = [ "io-util" ] } 25 | tokio-util = "0.6.7" 26 | warp = "0.3" 27 | walkdir = "2" 28 | zstd = "0.11" 29 | -------------------------------------------------------------------------------- /src/dispatch_profile.rs: -------------------------------------------------------------------------------- 1 | use std::os::unix::ffi::OsStrExt; 2 | 3 | use http::response::Builder; 4 | use warp::Rejection; 5 | 6 | use crate::dispatch::{redirect_symlink_to_boot, NetbootIpxeTuning}; 7 | use crate::webservercontext::{feature_disabled, WebserverContext}; 8 | 9 | pub async fn serve_profile( 10 | name: String, 11 | tuning: NetbootIpxeTuning, 12 | context: WebserverContext, 13 | ) -> Result { 14 | let symlink = context 15 | .profile_dir 16 | .as_ref() 17 | .ok_or_else(|| feature_disabled("Profile booting is not configured on this server."))? 18 | .join(&name); 19 | 20 | Ok(Builder::new() 21 | .status(302) 22 | .header( 23 | "Location", 24 | redirect_symlink_to_boot(&symlink, tuning)?.as_bytes(), 25 | ) 26 | .body(String::new())) 27 | } 28 | -------------------------------------------------------------------------------- /src/nofiles.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | pub fn set_nofiles(limit: u64) -> io::Result<()> { 4 | let (soft, hard) = rlimit::Resource::NOFILE.get()?; 5 | 6 | if soft > limit { 7 | info!("nNot increasing NOFILES ulimit: current soft ({}) is already higher than the specified ({})", soft, limit); 8 | return Ok(()); 9 | } 10 | 11 | let mut setto = limit; 12 | 13 | if limit > hard { 14 | info!( 15 | "Requested NOFILES ({}) larger than the hard limit ({}), capping at {}.", 16 | limit, hard, hard 17 | ); 18 | setto = hard; 19 | } 20 | 21 | if setto == soft { 22 | info!( 23 | "Requested NOFILES ({}) is the same as the current soft limit.", 24 | setto 25 | ); 26 | return Ok(()); 27 | } 28 | 29 | info!("Setting open files to {} (hard: {})", setto, hard); 30 | 31 | rlimit::Resource::NOFILE.set(setto, hard)?; 32 | 33 | Ok(()) 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/options.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use structopt::StructOpt; 3 | 4 | #[derive(Debug, StructOpt)] 5 | #[structopt(name = "nix-netboot-serve", about = "Serve up some netboots")] 6 | pub struct Opt { 7 | /// Path to a directory of Nix profiles for booting 8 | #[structopt(long, parse(from_os_str))] 9 | pub profile_dir: Option, 10 | 11 | /// Path to a Nix directory of directories of NixOS configurations 12 | #[structopt(long, parse(from_os_str))] 13 | pub config_dir: Option, 14 | 15 | /// Path to directory to put GC roots 16 | #[structopt(long, parse(from_os_str))] 17 | pub gc_root_dir: PathBuf, 18 | 19 | /// Path to directory to put cached cpio files 20 | #[structopt(long, parse(from_os_str))] 21 | pub cpio_cache_dir: PathBuf, 22 | 23 | /// IP:port to listen on 24 | #[structopt(long)] 25 | pub listen: String, 26 | 27 | /// Number of open files to set the ulimit to 28 | #[structopt(long, default_value = "50000")] 29 | pub open_files: u64, 30 | 31 | /// Size in bytes of how much space the CPIO cache is allowed to consume 32 | #[structopt(long, default_value = "5368709120")] // 5 GiB in bytes 33 | pub max_cpio_cache_bytes: u64, 34 | } 35 | -------------------------------------------------------------------------------- /nixos-test.nix: -------------------------------------------------------------------------------- 1 | { pkgs, nixosModules }: 2 | import "${pkgs.path}/nixos/tests/make-test-python.nix" ({ pkgs, ... }: { 3 | name = "nix-netboot-serve"; 4 | meta.maintainers = pkgs.lib.teams.determinatesystems.members; 5 | 6 | nodes.machine = { pkgs, ... }: { 7 | imports = [ nixosModules.nix-netboot-serve ]; 8 | environment.systemPackages = [ 9 | pkgs.hello 10 | ]; 11 | 12 | services.nix-netboot-serve.enable = true; 13 | }; 14 | 15 | testScript = '' 16 | machine.start() 17 | 18 | machine.wait_for_unit("default.target") 19 | 20 | # Fetch the closure of the current system 21 | system_store_path_name = machine.succeed("readlink /run/current-system").strip().split("/")[3] 22 | 23 | machine.wait_for_open_port(3030) 24 | machine.succeed(f"curl --fail http://127.0.0.1:3030/boot/{system_store_path_name}/netboot.ipxe") 25 | machine.succeed(f"curl --fail http://127.0.0.1:3030/boot/{system_store_path_name}/bzImage > /dev/null") 26 | 27 | # Note: We don't generate the initrd for the system store path because 28 | # it kept running out of open files. This is despite setting NOFILES to ~500,000, the hard limit. 29 | # machine.succeed(f"curl --fail http://127.0.0.1:3030/boot/{system_store_path_name}/initrd > /dev/null") 30 | 31 | hello_store_path_name = machine.succeed("readlink $(which hello)").strip().split("/")[3] 32 | machine.succeed(f"curl --fail http://127.0.0.1:3030/boot/{hello_store_path_name}/initrd > /dev/null") 33 | print(machine.succeed(f"curl --fail --head http://127.0.0.1:3030/boot/{hello_store_path_name}/initrd")) 34 | ''; 35 | }) 36 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "cpiotools": { 4 | "inputs": { 5 | "nixpkgs": "nixpkgs" 6 | }, 7 | "locked": { 8 | "lastModified": 1702755016, 9 | "narHash": "sha256-avRrxBjC+z3XcKjosv6vzRlyDRNIKt/Dw7/pEzcTvYY=", 10 | "owner": "DeterminateSystems", 11 | "repo": "cpiotools", 12 | "rev": "189f7f5f672eb496bbba441aca1cdb208cb592ec", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "DeterminateSystems", 17 | "repo": "cpiotools", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1655567057, 24 | "narHash": "sha256-Cc5hQSMsTzOHmZnYm8OSJ5RNUp22bd5NADWLHorULWQ=", 25 | "owner": "nixos", 26 | "repo": "nixpkgs", 27 | "rev": "e0a42267f73ea52adc061a64650fddc59906fc99", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "nixos", 32 | "ref": "nixos-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "nixpkgs_2": { 38 | "locked": { 39 | "lastModified": 1702312524, 40 | "narHash": "sha256-gkZJRDBUCpTPBvQk25G0B7vfbpEYM5s5OZqghkjZsnE=", 41 | "owner": "nixos", 42 | "repo": "nixpkgs", 43 | "rev": "a9bf124c46ef298113270b1f84a164865987a91c", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "owner": "nixos", 48 | "ref": "nixos-unstable", 49 | "repo": "nixpkgs", 50 | "type": "github" 51 | } 52 | }, 53 | "root": { 54 | "inputs": { 55 | "cpiotools": "cpiotools", 56 | "nixpkgs": "nixpkgs_2" 57 | } 58 | } 59 | }, 60 | "root": "root", 61 | "version": 7 62 | } 63 | -------------------------------------------------------------------------------- /src/dispatch.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::path::Path; 3 | 4 | use serde::{Deserialize, Serialize}; 5 | use warp::reject; 6 | use warp::Rejection; 7 | 8 | #[derive(Deserialize, Serialize, Debug)] 9 | pub struct NetbootIpxeTuning { 10 | pub cmdline_prefix_args: Option, 11 | pub cmdline_suffix_args: Option, 12 | } 13 | 14 | pub fn redirect_symlink_to_boot( 15 | symlink: &Path, 16 | tuning: NetbootIpxeTuning, 17 | ) -> Result { 18 | let path = symlink.read_link().map_err(|e| { 19 | warn!("Reading the link {:?} failed with: {:?}", symlink, e); 20 | reject::not_found() 21 | })?; 22 | 23 | trace!("Resolved symlink {:?} to {:?}", symlink, path); 24 | redirect_to_boot_store_path(&path, tuning) 25 | } 26 | 27 | pub fn redirect_to_boot_store_path( 28 | path: &Path, 29 | tuning: NetbootIpxeTuning, 30 | ) -> Result { 31 | if !path.exists() { 32 | warn!("Path does not exist: {:?}", &path); 33 | return Err(reject::not_found()); 34 | } 35 | 36 | if let Some(std::path::Component::Normal(pathname)) = path.components().last() { 37 | let mut location = OsString::from("/boot/"); 38 | location.push(pathname); 39 | location.push(format!( 40 | "/netboot.ipxe?{}", 41 | serde_urlencoded::to_string(&tuning).map_err(|e| { 42 | warn!( 43 | "failed to urlencode these tuning parameters: {:?}, err: {}", 44 | tuning, e 45 | ); 46 | reject::not_found() 47 | })? 48 | )); 49 | 50 | return Ok(location); 51 | } else { 52 | error!( 53 | "Store path {:?} resolves to {:?} which has no path components?", 54 | &path, &path 55 | ); 56 | 57 | return Err(reject::not_found()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /nix-modules/tmpfs-root.nix: -------------------------------------------------------------------------------- 1 | # tmpfs-root 2 | # 3 | # Patch the kernel to make / in the early boot environment a tmpfs 4 | # instead of a rootfs. 5 | # 6 | # Without this patch, Nix and other container engines cannot use 7 | # pivot_root. 8 | { pkgs, ... }: { 9 | boot.kernelParams = [ "nonroot_initramfs" ]; 10 | boot.kernelPatches = [ 11 | { 12 | name = "nonroot_initramfs"; 13 | 14 | # Linux upstream unpacks the initramfs in to the rootfs directly. This breaks 15 | # pivot_root which breaks Nix's process of setting up the build sandbox. This 16 | # Nix uses pivot_root even when the sandbox is disabled. 17 | # 18 | # This patch has been upstreamed by Ignat Korchagin before, 19 | # then updated by me and upstreamed again here: 20 | # 21 | # https://lore.kernel.org/all/20210914170933.1922584-2-graham@determinate.systems/T/#m433939dc30c753176404792628b9bcd64d05ed7b 22 | # 23 | # It is available on my Linux fork on GitHub: 24 | # https://github.com/grahamc/linux/tree/v5.15-rc1-nonroot-initramfs 25 | # 26 | # If this patch stops applying it should be fairly easy to rebase that 27 | # branch on future revisions of the kernel. If it stops being easy to 28 | # rebase, we can stop building our own kernel and take a slower approach 29 | # instead, proposed on the LKML: as the very first step in our init: 30 | # 31 | # 1. create a tmpfs at /root 32 | # 2. copy everything in / to /root 33 | # 3. switch_root to /root 34 | # 35 | # This takes extra time as it will need to copy everything, and it may use 36 | # double the memory. Unsure. Hopefully this patch is merged or applies 37 | # easily forever. 38 | patch = pkgs.fetchpatch { 39 | name = "nonroot_initramfs"; 40 | url = "https://github.com/grahamc/linux/commit/65d2e9daeb2c849ad5c73f587604fec24c5cce43.patch"; 41 | sha256 = "sha256-ERzjkick0Kzq4Zxgp6f7a+oiT3IbL05k+c9P+MdMi+h="; 42 | }; 43 | } 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /src/dispatch_hydra.rs: -------------------------------------------------------------------------------- 1 | use std::os::unix::ffi::OsStrExt; 2 | use std::path::Path; 3 | 4 | use http::response::Builder; 5 | use warp::reject; 6 | use warp::Rejection; 7 | 8 | use crate::dispatch::{redirect_to_boot_store_path, NetbootIpxeTuning}; 9 | use crate::hydra; 10 | use crate::nix::realize_path; 11 | use crate::webservercontext::{server_error, WebserverContext}; 12 | 13 | pub async fn serve_hydra( 14 | server: String, 15 | project: String, 16 | jobset: String, 17 | job_name: String, 18 | tuning: NetbootIpxeTuning, 19 | context: WebserverContext, 20 | ) -> Result { 21 | let job = hydra::get_latest_job(&server, &project, &jobset, &job_name) 22 | .await 23 | .map_err(|e| { 24 | warn!( 25 | "Getting the latest job from {} {}:{}:{} failed: {:?}", 26 | server, project, jobset, job_name, e 27 | ); 28 | server_error() 29 | })?; 30 | 31 | let output = &job 32 | .buildoutputs 33 | .get("out") 34 | .ok_or_else(|| { 35 | warn!("No out for job {:?}. Got: {:?}", &job_name, job); 36 | reject::not_found() 37 | })? 38 | .path; 39 | 40 | let realize = realize_path( 41 | format!("{}-{}-{}-{}", &server, &project, &jobset, &job_name), 42 | &output, 43 | &context.gc_root, 44 | ) 45 | .await 46 | .map_err(|e| { 47 | warn!( 48 | "Getting the latest job from {} {}:{}:{} failed: {:?}", 49 | server, project, jobset, job_name, e 50 | ); 51 | server_error() 52 | })?; 53 | 54 | if realize { 55 | Ok(Builder::new() 56 | .status(302) 57 | .header( 58 | "Location", 59 | redirect_to_boot_store_path(Path::new(&output), tuning)?.as_bytes(), 60 | ) 61 | .body(String::new())) 62 | } else { 63 | warn!("Failed to realize output {} for {:?}", &output, &job_name); 64 | Err(reject::not_found()) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/dispatch_configuration.rs: -------------------------------------------------------------------------------- 1 | use http::response::Builder; 2 | use std::os::unix::ffi::OsStrExt; 3 | 4 | use tokio::process::Command; 5 | use warp::reject; 6 | use warp::Rejection; 7 | 8 | use crate::dispatch::{redirect_symlink_to_boot, NetbootIpxeTuning}; 9 | use crate::webservercontext::{feature_disabled, server_error, WebserverContext}; 10 | 11 | pub async fn serve_configuration( 12 | name: String, 13 | tuning: NetbootIpxeTuning, 14 | context: WebserverContext, 15 | ) -> Result { 16 | let config = context 17 | .configuration_dir 18 | .as_ref() 19 | .ok_or_else(|| feature_disabled("Configuration booting is not configured on this server."))? 20 | .join(&name) 21 | .join("default.nix"); 22 | 23 | if !config.is_file() { 24 | println!( 25 | "Configuration {} resolves to {:?} which is not a file", 26 | name, config 27 | ); 28 | return Err(reject::not_found()); 29 | } 30 | 31 | // TODO: not thread safe sorta, but kinda is, unless the config 32 | // changes between two boots. I'm definitely going to regret this. 33 | let symlink = context.gc_root.join(&name); 34 | 35 | let build = Command::new(env!("NIX_BUILD_BIN")) 36 | .arg(&config) 37 | .arg("--out-link") 38 | .arg(&symlink) 39 | .status() 40 | .await 41 | .map_err(|e| { 42 | warn!( 43 | "Executing nix-build on {:?} failed at some fundamental level: {:?}", 44 | config, e 45 | ); 46 | server_error() 47 | })?; 48 | 49 | if !build.success() { 50 | return Ok(Builder::new().status(200).body(format!( 51 | "#!ipxe 52 | 53 | echo Failed to render the configuration. 54 | echo Will retry in 5s, press enter to retry immediately. 55 | 56 | menu Failed to render the configuration. Will retry in 5s, or press enter to retry immediately. 57 | item gonow Retry now 58 | choose --default gonow --timeout 5000 shouldwedoit 59 | 60 | chain /dispatch/configuration/{}", 61 | name 62 | ))); 63 | } 64 | 65 | Ok(Builder::new() 66 | .status(302) 67 | .header( 68 | "Location", 69 | redirect_symlink_to_boot(&symlink, tuning)?.as_bytes(), 70 | ) 71 | .body(String::new())) 72 | } 73 | -------------------------------------------------------------------------------- /nix-modules/swap-to-disk.nix: -------------------------------------------------------------------------------- 1 | # swap-to-disk 2 | # 3 | # Harness all the block devices on the system as part of a striped, 4 | # encrypted swap disk. 5 | # 6 | # WARNING: This will erase all of the disks in the system. It is not a 7 | # feature if it happens to not erase a specific disk. It may change 8 | # in the future to do so. 9 | # 10 | # Instead of writing out a filesystem to disks or other tricks like 11 | # an overlayfs, we can stay in the rootfs (or tmpfs with `tmpfs-root`) 12 | # and add all the disks in the system as swap. 13 | # 14 | # The root filesystem is limited to the size of the disks. In other 15 | # words, even if the `/` memory-backed filesystem is 100% full, none 16 | # of your system's RAM will be required for holding filesystem data. 17 | { pkgs, ... }: 18 | { 19 | systemd.services.add-disks-to-swap = { 20 | wantedBy = [ "multi-user.target" ]; 21 | serviceConfig = { 22 | Type = "oneshot"; 23 | Restart = "on-failure"; 24 | RestartSec = "5s"; 25 | }; 26 | unitConfig = { 27 | X-ReloadIfChanged = false; 28 | X-RestartIfChanged = false; 29 | X-StopIfChanged = false; 30 | X-StopOnReconfiguration = false; 31 | X-StopOnRemoval = false; 32 | }; 33 | script = '' 34 | set -eux 35 | if [ ! -e /dev/md/spill.decrypted ]; then 36 | ${pkgs.kmod}/bin/modprobe raid0 37 | 38 | echo 2 > /sys/module/raid0/parameters/default_layout 39 | 40 | ${pkgs.util-linux}/bin/lsblk -d -e 1,7,11,230 -o PATH -n > disklist 41 | ${pkgs.coreutils}/bin/cat disklist 42 | ${pkgs.coreutils}/bin/cat disklist | ${pkgs.findutils}/bin/xargs ${pkgs.mdadm}/bin/mdadm /dev/md/spill.decrypted --create --level=0 --force --raid-devices=$(${pkgs.coreutils}/bin/cat disklist | ${pkgs.busybox}/bin/wc -l) 43 | rm disklist 44 | fi 45 | 46 | ${pkgs.cryptsetup}/bin/cryptsetup -c aes-xts-plain64 -d /dev/random create spill.encrypted /dev/md/spill.decrypted 47 | 48 | ${pkgs.util-linux}/bin/mkswap /dev/mapper/spill.encrypted 49 | ${pkgs.util-linux}/bin/swapon /dev/mapper/spill.encrypted 50 | 51 | size=$(${pkgs.util-linux}/bin/lsblk --noheadings --bytes --output SIZE /dev/mapper/spill.encrypted) 52 | pagesize=$(${pkgs.glibc.bin}/bin/getconf PAGESIZE) 53 | inodes=$((size / pagesize)) 54 | ${pkgs.util-linux}/bin/mount -o remount,size=$size,nr_inodes=$inodes / 55 | ''; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /src/boot.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use futures::stream::{FuturesOrdered, FuturesUnordered, TryStreamExt}; 3 | use http::response::Builder; 4 | use std::path::Path; 5 | use tokio::fs; 6 | use warp::hyper::Body; 7 | use warp::reject; 8 | use warp::Rejection; 9 | 10 | use crate::dispatch::NetbootIpxeTuning; 11 | use crate::files::open_file_stream; 12 | use crate::webservercontext::{server_error, WebserverContext}; 13 | 14 | pub async fn serve_ipxe( 15 | name: String, 16 | tuning: NetbootIpxeTuning, 17 | ) -> Result { 18 | let params = Path::new("/nix/store").join(&name).join("kernel-params"); 19 | let init = Path::new("/nix/store").join(&name).join("init"); 20 | info!("Sending netboot.ipxe: {:?}", &name); 21 | 22 | let response = format!( 23 | "#!ipxe 24 | echo Booting NixOS closure {name}. Note: initrd may stay pre-0% for a minute or two. 25 | 26 | 27 | kernel bzImage rdinit={init} {pre_params} {params} {post_params} 28 | initrd initrd 29 | boot 30 | ", 31 | name = &name, 32 | init = init.display(), 33 | pre_params = tuning.cmdline_prefix_args.unwrap_or("".to_string()), 34 | post_params = tuning.cmdline_suffix_args.unwrap_or("".to_string()), 35 | params = fs::read_to_string(¶ms).await.map_err(|e| { 36 | warn!( 37 | "Failed to load parameters from the generation at {:?}: {:?}", 38 | params, e 39 | ); 40 | server_error() 41 | })? 42 | ); 43 | 44 | Ok(Builder::new().status(200).body(response)) 45 | } 46 | 47 | pub async fn serve_initrd( 48 | name: String, 49 | context: WebserverContext, 50 | ) -> Result { 51 | let store_path = Path::new("/nix/store").join(name); 52 | info!("Sending closure: {:?}", &store_path); 53 | 54 | let (size, stream) = nix_cpio_generator::stream::stream(&context.cpio_cache, &store_path) 55 | .await 56 | .map_err(|e| { 57 | warn!("Error streaming the CPIO for {:?}: {:?}", store_path, e); 58 | server_error() 59 | })?; 60 | 61 | Ok(Builder::new() 62 | .header("Content-Length", size) 63 | .status(200) 64 | .body(Body::wrap_stream(stream))) 65 | } 66 | 67 | pub async fn serve_kernel(name: String) -> Result { 68 | let kernel = Path::new("/nix/store").join(name).join("kernel"); 69 | info!("Sending kernel: {:?}", kernel); 70 | 71 | let read_stream = open_file_stream(&kernel).await.map_err(|e| { 72 | warn!("Failed to serve kernel {:?}: {:?}", kernel, e); 73 | reject::not_found() 74 | })?; 75 | 76 | Ok(Builder::new() 77 | .status(200) 78 | .body(Body::wrap_stream(read_stream))) 79 | } 80 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Make any NixOS system netbootable with 10s cycle times."; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 6 | cpiotools.url = "github:DeterminateSystems/cpiotools"; 7 | }; 8 | 9 | outputs = 10 | { self 11 | , nixpkgs 12 | , cpiotools 13 | , ... 14 | } @ inputs: 15 | let 16 | nameValuePair = name: value: { inherit name value; }; 17 | genAttrs = names: f: builtins.listToAttrs (map (n: nameValuePair n (f n)) names); 18 | allSystems = [ "x86_64-linux" "aarch64-linux" "i686-linux" "x86_64-darwin" "aarch64-darwin" ]; 19 | 20 | forAllSystems = f: genAttrs allSystems (system: f { 21 | inherit system; 22 | pkgs = import nixpkgs { inherit system; }; 23 | }); 24 | in 25 | { 26 | devShell = forAllSystems ({ system, pkgs, ... }: self.packages.${system}.package.overrideAttrs ({ nativeBuildInputs ? [ ], ... }: { 27 | nativeBuildInputs = nativeBuildInputs ++ (with pkgs; [ 28 | binwalk 29 | codespell 30 | entr 31 | file 32 | nixpkgs-fmt 33 | rustfmt 34 | vim # xxd 35 | cpiotools.packages.${system}.package 36 | ]); 37 | })); 38 | 39 | packages = forAllSystems 40 | ({ system, pkgs, ... }: { 41 | package = pkgs.rustPlatform.buildRustPackage rec { 42 | pname = "nix-netboot-serve"; 43 | version = "unreleased"; 44 | 45 | nativeBuildInputs = with pkgs; [ 46 | which 47 | coreutils 48 | cpio 49 | nix 50 | zstd 51 | pkg-config 52 | ]; 53 | 54 | buildInputs = with pkgs; [ 55 | openssl 56 | ] ++ lib.optionals (pkgs.stdenv.isDarwin) (with pkgs; with darwin.apple_sdk.frameworks; [ 57 | SystemConfiguration 58 | ]); 59 | 60 | 61 | src = self; 62 | 63 | cargoLock.lockFile = src + "/Cargo.lock"; 64 | }; 65 | 66 | nixos-test = import ./nixos-test.nix { inherit pkgs; inherit (self) nixosModules; } { inherit pkgs system; }; 67 | }); 68 | 69 | defaultPackage = forAllSystems 70 | ({ system, ... }: self.packages.${system}.package); 71 | 72 | nixosModules = { 73 | nix-netboot-serve = { 74 | imports = [ ./nix-modules/nix-netboot-serve-service.nix ]; 75 | nixpkgs.overlays = [ 76 | (final: prev: { 77 | nix-netboot-serve = self.defaultPackage."${final.stdenv.hostPlatform.system}"; 78 | }) 79 | ]; 80 | }; 81 | no-filesystem = ./nix-modules/no-filesystem.nix; 82 | register-nix-store = ./nix-modules/register-nix-store.nix; 83 | swap-to-disk = ./nix-modules/swap-to-disk.nix; 84 | tmpfs-root = ./nix-modules/tmpfs-root.nix; 85 | }; 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /nix-modules/nix-netboot-serve-service.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, options, ... }: 2 | let 3 | cfg = config.services.nix-netboot-serve; 4 | opts = options.services.nix-netboot-serve; 5 | in 6 | { 7 | options = { 8 | services.nix-netboot-serve = { 9 | enable = lib.mkEnableOption "nix-netboot-serve"; 10 | 11 | profile_dir = lib.mkOption { 12 | type = lib.types.nullOr lib.types.path; 13 | default = null; 14 | }; 15 | 16 | configuration_dir = lib.mkOption { 17 | type = lib.types.nullOr lib.types.path; 18 | default = null; 19 | }; 20 | 21 | gc_root_dir = lib.mkOption { 22 | type = lib.types.path; 23 | default = "/var/cache/nix-netboot-serve/gc-roots"; 24 | }; 25 | 26 | cpio_cache_dir = lib.mkOption { 27 | type = lib.types.path; 28 | default = "/var/cache/nix-netboot-serve/cpios"; 29 | }; 30 | 31 | cpio_cache_max_bytes = lib.mkOption { 32 | type = lib.types.int; 33 | description = "Maximum amount of space the CPIO cache may take up, in bytes."; 34 | default = 5 * 1024 * 1024 * 1024; 35 | }; 36 | 37 | listen = lib.mkOption { 38 | type = lib.types.str; 39 | default = "0.0.0.0:3030"; 40 | }; 41 | 42 | debug = lib.mkOption { 43 | type = lib.types.bool; 44 | default = false; 45 | }; 46 | 47 | open_files = lib.mkOption { 48 | type = lib.types.nullOr lib.types.ints.u32; 49 | default = null; 50 | }; 51 | }; 52 | }; 53 | 54 | config = lib.mkIf cfg.enable { 55 | systemd.tmpfiles.rules = 56 | (lib.optional (cfg.gc_root_dir == opts.gc_root_dir.default) "d ${cfg.gc_root_dir} 0700 nix-netboot-serve nix-netboot-serve -") 57 | ++ (lib.optional (cfg.cpio_cache_dir == opts.cpio_cache_dir.default) "d ${cfg.cpio_cache_dir} 0700 nix-netboot-serve nix-netboot-serve -"); 58 | 59 | users.users.nix-netboot-serve = { 60 | group = "nix-netboot-serve"; 61 | isSystemUser = true; 62 | }; 63 | users.groups.nix-netboot-serve = { }; 64 | 65 | systemd.services.nix-netboot-serve = { 66 | wantedBy = [ "multi-user.target" ]; 67 | description = "A netboot image generator for NixOS closures."; 68 | environment.RUST_LOG = if cfg.debug then "debug" else "info"; 69 | serviceConfig = { 70 | User = "nix-netboot-serve"; 71 | Group = "nix-netboot-serve"; 72 | ExecStart = "${pkgs.nix-netboot-serve}/bin/nix-netboot-serve " + 73 | (lib.escapeShellArgs ( 74 | [ "--gc-root-dir" cfg.gc_root_dir ] 75 | ++ [ "--cpio-cache-dir" cfg.cpio_cache_dir ] 76 | ++ [ "--max-cpio-cache-bytes" cfg.cpio_cache_max_bytes ] 77 | ++ [ "--listen" cfg.listen ] 78 | ++ (lib.optionals (cfg.profile_dir != null) [ "--profile-dir" cfg.profile_dir ]) 79 | ++ (lib.optionals (cfg.configuration_dir != null) [ "--config-dir" cfg.configuration_dir ]) 80 | ++ (lib.optionals (cfg.open_files != null) [ "--open-files" cfg.open_files ]) 81 | )); 82 | }; 83 | }; 84 | }; 85 | } 86 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | use std::path::PathBuf; 3 | 4 | use nix_cpio_generator::cpio_cache::CpioCache; 5 | use structopt::StructOpt; 6 | use warp::Filter; 7 | 8 | #[macro_use] 9 | extern crate log; 10 | 11 | mod boot; 12 | mod dispatch; 13 | mod dispatch_configuration; 14 | mod dispatch_hydra; 15 | mod dispatch_profile; 16 | mod files; 17 | mod hydra; 18 | mod nix; 19 | mod nofiles; 20 | mod options; 21 | mod webservercontext; 22 | use crate::boot::{serve_initrd, serve_ipxe, serve_kernel}; 23 | use crate::dispatch_configuration::serve_configuration; 24 | use crate::dispatch_hydra::serve_hydra; 25 | use crate::dispatch_profile::serve_profile; 26 | use crate::nofiles::set_nofiles; 27 | use crate::options::Opt; 28 | use crate::webservercontext::{with_context, WebserverContext}; 29 | 30 | #[tokio::main] 31 | async fn main() { 32 | pretty_env_logger::init(); 33 | 34 | let opt = Opt::from_args(); 35 | 36 | set_nofiles(opt.open_files).expect("Failed to set ulimit for the number of open files"); 37 | 38 | let check_dir_exists = |path: PathBuf| { 39 | if !path.is_dir() { 40 | error!("Directory does not exist: {:?}", path); 41 | panic!(); 42 | } 43 | 44 | path 45 | }; 46 | 47 | let webserver = WebserverContext { 48 | profile_dir: opt.profile_dir.map(check_dir_exists), 49 | configuration_dir: opt.config_dir.map(check_dir_exists), 50 | gc_root: check_dir_exists(opt.gc_root_dir), 51 | cpio_cache: CpioCache::new( 52 | check_dir_exists(opt.cpio_cache_dir), 53 | None, 54 | opt.max_cpio_cache_bytes, 55 | ) 56 | .expect("Cannot construct a CPIO Cache"), 57 | }; 58 | 59 | let root = warp::path::end().map(|| "nix-netboot-serve"); 60 | let profile = warp::path!("dispatch" / "profile" / String) 61 | .and(warp::query::()) 62 | .and(with_context(webserver.clone())) 63 | .and_then(serve_profile); 64 | let configuration = warp::path!("dispatch" / "configuration" / String) 65 | .and(warp::query::()) 66 | .and(with_context(webserver.clone())) 67 | .and_then(serve_configuration); 68 | let hydra = warp::path!("dispatch" / "hydra" / String / String / String / String) 69 | .and(warp::query::()) 70 | .and(with_context(webserver.clone())) 71 | .and_then(serve_hydra); 72 | let ipxe = warp::path!("boot" / String / "netboot.ipxe") 73 | .and(warp::query::()) 74 | .and_then(serve_ipxe); 75 | let initrd = warp::path!("boot" / String / "initrd") 76 | .and(with_context(webserver.clone())) 77 | .and_then(serve_initrd); 78 | let kernel = warp::path!("boot" / String / "bzImage").and_then(serve_kernel); 79 | 80 | let log = warp::log("nix-netboot-serve::web"); 81 | 82 | let routes = warp::get() 83 | .and( 84 | root.or(profile) 85 | .or(configuration) 86 | .or(hydra) 87 | .or(ipxe) 88 | .or(initrd.clone()) 89 | .or(kernel), 90 | ) 91 | .or(warp::head().and(initrd)) 92 | .with(log); 93 | 94 | warp::serve(routes) 95 | .run( 96 | opt.listen 97 | .parse::() 98 | .expect("Failed to parse the listen argument"), 99 | ) 100 | .await; 101 | } 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nix-netboot-serve 2 | 3 | Dynamically generate netboot images for arbitrary NixOS system closures, 4 | profiles, or configurations with 10s iteration times. 5 | 6 | ## Usage 7 | 8 | Create working directories for it: 9 | 10 | ``` 11 | mkdir ./gc-roots ./profiles ./configurations ./cpio-cache 12 | ``` 13 | 14 | Then start up the server: 15 | 16 | ``` 17 | RUST_LOG=info cargo run -- --gc-root-dir ./gc-roots --config-dir ./configurations --profile-dir ./profiles/ --cpio-cache-dir ./cpio-cache/ --listen 127.0.0.1:3030 18 | ``` 19 | 20 | See `./boot.sh` for an example of booting with QEMU. 21 | 22 | ## Booting an absolute closure 23 | 24 | ### How To 25 | 26 | To boot from a specific closure like 27 | `/nix/store/0m60ngchp6ki34jpwmpbdx3fby6ya0sf-nixos-system-nginx-21.11pre307912.fe01052444c`, 28 | use `/boot/0m60ngchp6ki34jpwmpbdx3fby6ya0sf-nixos-system-nginx-21.11pre307912.fe01052444c/netboot.ipxe` 29 | as your chain url. 30 | 31 | ## Behavior 32 | 33 | As long as that closure exists on the host, that closure will always 34 | be booted, unchanged. 35 | 36 | ## Booting a profile 37 | 38 | ### How To 39 | 40 | In the `profiles` directory, create symlinks to top level system paths. 41 | For example: 42 | 43 | ```console 44 | $ ls -la profiles/ 45 | example-host -> /nix/store/4y829p7lljdvwnmsk6pnig3mlh6ygklj-nixos-system-example-host-21.11pre130979.gfedcba 46 | ``` 47 | 48 | then use `/dispatch/profile/example-host` to boot it. 49 | 50 | ### Behavior 51 | 52 | The symlink will be resolved every time a machine boots. 53 | 54 | ## Booting a configuration 55 | 56 | ### How To 57 | In the `configurations` directory, create a directory for each system, 58 | and create a `default.nix` inside. For example: 59 | 60 | ```console 61 | $ tree configurations/ 62 | configurations/ 63 | └── m1.small 64 | └── default.nix 65 | ``` 66 | 67 | In the `default.nix`, create an expression with your NixOS configuration 68 | ready to be built: 69 | 70 | ```nix 71 | (import { 72 | configuration = { pkgs, ... }: { 73 | networking.hostName = "m1small"; 74 | environment.systemPackages = [ pkgs.hello ]; 75 | fileSystems."/" = { 76 | device = "/dev/bogus"; 77 | fsType = "ext4"; 78 | }; 79 | boot.loader.grub.devices = [ "/dev/bogus" ]; 80 | boot.postBootCommands = '' 81 | PATH=${pkgs.nix}/bin /nix/.nix-netboot-serve-db/register 82 | ''; 83 | }; 84 | }).system 85 | ``` 86 | 87 | Then use `/dispatch/configuration/m1.small` to boot it. 88 | 89 | ## Booting from Hydra 90 | 91 | ### How To 92 | 93 | Create a Hydra project and jobset which contains a job which produces a 94 | bootable system configuration. 95 | 96 | Then use the URL `/dispatch/hydra/HOSTNAME/PROJECT/JOBSET/JOB`, substituting 97 | those URL sections with names from your system to boot it. 98 | 99 | Note that nix-netboot-serve will query the provided Hydra for the store path 100 | to boot and will then try to substitute the closure. Nix must already be 101 | configured with the requested hydra's cache for this to work. 102 | 103 | ### Behavior 104 | 105 | The configuration will be `nix-build` once per boot, and create a symlink 106 | in the `--gc-root-dir` directory with the same name as the configuration. 107 | 108 | If the build fails, the ipxe client will be told to retry in 5s. 109 | 110 | Note: there is currently a buggy race condition. In the following circumstance: 111 | 112 | 1. machine A turns on 113 | 1. machine B turns on 114 | 1. machine A hits the build URL and a long build starts 115 | 1. you change the configuration to have a very short build 116 | 1. machine B hits the build URL and the short build starts 117 | 1. machine B's configuration finishes building 118 | 1. machine B boots the short build configuration 119 | 1. machine A's configuration finishes building 120 | 1. machine A boots the **short configuration** instead of the long configuration 121 | 122 | ## Theory of Operation 123 | 124 | Linux's boot process starts with two things: 125 | 126 | 1. the kernel 127 | 1. an initrd, or an initial ram disk 128 | 129 | The ramdisk has all the files needed to mount any disks and start any 130 | software needed for the machine. Typically the ramdisk is constructed 131 | of a [CPIO](https://en.wikipedia.org/wiki/Cpio), a very simple file 132 | archive. 133 | 134 | Linux supports a special case of its initrd being comprised of 135 | _multiple_ CPIOs. By simply concatenating two CPIOs together, 136 | Linux's boot process will see the merged contents of both CPIOs. 137 | 138 | Furthermore, individual CPIOs can be compressed independently, 139 | merged together with concatenation, and Linux will decompress 140 | and read each CPIO independently. 141 | 142 | A NixOS system is comprised of hundreds of independent, immutable 143 | `/nix/store` paths. 144 | 145 | Merging these together, we can dynamically create a single, compressed 146 | CPIO per Nix store path and cache it for later. 147 | 148 | When a new boot request comes in, the software fetches the list of 149 | Nix store paths for the requested NixOS system. Then, every path 150 | has a CPIO built for it. Once each store path has a CPIO, the results 151 | are streamed back to the iPXE client. By caching the resulting CPIO, 152 | iterative development on a system configuration can result in just 153 | 3-5 new CPIOs per change. 154 | 155 | ## Improvements over NixOS's NetBoot Support 156 | 157 | NixOS's NetBoot image creation support works well, however iterating 158 | on a single closure involves recreating the CPIO and recompressing for 159 | every store path every time. This can add several minutes to cycle 160 | time. 161 | 162 | ## Other API Information 163 | 164 | * Get the size of the initrd: `HEAD /boot/PATH/initrd` 165 | * Pass additional kernel commandline arguments: `/dispatch/...?cmdline_prefix_args=...&cmdline_suffix_args=...` 166 | 167 | ## Caveats 168 | 169 | ### Loading the Nix Database 170 | 171 | Before using Nix inside the booted machine, make sure to **load the Nix 172 | database**. To do that, add this to your NixOS configuration: 173 | 174 | ``` 175 | { pkgs, ... }: { 176 | boot.postBootCommands = '' 177 | PATH=${pkgs.nix}/bin /nix/.nix-netboot-serve-db/register 178 | ''; 179 | } 180 | ``` 181 | 182 | This is not necessary if the system will not execute Nix commands. 183 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "ahash" 22 | version = "0.7.8" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 25 | dependencies = [ 26 | "getrandom", 27 | "once_cell", 28 | "version_check", 29 | ] 30 | 31 | [[package]] 32 | name = "aho-corasick" 33 | version = "1.1.3" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 36 | dependencies = [ 37 | "memchr", 38 | ] 39 | 40 | [[package]] 41 | name = "ansi_term" 42 | version = "0.12.1" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 45 | dependencies = [ 46 | "winapi", 47 | ] 48 | 49 | [[package]] 50 | name = "atty" 51 | version = "0.2.14" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 54 | dependencies = [ 55 | "hermit-abi", 56 | "libc", 57 | "winapi", 58 | ] 59 | 60 | [[package]] 61 | name = "autocfg" 62 | version = "1.4.0" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 65 | 66 | [[package]] 67 | name = "backtrace" 68 | version = "0.3.74" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 71 | dependencies = [ 72 | "addr2line", 73 | "cfg-if", 74 | "libc", 75 | "miniz_oxide", 76 | "object", 77 | "rustc-demangle", 78 | "windows-targets 0.52.6", 79 | ] 80 | 81 | [[package]] 82 | name = "base64" 83 | version = "0.21.7" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 86 | 87 | [[package]] 88 | name = "bitflags" 89 | version = "1.3.2" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 92 | 93 | [[package]] 94 | name = "bitflags" 95 | version = "2.6.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 98 | 99 | [[package]] 100 | name = "block-buffer" 101 | version = "0.10.4" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 104 | dependencies = [ 105 | "generic-array", 106 | ] 107 | 108 | [[package]] 109 | name = "bumpalo" 110 | version = "3.16.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 113 | 114 | [[package]] 115 | name = "byteorder" 116 | version = "1.5.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 119 | 120 | [[package]] 121 | name = "bytes" 122 | version = "1.9.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 125 | 126 | [[package]] 127 | name = "cc" 128 | version = "1.2.7" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" 131 | dependencies = [ 132 | "jobserver", 133 | "libc", 134 | "shlex", 135 | ] 136 | 137 | [[package]] 138 | name = "cfg-if" 139 | version = "1.0.0" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 142 | 143 | [[package]] 144 | name = "clap" 145 | version = "2.34.0" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 148 | dependencies = [ 149 | "ansi_term", 150 | "atty", 151 | "bitflags 1.3.2", 152 | "strsim", 153 | "textwrap", 154 | "unicode-width", 155 | "vec_map", 156 | ] 157 | 158 | [[package]] 159 | name = "core-foundation" 160 | version = "0.9.4" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 163 | dependencies = [ 164 | "core-foundation-sys", 165 | "libc", 166 | ] 167 | 168 | [[package]] 169 | name = "core-foundation-sys" 170 | version = "0.8.7" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 173 | 174 | [[package]] 175 | name = "cpio" 176 | version = "0.2.2" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "27e77cfc4543efb4837662cb7cd53464ae66f0fd5c708d71e0f338b1c11d62d3" 179 | 180 | [[package]] 181 | name = "cpufeatures" 182 | version = "0.2.16" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" 185 | dependencies = [ 186 | "libc", 187 | ] 188 | 189 | [[package]] 190 | name = "crypto-common" 191 | version = "0.1.6" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 194 | dependencies = [ 195 | "generic-array", 196 | "typenum", 197 | ] 198 | 199 | [[package]] 200 | name = "data-encoding" 201 | version = "2.6.0" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" 204 | 205 | [[package]] 206 | name = "digest" 207 | version = "0.10.7" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 210 | dependencies = [ 211 | "block-buffer", 212 | "crypto-common", 213 | ] 214 | 215 | [[package]] 216 | name = "displaydoc" 217 | version = "0.2.5" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 220 | dependencies = [ 221 | "proc-macro2", 222 | "quote", 223 | "syn 2.0.95", 224 | ] 225 | 226 | [[package]] 227 | name = "encoding_rs" 228 | version = "0.8.35" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 231 | dependencies = [ 232 | "cfg-if", 233 | ] 234 | 235 | [[package]] 236 | name = "env_logger" 237 | version = "0.7.1" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" 240 | dependencies = [ 241 | "atty", 242 | "humantime", 243 | "log", 244 | "regex", 245 | "termcolor", 246 | ] 247 | 248 | [[package]] 249 | name = "equivalent" 250 | version = "1.0.1" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 253 | 254 | [[package]] 255 | name = "errno" 256 | version = "0.3.10" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 259 | dependencies = [ 260 | "libc", 261 | "windows-sys 0.59.0", 262 | ] 263 | 264 | [[package]] 265 | name = "fastrand" 266 | version = "2.3.0" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 269 | 270 | [[package]] 271 | name = "fnv" 272 | version = "1.0.7" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 275 | 276 | [[package]] 277 | name = "foreign-types" 278 | version = "0.3.2" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 281 | dependencies = [ 282 | "foreign-types-shared", 283 | ] 284 | 285 | [[package]] 286 | name = "foreign-types-shared" 287 | version = "0.1.1" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 290 | 291 | [[package]] 292 | name = "form_urlencoded" 293 | version = "1.2.1" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 296 | dependencies = [ 297 | "percent-encoding", 298 | ] 299 | 300 | [[package]] 301 | name = "futures" 302 | version = "0.3.31" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 305 | dependencies = [ 306 | "futures-channel", 307 | "futures-core", 308 | "futures-executor", 309 | "futures-io", 310 | "futures-sink", 311 | "futures-task", 312 | "futures-util", 313 | ] 314 | 315 | [[package]] 316 | name = "futures-channel" 317 | version = "0.3.31" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 320 | dependencies = [ 321 | "futures-core", 322 | "futures-sink", 323 | ] 324 | 325 | [[package]] 326 | name = "futures-core" 327 | version = "0.3.31" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 330 | 331 | [[package]] 332 | name = "futures-executor" 333 | version = "0.3.31" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 336 | dependencies = [ 337 | "futures-core", 338 | "futures-task", 339 | "futures-util", 340 | ] 341 | 342 | [[package]] 343 | name = "futures-io" 344 | version = "0.3.31" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 347 | 348 | [[package]] 349 | name = "futures-macro" 350 | version = "0.3.31" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 353 | dependencies = [ 354 | "proc-macro2", 355 | "quote", 356 | "syn 2.0.95", 357 | ] 358 | 359 | [[package]] 360 | name = "futures-sink" 361 | version = "0.3.31" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 364 | 365 | [[package]] 366 | name = "futures-task" 367 | version = "0.3.31" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 370 | 371 | [[package]] 372 | name = "futures-util" 373 | version = "0.3.31" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 376 | dependencies = [ 377 | "futures-channel", 378 | "futures-core", 379 | "futures-io", 380 | "futures-macro", 381 | "futures-sink", 382 | "futures-task", 383 | "memchr", 384 | "pin-project-lite", 385 | "pin-utils", 386 | "slab", 387 | ] 388 | 389 | [[package]] 390 | name = "generic-array" 391 | version = "0.14.7" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 394 | dependencies = [ 395 | "typenum", 396 | "version_check", 397 | ] 398 | 399 | [[package]] 400 | name = "getrandom" 401 | version = "0.2.15" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 404 | dependencies = [ 405 | "cfg-if", 406 | "libc", 407 | "wasi", 408 | ] 409 | 410 | [[package]] 411 | name = "gimli" 412 | version = "0.31.1" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 415 | 416 | [[package]] 417 | name = "h2" 418 | version = "0.3.26" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 421 | dependencies = [ 422 | "bytes", 423 | "fnv", 424 | "futures-core", 425 | "futures-sink", 426 | "futures-util", 427 | "http 0.2.12", 428 | "indexmap", 429 | "slab", 430 | "tokio", 431 | "tokio-util 0.7.13", 432 | "tracing", 433 | ] 434 | 435 | [[package]] 436 | name = "hashbrown" 437 | version = "0.12.3" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 440 | dependencies = [ 441 | "ahash", 442 | ] 443 | 444 | [[package]] 445 | name = "hashbrown" 446 | version = "0.15.2" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 449 | 450 | [[package]] 451 | name = "headers" 452 | version = "0.3.9" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" 455 | dependencies = [ 456 | "base64", 457 | "bytes", 458 | "headers-core", 459 | "http 0.2.12", 460 | "httpdate", 461 | "mime", 462 | "sha1", 463 | ] 464 | 465 | [[package]] 466 | name = "headers-core" 467 | version = "0.2.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 470 | dependencies = [ 471 | "http 0.2.12", 472 | ] 473 | 474 | [[package]] 475 | name = "heck" 476 | version = "0.3.3" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 479 | dependencies = [ 480 | "unicode-segmentation", 481 | ] 482 | 483 | [[package]] 484 | name = "hermit-abi" 485 | version = "0.1.19" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 488 | dependencies = [ 489 | "libc", 490 | ] 491 | 492 | [[package]] 493 | name = "http" 494 | version = "0.2.12" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 497 | dependencies = [ 498 | "bytes", 499 | "fnv", 500 | "itoa", 501 | ] 502 | 503 | [[package]] 504 | name = "http" 505 | version = "1.2.0" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 508 | dependencies = [ 509 | "bytes", 510 | "fnv", 511 | "itoa", 512 | ] 513 | 514 | [[package]] 515 | name = "http-body" 516 | version = "0.4.6" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 519 | dependencies = [ 520 | "bytes", 521 | "http 0.2.12", 522 | "pin-project-lite", 523 | ] 524 | 525 | [[package]] 526 | name = "httparse" 527 | version = "1.9.5" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 530 | 531 | [[package]] 532 | name = "httpdate" 533 | version = "1.0.3" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 536 | 537 | [[package]] 538 | name = "humantime" 539 | version = "1.3.0" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 542 | dependencies = [ 543 | "quick-error", 544 | ] 545 | 546 | [[package]] 547 | name = "hyper" 548 | version = "0.14.32" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" 551 | dependencies = [ 552 | "bytes", 553 | "futures-channel", 554 | "futures-core", 555 | "futures-util", 556 | "h2", 557 | "http 0.2.12", 558 | "http-body", 559 | "httparse", 560 | "httpdate", 561 | "itoa", 562 | "pin-project-lite", 563 | "socket2", 564 | "tokio", 565 | "tower-service", 566 | "tracing", 567 | "want", 568 | ] 569 | 570 | [[package]] 571 | name = "hyper-tls" 572 | version = "0.5.0" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 575 | dependencies = [ 576 | "bytes", 577 | "hyper", 578 | "native-tls", 579 | "tokio", 580 | "tokio-native-tls", 581 | ] 582 | 583 | [[package]] 584 | name = "icu_collections" 585 | version = "1.5.0" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 588 | dependencies = [ 589 | "displaydoc", 590 | "yoke", 591 | "zerofrom", 592 | "zerovec", 593 | ] 594 | 595 | [[package]] 596 | name = "icu_locid" 597 | version = "1.5.0" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 600 | dependencies = [ 601 | "displaydoc", 602 | "litemap", 603 | "tinystr", 604 | "writeable", 605 | "zerovec", 606 | ] 607 | 608 | [[package]] 609 | name = "icu_locid_transform" 610 | version = "1.5.0" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 613 | dependencies = [ 614 | "displaydoc", 615 | "icu_locid", 616 | "icu_locid_transform_data", 617 | "icu_provider", 618 | "tinystr", 619 | "zerovec", 620 | ] 621 | 622 | [[package]] 623 | name = "icu_locid_transform_data" 624 | version = "1.5.0" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 627 | 628 | [[package]] 629 | name = "icu_normalizer" 630 | version = "1.5.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 633 | dependencies = [ 634 | "displaydoc", 635 | "icu_collections", 636 | "icu_normalizer_data", 637 | "icu_properties", 638 | "icu_provider", 639 | "smallvec", 640 | "utf16_iter", 641 | "utf8_iter", 642 | "write16", 643 | "zerovec", 644 | ] 645 | 646 | [[package]] 647 | name = "icu_normalizer_data" 648 | version = "1.5.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 651 | 652 | [[package]] 653 | name = "icu_properties" 654 | version = "1.5.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 657 | dependencies = [ 658 | "displaydoc", 659 | "icu_collections", 660 | "icu_locid_transform", 661 | "icu_properties_data", 662 | "icu_provider", 663 | "tinystr", 664 | "zerovec", 665 | ] 666 | 667 | [[package]] 668 | name = "icu_properties_data" 669 | version = "1.5.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 672 | 673 | [[package]] 674 | name = "icu_provider" 675 | version = "1.5.0" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 678 | dependencies = [ 679 | "displaydoc", 680 | "icu_locid", 681 | "icu_provider_macros", 682 | "stable_deref_trait", 683 | "tinystr", 684 | "writeable", 685 | "yoke", 686 | "zerofrom", 687 | "zerovec", 688 | ] 689 | 690 | [[package]] 691 | name = "icu_provider_macros" 692 | version = "1.5.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 695 | dependencies = [ 696 | "proc-macro2", 697 | "quote", 698 | "syn 2.0.95", 699 | ] 700 | 701 | [[package]] 702 | name = "idna" 703 | version = "1.0.3" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 706 | dependencies = [ 707 | "idna_adapter", 708 | "smallvec", 709 | "utf8_iter", 710 | ] 711 | 712 | [[package]] 713 | name = "idna_adapter" 714 | version = "1.2.0" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 717 | dependencies = [ 718 | "icu_normalizer", 719 | "icu_properties", 720 | ] 721 | 722 | [[package]] 723 | name = "indexmap" 724 | version = "2.7.0" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 727 | dependencies = [ 728 | "equivalent", 729 | "hashbrown 0.15.2", 730 | ] 731 | 732 | [[package]] 733 | name = "ipnet" 734 | version = "2.10.1" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" 737 | 738 | [[package]] 739 | name = "itoa" 740 | version = "1.0.14" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 743 | 744 | [[package]] 745 | name = "jobserver" 746 | version = "0.1.32" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 749 | dependencies = [ 750 | "libc", 751 | ] 752 | 753 | [[package]] 754 | name = "js-sys" 755 | version = "0.3.76" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 758 | dependencies = [ 759 | "once_cell", 760 | "wasm-bindgen", 761 | ] 762 | 763 | [[package]] 764 | name = "lazy_static" 765 | version = "1.5.0" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 768 | 769 | [[package]] 770 | name = "libc" 771 | version = "0.2.169" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 774 | 775 | [[package]] 776 | name = "linux-raw-sys" 777 | version = "0.4.15" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 780 | 781 | [[package]] 782 | name = "litemap" 783 | version = "0.7.4" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 786 | 787 | [[package]] 788 | name = "lock_api" 789 | version = "0.4.12" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 792 | dependencies = [ 793 | "autocfg", 794 | "scopeguard", 795 | ] 796 | 797 | [[package]] 798 | name = "log" 799 | version = "0.4.22" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 802 | 803 | [[package]] 804 | name = "lru" 805 | version = "0.8.1" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" 808 | dependencies = [ 809 | "hashbrown 0.12.3", 810 | ] 811 | 812 | [[package]] 813 | name = "memchr" 814 | version = "2.7.4" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 817 | 818 | [[package]] 819 | name = "mime" 820 | version = "0.3.17" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 823 | 824 | [[package]] 825 | name = "mime_guess" 826 | version = "2.0.5" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" 829 | dependencies = [ 830 | "mime", 831 | "unicase", 832 | ] 833 | 834 | [[package]] 835 | name = "miniz_oxide" 836 | version = "0.8.2" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" 839 | dependencies = [ 840 | "adler2", 841 | ] 842 | 843 | [[package]] 844 | name = "mio" 845 | version = "1.0.3" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 848 | dependencies = [ 849 | "libc", 850 | "wasi", 851 | "windows-sys 0.52.0", 852 | ] 853 | 854 | [[package]] 855 | name = "multer" 856 | version = "2.1.0" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" 859 | dependencies = [ 860 | "bytes", 861 | "encoding_rs", 862 | "futures-util", 863 | "http 0.2.12", 864 | "httparse", 865 | "log", 866 | "memchr", 867 | "mime", 868 | "spin", 869 | "version_check", 870 | ] 871 | 872 | [[package]] 873 | name = "native-tls" 874 | version = "0.2.12" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 877 | dependencies = [ 878 | "libc", 879 | "log", 880 | "openssl", 881 | "openssl-probe", 882 | "openssl-sys", 883 | "schannel", 884 | "security-framework", 885 | "security-framework-sys", 886 | "tempfile", 887 | ] 888 | 889 | [[package]] 890 | name = "nix-cpio-generator" 891 | version = "0.3.3" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "dc679d2d94252be9bfc7cc664cb3eb208aba4a1c4bd68b6d61138df906033edf" 894 | dependencies = [ 895 | "bytes", 896 | "cpio", 897 | "futures", 898 | "lazy_static", 899 | "log", 900 | "lru", 901 | "tempfile", 902 | "thiserror", 903 | "tokio", 904 | "tokio-stream", 905 | "tokio-util 0.6.10", 906 | "walkdir", 907 | "zstd", 908 | ] 909 | 910 | [[package]] 911 | name = "nix-netboot-serve" 912 | version = "0.1.0" 913 | dependencies = [ 914 | "cpio", 915 | "futures", 916 | "http 0.2.12", 917 | "lazy_static", 918 | "log", 919 | "nix-cpio-generator", 920 | "pretty_env_logger", 921 | "reqwest", 922 | "rlimit", 923 | "serde", 924 | "serde_urlencoded", 925 | "structopt", 926 | "tempfile", 927 | "tokio", 928 | "tokio-stream", 929 | "tokio-util 0.6.10", 930 | "walkdir", 931 | "warp", 932 | "zstd", 933 | ] 934 | 935 | [[package]] 936 | name = "object" 937 | version = "0.36.7" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 940 | dependencies = [ 941 | "memchr", 942 | ] 943 | 944 | [[package]] 945 | name = "once_cell" 946 | version = "1.20.2" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 949 | 950 | [[package]] 951 | name = "openssl" 952 | version = "0.10.72" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" 955 | dependencies = [ 956 | "bitflags 2.6.0", 957 | "cfg-if", 958 | "foreign-types", 959 | "libc", 960 | "once_cell", 961 | "openssl-macros", 962 | "openssl-sys", 963 | ] 964 | 965 | [[package]] 966 | name = "openssl-macros" 967 | version = "0.1.1" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 970 | dependencies = [ 971 | "proc-macro2", 972 | "quote", 973 | "syn 2.0.95", 974 | ] 975 | 976 | [[package]] 977 | name = "openssl-probe" 978 | version = "0.1.5" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 981 | 982 | [[package]] 983 | name = "openssl-sys" 984 | version = "0.9.107" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" 987 | dependencies = [ 988 | "cc", 989 | "libc", 990 | "pkg-config", 991 | "vcpkg", 992 | ] 993 | 994 | [[package]] 995 | name = "parking_lot" 996 | version = "0.12.3" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 999 | dependencies = [ 1000 | "lock_api", 1001 | "parking_lot_core", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "parking_lot_core" 1006 | version = "0.9.10" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1009 | dependencies = [ 1010 | "cfg-if", 1011 | "libc", 1012 | "redox_syscall", 1013 | "smallvec", 1014 | "windows-targets 0.52.6", 1015 | ] 1016 | 1017 | [[package]] 1018 | name = "percent-encoding" 1019 | version = "2.3.1" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1022 | 1023 | [[package]] 1024 | name = "pin-project" 1025 | version = "1.1.8" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" 1028 | dependencies = [ 1029 | "pin-project-internal", 1030 | ] 1031 | 1032 | [[package]] 1033 | name = "pin-project-internal" 1034 | version = "1.1.8" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" 1037 | dependencies = [ 1038 | "proc-macro2", 1039 | "quote", 1040 | "syn 2.0.95", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "pin-project-lite" 1045 | version = "0.2.16" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1048 | 1049 | [[package]] 1050 | name = "pin-utils" 1051 | version = "0.1.0" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1054 | 1055 | [[package]] 1056 | name = "pkg-config" 1057 | version = "0.3.31" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1060 | 1061 | [[package]] 1062 | name = "ppv-lite86" 1063 | version = "0.2.20" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1066 | dependencies = [ 1067 | "zerocopy", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "pretty_env_logger" 1072 | version = "0.4.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" 1075 | dependencies = [ 1076 | "env_logger", 1077 | "log", 1078 | ] 1079 | 1080 | [[package]] 1081 | name = "proc-macro-error" 1082 | version = "1.0.4" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1085 | dependencies = [ 1086 | "proc-macro-error-attr", 1087 | "proc-macro2", 1088 | "quote", 1089 | "syn 1.0.109", 1090 | "version_check", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "proc-macro-error-attr" 1095 | version = "1.0.4" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1098 | dependencies = [ 1099 | "proc-macro2", 1100 | "quote", 1101 | "version_check", 1102 | ] 1103 | 1104 | [[package]] 1105 | name = "proc-macro2" 1106 | version = "1.0.92" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 1109 | dependencies = [ 1110 | "unicode-ident", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "quick-error" 1115 | version = "1.2.3" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1118 | 1119 | [[package]] 1120 | name = "quote" 1121 | version = "1.0.38" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1124 | dependencies = [ 1125 | "proc-macro2", 1126 | ] 1127 | 1128 | [[package]] 1129 | name = "rand" 1130 | version = "0.8.5" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1133 | dependencies = [ 1134 | "libc", 1135 | "rand_chacha", 1136 | "rand_core", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "rand_chacha" 1141 | version = "0.3.1" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1144 | dependencies = [ 1145 | "ppv-lite86", 1146 | "rand_core", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "rand_core" 1151 | version = "0.6.4" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1154 | dependencies = [ 1155 | "getrandom", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "redox_syscall" 1160 | version = "0.5.8" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" 1163 | dependencies = [ 1164 | "bitflags 2.6.0", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "regex" 1169 | version = "1.11.1" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1172 | dependencies = [ 1173 | "aho-corasick", 1174 | "memchr", 1175 | "regex-automata", 1176 | "regex-syntax", 1177 | ] 1178 | 1179 | [[package]] 1180 | name = "regex-automata" 1181 | version = "0.4.9" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1184 | dependencies = [ 1185 | "aho-corasick", 1186 | "memchr", 1187 | "regex-syntax", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "regex-syntax" 1192 | version = "0.8.5" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1195 | 1196 | [[package]] 1197 | name = "reqwest" 1198 | version = "0.11.27" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 1201 | dependencies = [ 1202 | "base64", 1203 | "bytes", 1204 | "encoding_rs", 1205 | "futures-core", 1206 | "futures-util", 1207 | "h2", 1208 | "http 0.2.12", 1209 | "http-body", 1210 | "hyper", 1211 | "hyper-tls", 1212 | "ipnet", 1213 | "js-sys", 1214 | "log", 1215 | "mime", 1216 | "native-tls", 1217 | "once_cell", 1218 | "percent-encoding", 1219 | "pin-project-lite", 1220 | "rustls-pemfile", 1221 | "serde", 1222 | "serde_json", 1223 | "serde_urlencoded", 1224 | "sync_wrapper", 1225 | "system-configuration", 1226 | "tokio", 1227 | "tokio-native-tls", 1228 | "tower-service", 1229 | "url", 1230 | "wasm-bindgen", 1231 | "wasm-bindgen-futures", 1232 | "web-sys", 1233 | "winreg", 1234 | ] 1235 | 1236 | [[package]] 1237 | name = "rlimit" 1238 | version = "0.6.2" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "cc0bf25554376fd362f54332b8410a625c71f15445bca32ffdfdf4ec9ac91726" 1241 | dependencies = [ 1242 | "libc", 1243 | ] 1244 | 1245 | [[package]] 1246 | name = "rustc-demangle" 1247 | version = "0.1.24" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1250 | 1251 | [[package]] 1252 | name = "rustix" 1253 | version = "0.38.43" 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" 1255 | checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" 1256 | dependencies = [ 1257 | "bitflags 2.6.0", 1258 | "errno", 1259 | "libc", 1260 | "linux-raw-sys", 1261 | "windows-sys 0.59.0", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "rustls-pemfile" 1266 | version = "1.0.4" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1269 | dependencies = [ 1270 | "base64", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "ryu" 1275 | version = "1.0.18" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1278 | 1279 | [[package]] 1280 | name = "same-file" 1281 | version = "1.0.6" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1284 | dependencies = [ 1285 | "winapi-util", 1286 | ] 1287 | 1288 | [[package]] 1289 | name = "schannel" 1290 | version = "0.1.27" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1293 | dependencies = [ 1294 | "windows-sys 0.59.0", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "scoped-tls" 1299 | version = "1.0.1" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1302 | 1303 | [[package]] 1304 | name = "scopeguard" 1305 | version = "1.2.0" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1308 | 1309 | [[package]] 1310 | name = "security-framework" 1311 | version = "2.11.1" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1314 | dependencies = [ 1315 | "bitflags 2.6.0", 1316 | "core-foundation", 1317 | "core-foundation-sys", 1318 | "libc", 1319 | "security-framework-sys", 1320 | ] 1321 | 1322 | [[package]] 1323 | name = "security-framework-sys" 1324 | version = "2.14.0" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 1327 | dependencies = [ 1328 | "core-foundation-sys", 1329 | "libc", 1330 | ] 1331 | 1332 | [[package]] 1333 | name = "serde" 1334 | version = "1.0.217" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1337 | dependencies = [ 1338 | "serde_derive", 1339 | ] 1340 | 1341 | [[package]] 1342 | name = "serde_derive" 1343 | version = "1.0.217" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1346 | dependencies = [ 1347 | "proc-macro2", 1348 | "quote", 1349 | "syn 2.0.95", 1350 | ] 1351 | 1352 | [[package]] 1353 | name = "serde_json" 1354 | version = "1.0.135" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" 1357 | dependencies = [ 1358 | "itoa", 1359 | "memchr", 1360 | "ryu", 1361 | "serde", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "serde_urlencoded" 1366 | version = "0.7.1" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1369 | dependencies = [ 1370 | "form_urlencoded", 1371 | "itoa", 1372 | "ryu", 1373 | "serde", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "sha1" 1378 | version = "0.10.6" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1381 | dependencies = [ 1382 | "cfg-if", 1383 | "cpufeatures", 1384 | "digest", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "shlex" 1389 | version = "1.3.0" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1392 | 1393 | [[package]] 1394 | name = "signal-hook-registry" 1395 | version = "1.4.2" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1398 | dependencies = [ 1399 | "libc", 1400 | ] 1401 | 1402 | [[package]] 1403 | name = "slab" 1404 | version = "0.4.9" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1407 | dependencies = [ 1408 | "autocfg", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "smallvec" 1413 | version = "1.13.2" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1416 | 1417 | [[package]] 1418 | name = "socket2" 1419 | version = "0.5.8" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 1422 | dependencies = [ 1423 | "libc", 1424 | "windows-sys 0.52.0", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "spin" 1429 | version = "0.9.8" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1432 | 1433 | [[package]] 1434 | name = "stable_deref_trait" 1435 | version = "1.2.0" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1438 | 1439 | [[package]] 1440 | name = "strsim" 1441 | version = "0.8.0" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1444 | 1445 | [[package]] 1446 | name = "structopt" 1447 | version = "0.3.26" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" 1450 | dependencies = [ 1451 | "clap", 1452 | "lazy_static", 1453 | "structopt-derive", 1454 | ] 1455 | 1456 | [[package]] 1457 | name = "structopt-derive" 1458 | version = "0.4.18" 1459 | source = "registry+https://github.com/rust-lang/crates.io-index" 1460 | checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" 1461 | dependencies = [ 1462 | "heck", 1463 | "proc-macro-error", 1464 | "proc-macro2", 1465 | "quote", 1466 | "syn 1.0.109", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "syn" 1471 | version = "1.0.109" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1474 | dependencies = [ 1475 | "proc-macro2", 1476 | "quote", 1477 | "unicode-ident", 1478 | ] 1479 | 1480 | [[package]] 1481 | name = "syn" 1482 | version = "2.0.95" 1483 | source = "registry+https://github.com/rust-lang/crates.io-index" 1484 | checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" 1485 | dependencies = [ 1486 | "proc-macro2", 1487 | "quote", 1488 | "unicode-ident", 1489 | ] 1490 | 1491 | [[package]] 1492 | name = "sync_wrapper" 1493 | version = "0.1.2" 1494 | source = "registry+https://github.com/rust-lang/crates.io-index" 1495 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1496 | 1497 | [[package]] 1498 | name = "synstructure" 1499 | version = "0.13.1" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1502 | dependencies = [ 1503 | "proc-macro2", 1504 | "quote", 1505 | "syn 2.0.95", 1506 | ] 1507 | 1508 | [[package]] 1509 | name = "system-configuration" 1510 | version = "0.5.1" 1511 | source = "registry+https://github.com/rust-lang/crates.io-index" 1512 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 1513 | dependencies = [ 1514 | "bitflags 1.3.2", 1515 | "core-foundation", 1516 | "system-configuration-sys", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "system-configuration-sys" 1521 | version = "0.5.0" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 1524 | dependencies = [ 1525 | "core-foundation-sys", 1526 | "libc", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "tempfile" 1531 | version = "3.15.0" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" 1534 | dependencies = [ 1535 | "cfg-if", 1536 | "fastrand", 1537 | "getrandom", 1538 | "once_cell", 1539 | "rustix", 1540 | "windows-sys 0.59.0", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "termcolor" 1545 | version = "1.4.1" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1548 | dependencies = [ 1549 | "winapi-util", 1550 | ] 1551 | 1552 | [[package]] 1553 | name = "textwrap" 1554 | version = "0.11.0" 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" 1556 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1557 | dependencies = [ 1558 | "unicode-width", 1559 | ] 1560 | 1561 | [[package]] 1562 | name = "thiserror" 1563 | version = "1.0.69" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1566 | dependencies = [ 1567 | "thiserror-impl", 1568 | ] 1569 | 1570 | [[package]] 1571 | name = "thiserror-impl" 1572 | version = "1.0.69" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1575 | dependencies = [ 1576 | "proc-macro2", 1577 | "quote", 1578 | "syn 2.0.95", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "tinystr" 1583 | version = "0.7.6" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1586 | dependencies = [ 1587 | "displaydoc", 1588 | "zerovec", 1589 | ] 1590 | 1591 | [[package]] 1592 | name = "tokio" 1593 | version = "1.43.1" 1594 | source = "registry+https://github.com/rust-lang/crates.io-index" 1595 | checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c" 1596 | dependencies = [ 1597 | "backtrace", 1598 | "bytes", 1599 | "libc", 1600 | "mio", 1601 | "parking_lot", 1602 | "pin-project-lite", 1603 | "signal-hook-registry", 1604 | "socket2", 1605 | "tokio-macros", 1606 | "windows-sys 0.52.0", 1607 | ] 1608 | 1609 | [[package]] 1610 | name = "tokio-macros" 1611 | version = "2.5.0" 1612 | source = "registry+https://github.com/rust-lang/crates.io-index" 1613 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1614 | dependencies = [ 1615 | "proc-macro2", 1616 | "quote", 1617 | "syn 2.0.95", 1618 | ] 1619 | 1620 | [[package]] 1621 | name = "tokio-native-tls" 1622 | version = "0.3.1" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1625 | dependencies = [ 1626 | "native-tls", 1627 | "tokio", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "tokio-stream" 1632 | version = "0.1.17" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 1635 | dependencies = [ 1636 | "futures-core", 1637 | "pin-project-lite", 1638 | "tokio", 1639 | ] 1640 | 1641 | [[package]] 1642 | name = "tokio-tungstenite" 1643 | version = "0.21.0" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" 1646 | dependencies = [ 1647 | "futures-util", 1648 | "log", 1649 | "tokio", 1650 | "tungstenite", 1651 | ] 1652 | 1653 | [[package]] 1654 | name = "tokio-util" 1655 | version = "0.6.10" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" 1658 | dependencies = [ 1659 | "bytes", 1660 | "futures-core", 1661 | "futures-sink", 1662 | "log", 1663 | "pin-project-lite", 1664 | "tokio", 1665 | ] 1666 | 1667 | [[package]] 1668 | name = "tokio-util" 1669 | version = "0.7.13" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 1672 | dependencies = [ 1673 | "bytes", 1674 | "futures-core", 1675 | "futures-sink", 1676 | "pin-project-lite", 1677 | "tokio", 1678 | ] 1679 | 1680 | [[package]] 1681 | name = "tower-service" 1682 | version = "0.3.3" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1685 | 1686 | [[package]] 1687 | name = "tracing" 1688 | version = "0.1.41" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1691 | dependencies = [ 1692 | "log", 1693 | "pin-project-lite", 1694 | "tracing-core", 1695 | ] 1696 | 1697 | [[package]] 1698 | name = "tracing-core" 1699 | version = "0.1.33" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1702 | dependencies = [ 1703 | "once_cell", 1704 | ] 1705 | 1706 | [[package]] 1707 | name = "try-lock" 1708 | version = "0.2.5" 1709 | source = "registry+https://github.com/rust-lang/crates.io-index" 1710 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1711 | 1712 | [[package]] 1713 | name = "tungstenite" 1714 | version = "0.21.0" 1715 | source = "registry+https://github.com/rust-lang/crates.io-index" 1716 | checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" 1717 | dependencies = [ 1718 | "byteorder", 1719 | "bytes", 1720 | "data-encoding", 1721 | "http 1.2.0", 1722 | "httparse", 1723 | "log", 1724 | "rand", 1725 | "sha1", 1726 | "thiserror", 1727 | "url", 1728 | "utf-8", 1729 | ] 1730 | 1731 | [[package]] 1732 | name = "typenum" 1733 | version = "1.17.0" 1734 | source = "registry+https://github.com/rust-lang/crates.io-index" 1735 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1736 | 1737 | [[package]] 1738 | name = "unicase" 1739 | version = "2.8.1" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" 1742 | 1743 | [[package]] 1744 | name = "unicode-ident" 1745 | version = "1.0.14" 1746 | source = "registry+https://github.com/rust-lang/crates.io-index" 1747 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 1748 | 1749 | [[package]] 1750 | name = "unicode-segmentation" 1751 | version = "1.12.0" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 1754 | 1755 | [[package]] 1756 | name = "unicode-width" 1757 | version = "0.1.14" 1758 | source = "registry+https://github.com/rust-lang/crates.io-index" 1759 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 1760 | 1761 | [[package]] 1762 | name = "url" 1763 | version = "2.5.4" 1764 | source = "registry+https://github.com/rust-lang/crates.io-index" 1765 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1766 | dependencies = [ 1767 | "form_urlencoded", 1768 | "idna", 1769 | "percent-encoding", 1770 | ] 1771 | 1772 | [[package]] 1773 | name = "utf-8" 1774 | version = "0.7.6" 1775 | source = "registry+https://github.com/rust-lang/crates.io-index" 1776 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1777 | 1778 | [[package]] 1779 | name = "utf16_iter" 1780 | version = "1.0.5" 1781 | source = "registry+https://github.com/rust-lang/crates.io-index" 1782 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1783 | 1784 | [[package]] 1785 | name = "utf8_iter" 1786 | version = "1.0.4" 1787 | source = "registry+https://github.com/rust-lang/crates.io-index" 1788 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1789 | 1790 | [[package]] 1791 | name = "vcpkg" 1792 | version = "0.2.15" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1795 | 1796 | [[package]] 1797 | name = "vec_map" 1798 | version = "0.8.2" 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" 1800 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1801 | 1802 | [[package]] 1803 | name = "version_check" 1804 | version = "0.9.5" 1805 | source = "registry+https://github.com/rust-lang/crates.io-index" 1806 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1807 | 1808 | [[package]] 1809 | name = "walkdir" 1810 | version = "2.5.0" 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" 1812 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1813 | dependencies = [ 1814 | "same-file", 1815 | "winapi-util", 1816 | ] 1817 | 1818 | [[package]] 1819 | name = "want" 1820 | version = "0.3.1" 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" 1822 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1823 | dependencies = [ 1824 | "try-lock", 1825 | ] 1826 | 1827 | [[package]] 1828 | name = "warp" 1829 | version = "0.3.7" 1830 | source = "registry+https://github.com/rust-lang/crates.io-index" 1831 | checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" 1832 | dependencies = [ 1833 | "bytes", 1834 | "futures-channel", 1835 | "futures-util", 1836 | "headers", 1837 | "http 0.2.12", 1838 | "hyper", 1839 | "log", 1840 | "mime", 1841 | "mime_guess", 1842 | "multer", 1843 | "percent-encoding", 1844 | "pin-project", 1845 | "scoped-tls", 1846 | "serde", 1847 | "serde_json", 1848 | "serde_urlencoded", 1849 | "tokio", 1850 | "tokio-tungstenite", 1851 | "tokio-util 0.7.13", 1852 | "tower-service", 1853 | "tracing", 1854 | ] 1855 | 1856 | [[package]] 1857 | name = "wasi" 1858 | version = "0.11.0+wasi-snapshot-preview1" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1861 | 1862 | [[package]] 1863 | name = "wasm-bindgen" 1864 | version = "0.2.99" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 1867 | dependencies = [ 1868 | "cfg-if", 1869 | "once_cell", 1870 | "wasm-bindgen-macro", 1871 | ] 1872 | 1873 | [[package]] 1874 | name = "wasm-bindgen-backend" 1875 | version = "0.2.99" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 1878 | dependencies = [ 1879 | "bumpalo", 1880 | "log", 1881 | "proc-macro2", 1882 | "quote", 1883 | "syn 2.0.95", 1884 | "wasm-bindgen-shared", 1885 | ] 1886 | 1887 | [[package]] 1888 | name = "wasm-bindgen-futures" 1889 | version = "0.4.49" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" 1892 | dependencies = [ 1893 | "cfg-if", 1894 | "js-sys", 1895 | "once_cell", 1896 | "wasm-bindgen", 1897 | "web-sys", 1898 | ] 1899 | 1900 | [[package]] 1901 | name = "wasm-bindgen-macro" 1902 | version = "0.2.99" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 1905 | dependencies = [ 1906 | "quote", 1907 | "wasm-bindgen-macro-support", 1908 | ] 1909 | 1910 | [[package]] 1911 | name = "wasm-bindgen-macro-support" 1912 | version = "0.2.99" 1913 | source = "registry+https://github.com/rust-lang/crates.io-index" 1914 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 1915 | dependencies = [ 1916 | "proc-macro2", 1917 | "quote", 1918 | "syn 2.0.95", 1919 | "wasm-bindgen-backend", 1920 | "wasm-bindgen-shared", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "wasm-bindgen-shared" 1925 | version = "0.2.99" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 1928 | 1929 | [[package]] 1930 | name = "web-sys" 1931 | version = "0.3.76" 1932 | source = "registry+https://github.com/rust-lang/crates.io-index" 1933 | checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" 1934 | dependencies = [ 1935 | "js-sys", 1936 | "wasm-bindgen", 1937 | ] 1938 | 1939 | [[package]] 1940 | name = "winapi" 1941 | version = "0.3.9" 1942 | source = "registry+https://github.com/rust-lang/crates.io-index" 1943 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1944 | dependencies = [ 1945 | "winapi-i686-pc-windows-gnu", 1946 | "winapi-x86_64-pc-windows-gnu", 1947 | ] 1948 | 1949 | [[package]] 1950 | name = "winapi-i686-pc-windows-gnu" 1951 | version = "0.4.0" 1952 | source = "registry+https://github.com/rust-lang/crates.io-index" 1953 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1954 | 1955 | [[package]] 1956 | name = "winapi-util" 1957 | version = "0.1.9" 1958 | source = "registry+https://github.com/rust-lang/crates.io-index" 1959 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 1960 | dependencies = [ 1961 | "windows-sys 0.59.0", 1962 | ] 1963 | 1964 | [[package]] 1965 | name = "winapi-x86_64-pc-windows-gnu" 1966 | version = "0.4.0" 1967 | source = "registry+https://github.com/rust-lang/crates.io-index" 1968 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1969 | 1970 | [[package]] 1971 | name = "windows-sys" 1972 | version = "0.48.0" 1973 | source = "registry+https://github.com/rust-lang/crates.io-index" 1974 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1975 | dependencies = [ 1976 | "windows-targets 0.48.5", 1977 | ] 1978 | 1979 | [[package]] 1980 | name = "windows-sys" 1981 | version = "0.52.0" 1982 | source = "registry+https://github.com/rust-lang/crates.io-index" 1983 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1984 | dependencies = [ 1985 | "windows-targets 0.52.6", 1986 | ] 1987 | 1988 | [[package]] 1989 | name = "windows-sys" 1990 | version = "0.59.0" 1991 | source = "registry+https://github.com/rust-lang/crates.io-index" 1992 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1993 | dependencies = [ 1994 | "windows-targets 0.52.6", 1995 | ] 1996 | 1997 | [[package]] 1998 | name = "windows-targets" 1999 | version = "0.48.5" 2000 | source = "registry+https://github.com/rust-lang/crates.io-index" 2001 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2002 | dependencies = [ 2003 | "windows_aarch64_gnullvm 0.48.5", 2004 | "windows_aarch64_msvc 0.48.5", 2005 | "windows_i686_gnu 0.48.5", 2006 | "windows_i686_msvc 0.48.5", 2007 | "windows_x86_64_gnu 0.48.5", 2008 | "windows_x86_64_gnullvm 0.48.5", 2009 | "windows_x86_64_msvc 0.48.5", 2010 | ] 2011 | 2012 | [[package]] 2013 | name = "windows-targets" 2014 | version = "0.52.6" 2015 | source = "registry+https://github.com/rust-lang/crates.io-index" 2016 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2017 | dependencies = [ 2018 | "windows_aarch64_gnullvm 0.52.6", 2019 | "windows_aarch64_msvc 0.52.6", 2020 | "windows_i686_gnu 0.52.6", 2021 | "windows_i686_gnullvm", 2022 | "windows_i686_msvc 0.52.6", 2023 | "windows_x86_64_gnu 0.52.6", 2024 | "windows_x86_64_gnullvm 0.52.6", 2025 | "windows_x86_64_msvc 0.52.6", 2026 | ] 2027 | 2028 | [[package]] 2029 | name = "windows_aarch64_gnullvm" 2030 | version = "0.48.5" 2031 | source = "registry+https://github.com/rust-lang/crates.io-index" 2032 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2033 | 2034 | [[package]] 2035 | name = "windows_aarch64_gnullvm" 2036 | version = "0.52.6" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2039 | 2040 | [[package]] 2041 | name = "windows_aarch64_msvc" 2042 | version = "0.48.5" 2043 | source = "registry+https://github.com/rust-lang/crates.io-index" 2044 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2045 | 2046 | [[package]] 2047 | name = "windows_aarch64_msvc" 2048 | version = "0.52.6" 2049 | source = "registry+https://github.com/rust-lang/crates.io-index" 2050 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2051 | 2052 | [[package]] 2053 | name = "windows_i686_gnu" 2054 | version = "0.48.5" 2055 | source = "registry+https://github.com/rust-lang/crates.io-index" 2056 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2057 | 2058 | [[package]] 2059 | name = "windows_i686_gnu" 2060 | version = "0.52.6" 2061 | source = "registry+https://github.com/rust-lang/crates.io-index" 2062 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2063 | 2064 | [[package]] 2065 | name = "windows_i686_gnullvm" 2066 | version = "0.52.6" 2067 | source = "registry+https://github.com/rust-lang/crates.io-index" 2068 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2069 | 2070 | [[package]] 2071 | name = "windows_i686_msvc" 2072 | version = "0.48.5" 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" 2074 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2075 | 2076 | [[package]] 2077 | name = "windows_i686_msvc" 2078 | version = "0.52.6" 2079 | source = "registry+https://github.com/rust-lang/crates.io-index" 2080 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2081 | 2082 | [[package]] 2083 | name = "windows_x86_64_gnu" 2084 | version = "0.48.5" 2085 | source = "registry+https://github.com/rust-lang/crates.io-index" 2086 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2087 | 2088 | [[package]] 2089 | name = "windows_x86_64_gnu" 2090 | version = "0.52.6" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2093 | 2094 | [[package]] 2095 | name = "windows_x86_64_gnullvm" 2096 | version = "0.48.5" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2099 | 2100 | [[package]] 2101 | name = "windows_x86_64_gnullvm" 2102 | version = "0.52.6" 2103 | source = "registry+https://github.com/rust-lang/crates.io-index" 2104 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2105 | 2106 | [[package]] 2107 | name = "windows_x86_64_msvc" 2108 | version = "0.48.5" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2111 | 2112 | [[package]] 2113 | name = "windows_x86_64_msvc" 2114 | version = "0.52.6" 2115 | source = "registry+https://github.com/rust-lang/crates.io-index" 2116 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2117 | 2118 | [[package]] 2119 | name = "winreg" 2120 | version = "0.50.0" 2121 | source = "registry+https://github.com/rust-lang/crates.io-index" 2122 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 2123 | dependencies = [ 2124 | "cfg-if", 2125 | "windows-sys 0.48.0", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "write16" 2130 | version = "1.0.0" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2133 | 2134 | [[package]] 2135 | name = "writeable" 2136 | version = "0.5.5" 2137 | source = "registry+https://github.com/rust-lang/crates.io-index" 2138 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2139 | 2140 | [[package]] 2141 | name = "yoke" 2142 | version = "0.7.5" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 2145 | dependencies = [ 2146 | "serde", 2147 | "stable_deref_trait", 2148 | "yoke-derive", 2149 | "zerofrom", 2150 | ] 2151 | 2152 | [[package]] 2153 | name = "yoke-derive" 2154 | version = "0.7.5" 2155 | source = "registry+https://github.com/rust-lang/crates.io-index" 2156 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 2157 | dependencies = [ 2158 | "proc-macro2", 2159 | "quote", 2160 | "syn 2.0.95", 2161 | "synstructure", 2162 | ] 2163 | 2164 | [[package]] 2165 | name = "zerocopy" 2166 | version = "0.7.35" 2167 | source = "registry+https://github.com/rust-lang/crates.io-index" 2168 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2169 | dependencies = [ 2170 | "byteorder", 2171 | "zerocopy-derive", 2172 | ] 2173 | 2174 | [[package]] 2175 | name = "zerocopy-derive" 2176 | version = "0.7.35" 2177 | source = "registry+https://github.com/rust-lang/crates.io-index" 2178 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2179 | dependencies = [ 2180 | "proc-macro2", 2181 | "quote", 2182 | "syn 2.0.95", 2183 | ] 2184 | 2185 | [[package]] 2186 | name = "zerofrom" 2187 | version = "0.1.5" 2188 | source = "registry+https://github.com/rust-lang/crates.io-index" 2189 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 2190 | dependencies = [ 2191 | "zerofrom-derive", 2192 | ] 2193 | 2194 | [[package]] 2195 | name = "zerofrom-derive" 2196 | version = "0.1.5" 2197 | source = "registry+https://github.com/rust-lang/crates.io-index" 2198 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 2199 | dependencies = [ 2200 | "proc-macro2", 2201 | "quote", 2202 | "syn 2.0.95", 2203 | "synstructure", 2204 | ] 2205 | 2206 | [[package]] 2207 | name = "zerovec" 2208 | version = "0.10.4" 2209 | source = "registry+https://github.com/rust-lang/crates.io-index" 2210 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2211 | dependencies = [ 2212 | "yoke", 2213 | "zerofrom", 2214 | "zerovec-derive", 2215 | ] 2216 | 2217 | [[package]] 2218 | name = "zerovec-derive" 2219 | version = "0.10.3" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2222 | dependencies = [ 2223 | "proc-macro2", 2224 | "quote", 2225 | "syn 2.0.95", 2226 | ] 2227 | 2228 | [[package]] 2229 | name = "zstd" 2230 | version = "0.11.2+zstd.1.5.2" 2231 | source = "registry+https://github.com/rust-lang/crates.io-index" 2232 | checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" 2233 | dependencies = [ 2234 | "zstd-safe", 2235 | ] 2236 | 2237 | [[package]] 2238 | name = "zstd-safe" 2239 | version = "5.0.2+zstd.1.5.2" 2240 | source = "registry+https://github.com/rust-lang/crates.io-index" 2241 | checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" 2242 | dependencies = [ 2243 | "libc", 2244 | "zstd-sys", 2245 | ] 2246 | 2247 | [[package]] 2248 | name = "zstd-sys" 2249 | version = "2.0.13+zstd.1.5.6" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" 2252 | dependencies = [ 2253 | "cc", 2254 | "pkg-config", 2255 | ] 2256 | --------------------------------------------------------------------------------