diff options
Diffstat (limited to 'ops')
143 files changed, 5367 insertions, 1671 deletions
diff --git a/ops/besadii/main.go b/ops/besadii/main.go index e22dbb1e48..809acc29e8 100644 --- a/ops/besadii/main.go +++ b/ops/besadii/main.go @@ -19,7 +19,7 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" + "io" "log/syslog" "net/http" "net/mail" @@ -130,7 +130,7 @@ func loadConfig() (*config, error) { } } - configJson, err := ioutil.ReadFile(configPath) + configJson, err := os.ReadFile(configPath) if err != nil { return nil, fmt.Errorf("failed to load besadii config: %w", err) } @@ -182,12 +182,12 @@ func linkToChange(cfg *config, changeId, patchset string) string { // updateGerrit posts a comment on a Gerrit CL to indicate the current build status. func updateGerrit(cfg *config, review reviewInput, changeId, patchset string) { body, _ := json.Marshal(review) - reader := ioutil.NopCloser(bytes.NewReader(body)) + reader := io.NopCloser(bytes.NewReader(body)) url := fmt.Sprintf("%s/a/changes/%s/revisions/%s/review", cfg.GerritUrl, changeId, patchset) req, err := http.NewRequest("POST", url, reader) if err != nil { - fmt.Fprintf(os.Stderr, "failed to create an HTTP request: %w", err) + fmt.Fprintf(os.Stderr, "failed to create an HTTP request: %s", err) os.Exit(1) } @@ -196,12 +196,12 @@ func updateGerrit(cfg *config, review reviewInput, changeId, patchset string) { resp, err := http.DefaultClient.Do(req) if err != nil { - fmt.Errorf("failed to update %s on %s: %w", cfg.GerritChangeName, cfg.GerritUrl, err) + fmt.Fprintf(os.Stderr, "failed to update %s on %s: %s", cfg.GerritChangeName, cfg.GerritUrl, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) fmt.Fprintf(os.Stderr, "received non-success response from Gerrit: %s (%v)", respBody, resp.Status) } else { fmt.Printf("Added CI status comment on %s", linkToChange(cfg, changeId, patchset)) @@ -241,7 +241,7 @@ func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error } body, _ := json.Marshal(build) - reader := ioutil.NopCloser(bytes.NewReader(body)) + reader := io.NopCloser(bytes.NewReader(body)) bkUrl := fmt.Sprintf("https://api.buildkite.com/v2/organizations/%s/pipelines/%s/builds", cfg.BuildkiteOrg, cfg.BuildkiteProject) req, err := http.NewRequest("POST", bkUrl, reader) @@ -259,7 +259,7 @@ func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read Buildkite response body: %w", err) } @@ -459,7 +459,7 @@ func gerritHookMain(cfg *config, log *syslog.Writer, trigger *buildTrigger) { log.Err(fmt.Sprintf("failed to trigger Buildkite build: %s", err)) } - if cfg.SourcegraphUrl != "" && trigger.ref == "refs/heads/canon" { + if cfg.SourcegraphUrl != "" && trigger.ref == cfg.Branch { err = triggerIndexUpdate(cfg, log) if err != nil { log.Err(fmt.Sprintf("failed to trigger sourcegraph index update: %s", err)) @@ -475,7 +475,7 @@ func postCommandMain(cfg *config) { // If these variables are unset, but the hook was invoked, the // build was most likely for a branch and not for a CL - no status // needs to be reported back to Gerrit! - fmt.Println("This isn't a %s build, nothing to do. Have a nice day!", cfg.GerritChangeName) + fmt.Printf("This isn't a %s build, nothing to do. Have a nice day!\n", cfg.GerritChangeName) return } diff --git a/ops/buildkite/.gitignore b/ops/buildkite/.gitignore new file mode 100644 index 0000000000..41c1b33462 --- /dev/null +++ b/ops/buildkite/.gitignore @@ -0,0 +1,2 @@ +.envrc +.terraform* diff --git a/ops/buildkite/README.md b/ops/buildkite/README.md new file mode 100644 index 0000000000..9d31a53fd3 --- /dev/null +++ b/ops/buildkite/README.md @@ -0,0 +1,24 @@ +Buildkite configuration +======================= + +This contains Terraform configuration for setting up our Buildkite +pipelines. + +Each pipeline (such as the one for depot itself, or exported subsets +of the depot) needs some static configuration stored in Buildkite. + +Through `//tools/depot-deps` a `tf-buildkite` binary is made available +which contains a Terraform binary pre-configured with the correct +providers. This is automatically on your `$PATH` through `direnv`. + +However, secrets still need to be loaded to access the Terraform state +and speak to the Buildkite API. These are available to certain users +through `//ops/secrets`. + +This can be done with separate direnv configuration, for example: + +``` +# //ops/buildkite/.envrc +source_up +eval $(age --decrypt -i ~/.ssh/id_ed25519 $(git rev-parse --show-toplevel)/ops/secrets/tf-buildkite.age) +``` diff --git a/ops/buildkite/default.nix b/ops/buildkite/default.nix new file mode 100644 index 0000000000..0d39bc0601 --- /dev/null +++ b/ops/buildkite/default.nix @@ -0,0 +1,14 @@ +{ depot, lib, pkgs, ... }: + +depot.nix.readTree.drvTargets rec { + terraform = pkgs.terraform.withPlugins (p: [ + p.buildkite + ]); + + validate = depot.tools.checks.validateTerraform { + inherit terraform; + name = "buildkite"; + src = lib.cleanSource ./.; + env.BUILDKITE_API_TOKEN = "ci-dummy"; + }; +} diff --git a/ops/buildkite/steps-depot.yml b/ops/buildkite/steps-depot.yml new file mode 100644 index 0000000000..011b299771 --- /dev/null +++ b/ops/buildkite/steps-depot.yml @@ -0,0 +1,6 @@ +--- +steps: + - label: ":buildkite:" + key: ":init:" + command: | + buildkite-agent pipeline upload ops/pipelines/static-pipeline.yaml diff --git a/ops/buildkite/steps-tvix.yml b/ops/buildkite/steps-tvix.yml new file mode 100644 index 0000000000..a6e9f13b16 --- /dev/null +++ b/ops/buildkite/steps-tvix.yml @@ -0,0 +1,4 @@ +--- +steps: + - label: ":buildkite: Upload pipeline" + command: "buildkite-agent pipeline upload" diff --git a/ops/buildkite/steps-tvl-kit.yml b/ops/buildkite/steps-tvl-kit.yml new file mode 100644 index 0000000000..a6e9f13b16 --- /dev/null +++ b/ops/buildkite/steps-tvl-kit.yml @@ -0,0 +1,4 @@ +--- +steps: + - label: ":buildkite: Upload pipeline" + command: "buildkite-agent pipeline upload" diff --git a/ops/buildkite/tvl.tf b/ops/buildkite/tvl.tf new file mode 100644 index 0000000000..4c45909a0c --- /dev/null +++ b/ops/buildkite/tvl.tf @@ -0,0 +1,48 @@ +# Buildkite configuration for TVL. + +terraform { + required_providers { + buildkite = { + source = "buildkite/buildkite" + } + } + + backend "s3" { + endpoint = "https://objects.dc-sto1.glesys.net" + bucket = "tvl-state" + key = "terraform/tvl-buildkite" + region = "glesys" + + skip_credentials_validation = true + skip_region_validation = true + skip_metadata_api_check = true + } +} + +provider "buildkite" { + organization = "tvl" +} + +resource "buildkite_pipeline" "depot" { + name = "depot" + description = "Run full CI pipeline of the depot, TVL's monorepo." + repository = "https://cl.tvl.fyi/depot" + steps = file("./steps-depot.yml") + default_branch = "refs/heads/canon" +} + +resource "buildkite_pipeline" "tvix" { + name = "tvix" + description = "Tvix, an exported subset of TVL depot" + repository = "https://code.tvl.fyi/depot.git:workspace=views/tvix.git" + steps = file("./steps-tvix.yml") + default_branch = "canon" +} + +resource "buildkite_pipeline" "tvl_kit" { + name = "tvl-kit" + description = "TVL Kit, an exported subset of TVL depot" + repository = "https://code.tvl.fyi/depot.git:workspace=views/kit.git" + steps = file("./steps-tvl-kit.yml") + default_branch = "canon" +} diff --git a/ops/dns/default.nix b/ops/dns/default.nix index 136a4c58dc..33fe6d6fe7 100644 --- a/ops/dns/default.nix +++ b/ops/dns/default.nix @@ -2,11 +2,12 @@ { depot, pkgs, ... }: let - checkZone = zone: file: pkgs.runCommandNoCC "${zone}-check" {} '' + checkZone = zone: file: pkgs.runCommand "${zone}-check" { } '' ${pkgs.bind}/bin/named-checkzone -i local ${zone} ${file} | tee $out ''; -in depot.nix.readTree.drvTargets { +in +depot.nix.readTree.drvTargets { nixery-dev = checkZone "nixery.dev" ./nixery.dev.zone; tvl-fyi = checkZone "tvl.fyi" ./tvl.fyi.zone; tvl-su = checkZone "tvl.su" ./tvl.su.zone; diff --git a/ops/gerrit-autosubmit/.gitignore b/ops/gerrit-autosubmit/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/ops/gerrit-autosubmit/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/ops/gerrit-autosubmit/Cargo.lock b/ops/gerrit-autosubmit/Cargo.lock new file mode 100644 index 0000000000..7516c74034 --- /dev/null +++ b/ops/gerrit-autosubmit/Cargo.lock @@ -0,0 +1,302 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "crimp" +version = "4087.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ead2c83f7d1f9b8e5a6f7a25985d0d1759ccd2cd72abb1eee2db65d05e12b39" +dependencies = [ + "curl", + "serde", + "serde_json", +] + +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.68+curl-8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "windows-sys", +] + +[[package]] +name = "gerrit-autosubmit" +version = "0.1.0" +dependencies = [ + "anyhow", + "crimp", + "serde", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/ops/gerrit-autosubmit/Cargo.toml b/ops/gerrit-autosubmit/Cargo.toml new file mode 100644 index 0000000000..fa51614a08 --- /dev/null +++ b/ops/gerrit-autosubmit/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "gerrit-autosubmit" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +crimp = "4087.0.0" +serde = { version = "1.0.193", features = ["derive"] } +serde_json = "1.0.108" diff --git a/ops/gerrit-autosubmit/default.nix b/ops/gerrit-autosubmit/default.nix new file mode 100644 index 0000000000..f69a9248e3 --- /dev/null +++ b/ops/gerrit-autosubmit/default.nix @@ -0,0 +1,7 @@ +{ depot, pkgs, ... }: + +depot.third_party.naersk.buildPackage { + src = ./.; + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.openssl ]; +} diff --git a/ops/gerrit-autosubmit/src/main.rs b/ops/gerrit-autosubmit/src/main.rs new file mode 100644 index 0000000000..85d8a6af61 --- /dev/null +++ b/ops/gerrit-autosubmit/src/main.rs @@ -0,0 +1,194 @@ +//! gerrit-autosubmit connects to a Gerrit instance and submits the +//! longest chain of changes in which all ancestors are ready and +//! marked for autosubmit. +//! +//! It works like this: +//! +//! * it fetches all changes the Gerrit query API considers +//! submittable (i.e. all requirements fulfilled), and that have the +//! `Autosubmit` label set +//! +//! * it filters these changes down to those that are _actually_ +//! submittable (in Gerrit API terms: that have an active Submit button) +//! +//! * it filters out those that would submit ancestors that are *not* +//! marked with the `Autosubmit` label +//! +//! * it submits the longest chain +//! +//! After that it just loops. + +use anyhow::{Context, Result}; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::{thread, time}; + +mod gerrit { + use anyhow::{anyhow, Context, Result}; + use serde::Deserialize; + use serde_json::Value; + use std::collections::HashMap; + use std::env; + + pub struct Config { + gerrit_url: String, + username: String, + password: String, + } + + impl Config { + pub fn from_env() -> Result<Self> { + Ok(Config { + gerrit_url: env::var("GERRIT_URL") + .context("Gerrit base URL (no trailing slash) must be set in GERRIT_URL")?, + username: env::var("GERRIT_USERNAME") + .context("Gerrit username must be set in GERRIT_USERNAME")?, + password: env::var("GERRIT_PASSWORD") + .context("Gerrit password must be set in GERRIT_PASSWORD")?, + }) + } + } + + #[derive(Deserialize)] + pub struct ChangeInfo { + pub id: String, + pub revisions: HashMap<String, Value>, + } + + #[derive(Deserialize)] + pub struct Action { + #[serde(default)] + pub enabled: bool, + } + + const GERRIT_RESPONSE_PREFIX: &str = ")]}'"; + + pub fn get<T: serde::de::DeserializeOwned>(cfg: &Config, endpoint: &str) -> Result<T> { + let response = crimp::Request::get(&format!("{}/a{}", cfg.gerrit_url, endpoint)) + .user_agent("gerrit-autosubmit")? + .basic_auth(&cfg.username, &cfg.password)? + .send()? + .error_for_status(|r| anyhow!("request failed with status {}", r.status))?; + + let result: T = serde_json::from_slice(&response.body[GERRIT_RESPONSE_PREFIX.len()..])?; + Ok(result) + } + + pub fn submit(cfg: &Config, change_id: &str) -> Result<()> { + crimp::Request::post(&format!( + "{}/a/changes/{}/submit", + cfg.gerrit_url, change_id + )) + .user_agent("gerrit-autosubmit")? + .basic_auth(&cfg.username, &cfg.password)? + .send()? + .error_for_status(|r| anyhow!("submit failed with status {}", r.status))?; + + Ok(()) + } +} + +#[derive(Debug)] +struct SubmittableChange { + id: String, + revision: String, +} + +fn list_submittable(cfg: &gerrit::Config) -> Result<Vec<SubmittableChange>> { + let mut out = Vec::new(); + + let changes: Vec<gerrit::ChangeInfo> = gerrit::get( + &cfg, + "/changes/?q=is:submittable+label:Autosubmit+-is:wip+is:open&o=SKIP_DIFFSTAT&o=CURRENT_REVISION", + ) + .context("failed to list submittable changes")?; + + for change in changes.into_iter() { + out.push(SubmittableChange { + id: change.id, + revision: change + .revisions + .into_keys() + .next() + .context("change had no current revision")?, + }); + } + + Ok(out) +} + +fn is_submittable(cfg: &gerrit::Config, change: &SubmittableChange) -> Result<bool> { + let response: HashMap<String, gerrit::Action> = gerrit::get( + cfg, + &format!( + "/changes/{}/revisions/{}/actions", + change.id, change.revision + ), + ) + .context("failed to fetch actions for change")?; + + match response.get("submit") { + None => Ok(false), + Some(action) => Ok(action.enabled), + } +} + +fn submitted_with(cfg: &gerrit::Config, change_id: &str) -> Result<HashSet<String>> { + let response: Vec<gerrit::ChangeInfo> = + gerrit::get(cfg, &format!("/changes/{}/submitted_together", change_id)) + .context("failed to fetch related change list")?; + + Ok(response.into_iter().map(|c| c.id).collect()) +} + +fn autosubmit(cfg: &gerrit::Config) -> Result<bool> { + let mut submittable_changes: HashSet<String> = Default::default(); + + for change in list_submittable(&cfg)? { + if !is_submittable(&cfg, &change)? { + continue; + } + + submittable_changes.insert(change.id.clone()); + } + + let mut chains: BTreeMap<usize, String> = Default::default(); + for change_id in &submittable_changes { + let ancestors = submitted_with(&cfg, &change_id)?; + if ancestors.is_subset(&submittable_changes) { + chains.insert( + if ancestors.is_empty() { + 1 + } else { + ancestors.len() + }, + change_id.clone(), + ); + } + } + + // BTreeMap::last_key_value gives us the value associated with the + // largest key, i.e. with the longest submittable chain of changes. + if let Some((count, change_id)) = chains.last_key_value() { + println!( + "submitting change {} with chain length {}", + change_id, count + ); + + gerrit::submit(cfg, change_id).context("while submitting")?; + + Ok(true) + } else { + println!("nothing ready for autosubmit, waiting ..."); + Ok(false) + } +} + +fn main() -> Result<()> { + let cfg = gerrit::Config::from_env()?; + + loop { + if !autosubmit(&cfg)? { + thread::sleep(time::Duration::from_secs(30)); + } + } +} diff --git a/ops/gerrit-tvl/static/tvl.js b/ops/gerrit-tvl/static/tvl.js index 2c4d7ee473..684636de30 100644 --- a/ops/gerrit-tvl/static/tvl.js +++ b/ops/gerrit-tvl/static/tvl.js @@ -79,12 +79,11 @@ function jobStateToCheckRunStatus(state) { const tvlChecksProvider = { async fetch(change) { - let {changeNumber, patchsetNumber, repo} = change; + let {patchsetSha, repo} = change; const experiments = window.ENABLED_EXPERIMENTS || []; if (experiments.includes("UiFeature__tvl_check_debug")) { - changeNumber = 2872; - patchsetNumber = 4; + patchsetSha = '76692104f58b849b1503a8d8a700298003fa7b5f'; repo = 'depot'; } @@ -94,8 +93,7 @@ const tvlChecksProvider = { } const params = { - // besadii groups different patchsets of the same CL under this fake ref - branch: `cl/${changeNumber.toString()}`, + commit: patchsetSha, }; const url = `https://api.buildkite.com/v2/organizations/tvl/pipelines/depot/builds?${encodeParams(params)}`; const resp = await fetch(url, { diff --git a/ops/glesys/default.nix b/ops/glesys/default.nix index f4c0478c5d..e511e1f6b6 100644 --- a/ops/glesys/default.nix +++ b/ops/glesys/default.nix @@ -1,8 +1,15 @@ -{ depot, pkgs, ... }: +{ depot, lib, pkgs, ... }: -depot.nix.readTree.drvTargets { +depot.nix.readTree.drvTargets rec { # Provide a Terraform wrapper with the right provider installed. - terraform = pkgs.terraform.withPlugins(_: [ + terraform = pkgs.terraform.withPlugins (_: [ depot.third_party.terraform-provider-glesys ]); + + validate = depot.tools.checks.validateTerraform { + inherit terraform; + name = "glesys"; + src = lib.cleanSource ./.; + env.GLESYS_TOKEN = "ci-dummy"; + }; } diff --git a/ops/glesys/dns-nixery-dev.tf b/ops/glesys/dns-nixery-dev.tf index 53a421d20e..42bcec7e21 100644 --- a/ops/glesys/dns-nixery-dev.tf +++ b/ops/glesys/dns-nixery-dev.tf @@ -12,14 +12,7 @@ resource "glesys_dnsdomain_record" "nixery_dev_apex_A" { domain = glesys_dnsdomain.nixery_dev.id host = "@" type = "A" - data = var.whitby_ipv4 -} - -resource "glesys_dnsdomain_record" "nixery_dev_apex_AAAA" { - domain = glesys_dnsdomain.nixery_dev.id - host = "@" - type = "AAAA" - data = var.whitby_ipv6 + data = "51.250.51.78" # nixery-01.tvl.fyi } resource "glesys_dnsdomain_record" "nixery_dev_NS1" { diff --git a/ops/glesys/dns-tvix-dev.tf b/ops/glesys/dns-tvix-dev.tf new file mode 100644 index 0000000000..296532a02b --- /dev/null +++ b/ops/glesys/dns-tvix-dev.tf @@ -0,0 +1,54 @@ +# DNS configuration for tvix.dev + +resource "glesys_dnsdomain" "tvix_dev" { + name = "tvix.dev" +} + +resource "glesys_dnsdomain_record" "tvix_dev_apex_A" { + domain = glesys_dnsdomain.tvix_dev.id + host = "@" + type = "A" + data = var.whitby_ipv4 +} + +resource "glesys_dnsdomain_record" "tvix_dev_apex_AAAA" { + domain = glesys_dnsdomain.tvix_dev.id + host = "@" + type = "AAAA" + data = var.whitby_ipv6 +} + +resource "glesys_dnsdomain_record" "tvix_dev_bolt_CNAME" { + domain = glesys_dnsdomain.tvix_dev.id + host = "bolt" + type = "CNAME" + data = "whitby.tvl.su." +} + +resource "glesys_dnsdomain_record" "tvix_dev_docs_CNAME" { + domain = glesys_dnsdomain.tvix_dev.id + host = "docs" + type = "CNAME" + data = "whitby.tvl.fyi." +} + +resource "glesys_dnsdomain_record" "tvix_dev_NS1" { + domain = glesys_dnsdomain.tvix_dev.id + host = "@" + type = "NS" + data = "ns1.namesystem.se." +} + +resource "glesys_dnsdomain_record" "tvix_dev_NS2" { + domain = glesys_dnsdomain.tvix_dev.id + host = "@" + type = "NS" + data = "ns2.namesystem.se." +} + +resource "glesys_dnsdomain_record" "tvix_dev_NS3" { + domain = glesys_dnsdomain.tvix_dev.id + host = "@" + type = "NS" + data = "ns3.namesystem.se." +} diff --git a/ops/glesys/dns-tvl-fyi.tf b/ops/glesys/dns-tvl-fyi.tf index 803bfeae08..9d7972c412 100644 --- a/ops/glesys/dns-tvl-fyi.tf +++ b/ops/glesys/dns-tvl-fyi.tf @@ -53,13 +53,27 @@ resource "glesys_dnsdomain_record" "tvl_fyi_whitby_AAAA" { data = var.whitby_ipv6 } -# This record is responsible for hosting ~all TVL services. Be -# mindful! -resource "glesys_dnsdomain_record" "tvl_fyi_wildcard" { +resource "glesys_dnsdomain_record" "tvl_fyi_nixery-01_A" { + domain = glesys_dnsdomain.tvl_fyi.id + host = "nixery-01" + type = "A" + data = "51.250.51.78" +} + +# Explicit records for all services running on whitby +resource "glesys_dnsdomain_record" "tvl_fyi_whitby_services" { + domain = glesys_dnsdomain.tvl_fyi.id + type = "CNAME" + data = "whitby.tvl.fyi." + host = each.key + for_each = toset(local.whitby_services) +} + +resource "glesys_dnsdomain_record" "tvl_fyi_net_CNAME" { domain = glesys_dnsdomain.tvl_fyi.id - host = "*" type = "CNAME" - data = "whitby.tvl.fyi." + data = "sanduny.tvl.su." + host = "net" } # Google Domains mail forwarding configuration (no sending) diff --git a/ops/glesys/dns-tvl-su.tf b/ops/glesys/dns-tvl-su.tf index 9b8bcd9a87..f2286cf1cf 100644 --- a/ops/glesys/dns-tvl-su.tf +++ b/ops/glesys/dns-tvl-su.tf @@ -53,68 +53,85 @@ resource "glesys_dnsdomain_record" "tvl_su_whitby_AAAA" { data = var.whitby_ipv6 } -# This record is responsible for hosting ~all TVL services. Be -# mindful! -resource "glesys_dnsdomain_record" "tvl_su_wildcard" { +resource "glesys_dnsdomain_record" "tvl_su_sanduny_A" { domain = glesys_dnsdomain.tvl_su.id - host = "*" - type = "CNAME" - data = "whitby.tvl.su." + host = "sanduny" + type = "A" + data = var.sanduny_ipv4 } -# # Google Domains mail forwarding configuration (no sending) -resource "glesys_dnsdomain_record" "tvl_su_MX_aspmx" { +resource "glesys_dnsdomain_record" "tvl_su_sanduny_AAAA" { domain = glesys_dnsdomain.tvl_su.id - host = "@" - type = "MX" - data = "1 aspmx.l.google.com." + host = "sanduny" + type = "AAAA" + data = var.sanduny_ipv6 +} + +# Explicit records for all services running on whitby +resource "glesys_dnsdomain_record" "tvl_su_whitby_services" { + domain = glesys_dnsdomain.tvl_su.id + type = "CNAME" + data = "whitby.tvl.su." + host = each.key + for_each = toset(local.whitby_services) } -resource "glesys_dnsdomain_record" "tvl_su_MX_alt1" { +# historical tvixbolt.tvl.su record, redirects to bolt.tvix.dev +resource "glesys_dnsdomain_record" "tvix_su_tvixbolt_CNAME" { domain = glesys_dnsdomain.tvl_su.id - host = "@" - type = "MX" - data = "5 alt1.aspmx.l.google.com." + host = "tvixbolt" + type = "CNAME" + data = "whitby.tvl.su." } -resource "glesys_dnsdomain_record" "tvl_su_MX_alt2" { +resource "glesys_dnsdomain_record" "tvl_su_inbox_CNAME" { + domain = glesys_dnsdomain.tvl_su.id + type = "CNAME" + data = "sanduny.tvl.su." + host = "inbox.tvl.su." +} + +resource "glesys_dnsdomain_record" "tvl_su_TXT_google_site" { domain = glesys_dnsdomain.tvl_su.id host = "@" - type = "MX" - data = "5 alt2.aspmx.l.google.com." + type = "TXT" + data = "google-site-verification=3ksTBzFK3lZlzD3ddBfpaHs9qasfAiYBmvbW2T_ejH4" } -resource "glesys_dnsdomain_record" "tvl_su_MX_alt3" { +# Yandex 360 setup + +resource "glesys_dnsdomain_record" "tvl_su_TXT_yandex" { domain = glesys_dnsdomain.tvl_su.id host = "@" - type = "MX" - data = "10 alt3.aspmx.l.google.com." + type = "TXT" + data = "yandex-verification: b99c43b7838949dc" } -resource "glesys_dnsdomain_record" "tvl_su_MX_alt4" { +resource "glesys_dnsdomain_record" "tvl_su_MX_yandex" { domain = glesys_dnsdomain.tvl_su.id host = "@" type = "MX" - data = "10 alt4.aspmx.l.google.com." + data = "10 mx.yandex.net." } -resource "glesys_dnsdomain_record" "tvl_su_TXT_google_site" { +resource "glesys_dnsdomain_record" "tvl_su_TXT_yandex_spf" { domain = glesys_dnsdomain.tvl_su.id host = "@" type = "TXT" - data = "google-site-verification=3ksTBzFK3lZlzD3ddBfpaHs9qasfAiYBmvbW2T_ejH4" + data = "v=spf1 redirect=_spf.yandex.net" + } -resource "glesys_dnsdomain_record" "tvl_su_TXT_google_spf" { +resource "glesys_dnsdomain_record" "tvl_su_TXT_yandex_dkim" { domain = glesys_dnsdomain.tvl_su.id - host = "@" + host = "mail._domainkey" type = "TXT" - data = "v=spf1 include:_spf.google.com ~all" + data = "v=DKIM1; k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaRdWF8BtCHlTTQN8O+E5Qn27FVIpUEAdk1uq2vdIKh1Un/3NfdWtxStcS1Mf0iEprt1Fb4zgWOkDlPi+hH/UZqiC9QNeNqEBGMB9kgJyfsUt6cDCIVGvn8PT9JcZW1jxSziOj8nUWB4noqbaVcQNqNbwtaHPm3aifwKwScxVO7wIDAQAB" } -resource "glesys_dnsdomain_record" "tvl_su_TXT_google_dkim" { +resource "glesys_dnsdomain_record" "tvl_su_CNAME_yandex_mail" { domain = glesys_dnsdomain.tvl_su.id - host = "google._domainkey" - type = "TXT" - data = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlqCbnGa8oPwrudJK60l6MJj3NBnwj8wAPXNGtYy2SXrOBi7FT+ySwW7ATpfv6Xq9zGDUWJsENPUlFmvDiUs7Qi4scnNvSO1L+sDseB9/q1m3gMFVnTuieDO/T+KKkg0+uYgMM7YX5PahsAAJJ+EMb/r4afl3tcBMPR64VveKQ0hiSHA4zIYPsB9FB+b8S5C46uyY0r6WR7IzGjq2Gzb1do0kxvaKItTITWLSImcUu5ZZuXOUKJb441frVBWur5lXaYuedkxb1IRTTK0V/mBODE1D7k73MxGrqlzaMPdCqz+c3hRE18WVUkBTYjANVXDrs3yzBBVxaIAeu++vkO6BvQIDAQAB" + host = "mail" + type = "CNAME" + data = "domain.mail.yandex.net." } diff --git a/ops/glesys/main.tf b/ops/glesys/main.tf index 857c1677fb..ec6bb7c397 100644 --- a/ops/glesys/main.tf +++ b/ops/glesys/main.tf @@ -12,14 +12,18 @@ terraform { } backend "s3" { - endpoint = "https://objects.dc-sto1.glesys.net" - bucket = "tvl-state" - key = "terraform/tvl-glesys" - region = "glesys" + endpoints = { + s3 = "https://objects.dc-sto1.glesys.net" + } + bucket = "tvl-state" + key = "terraform/tvl-glesys" + region = "glesys" skip_credentials_validation = true skip_region_validation = true skip_metadata_api_check = true + skip_requesting_account_id = true + skip_s3_checksum = true } } @@ -35,10 +39,6 @@ resource "glesys_objectstorage_instance" "tvl-backups" { resource "glesys_objectstorage_instance" "tvl-state" { description = "tvl-state" datacenter = "dc-sto1" - - lifecycle { - ignore_changes = [accesskey] - } } resource "glesys_objectstorage_credential" "terraform-state" { @@ -60,3 +60,33 @@ variable "whitby_ipv6" { type = string default = "2a01:4f8:242:5b21:0:feed:edef:beef" } + +variable "sanduny_ipv4" { + type = string + default = "85.119.82.231" +} + +variable "sanduny_ipv6" { + type = string + default = "2001:ba8:1f1:f109::feed:edef:beef" +} + +locals { + # Hostnames of all public services on whitby + whitby_services = [ + "at", + "atward", + "auth", + "b", + "cache", + "cl", + "code", + "cs", + "deploys", + "images", + "signup", + "static", + "status", + "todo", + ] +} diff --git a/ops/journaldriver/Cargo.lock b/ops/journaldriver/Cargo.lock index f7c697068f..97bbe16ceb 100644 --- a/ops/journaldriver/Cargo.lock +++ b/ops/journaldriver/Cargo.lock @@ -1,818 +1,646 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "aho-corasick" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ascii" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] +version = 3 [[package]] -name = "backtrace" -version = "0.3.9" +name = "aho-corasick" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ - "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] -name = "backtrace-sys" -version = "0.1.24" +name = "anyhow" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "base64" -version = "0.9.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bitflags" -version = "1.0.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] -name = "byteorder" -version = "1.2.6" +name = "build-env" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e068f31938f954b695423ecaf756179597627d0828c0d3e48c0a722a8b23cf9e" [[package]] name = "cc" -version = "1.0.25" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" -version = "0.1.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.6" +name = "crimp" +version = "4087.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ead2c83f7d1f9b8e5a6f7a25985d0d1759ccd2cd72abb1eee2db65d05e12b39" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "curl", + "serde", + "serde_json", ] [[package]] -name = "chunked_transfer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cloudabi" -version = "0.0.3" +name = "cstr-argument" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bd9c8e659a473bce955ae5c35b116af38af11a7acb0b480e01f3ed348aeb40" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "memchr", ] [[package]] -name = "cookie" -version = "0.11.0" +name = "curl" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" dependencies = [ - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", ] [[package]] -name = "core-foundation" -version = "0.5.1" +name = "curl-sys" +version = "0.4.68+curl-8.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" dependencies = [ - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "windows-sys", ] [[package]] -name = "core-foundation-sys" -version = "0.5.1" +name = "deranged" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "powerfmt", + "serde", ] [[package]] -name = "cstr-argument" -version = "0.0.2" +name = "env_logger" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", ] [[package]] -name = "env_logger" -version = "0.5.13" +name = "errno" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "windows-sys", ] [[package]] -name = "failure" -version = "0.1.2" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-shared 0.1.1", ] [[package]] -name = "failure_derive" -version = "0.1.2" +name = "foreign-types" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-macros", + "foreign-types-shared 0.3.1", ] [[package]] -name = "foreign-types" -version = "0.3.2" +name = "foreign-types-macros" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "foreign-types-shared" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] -name = "fuchsia-zircon-sys" +name = "hermit-abi" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "humantime" -version = "1.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "idna" -version = "0.1.5" +name = "is-terminal" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "rustix", + "windows-sys", ] [[package]] name = "itoa" -version = "0.4.3" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "journaldriver" -version = "1.1.0" +version = "5656.0.0" dependencies = [ - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "medallion 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", - "systemd 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ureq 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "crimp", + "env_logger", + "lazy_static", + "log", + "medallion", + "pkg-config", + "serde", + "serde_json", + "systemd", + "time", ] [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.43" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libsystemd-sys" -version = "0.2.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d28ad38d7bee81aabd41201ee7d36df8d7f76aa0a455c77d5c365c4669b4b4b6" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "build-env", + "libc", + "pkg-config", ] [[package]] -name = "log" -version = "0.4.5" +name = "libz-sys" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] -name = "matches" -version = "0.1.8" +name = "linux-raw-sys" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] -name = "medallion" -version = "2.2.3" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "memchr" -version = "1.0.2" +name = "medallion" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b83c0c3277d722b53a6eb24e3c1321172f85b715cc7405add8ffd1f2f06288" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "base64", + "openssl", + "serde", + "serde_json", + "time", ] [[package]] name = "memchr" -version = "2.1.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] -name = "native-tls" -version = "0.2.1" +name = "once_cell" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "num-integer" -version = "0.1.39" +name = "openssl" +version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", ] [[package]] -name = "num-traits" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl" -version = "0.10.12" +name = "openssl-macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "openssl-probe" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.36" +version = "0.9.95" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "pkg-config" -version = "0.3.14" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] -name = "proc-macro2" -version = "0.4.20" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "qstring" -version = "0.6.0" +name = "proc-macro2" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-ident", ] [[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "quote" -version = "0.6.8" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] -name = "rand" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_syscall" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" +name = "regex" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "regex" -version = "1.0.5" +name = "regex-automata" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ - "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] -name = "remove_dir_all" -version = "0.5.1" +name = "rustix" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] -name = "rustc-demangle" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "ryu" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "safemem" -version = "0.3.0" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schannel" -version = "0.1.14" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-sys", ] [[package]] -name = "security-framework" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.2.1" +name = "serde" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive", ] [[package]] -name = "serde" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "serde_derive" -version = "1.0.79" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "serde_json" -version = "1.0.32" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] -name = "syn" -version = "0.14.9" +name = "socket2" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi", ] [[package]] name = "syn" -version = "0.15.8" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "synstructure" -version = "0.9.0" +name = "systemd" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95085b9c6eedbcf0b828302a3483a84bdbf772158e586b787092112008fd1f" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cstr-argument", + "foreign-types 0.5.0", + "libc", + "libsystemd-sys", + "log", + "utf8-cstr", ] [[package]] -name = "systemd" -version = "0.3.0" +name = "termcolor" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ - "cstr-argument 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "libsystemd-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-cstr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] -name = "tempfile" -version = "3.0.4" +name = "time" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "termcolor" -version = "1.0.4" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "termion" -version = "1.5.1" +name = "time-macros" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time-core", ] [[package]] -name = "thread_local" -version = "0.3.6" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "time" -version = "0.1.40" +name = "utf8-cstr" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "55bcbb425141152b10d5693095950b51c3745d019363fc2929ffd8f61449b628" [[package]] -name = "ucd-util" -version = "0.1.1" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] -name = "unicode-bidi" -version = "0.3.4" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "unicode-normalization" -version = "0.1.7" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "unicode-xid" -version = "0.1.0" +name = "winapi-util" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] [[package]] -name = "ureq" -version = "0.6.2" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "qstring 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "url" -version = "1.7.1" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-targets", ] [[package]] -name = "utf8-cstr" -version = "0.1.6" +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] [[package]] -name = "utf8-ranges" -version = "1.0.1" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "vcpkg" -version = "0.2.6" +name = "windows_aarch64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "version_check" -version = "0.1.5" +name = "windows_i686_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "winapi" -version = "0.3.6" +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_x86_64_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "winapi-util" -version = "0.1.1" +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_x86_64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wincolor" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" -"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" -"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf" -"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" -"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" -"checksum cstr-argument 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "514570a4b719329df37f93448a70df2baac553020d0eb43a8dfa9c1f5ba7b658" -"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" -"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" -"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum libsystemd-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e751b723417158e0949ba470bee4affd6f1dd6b67622b5240d79186631b6a0d9" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum medallion 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2e6f0713b388174fc3de9b63a0a63dfcee191a8abc8e06c0a9c6d80821c1891" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" -"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" -"checksum native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0a7bd714e83db15676d31caf968ad7318e9cc35f93c85a90231c8f22867549" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2e79eede055813a3ac52fb3915caf8e1c9da2dec1587871aec9f6f7b48508d" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" -"checksum qstring 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "545ec057a36a93e25fb5883baed912e4984af4e2543bbf0e3463d962e0408469" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" -"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" -"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" -"checksum security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697d3f3c23a618272ead9e1fb259c1411102b31c6af8b93f1d64cca9c3b0e8e0" -"checksum security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab01dfbe5756785b5b4d46e0289e5a18071dfa9a7c2b24213ea00b9ef9b665bf" -"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" -"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" -"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" -"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.8 (registry+https://github.com/rust-lang/crates.io-index)" = "356d1c5043597c40489e9af2d2498c7fefc33e99b7d75b43be336c8a59b3e45e" -"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" -"checksum systemd 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b62a732355787f960c25536210ae0a981aca2e5dae9dab8491bdae39613ce48" -"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum ureq 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f3f941c0434783c82e46d30508834be5f3c1f2c85dd1b98f0681984c7be8e03" -"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" -"checksum utf8-cstr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "55bcbb425141152b10d5693095950b51c3745d019363fc2929ffd8f61449b628" -"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/ops/journaldriver/Cargo.toml b/ops/journaldriver/Cargo.toml index 248b22807f..65510d8705 100644 --- a/ops/journaldriver/Cargo.toml +++ b/ops/journaldriver/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "journaldriver" -version = "1.1.0" -authors = ["Vincent Ambo <mail@tazj.in>"] +version = "5656.0.0" +authors = ["Vincent Ambo <tazjin@tvl.su>"] license = "GPL-3.0-or-later" +edition = "2021" [dependencies] -chrono = { version = "0.4", features = [ "serde" ]} -env_logger = "0.5" -failure = "0.1" -lazy_static = "1.0" +anyhow = "1.0" +crimp = "4087.0" +env_logger = "0.10" +lazy_static = "1.4" log = "0.4" -medallion = "2.2" -serde = "1.0" -serde_derive = "1.0" +medallion = "2.5" +serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" -systemd = "0.3" -ureq = { version = "0.6.2", features = [ "json" ]} +systemd = "0.5" +time = { version = "0.3", features = [ "serde-well-known", "macros" ]} [build-dependencies] pkg-config = "0.3" diff --git a/ops/journaldriver/build.rs b/ops/journaldriver/build.rs index d64c82a88a..79eb1001bf 100644 --- a/ops/journaldriver/build.rs +++ b/ops/journaldriver/build.rs @@ -1,6 +1,5 @@ extern crate pkg_config; fn main() { - pkg_config::probe_library("libsystemd") - .expect("Could not probe libsystemd"); + pkg_config::probe_library("libsystemd").expect("Could not probe libsystemd"); } diff --git a/ops/journaldriver/default.nix b/ops/journaldriver/default.nix index d2413e74cc..2a3836c358 100644 --- a/ops/journaldriver/default.nix +++ b/ops/journaldriver/default.nix @@ -4,6 +4,8 @@ depot.third_party.naersk.buildPackage { src = ./.; buildInputs = with pkgs; [ - pkgconfig openssl systemd.dev + pkg-config + openssl + systemd.dev ]; } diff --git a/ops/journaldriver/src/main.rs b/ops/journaldriver/src/main.rs index 9886af1c36..4c404e607e 100644 --- a/ops/journaldriver/src/main.rs +++ b/ops/journaldriver/src/main.rs @@ -31,30 +31,17 @@ //! `GOOGLE_APPLICATION_CREDENTIALS`, `GOOGLE_CLOUD_PROJECT` and //! `LOG_NAME` environment variables. -#[macro_use] extern crate failure; -#[macro_use] extern crate log; -#[macro_use] extern crate serde_derive; -#[macro_use] extern crate serde_json; -#[macro_use] extern crate lazy_static; - -extern crate chrono; -extern crate env_logger; -extern crate medallion; -extern crate serde; -extern crate systemd; -extern crate ureq; - -use chrono::offset::LocalResult; -use chrono::prelude::{DateTime, TimeZone, Utc}; -use failure::ResultExt; -use serde_json::{from_str, Value}; -use std::env; -use std::fs::{self, File, rename}; -use std::io::{self, Read, ErrorKind, Write}; -use std::mem; +use anyhow::{bail, Context, Result}; +use lazy_static::lazy_static; +use log::{debug, error, info, trace}; +use serde::{Deserialize, Serialize}; +use serde_json::{from_str, json, Value}; +use std::convert::TryInto; +use std::fs::{self, rename, File}; +use std::io::{self, ErrorKind, Read, Write}; use std::path::PathBuf; -use std::process; use std::time::{Duration, Instant}; +use std::{env, mem, process}; use systemd::journal::{Journal, JournalFiles, JournalRecord, JournalSeek}; #[cfg(test)] @@ -62,13 +49,12 @@ mod tests; const LOGGING_SERVICE: &str = "https://logging.googleapis.com/google.logging.v2.LoggingServiceV2"; const ENTRIES_WRITE_URL: &str = "https://logging.googleapis.com/v2/entries:write"; -const METADATA_TOKEN_URL: &str = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"; +const METADATA_TOKEN_URL: &str = + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"; const METADATA_ID_URL: &str = "http://metadata.google.internal/computeMetadata/v1/instance/id"; const METADATA_ZONE_URL: &str = "http://metadata.google.internal/computeMetadata/v1/instance/zone"; -const METADATA_PROJECT_URL: &str = "http://metadata.google.internal/computeMetadata/v1/project/project-id"; - -/// Convenience type alias for results using failure's `Error` type. -type Result<T> = std::result::Result<T, failure::Error>; +const METADATA_PROJECT_URL: &str = + "http://metadata.google.internal/computeMetadata/v1/project/project-id"; /// Representation of static service account credentials for GCP. #[derive(Debug, Deserialize)] @@ -126,32 +112,27 @@ lazy_static! { /// Convenience helper for retrieving values from the metadata server. fn get_metadata(url: &str) -> Result<String> { - let response = ureq::get(url) - .set("Metadata-Flavor", "Google") - .timeout_connect(5000) - .timeout_read(5000) - .call(); - - if response.ok() { - // Whitespace is trimmed to remove newlines from responses. - let body = response.into_string() - .context("Failed to decode metadata response")? - .trim().to_string(); - - Ok(body) - } else { - let status = response.status_line().to_string(); - let body = response.into_string() - .unwrap_or_else(|e| format!("Metadata body error: {}", e)); - bail!("Metadata failure: {} ({})", body, status) + let response = crimp::Request::get(url) + .header("Metadata-Flavor", "Google")? + .timeout(std::time::Duration::from_secs(5))? + .send()? + .as_string()?; + + if !response.is_success() { + bail!( + "Error response ({}) from metadata server: {}", + response.status, + response.body + ); } + + Ok(response.body.trim().to_owned()) } /// Convenience helper for determining the project ID. fn get_project_id() -> String { env::var("GOOGLE_CLOUD_PROJECT") - .map_err(Into::into) - .or_else(|_: failure::Error| get_metadata(METADATA_PROJECT_URL)) + .or_else(|_| get_metadata(METADATA_PROJECT_URL)) .expect("Could not determine project ID") } @@ -186,11 +167,9 @@ fn determine_monitored_resource() -> Value { } }) } else { - let instance_id = get_metadata(METADATA_ID_URL) - .expect("Could not determine instance ID"); + let instance_id = get_metadata(METADATA_ID_URL).expect("Could not determine instance ID"); - let zone = get_metadata(METADATA_ZONE_URL) - .expect("Could not determine instance zone"); + let zone = get_metadata(METADATA_ZONE_URL).expect("Could not determine instance zone"); json!({ "type": "gce_instance", @@ -252,9 +231,8 @@ fn get_metadata_token() -> Result<Token> { fn sign_service_account_token(credentials: &Credentials) -> Result<Token> { use medallion::{Algorithm, Header, Payload}; - let iat = Utc::now(); - let exp = iat.checked_add_signed(chrono::Duration::seconds(3600)) - .ok_or_else(|| format_err!("Failed to calculate token expiry"))?; + let iat = time::OffsetDateTime::now_utc(); + let exp = iat + time::Duration::seconds(3600); let header = Header { alg: Algorithm::RS256, @@ -267,8 +245,8 @@ fn sign_service_account_token(credentials: &Credentials) -> Result<Token> { iss: Some(credentials.client_email.clone()), sub: Some(credentials.client_email.clone()), aud: Some(LOGGING_SERVICE.to_string()), - iat: Some(iat.timestamp() as u64), - exp: Some(exp.timestamp() as u64), + iat: Some(iat.unix_timestamp().try_into().unwrap()), + exp: Some(exp.unix_timestamp().try_into().unwrap()), ..Default::default() }; @@ -323,7 +301,9 @@ enum Payload { /// text format. fn message_to_payload(message: Option<String>) -> Payload { match message { - None => Payload::TextPayload { text_payload: "empty log entry".into() }, + None => Payload::TextPayload { + text_payload: "empty log entry".into(), + }, Some(text_payload) => { // Attempt to deserialize the text payload as a generic // JSON value. @@ -333,7 +313,7 @@ fn message_to_payload(message: Option<String>) -> Payload { // expect other types of JSON payload) and return it // in that case. if json_payload.is_object() { - return Payload::JsonPayload { json_payload } + return Payload::JsonPayload { json_payload }; } } @@ -348,18 +328,15 @@ fn message_to_payload(message: Option<String>) -> Payload { /// Parse errors are dismissed and returned as empty options: There /// simply aren't any useful fallback mechanisms other than defaulting /// to ingestion time for journaldriver's use-case. -fn parse_microseconds(input: String) -> Option<DateTime<Utc>> { +fn parse_microseconds(input: String) -> Option<time::OffsetDateTime> { if input.len() != 16 { return None; } - let seconds: i64 = (&input[..10]).parse().ok()?; - let micros: u32 = (&input[10..]).parse().ok()?; + let micros: i128 = input.parse().ok()?; + let nanos: i128 = micros * 1000; - match Utc.timestamp_opt(seconds, micros * 1000) { - LocalResult::Single(time) => Some(time), - _ => None, - } + time::OffsetDateTime::from_unix_timestamp_nanos(nanos).ok() } /// Converts a journald log message priority to a @@ -408,7 +385,8 @@ struct LogEntry { labels: Value, #[serde(skip_serializing_if = "Option::is_none")] - timestamp: Option<DateTime<Utc>>, + #[serde(with = "time::serde::rfc3339::option")] + timestamp: Option<time::OffsetDateTime>, #[serde(flatten)] payload: Payload, @@ -450,9 +428,7 @@ impl From<JournalRecord> for LogEntry { // Journald uses syslogd's concept of priority. No idea if this is // always present, but it's optional in the Stackdriver API, so we just // omit it if we can't find or parse it. - let severity = record - .remove("PRIORITY") - .and_then(priority_to_severity); + let severity = record.remove("PRIORITY").and_then(priority_to_severity); LogEntry { payload, @@ -468,8 +444,7 @@ impl From<JournalRecord> for LogEntry { /// Attempt to read from the journal. If no new entry is present, /// await the next one up to the specified timeout. -fn receive_next_record(timeout: Duration, journal: &mut Journal) - -> Result<Option<JournalRecord>> { +fn receive_next_record(timeout: Duration, journal: &mut Journal) -> Result<Option<JournalRecord>> { let next_record = journal.next_record()?; if next_record.is_some() { return Ok(next_record); @@ -525,11 +500,10 @@ fn persist_cursor(cursor: String) -> Result<()> { if cursor.is_empty() { error!("Received empty journald cursor position, refusing to persist!"); error!("Please report this message at https://github.com/tazjin/journaldriver/issues/2"); - return Ok(()) + return Ok(()); } - let mut file = File::create(&*CURSOR_TMP_FILE) - .context("Failed to create cursor file")?; + let mut file = File::create(&*CURSOR_TMP_FILE).context("Failed to create cursor file")?; write!(file, "{}", cursor).context("Failed to write cursor file")?; @@ -547,9 +521,7 @@ fn persist_cursor(cursor: String) -> Result<()> { /// /// If flushing is successful the last cursor position will be /// persisted to disk. -fn flush(token: &mut Token, - entries: Vec<LogEntry>, - cursor: String) -> Result<()> { +fn flush(token: &mut Token, entries: Vec<LogEntry>, cursor: String) -> Result<()> { if token.is_expired() { debug!("Refreshing Google metadata access token"); let new_token = get_token()?; @@ -583,25 +555,28 @@ fn prepare_request(entries: &[LogEntry]) -> Value { /// Perform the log entry insertion in Stackdriver Logging. fn write_entries(token: &Token, request: Value) -> Result<()> { - let response = ureq::post(ENTRIES_WRITE_URL) - .set("Authorization", format!("Bearer {}", token.token).as_str()) + let response = crimp::Request::post(ENTRIES_WRITE_URL) + .json(&request)? + .header("Authorization", format!("Bearer {}", token.token).as_str())? // The timeout values are set relatively high, not because of // an expectation of Stackdriver being slow but just to - // eventually hit an error case in case of network troubles. + // eventually force an error in case of network troubles. // Presumably no request in a functioning environment will // ever hit these limits. - .timeout_connect(2000) - .timeout_read(5000) - .send_json(request); + .timeout(std::time::Duration::from_secs(5))? + .send()?; - if response.ok() { - Ok(()) - } else { - let status = response.status_line().to_string(); - let body = response.into_string() - .unwrap_or_else(|_| "no response body".into()); - bail!("Write failure: {} ({})", body, status) + if !response.is_success() { + let status = response.status; + let body = response + .as_string() + .map(|r| r.body) + .unwrap_or_else(|_| "no valid response body".to_owned()); + + bail!("Writing to Stackdriver failed({}): {}", status, body); } + + Ok(()) } /// Attempt to read the initial cursor position from the configured @@ -624,14 +599,12 @@ fn initial_cursor() -> Result<JournalSeek> { Err(ref err) if err.kind() == ErrorKind::NotFound => { info!("No previous cursor position, reading from journal tail"); Ok(JournalSeek::Tail) - }, - Err(err) => { - (Err(err).context("Could not read cursor position"))? } + Err(err) => (Err(err).context("Could not read cursor position"))?, } } -fn main () { +fn main() { env_logger::init(); // The directory in which cursor positions are persisted should @@ -641,17 +614,17 @@ fn main () { process::exit(1); } - let cursor_position_dir = CURSOR_FILE.parent() + let cursor_position_dir = CURSOR_FILE + .parent() .expect("Invalid cursor position file path"); fs::create_dir_all(cursor_position_dir) .expect("Could not create directory to store cursor position in"); - let mut journal = Journal::open(JournalFiles::All, false, true) - .expect("Failed to open systemd journal"); + let mut journal = + Journal::open(JournalFiles::All, false, true).expect("Failed to open systemd journal"); - let seek_position = initial_cursor() - .expect("Failed to determine initial cursor position"); + let seek_position = initial_cursor().expect("Failed to determine initial cursor position"); match journal.seek(seek_position) { Ok(cursor) => info!("Opened journal at cursor '{}'", cursor), diff --git a/ops/journaldriver/src/tests.rs b/ops/journaldriver/src/tests.rs index 779add7a70..6f5045d6a5 100644 --- a/ops/journaldriver/src/tests.rs +++ b/ops/journaldriver/src/tests.rs @@ -1,5 +1,6 @@ use super::*; use serde_json::to_string; +use time::macros::datetime; #[test] fn test_text_entry_serialization() { @@ -15,7 +16,31 @@ fn test_text_entry_serialization() { let expected = "{\"labels\":null,\"textPayload\":\"test entry\"}"; let result = to_string(&entry).expect("serialization failed"); - assert_eq!(expected, result, "Plain text payload should serialize correctly") + assert_eq!( + expected, result, + "Plain text payload should serialize correctly" + ) +} + +#[test] +fn test_timestamped_entry_serialization() { + let entry = LogEntry { + labels: Value::Null, + timestamp: Some(datetime!(1952-10-07 12:00:00 UTC)), + payload: Payload::TextPayload { + text_payload: "test entry".into(), + }, + severity: None, + }; + + let expected = + "{\"labels\":null,\"timestamp\":\"1952-10-07T12:00:00Z\",\"textPayload\":\"test entry\"}"; + let result = to_string(&entry).expect("serialization failed"); + + assert_eq!( + expected, result, + "Plain text payload should serialize correctly" + ) } #[test] @@ -26,7 +51,7 @@ fn test_json_entry_serialization() { payload: Payload::JsonPayload { json_payload: json!({ "message": "JSON test" - }) + }), }, severity: None, }; @@ -34,7 +59,7 @@ fn test_json_entry_serialization() { let expected = "{\"labels\":null,\"jsonPayload\":{\"message\":\"JSON test\"}}"; let result = to_string(&entry).expect("serialization failed"); - assert_eq!(expected, result, "JSOn payload should serialize correctly") + assert_eq!(expected, result, "JSON payload should serialize correctly") } #[test] @@ -45,7 +70,10 @@ fn test_plain_text_payload() { text_payload: "plain text payload".into(), }; - assert_eq!(expected, payload, "Plain text payload should be detected correctly"); + assert_eq!( + expected, payload, + "Plain text payload should be detected correctly" + ); } #[test] @@ -55,7 +83,10 @@ fn test_empty_payload() { text_payload: "empty log entry".into(), }; - assert_eq!(expected, payload, "Empty payload should be handled correctly"); + assert_eq!( + expected, payload, + "Empty payload should be handled correctly" + ); } #[test] @@ -66,10 +97,13 @@ fn test_json_payload() { json_payload: json!({ "someKey": "someValue", "otherKey": 42 - }) + }), }; - assert_eq!(expected, payload, "JSON payload should be detected correctly"); + assert_eq!( + expected, payload, + "JSON payload should be detected correctly" + ); } #[test] @@ -82,14 +116,16 @@ fn test_json_no_object() { text_payload: "42".into(), }; - assert_eq!(expected, payload, "Non-object JSON payload should be plain text"); + assert_eq!( + expected, payload, + "Non-object JSON payload should be plain text" + ); } #[test] fn test_parse_microseconds() { let input: String = "1529175149291187".into(); - let expected: DateTime<Utc> = "2018-06-16T18:52:29.291187Z" - .to_string().parse().unwrap(); + let expected: time::OffsetDateTime = datetime!(2018-06-16 18:52:29.291187 UTC); assert_eq!(Some(expected), parse_microseconds(input)); } diff --git a/ops/keycloak/README.md b/ops/keycloak/README.md index e8ffd700b5..fd72daa87d 100644 --- a/ops/keycloak/README.md +++ b/ops/keycloak/README.md @@ -12,7 +12,7 @@ credentials. An example `direnv` configuration used by tazjin is this: ``` -# //ops/secrets/.envrc +# //ops/keycloak/.envrc source_up eval $(age --decrypt -i ~/.ssh/id_ed25519 $(git rev-parse --show-toplevel)/ops/secrets/tf-keycloak.age) ``` diff --git a/ops/keycloak/clients.tf b/ops/keycloak/clients.tf index 5f2fd21a35..178971ae36 100644 --- a/ops/keycloak/clients.tf +++ b/ops/keycloak/clients.tf @@ -70,23 +70,16 @@ resource "keycloak_saml_user_attribute_protocol_mapper" "buildkite_name" { saml_attribute_name_format = "Unspecified" } -resource "keycloak_openid_client" "oauth2_proxy" { +resource "keycloak_openid_client" "panettone" { realm_id = keycloak_realm.tvl.id - client_id = "oauth2-proxy" - name = "TVL OAuth2 Proxy" + client_id = "panettone" + name = "Panettone" enabled = true access_type = "CONFIDENTIAL" standard_flow_enabled = true valid_redirect_uris = [ - "https://login.tvl.fyi/oauth2/callback", - "http://localhost:4774/oauth2/callback", + "https://b.tvl.fyi/auth", + "http://localhost:6161/auth", ] } - -resource "keycloak_openid_audience_protocol_mapper" "oauth2_proxy_audience" { - realm_id = keycloak_realm.tvl.id - client_id = keycloak_openid_client.oauth2_proxy.id - name = "oauth2-proxy-audience" - included_custom_audience = keycloak_openid_client.oauth2_proxy.client_id -} diff --git a/ops/keycloak/default.nix b/ops/keycloak/default.nix index 96f0c40e5e..94ed912dc9 100644 --- a/ops/keycloak/default.nix +++ b/ops/keycloak/default.nix @@ -1,8 +1,14 @@ -{ depot, pkgs, ... }: +{ depot, lib, pkgs, ... }: -depot.nix.readTree.drvTargets { +depot.nix.readTree.drvTargets rec { # Provide a Terraform wrapper with the right provider installed. - terraform = pkgs.terraform.withPlugins(p: [ + terraform = pkgs.terraform.withPlugins (p: [ p.keycloak ]); + + validate = depot.tools.checks.validateTerraform { + inherit terraform; + name = "keycloak"; + src = lib.cleanSource ./.; + }; } diff --git a/ops/keycloak/main.tf b/ops/keycloak/main.tf index 819267ff96..923ac19397 100644 --- a/ops/keycloak/main.tf +++ b/ops/keycloak/main.tf @@ -1,6 +1,6 @@ # Configure TVL Keycloak instance. # -# TODO(tazjin): Configure GitHub/GitLab IDP +# TODO(tazjin): Configure GitLab IDP terraform { required_providers { @@ -31,4 +31,14 @@ resource "keycloak_realm" "tvl" { enabled = true display_name = "The Virus Lounge" default_signature_algorithm = "RS256" + + smtp_server { + from = "tvlbot@tazj.in" + from_display_name = "The Virus Lounge" + host = "127.0.0.1" + port = "25" + reply_to = "depot@tvl.su" + ssl = false + starttls = false + } } diff --git a/ops/keycloak/user_sources.tf b/ops/keycloak/user_sources.tf index 3fde6e07cc..01307fff8d 100644 --- a/ops/keycloak/user_sources.tf +++ b/ops/keycloak/user_sources.tf @@ -2,6 +2,10 @@ # information (either by accessing a system like LDAP or integration # through protocols like OIDC). +variable "github_client_secret" { + type = string +} + resource "keycloak_ldap_user_federation" "tvl_ldap" { name = "tvl-ldap" realm_id = keycloak_realm.tvl.id @@ -19,3 +23,22 @@ resource "keycloak_ldap_user_federation" "tvl_ldap" { "organizationalPerson", ] } + +# keycloak_oidc_identity_provider.github will be destroyed +# (because keycloak_oidc_identity_provider.github is not in configuration) +resource "keycloak_oidc_identity_provider" "github" { + alias = "github" + provider_id = "github" + client_id = "6d7f8bb2e82bb6739556" + client_secret = var.github_client_secret + realm = keycloak_realm.tvl.id + backchannel_supported = false + gui_order = "1" + store_token = false + sync_mode = "IMPORT" + trust_email = true + + # These default to built-in values for the `github` provider_id. + authorization_url = "" + token_url = "" +} diff --git a/ops/kontemplate/release.nix b/ops/kontemplate/release.nix index 8a04109526..6a3dbd5efe 100644 --- a/ops/kontemplate/release.nix +++ b/ops/kontemplate/release.nix @@ -10,13 +10,17 @@ # This file is the Nix derivation used to build release binaries for # several different architectures and operating systems. -let pkgs = import ((import <nixpkgs> {}).fetchFromGitHub { - owner = "NixOS"; - repo = "nixpkgs-channels"; - rev = "541d9cce8af7a490fb9085305939569567cb58e6"; - sha256 = "0jgz72hhzkd5vyq5v69vpljjlnf0lqaz7fh327bvb3cvmwbfxrja"; -}) {}; -in with pkgs; buildGoPackage rec { +let + pkgs = import + ((import <nixpkgs> { }).fetchFromGitHub { + owner = "NixOS"; + repo = "nixpkgs-channels"; + rev = "541d9cce8af7a490fb9085305939569567cb58e6"; + sha256 = "0jgz72hhzkd5vyq5v69vpljjlnf0lqaz7fh327bvb3cvmwbfxrja"; + }) + { }; +in +with pkgs; buildGoPackage rec { name = "kontemplate-${version}"; version = "canon"; src = ./.; @@ -29,8 +33,8 @@ in with pkgs; buildGoPackage rec { # reason for setting the 'allowGoReference' flag. dontStrip = true; # Linker configuration handles stripping allowGoReference = true; - CGO_ENABLED="0"; - GOCACHE="off"; + CGO_ENABLED = "0"; + GOCACHE = "off"; # Configure release builds via the "build-matrix" script: buildInputs = [ git ]; diff --git a/ops/machines/all-systems.nix b/ops/machines/all-systems.nix index df1cfa6a48..c4382fbddb 100644 --- a/ops/machines/all-systems.nix +++ b/ops/machines/all-systems.nix @@ -1,6 +1,7 @@ { depot, ... }: (with depot.ops.machines; [ + sanduny whitby ]) ++ @@ -8,13 +9,19 @@ camden frog tverskoy + zamalek ]) ++ -(with depot.users.grfn.system.system; [ +(with depot.users.aspen.system.system; [ yeren mugwump + ogopogo + lusca ]) ++ (with depot.users.wpcarro.nixos; [ + ava + kyoko marcus + tarasco ]) diff --git a/ops/machines/nixery-01/default.nix b/ops/machines/nixery-01/default.nix new file mode 100644 index 0000000000..c99db214d8 --- /dev/null +++ b/ops/machines/nixery-01/default.nix @@ -0,0 +1,40 @@ +# nixery.dev backing host in ru-central1-b +{ depot, lib, pkgs, ... }: # readTree options +{ config, ... }: # passed by module system + +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); +in +{ + imports = [ + (mod "known-hosts.nix") + (mod "nixery.nix") + (mod "tvl-users.nix") + (mod "www/nixery.dev.nix") + (mod "yandex-cloud.nix") + + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + networking = { + hostName = "nixery-01"; + domain = "tvl.fyi"; + firewall.allowedTCPPorts = [ 22 80 443 ]; + }; + + security.sudo.extraRules = lib.singleton { + groups = [ "wheel" ]; + commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }]; + }; + + services.depot.nixery.enable = true; + + # Automatically collect garbage from the Nix store. + services.depot.automatic-gc = { + enable = true; + interval = "1 hour"; + diskThreshold = 25; # GiB + maxFreed = 150; # GiB + preserveGenerations = "30d"; + }; +} diff --git a/ops/machines/sanduny/default.nix b/ops/machines/sanduny/default.nix new file mode 100644 index 0000000000..af2dfb02a5 --- /dev/null +++ b/ops/machines/sanduny/default.nix @@ -0,0 +1,138 @@ +# sanduny.tvl.su +# +# This is a VPS hosted with Bitfolk, intended to additionally serve +# some of our public services like cgit, josh and the websites. +# +# In case of whitby going down, sanduny will keep depot available. + +_: # ignore readTree options + +{ config, depot, lib, pkgs, ... }: + +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); +in +{ + imports = [ + (mod "cgit.nix") + (mod "depot-inbox.nix") + (mod "depot-replica.nix") + (mod "journaldriver.nix") + (mod "known-hosts.nix") + (mod "tvl-cache.nix") + (mod "tvl-headscale.nix") + (mod "tvl-users.nix") + (mod "www/inbox.tvl.su.nix") + (mod "www/self-redirect.nix") + (mod "www/volgasprint.org.nix") + ]; + + networking = { + hostName = "sanduny"; + domain = "tvl.su"; + useDHCP = false; + + interfaces.eth0 = { + ipv4.addresses = lib.singleton { + address = "85.119.82.231"; + prefixLength = 21; + }; + + ipv6.addresses = lib.singleton { + address = "2001:ba8:1f1:f109::feed:edef:beef"; + prefixLength = 64; + }; + }; + + defaultGateway = "85.119.80.1"; + defaultGateway6.address = "2001:ba8:1f1:f109::1"; + + firewall.allowedTCPPorts = [ 22 80 443 ]; + + # https://bitfolk.com/customer_information.html#toc_2_DNS + nameservers = [ + "85.119.80.232" + "85.119.80.233" + "2001:ba8:1f1:f205::53" + "2001:ba8:1f1:f206::53" + ]; + }; + + security.sudo.wheelNeedsPassword = false; + + environment.systemPackages = with pkgs; [ + emacs-nox + vim + curl + unzip + htop + ]; + + programs.mtr.enable = true; + + services.openssh.enable = true; + services.fail2ban.enable = true; + + # Run tailscale for the TVL net.tvl.fyi network. + # tailscale up --login-server https://net.tvl.fyi --accept-dns=false --advertise-exit-node + services.tailscale = { + enable = true; + useRoutingFeatures = "server"; # for exit-node usage + }; + + # Automatically collect garbage from the Nix store. + services.depot.automatic-gc = { + enable = true; + interval = "1 hour"; + diskThreshold = 2; # GiB + maxFreed = 5; # GiB + preserveGenerations = "90d"; + }; + + # Allow Gerrit to replicate depot to /var/lib/depot + services.depot.replica.enable = true; + + # Run git serving tools locally ... + services.depot.cgit = { + enable = true; + repo = "/var/lib/depot"; + }; + + # Serve public-inbox ... + services.depot.inbox.enable = true; + + time.timeZone = "UTC"; + + # GRUB does not actually need to be installed on disk; Bitfolk have + # their own way of booting systems as long as config is in place. + boot.loader.grub.device = "nodev"; + boot.loader.grub.enable = true; + boot.initrd.availableKernelModules = [ "xen_blkfront" ]; + + hardware.cpu.intel.updateMicrocode = true; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/aabc3638-43ca-45f3-af89-c451e8448e92"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/75aa99d5-fed7-4c5c-8570-7745f6cff9f5"; + fsType = "ext3"; + }; + + "/nix" = { + device = "/dev/disk/by-uuid/d1721678-c294-482b-b72e-3b15f2c56c63"; + fsType = "ext4"; + }; + }; + + tvl.cache.enable = true; + + swapDevices = lib.singleton { + device = "/dev/disk/by-uuid/df4ad9da-0a06-4c27-93e5-5d44e4750e55"; + }; + + system.stateVersion = "22.05"; # Did you read the comment? +} diff --git a/ops/machines/whitby/OWNERS b/ops/machines/whitby/OWNERS index b1b749e871..4581a80d61 100644 --- a/ops/machines/whitby/OWNERS +++ b/ops/machines/whitby/OWNERS @@ -1,6 +1,5 @@ -inherited: false +set noparent # Want in on this list? Try paying! -owners: - - lukegb - - tazjin +lukegb +tazjin diff --git a/ops/machines/whitby/default.nix b/ops/machines/whitby/default.nix index dbee33aa3f..6a8ee56abc 100644 --- a/ops/machines/whitby/default.nix +++ b/ops/machines/whitby/default.nix @@ -4,43 +4,52 @@ let inherit (builtins) listToAttrs; inherit (lib) range; -in { + + mod = name: depot.path.origSrc + ("/ops/modules/" + name); +in +{ imports = [ - "${depot.path}/ops/modules/atward.nix" - "${depot.path}/ops/modules/clbot.nix" - "${depot.path}/ops/modules/gerrit-queue.nix" - "${depot.path}/ops/modules/git-serving.nix" - "${depot.path}/ops/modules/irccat.nix" - "${depot.path}/ops/modules/monorepo-gerrit.nix" - "${depot.path}/ops/modules/nixery.nix" - "${depot.path}/ops/modules/oauth2_proxy.nix" - "${depot.path}/ops/modules/owothia.nix" - "${depot.path}/ops/modules/panettone.nix" - "${depot.path}/ops/modules/paroxysm.nix" - "${depot.path}/ops/modules/restic.nix" - "${depot.path}/ops/modules/smtprelay.nix" - "${depot.path}/ops/modules/sourcegraph.nix" - "${depot.path}/ops/modules/tvl-buildkite.nix" - "${depot.path}/ops/modules/tvl-slapd/default.nix" - "${depot.path}/ops/modules/www/atward.tvl.fyi.nix" - "${depot.path}/ops/modules/www/auth.tvl.fyi.nix" - "${depot.path}/ops/modules/www/b.tvl.fyi.nix" - "${depot.path}/ops/modules/www/cache.tvl.su.nix" - "${depot.path}/ops/modules/www/cl.tvl.fyi.nix" - "${depot.path}/ops/modules/www/code.tvl.fyi.nix" - "${depot.path}/ops/modules/www/cs.tvl.fyi.nix" - "${depot.path}/ops/modules/www/deploys.tvl.fyi.nix" - "${depot.path}/ops/modules/www/images.tvl.fyi.nix" - "${depot.path}/ops/modules/www/nixery.dev.nix" - "${depot.path}/ops/modules/www/static.tvl.fyi.nix" - "${depot.path}/ops/modules/www/status.tvl.su.nix" - "${depot.path}/ops/modules/www/tazj.in.nix" - "${depot.path}/ops/modules/www/todo.tvl.fyi.nix" - "${depot.path}/ops/modules/www/tvl.fyi.nix" - "${depot.path}/ops/modules/www/tvl.su.nix" - "${depot.path}/ops/modules/www/wigglydonke.rs.nix" - "${depot.third_party.agenix.src}/modules/age.nix" - "${pkgs.path}/nixos/modules/services/web-apps/gerrit.nix" + (mod "atward.nix") + (mod "cgit.nix") + (mod "clbot.nix") + (mod "gerrit-autosubmit.nix") + (mod "irccat.nix") + (mod "josh.nix") + (mod "journaldriver.nix") + (mod "known-hosts.nix") + (mod "livegrep.nix") + (mod "monorepo-gerrit.nix") + (mod "owothia.nix") + (mod "panettone.nix") + (mod "paroxysm.nix") + (mod "restic.nix") + (mod "smtprelay.nix") + (mod "sourcegraph.nix") + (mod "tvl-buildkite.nix") + (mod "tvl-slapd/default.nix") + (mod "tvl-users.nix") + (mod "www/atward.tvl.fyi.nix") + (mod "www/auth.tvl.fyi.nix") + (mod "www/b.tvl.fyi.nix") + (mod "www/cache.tvl.su.nix") + (mod "www/cl.tvl.fyi.nix") + (mod "www/code.tvl.fyi.nix") + (mod "www/cs.tvl.fyi.nix") + (mod "www/deploys.tvl.fyi.nix") + (mod "www/self-redirect.nix") + (mod "www/signup.tvl.fyi.nix") + (mod "www/static.tvl.fyi.nix") + (mod "www/status.tvl.su.nix") + (mod "www/todo.tvl.fyi.nix") + (mod "www/tvix.dev.nix") + (mod "www/tvl.fyi.nix") + (mod "www/tvl.su.nix") + (mod "www/wigglydonke.rs.nix") + + # experimental! + (mod "www/grep.tvl.fyi.nix") + + (depot.third_party.agenix.src + "/modules/age.nix") ]; hardware = { @@ -49,13 +58,19 @@ in { }; boot = { - tmpOnTmpfs = true; + tmp.useTmpfs = true; kernelModules = [ "kvm-amd" ]; supportedFilesystems = [ "zfs" ]; initrd = { availableKernelModules = [ - "igb" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sr_mod" + "igb" + "xhci_pci" + "nvme" + "ahci" + "usbhid" + "usb_storage" + "sr_mod" ]; # Enable SSH in the initrd so that we can enter disk encryption @@ -68,7 +83,7 @@ in { authorizedKeys = depot.users.tazjin.keys.all ++ depot.users.lukegb.keys.all - ++ [ depot.users.grfn.keys.whitby ]; + ++ [ depot.users.aspen.keys.whitby ]; hostKeys = [ /etc/secrets/initrd_host_ed25519_key @@ -89,7 +104,6 @@ in { loader.grub = { enable = true; - version = 2; efiSupport = true; efiInstallAsRemovable = true; device = "/dev/disk/by-id/nvme-SAMSUNG_MZQLB1T9HAJR-00007_S439NA0N201620"; @@ -170,26 +184,26 @@ in { nix = { nrBuildUsers = 256; - maxJobs = lib.mkDefault 64; - extraOptions = '' - secret-key-files = /run/agenix/nix-cache-priv - ''; - - trustedUsers = [ - "grfn" - "lukegb" - "tazjin" - "sterni" - ]; + settings = { + max-jobs = lib.mkDefault 64; + secret-key-files = "/run/agenix/nix-cache-priv"; + + trusted-users = [ + "aspen" + "lukegb" + "tazjin" + "sterni" + ]; + }; sshServe = { enable = true; keys = with depot.users; tazjin.keys.all ++ lukegb.keys.all - ++ [ grfn.keys.whitby ] + ++ [ aspen.keys.whitby ] ++ sterni.keys.all - ; + ; }; }; @@ -197,22 +211,24 @@ in { programs.mosh.enable = true; services.openssh = { enable = true; - passwordAuthentication = false; - challengeResponseAuthentication = false; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; }; # Configure secrets for services that need them. age.secrets = let secretFile = name: depot.ops.secrets."${name}.age"; - in { + in + { clbot.file = secretFile "clbot"; - gerrit-queue.file = secretFile "gerrit-queue"; + gerrit-autosubmit.file = secretFile "gerrit-autosubmit"; grafana.file = secretFile "grafana"; irccat.file = secretFile "irccat"; keycloak-db.file = secretFile "keycloak-db"; nix-cache-priv.file = secretFile "nix-cache-priv"; - oauth2_proxy.file = secretFile "oauth2_proxy"; owothia.file = secretFile "owothia"; panettone.file = secretFile "panettone"; smtprelay.file = secretFile "smtprelay"; @@ -235,6 +251,12 @@ in { group = "buildkite-agents"; }; + buildkite-private-key = { + file = secretFile "buildkite-ssh-private-key"; + mode = "0440"; + group = "buildkite-agents"; + }; + gerrit-besadii-config = { file = secretFile "besadii"; owner = "git"; @@ -257,6 +279,14 @@ in { file = secretFile "nix-cache-pub"; mode = "0444"; }; + + depot-replica-key = { + file = secretFile "depot-replica-key"; + mode = "0500"; + owner = "git"; + group = "git"; + path = "/var/lib/git/.ssh/id_ed25519"; + }; }; # Automatically collect garbage from the Nix store. @@ -315,13 +345,13 @@ in { # Start the Gerrit->IRC bot services.depot.clbot = { enable = true; - channels = [ "#tvl" ]; + channels = [ "#tvix-dev" "#tvl" ]; # See //fun/clbot for details. flags = { gerrit_host = "cl.tvl.fyi:29418"; gerrit_ssh_auth_username = "clbot"; - gerrit_ssh_auth_key = "/run/agenix/clbot-ssh"; + gerrit_ssh_auth_key = config.age.secretsDir + "/clbot-ssh"; irc_server = "localhost:${toString config.services.znc.config.Listener.l.Port}"; irc_user = "tvlbot"; @@ -340,6 +370,9 @@ in { # Run a SourceGraph code search instance sourcegraph.enable = true; + # Run a livegrep code search instance + livegrep.enable = true; + # Run the Panettone issue tracker panettone = { enable = true; @@ -380,11 +413,13 @@ in { # Run atward, the search engine redirection thing. atward.enable = true; - # Run a Nixery instance - nixery.enable = true; - # Run cgit & josh to serve git - git-serving.enable = true; + cgit = { + enable = true; + user = "git"; # run as the same user as gerrit + }; + + josh.enable = true; # Configure backups to GleSYS restic = { @@ -397,15 +432,13 @@ in { }; # Run autosubmit bot for Gerrit - gerrit-queue.enable = true; - - # Run oauth2_proxy for internal service auth - oauth2_proxy.enable = true; + gerrit-autosubmit.enable = true; }; services.postgresql = { enable = true; enableTCPIP = true; + package = pkgs.postgresql_16; authentication = lib.mkForce '' local all all trust @@ -421,9 +454,7 @@ in { ensureUsers = [{ name = "panettone"; - ensurePermissions = { - "DATABASE panettone" = "ALL PRIVILEGES"; - }; + ensureDBOwnership = true; }]; }; @@ -439,30 +470,26 @@ in { services.nix-serve = { enable = true; port = 6443; - secretKeyFile = "/run/agenix/nix-cache-priv"; + secretKeyFile = config.age.secretsDir + "/nix-cache-priv"; bindAddress = "localhost"; }; services.fail2ban.enable = true; environment.systemPackages = (with pkgs; [ - alacritty.terminfo bat bb curl direnv emacs-nox fd - foot.terminfo git htop hyperfine jq - kitty.terminfo nano nvd ripgrep - rxvt_unicode.terminfo tree unzip vim @@ -472,98 +499,97 @@ in { ops.deploy-whitby ]); - services.journaldriver = { - enable = true; - googleCloudProject = "tvl-fyi"; - logStream = "whitby"; - applicationCredentials = "/var/lib/journaldriver/key.json"; - }; + # Required for prometheus to be able to scrape stats + services.nginx.statusPage = true; # Configure Prometheus & Grafana. Exporter configuration for # Prometheus is inside the respective service modules. services.prometheus = { enable = true; - exporters.node = { - enable = true; + retentionTime = "90d"; - enabledCollectors = [ - "logind" - "processes" - "systemd" - ]; + exporters = { + node = { + enable = true; + + enabledCollectors = [ + "logind" + "processes" + "systemd" + ]; + }; + + nginx = { + enable = true; + sslVerify = false; + constLabels = [ "host=whitby" ]; + }; }; scrapeConfigs = [{ job_name = "node"; scrape_interval = "5s"; static_configs = [{ - targets = ["localhost:${toString config.services.prometheus.exporters.node.port}"]; + targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; + }]; + } + { + job_name = "nginx"; + scrape_interval = "5s"; + static_configs = [{ + targets = [ "localhost:${toString config.services.prometheus.exporters.nginx.port}" ]; + }]; }]; - }]; }; services.grafana = { enable = true; - port = 4723; # "graf" on phone keyboard - domain = "status.tvl.su"; - rootUrl = "https://status.tvl.su"; - analytics.reporting.enable = false; - extraOptions = let - options = { - auth = { - generic_oauth = { - enabled = true; - client_id = "grafana"; - scopes = "openid profile email"; - name = "TVL"; - email_attribute_path = "mail"; - login_attribute_path = "sub"; - name_attribute_path = "displayName"; - auth_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/auth"; - token_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/token"; - api_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/userinfo"; - - # Give lukegb, grfn, tazjin "Admin" rights. - role_attribute_path = "((sub == 'lukegb' || sub == 'grfn' || sub == 'tazjin') && 'Admin') || 'Editor'"; - - # Allow creating new Grafana accounts from OAuth accounts. - allow_sign_up = true; - }; - - anonymous = { - enabled = true; - org_name = "The Virus Lounge"; - org_role = "Viewer"; - }; - - basic.enabled = false; - oauth_auto_login = true; - disable_login_form = true; - }; + + settings = { + server = { + http_port = 4723; # "graf" on phone keyboard + domain = "status.tvl.su"; + root_url = "https://status.tvl.su"; + }; + + analytics.reporting_enabled = false; + + "auth.generic_oauth" = { + enabled = true; + client_id = "grafana"; + scopes = "openid profile email"; + name = "TVL"; + email_attribute_path = "mail"; + login_attribute_path = "sub"; + name_attribute_path = "displayName"; + auth_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/auth"; + token_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/token"; + api_url = "https://auth.tvl.fyi/auth/realms/TVL/protocol/openid-connect/userinfo"; + + # Give lukegb, aspen, tazjin "Admin" rights. + role_attribute_path = "((sub == 'lukegb' || sub == 'aspen' || sub == 'tazjin') && 'Admin') || 'Editor'"; + + # Allow creating new Grafana accounts from OAuth accounts. + allow_sign_up = true; }; - inherit (builtins) typeOf replaceStrings listToAttrs concatLists; - inherit (lib) toUpper mapAttrsToList nameValuePair concatStringsSep; - - # Take ["auth" "generic_oauth" "enabled"] and turn it into OPTIONS_GENERIC_OAUTH_ENABLED. - encodeName = raw: replaceStrings ["."] ["_"] (toUpper (concatStringsSep "_" raw)); - - # Turn an option value into a string, but we want bools to be sensible strings and not "1" or "". - optionToString = value: - if (typeOf value) == "bool" then - if value then "true" else "false" - else builtins.toString value; - - # Turn an nested options attrset into a flat listToAttrs-compatible list. - encodeOptions = prefix: inp: concatLists (mapAttrsToList (name: value: - if (typeOf value) == "set" - then encodeOptions (prefix ++ [name]) value - else [ (nameValuePair (encodeName (prefix ++ [name])) (optionToString value)) ] - ) inp); - in listToAttrs (encodeOptions [] options); + + "auth.anonymous" = { + enabled = true; + org_name = "The Virus Lounge"; + org_role = "Viewer"; + }; + + "auth.basic".enabled = false; + + auth = { + oauth_auto_login = true; + disable_login_form = true; + }; + }; provision = { enable = true; - datasources = [{ + datasources.settings.datasources = [{ name = "Prometheus"; type = "prometheus"; url = "http://localhost:9090"; @@ -572,30 +598,29 @@ in { }; # Contains GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET. - systemd.services.grafana.serviceConfig.EnvironmentFile = "/run/agenix/grafana"; + systemd.services.grafana.serviceConfig.EnvironmentFile = config.age.secretsDir + "/grafana"; services.keycloak = { enable = true; - httpPort = "5925"; # "kycl" - frontendUrl = "https://auth.tvl.fyi/auth/"; + + settings = { + http-port = 5925; # kycl + hostname = "auth.tvl.fyi"; + http-relative-path = "/auth"; + proxy = "edge"; + }; database = { type = "postgresql"; - passwordFile = "/run/agenix/keycloak-db"; + passwordFile = config.age.secretsDir + "/keycloak-db"; createLocally = false; }; + }; - # Configure Keycloak to look at forwarded headers from the reverse - # proxy. - extraConfig = { - "subsystem=undertow" = { - "server=default-server" = { - "http-listener=default" = { - proxy-address-forwarding = "true"; - }; - }; - }; - }; + # Join TVL Tailscale network at net.tvl.fyi + services.tailscale = { + enable = true; + useRoutingFeatures = "server"; # for exit-node usage }; # Allow Keycloak access to the LDAP module by forcing in the JVM @@ -605,89 +630,14 @@ in { security.sudo.extraRules = [ { - groups = ["wheel"]; - commands = [{ command = "ALL"; options = ["NOPASSWD"]; }]; + groups = [ "wheel" ]; + commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }]; } ]; users = { - users.tazjin = { - isNormalUser = true; - extraGroups = [ "git" "wheel" ]; - shell = pkgs.fish; - openssh.authorizedKeys.keys = depot.users.tazjin.keys.all; - }; - - users.lukegb = { - isNormalUser = true; - extraGroups = [ "git" "wheel" ]; - openssh.authorizedKeys.keys = depot.users.lukegb.keys.all; - }; - - users.grfn = { - isNormalUser = true; - extraGroups = [ "git" "wheel" ]; - openssh.authorizedKeys.keys = [ - depot.users.grfn.keys.whitby - ]; - }; - - users.isomer = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.isomer.keys.all; - }; - - users.riking = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.riking.keys.u2f ++ depot.users.riking.keys.passworded; - }; - - users.edef = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.edef.keys.all; - }; - - users.qyliss = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.qyliss.keys.all; - }; - - users.eta = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.eta.keys.whitby; - }; - - users.cynthia = { - isNormalUser = true; # I'm normal OwO :3 - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.cynthia.keys.all; - }; - - users.firefly = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.firefly.keys.whitby; - }; - - users.sterni = { - isNormalUser = true; - extraGroups = [ "git" "wheel" ]; - openssh.authorizedKeys.keys = depot.users.sterni.keys.all; - }; - - users.flokli = { - isNormalUser = true; - extraGroups = [ "git" ]; - openssh.authorizedKeys.keys = depot.users.flokli.keys.all; - }; - # Set up a user & group for git shenanigans - groups.git = {}; + groups.git = { }; users.git = { group = "git"; isSystemUser = true; @@ -696,10 +646,7 @@ in { }; }; - security.acme = { - acceptTerms = true; - defaults.email = "certs@tvl.fyi"; - }; + zramSwap.enable = true; system.stateVersion = "20.03"; } diff --git a/ops/modules/atward.nix b/ops/modules/atward.nix index 354f9ebdd3..f345a08e31 100644 --- a/ops/modules/atward.nix +++ b/ops/modules/atward.nix @@ -3,7 +3,8 @@ let cfg = config.services.depot.atward; description = "atward - (attempt to) cleverly route queries"; -in { +in +{ options.services.depot.atward = { enable = lib.mkEnableOption description; diff --git a/ops/modules/auto-deploy.nix b/ops/modules/auto-deploy.nix index 83a8273562..c504906b2b 100644 --- a/ops/modules/auto-deploy.nix +++ b/ops/modules/auto-deploy.nix @@ -45,7 +45,8 @@ let # NixOS in $STATE_DIRECTORY (cd / && ${rebuild-system}/bin/rebuild-system) ''; -in { +in +{ options.services.depot.auto-deploy = { enable = lib.mkEnableOption description; diff --git a/ops/modules/automatic-gc.nix b/ops/modules/automatic-gc.nix index 6347857210..003f160919 100644 --- a/ops/modules/automatic-gc.nix +++ b/ops/modules/automatic-gc.nix @@ -13,6 +13,11 @@ let gcScript = pkgs.writeShellScript "automatic-nix-gc" '' set -ueo pipefail + if [ -e /run/stop-automatic-gc ]; then + echo "GC is disabled through /run/stop-automatic-gc" + exit 0 + fi + readonly MIN_THRESHOLD_KIB="${toString (GiBtoKiB cfg.diskThreshold)}" readonly MAX_FREED_BYTES="${toString (GiBtoBytes cfg.maxFreed)}" readonly GEN_THRESHOLD="${cfg.preserveGenerations}" @@ -29,7 +34,8 @@ let echo "Skipping GC, enough space available" fi ''; -in { +in +{ options.services.depot.automatic-gc = { enable = lib.mkEnableOption description; diff --git a/ops/modules/btrfs-auto-scrub.nix b/ops/modules/btrfs-auto-scrub.nix new file mode 100644 index 0000000000..748bb75c5f --- /dev/null +++ b/ops/modules/btrfs-auto-scrub.nix @@ -0,0 +1,25 @@ +# Automatically performs a scrub on all btrfs filesystems configured in +# `config.fileSystems` on a daily schedule (by default). Activated by importing. +{ config, lib, ... }: + +{ + config = { + services = { + btrfs.autoScrub = { + enable = true; + interval = lib.mkDefault "*-*-* 03:30:00"; + # gather all btrfs fileSystems, extra ones can be added via the NixOS + # module merging mechanism, of course. + fileSystems = lib.concatLists ( + lib.mapAttrsToList + ( + _: + { fsType, mountPoint, ... }: + if fsType == "btrfs" then [ mountPoint ] else [ ] + ) + config.fileSystems + ); + }; + }; + }; +} diff --git a/ops/modules/cgit.nix b/ops/modules/cgit.nix new file mode 100644 index 0000000000..fc3f171585 --- /dev/null +++ b/ops/modules/cgit.nix @@ -0,0 +1,55 @@ +# Configuration for running the TVL cgit instance using thttpd. +{ config, depot, lib, pkgs, ... }: + +let + cfg = config.services.depot.cgit; + + userConfig = + if builtins.isNull cfg.user then { + DynamicUser = true; + } else { + User = cfg.user; + Group = cfg.user; + }; +in +{ + options.services.depot.cgit = with lib; { + enable = mkEnableOption "Run cgit web interface for depot"; + + port = mkOption { + description = "Port on which cgit should listen"; + type = types.int; + default = 2448; + }; + + repo = mkOption { + description = "Path to depot's .git folder on the machine"; + type = types.str; + default = "/var/lib/gerrit/git/depot.git/"; + }; + + user = mkOption { + description = '' + User to use for the cgit service. It is expected that this is + also the name of the user's primary group. + ''; + + type = with types; nullOr str; + default = null; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.cgit = { + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Restart = "on-failure"; + + ExecStart = depot.web.cgit-tvl.override { + inherit (cfg) port repo; + }; + } // userConfig; + }; + }; +} diff --git a/ops/modules/clbot.nix b/ops/modules/clbot.nix index ef4c2ab237..bdddff6c81 100644 --- a/ops/modules/clbot.nix +++ b/ops/modules/clbot.nix @@ -3,7 +3,7 @@ let inherit (builtins) attrValues concatStringsSep mapAttrs readFile; - inherit (pkgs) runCommandNoCC; + inherit (pkgs) runCommand; inherit (lib) listToAttrs @@ -21,7 +21,7 @@ let (attrValues (mapAttrs (key: value: "-${key} \"${toString value}\"") flags)); # Escapes a unit name for use in systemd - systemdEscape = name: removeSuffix "\n" (readFile (runCommandNoCC "unit-name" {} '' + systemdEscape = name: removeSuffix "\n" (readFile (runCommand "unit-name" { } '' ${pkgs.systemd}/bin/systemd-escape '${name}' >> $out '')); @@ -42,7 +42,8 @@ let }; }; }; -in { +in +{ options.services.depot.clbot = { enable = mkEnableOption description; @@ -59,7 +60,7 @@ in { secretsFile = mkOption { type = types.str; description = "EnvironmentFile from which to load secrets"; - default = "/run/agenix/clbot"; + default = config.age.secretsDir + "/clbot"; }; }; @@ -68,7 +69,7 @@ in { # (notably the SSH private key) readable by this user outside of # the module. users = { - groups.clbot = {}; + groups.clbot = { }; users.clbot = { group = "clbot"; diff --git a/ops/modules/default.nix b/ops/modules/default.nix index 8bdfecdf41..d747e8e131 100644 --- a/ops/modules/default.nix +++ b/ops/modules/default.nix @@ -1,2 +1,2 @@ # Make readTree happy at this level. -_: {} +_: { } diff --git a/ops/modules/depot-inbox.nix b/ops/modules/depot-inbox.nix new file mode 100644 index 0000000000..14fc646a9a --- /dev/null +++ b/ops/modules/depot-inbox.nix @@ -0,0 +1,148 @@ +# public-inbox configuration for depot@tvl.su +# +# The account itself is a Yandex 360 account in the tvl.su organisation, which +# is accessed via IMAP. Yandex takes care of spam filtering for us, so there is +# no particular SpamAssassin or other configuration. +{ config, depot, lib, pkgs, ... }: + +let + cfg = config.services.depot.inbox; + + imapConfig = pkgs.writeText "offlineimaprc" '' + [general] + accounts = depot + + [Account depot] + localrepository = Local + remoterepository = Remote + + [Repository Local] + type = Maildir + localfolders = /var/lib/public-inbox/depot-imap + + [Repository Remote] + type = IMAP + ssl = yes + sslcacertfile = /etc/ssl/certs/ca-bundle.crt + remotehost = imap.yandex.ru + remoteuser = depot@tvl.su + remotepassfile = /var/run/agenix/depot-inbox-imap + ''; +in +{ + options.services.depot.inbox = with lib; { + enable = mkEnableOption "Enable public-inbox for depot@tvl.su"; + + depotPath = mkOption { + description = "path to local depot replica"; + type = types.str; + default = "/var/lib/depot"; + }; + }; + + config = lib.mkIf cfg.enable { + # Having nginx *and* other services use ACME certificates for the + # same hostname is unsupported in NixOS without resorting to doing + # all ACME configuration manually. + # + # To work around this, we duplicate the TLS certificate used by + # nginx to a location that is readable by public-inbox daemons. + systemd.services.inbox-cert-sync = { + startAt = "daily"; + + script = '' + ${pkgs.coreutils}/bin/install -D -g ${config.users.groups."public-inbox".name} -m 0440 \ + /var/lib/acme/inbox.tvl.su/fullchain.pem /var/lib/public-inbox/tls/fullchain.pem + + ${pkgs.coreutils}/bin/install -D -g ${config.users.groups."public-inbox".name} -m 0440 \ + /var/lib/acme/inbox.tvl.su/key.pem /var/lib/public-inbox/tls/key.pem + ''; + }; + + services.public-inbox = { + enable = true; + + http.enable = true; + http.port = 8053; + + imap = { + enable = true; + port = 993; + cert = "/var/lib/public-inbox/tls/fullchain.pem"; + key = "/var/lib/public-inbox/tls/key.pem"; + }; + + nntp = { + enable = true; + port = 563; + cert = "/var/lib/public-inbox/tls/fullchain.pem"; + key = "/var/lib/public-inbox/tls/key.pem"; + }; + + inboxes.depot = rec { + address = [ + "depot@tvl.su" # primary address + "depot@tazj.in" # legacy address + ]; + + description = "TVL depot development (mail to depot@tvl.su)"; + coderepo = [ "depot" ]; + url = "https://inbox.tvl.su/depot"; + + watch = [ + "maildir:/var/lib/public-inbox/depot-imap/INBOX/" + ]; + + newsgroup = "su.tvl.depot"; + }; + + settings.coderepo.depot = { + dir = cfg.depotPath; + cgitUrl = "https://code.tvl.fyi"; + }; + + settings.publicinbox = { + wwwlisting = "all"; + nntpserver = [ "inbox.tvl.su" ]; + imapserver = [ "inbox.tvl.su" ]; + + depot.obfuscate = true; + noObfuscate = [ + "tvl.su" + "tvl.fyi" + ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 993 # imap + 563 # nntp + ]; + + age.secrets.depot-inbox-imap = { + file = depot.ops.secrets."depot-inbox-imap.age"; + mode = "0440"; + group = config.users.groups."public-inbox".name; + }; + + systemd.services.offlineimap-depot = { + description = "download mail for depot@tvl.su"; + wantedBy = [ "multi-user.target" ]; + startAt = "minutely"; + + script = '' + mkdir -p /var/lib/public-inbox/depot-imap + ${pkgs.offlineimap}/bin/offlineimap -c ${imapConfig} + ''; + + serviceConfig = { + Type = "oneshot"; + + # Run in the same user context as public-inbox itself to avoid + # permissions trouble. + User = config.users.users."public-inbox".name; + Group = config.users.groups."public-inbox".name; + }; + }; + }; +} diff --git a/ops/modules/depot-replica.nix b/ops/modules/depot-replica.nix new file mode 100644 index 0000000000..b71f10409a --- /dev/null +++ b/ops/modules/depot-replica.nix @@ -0,0 +1,45 @@ +# Configuration for receiving a depot replica from Gerrit's +# replication plugin. +# +# This only prepares the user and folder for receiving the replica, +# but Gerrit configuration still needs to be modified in addition. +{ config, depot, lib, pkgs, ... }: + +let + cfg = config.services.depot.replica; +in +{ + options.services.depot.replica = with lib; { + enable = mkEnableOption "Receive depot git replica from Gerrit"; + + key = mkOption { + description = "Public key to use for replication"; + type = types.str; + default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFFab9O1xaQ1TCyn+CxmXHexdlLzURREG+UR3Qdi3BvH"; + }; + + path = mkOption { + description = "Replication destination path (will be created)"; + type = types.str; + default = "/var/lib/depot"; + }; + }; + + config = lib.mkIf cfg.enable { + users.groups.depot = { }; + + users.users.depot = { + group = "depot"; + isSystemUser = true; + createHome = true; + home = cfg.path; + homeMode = "755"; # everyone can read depot + openssh.authorizedKeys.keys = lib.singleton cfg.key; + shell = pkgs.bashInteractive; # gerrit needs to run shell commands + }; + + environment.systemPackages = [ + pkgs.git + ]; + }; +} diff --git a/ops/modules/gerrit-autosubmit.nix b/ops/modules/gerrit-autosubmit.nix new file mode 100644 index 0000000000..34342c8d55 --- /dev/null +++ b/ops/modules/gerrit-autosubmit.nix @@ -0,0 +1,43 @@ +# Configuration for the Gerrit autosubmit bot (//ops/gerrit-autosubmit) +{ depot, pkgs, config, lib, ... }: + +let + cfg = config.services.depot.gerrit-autosubmit; + description = "gerrit-autosubmit - autosubmit bot for Gerrit"; + mkStringOption = default: lib.mkOption { + inherit default; + type = lib.types.str; + }; +in +{ + options.services.depot.gerrit-autosubmit = { + enable = lib.mkEnableOption description; + gerritUrl = mkStringOption "https://cl.tvl.fyi"; + + secretsFile = with lib; mkOption { + description = "Path to a systemd EnvironmentFile containing secrets"; + default = config.age.secretsDir + "/gerrit-autosubmit"; + type = types.str; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.gerrit-autosubmit = { + inherit description; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + serviceConfig = { + ExecStart = "${depot.ops.gerrit-autosubmit}/bin/gerrit-autosubmit"; + DynamicUser = true; + Restart = "always"; + EnvironmentFile = cfg.secretsFile; + }; + + environment = { + GERRIT_URL = cfg.gerritUrl; + }; + }; + }; +} diff --git a/ops/modules/gerrit-queue.nix b/ops/modules/gerrit-queue.nix deleted file mode 100644 index a4b073f856..0000000000 --- a/ops/modules/gerrit-queue.nix +++ /dev/null @@ -1,51 +0,0 @@ -# Configuration for the Gerrit autosubmit bot (//third_party/gerrit-queue) -{ depot, pkgs, config, lib, ... }: - -let - cfg = config.services.depot.gerrit-queue; - description = "gerrit-queue - autosubmit bot for Gerrit"; - mkStringOption = default: lib.mkOption { - inherit default; - type = lib.types.str; - }; -in { - options.services.depot.gerrit-queue = { - enable = lib.mkEnableOption description; - gerritUrl = mkStringOption "https://cl.tvl.fyi"; - gerritProject = mkStringOption "depot"; - gerritBranch = mkStringOption "canon"; - - interval = with lib; mkOption { - type = types.int; - default = 60; - description = "Interval (in seconds) for submit queue checks"; - }; - - secretsFile = with lib; mkOption { - description = "Path to a systemd EnvironmentFile containing secrets"; - default = "/run/agenix/gerrit-queue"; - type = types.str; - }; - }; - - config = lib.mkIf cfg.enable { - systemd.services.gerrit-queue = { - inherit description; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - ExecStart = "${depot.third_party.gerrit-queue}/bin/gerrit-queue"; - DynamicUser = true; - Restart = "always"; - EnvironmentFile = cfg.secretsFile; - }; - - environment = { - GERRIT_URL = cfg.gerritUrl; - GERRIT_PROJECT = cfg.gerritProject; - GERRIT_BRANCH = cfg.gerritBranch; - SUBMIT_QUEUE_TRIGGER_INTERVAL = toString cfg.interval; - }; - }; - }; -} diff --git a/ops/modules/git-serving.nix b/ops/modules/git-serving.nix deleted file mode 100644 index 6b8bef29b1..0000000000 --- a/ops/modules/git-serving.nix +++ /dev/null @@ -1,53 +0,0 @@ -# Configures public git-serving infrastructure for TVL, this involves: -# -# 1. cgit (running at code.tvl.fyi) for web views of the repository -# 2. josh (for cloning the repository and its distinct subtrees) -# -# We also run Sourcegraph for browsing the repository, but this is -# currently configured in a separate module -# (//ops/modules/sourcegraph.nix) -# -# TODO(tazjin): Move //web/cgit-taz configuration in here instead. -{ config, depot, lib, pkgs, ... }: - -let - cfg = config.services.depot.git-serving; -in { - options.services.depot.git-serving = with lib; { - enable = mkEnableOption "Enable cgit & josh configuration"; - - joshPort = mkOption { - description = "Port on which josh should listen"; - type = types.int; - default = 5674; - }; - }; - - config = lib.mkIf cfg.enable { - # Run cgit for the depot. The onion here is nginx(thttpd(cgit)). - systemd.services.cgit = { - wantedBy = [ "multi-user.target" ]; - script = "${depot.web.cgit-taz}/bin/cgit-launch"; - - serviceConfig = { - Restart = "on-failure"; - User = "git"; - Group = "git"; - }; - }; - - # Run josh for the depot. - systemd.services.josh = { - description = "josh - partial cloning of monorepos"; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.git pkgs.bash ]; - - serviceConfig = { - DynamicUser = true; - StateDirectory = "josh"; - Restart = "always"; - ExecStart = "${depot.third_party.josh}/bin/josh-proxy --no-background --local /var/lib/josh --port ${toString cfg.joshPort} --remote https://cl.tvl.fyi/"; - }; - }; - }; -} diff --git a/ops/modules/irccat.nix b/ops/modules/irccat.nix index deb0b4ecaf..2263118d99 100644 --- a/ops/modules/irccat.nix +++ b/ops/modules/irccat.nix @@ -27,19 +27,20 @@ let exec ${depot.third_party.irccat}/bin/irccat ''; -in { +in +{ options.services.depot.irccat = { enable = lib.mkEnableOption description; config = lib.mkOption { - type = lib.types.attrs; # varying value types + type = lib.types.attrsOf lib.types.anything; # varying value types description = "Configuration structure (unchecked!)"; }; secretsFile = lib.mkOption { type = lib.types.str; description = "Path to the secrets file to be merged"; - default = "/run/agenix/irccat"; + default = config.age.secretsDir + "/irccat"; }; }; diff --git a/ops/modules/josh.nix b/ops/modules/josh.nix new file mode 100644 index 0000000000..3c37d0fec3 --- /dev/null +++ b/ops/modules/josh.nix @@ -0,0 +1,33 @@ +# Configures the public josh instance for serving the depot. +{ config, depot, lib, pkgs, ... }: + +let + cfg = config.services.depot.josh; +in +{ + options.services.depot.josh = with lib; { + enable = mkEnableOption "Enable josh for serving the depot"; + + port = mkOption { + description = "Port on which josh should listen"; + type = types.int; + default = 5674; + }; + }; + + config = lib.mkIf cfg.enable { + # Run josh for the depot. + systemd.services.josh = { + description = "josh - partial cloning of monorepos"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.git pkgs.bash ]; + + serviceConfig = { + DynamicUser = true; + StateDirectory = "josh"; + Restart = "always"; + ExecStart = "${pkgs.josh}/bin/josh-proxy --no-background --local /var/lib/josh --port ${toString cfg.port} --remote https://cl.tvl.fyi/ --require-auth"; + }; + }; + }; +} diff --git a/ops/modules/journaldriver.nix b/ops/modules/journaldriver.nix new file mode 100644 index 0000000000..0d6b0bcc7f --- /dev/null +++ b/ops/modules/journaldriver.nix @@ -0,0 +1,26 @@ +# Configures journaldriver to forward to the tvl-fyi GCP project from +# TVL machines. +{ config, depot, lib, pkgs, ... }: + +{ + imports = [ + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + age.secrets.journaldriver.file = depot.ops.secrets."journaldriver.age"; + + services.journaldriver = { + enable = true; + googleCloudProject = "tvl-fyi"; + logStream = config.networking.hostName; + }; + + # Override the systemd service defined in the nixpkgs module to use + # the credentials provided by agenix. + systemd.services.journaldriver = { + serviceConfig = { + LoadCredential = "journaldriver.json:/run/agenix/journaldriver"; + ExecStart = lib.mkForce "${pkgs.coreutils}/bin/env GOOGLE_APPLICATION_CREDENTIALS=\"\${CREDENTIALS_DIRECTORY}/journaldriver.json\" ${depot.ops.journaldriver}/bin/journaldriver"; + }; + }; +} diff --git a/ops/modules/known-hosts.nix b/ops/modules/known-hosts.nix new file mode 100644 index 0000000000..9ea689178e --- /dev/null +++ b/ops/modules/known-hosts.nix @@ -0,0 +1,21 @@ +# Configure public keys for SSH hosts known to TVL. +{ ... }: + +{ + programs.ssh.knownHosts = { + whitby = { + hostNames = [ "whitby.tvl.fyi" "whitby.tvl.su" ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNh/w4BSKov0jdz3gKBc98tpoLta5bb87fQXWBhAl2I"; + }; + + sanduny = { + hostNames = [ "sanduny.tvl.su" ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOag0XhylaTVhmT6HB8EN2Fv5Ymrc4ZfypOXONUkykTX"; + }; + + github = { + hostNames = [ "github.com" ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"; + }; + }; +} diff --git a/ops/modules/livegrep.nix b/ops/modules/livegrep.nix new file mode 100644 index 0000000000..e25a301829 --- /dev/null +++ b/ops/modules/livegrep.nix @@ -0,0 +1,106 @@ +# Configures a code search instance using Livegrep. +# +# We do not currently build Livegrep in Nix, because it's a complex, +# multi-language Bazel build and doesn't play nicely with Nix. +{ config, lib, pkgs, ... }: + +let + cfg = config.services.depot.livegrep; + + livegrepConfig = { + name = "livegrep"; + + fs_paths = [{ + name = "depot"; + path = "/depot"; + metadata.url_pattern = "https://code.tvl.fyi/tree/{path}?id={version}#n{lno}"; + }]; + + repositories = [{ + name = "depot"; + path = "/depot"; + revisions = [ "HEAD" ]; + + metadata = { + url_pattern = "https://code.tvl.fyi/tree/{path}?id={version}#n{lno}"; + remote = "https://cl.tvl.fyi/depot.git"; + }; + }]; + }; + + configFile = pkgs.writeText "livegrep-config.json" (builtins.toJSON livegrepConfig); + + # latest as of 2024-02-17 + image = "ghcr.io/livegrep/livegrep/base:033fa0e93c"; +in +{ + options.services.depot.livegrep = with lib; { + enable = mkEnableOption "Run livegrep code search for depot"; + + port = mkOption { + description = "Port on which livegrep web UI should listen"; + type = types.int; + default = 5477; # lgrp + }; + }; + + config = lib.mkIf cfg.enable { + virtualisation.oci-containers.containers.livegrep-codesearch = { + inherit image; + extraOptions = [ "--net=host" ]; + + volumes = [ + "${configFile}:/etc/livegrep-config.json:ro" + "/var/lib/gerrit/git/depot.git:/depot:ro" + ]; + + entrypoint = "/livegrep/bin/codesearch"; + cmd = [ + "-grpc" + "0.0.0.0:5427" # lgcs + "-reload_rpc" + "-revparse" + "/etc/livegrep-config.json" + ]; + }; + + virtualisation.oci-containers.containers.livegrep-frontend = { + inherit image; + dependsOn = [ "livegrep-codesearch" ]; + extraOptions = [ "--net=host" ]; + + entrypoint = "/livegrep/bin/livegrep"; + cmd = [ + "-listen" + "0.0.0.0:${toString cfg.port}" + "-reload" + "-connect" + "localhost:5427" + "-docroot" + "/livegrep/web" + # TODO(tazjin): docroot with styles etc. + ]; + }; + + systemd.services.livegrep-reindex = { + script = "${pkgs.docker}/bin/docker exec livegrep-codesearch /livegrep/bin/livegrep-reload localhost:5427"; + serviceConfig.Type = "oneshot"; + }; + + systemd.paths.livegrep-reindex = { + description = "Executes a livegrep reindex if depot refs change"; + wantedBy = [ "multi-user.target" ]; + + pathConfig = { + PathChanged = [ + "/var/lib/gerrit/git/depot.git/packed-refs" + "/var/lib/gerrit/git/depot.git/refs" + ]; + }; + }; + }; +} + + +# sudo docker exec -ti livegrep /livegrep/bin/codesearch -reload_rpc -revparse /var/lib/livegrep/config.jsno +# sudo docker run -d --ip 172.17.0.3 --name livegrep -v /var/lib/livegrep:/varlib/livegrep -v /var/lib/gerrit/git/depot.git:/depot:ro -v /home/tazjin/livegrep-web:/livegrep/web:ro ghcr.io/livegrep/livegrep/base /livegrep/bin/livegrep -listen 0.0.0.0:8910 -reload -docroot /livegrep/webbsudo docker run -d --ip 172.17.0.3 --name livegrep -v /var/lib/livegrep:/varlib/livegrep -v /var/lib/gerrit/git/depot.git:/depot:ro -v /home/tazjin/livegrep-web:/livegrep/web:ro ghcr.io/livegrep/livegrep/base /livegrep/bin/livegrep -listen 0.0.0.0:8910 -reload -docroot /livegrep/webb diff --git a/ops/modules/monorepo-gerrit.nix b/ops/modules/monorepo-gerrit.nix index 6638f30b3f..b335fe61d5 100644 --- a/ops/modules/monorepo-gerrit.nix +++ b/ops/modules/monorepo-gerrit.nix @@ -9,23 +9,26 @@ let exec -a ${name} ${depot.ops.besadii}/bin/besadii "$@" ''; - gerritHooks = pkgs.runCommandNoCC "gerrit-hooks" {} '' + gerritHooks = pkgs.runCommand "gerrit-hooks" { } '' mkdir -p $out ln -s ${besadiiWithConfig "change-merged"} $out/change-merged ln -s ${besadiiWithConfig "patchset-created"} $out/patchset-created ''; -in { +in +{ services.gerrit = { enable = true; listenAddress = "[::]:4778"; # 4778 - grrt serverId = "4fdfa107-4df9-4596-8e0a-1d2bbdd96e36"; + builtinPlugins = [ "download-commands" "hooks" + "replication" ]; plugins = with depot.third_party.gerrit_plugins; [ - owners + code-owners oauth depot.ops.gerrit-tvl ]; @@ -39,7 +42,7 @@ in { # Gerrit. # # TODO(tazjin): Update Gerrit and remove this when possible. - jvmPackage = pkgs.openjdk11_headless; + jvmPackage = pkgs.openjdk17_headless; settings = { core.packedGitLimit = "100m"; @@ -84,26 +87,35 @@ in { # Auto-link panettone bug links commentlink.panettone = { - match = "b/(\\\\d+)"; - html = "<a href=\"https://b.tvl.fyi/issues/$1\">b/$1</a>"; + match = "b/(\\d+)"; + link = "https://b.tvl.fyi/issues/$1"; }; # Auto-link other CLs commentlink.gerrit = { - match = "cl/(\\\\d+)"; - html = "<a href=\"https://cl.tvl.fyi/$1\">cl/$1</a>"; + match = "cl/(\\d+)"; + link = "https://cl.tvl.fyi/$1"; }; # Configures integration with Keycloak, which then integrates with a # variety of backends. auth.type = "OAUTH"; plugin.gerrit-oauth-provider-keycloak-oauth = { - root-url = "https://auth.tvl.fyi"; + root-url = "https://auth.tvl.fyi/auth"; realm = "TVL"; client-id = "gerrit"; # client-secret is set in /var/lib/gerrit/etc/secure.config. }; + plugin.code-owners = { + # A Code-Review +2 vote is required from a code owner. + requiredApproval = "Code-Review+2"; + # The OWNERS check can be overriden using an Owners-Override vote. + overrideApproval = "Owners-Override+1"; + # People implicitly approve their own changes automatically. + enableImplicitApprovals = "TRUE"; + }; + # Allow users to add additional email addresses to their accounts. oauth.allowRegisterNewEmail = true; @@ -129,6 +141,17 @@ in { smtpServerPort = 2525; }; }; + + # Replication of the depot repository to secondary machines, for + # serving cgit/josh. + replicationSettings = { + gerrit.replicateOnStartup = true; + + remote.sanduny = { + url = "depot@sanduny.tvl.su:/var/lib/depot"; + projects = "depot"; + }; + }; }; systemd.services.gerrit = { diff --git a/ops/modules/nixery.nix b/ops/modules/nixery.nix index 60d1510457..29da46cc1d 100644 --- a/ops/modules/nixery.nix +++ b/ops/modules/nixery.nix @@ -5,8 +5,10 @@ let cfg = config.services.depot.nixery; description = "Nixery - container images on-demand"; - storagePath = "/var/lib/nixery/${pkgs.nixpkgsCommits.unstable}"; -in { + nixpkgsSrc = depot.third_party.sources.nixpkgs-stable; + storagePath = "/var/lib/nixery/${nixpkgsSrc.rev}"; +in +{ options.services.depot.nixery = { enable = lib.mkEnableOption description; @@ -27,12 +29,12 @@ in { StateDirectory = "nixery"; Restart = "always"; ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${storagePath}"; - ExecStart = "${depot.third_party.nixery.nixery-bin}/bin/nixery"; + ExecStart = "${depot.tools.nixery.nixery}/bin/server"; }; environment = { PORT = toString cfg.port; - NIXERY_PKGS_PATH = pkgs.path; + NIXERY_PKGS_PATH = nixpkgsSrc.outPath; NIXERY_STORAGE_BACKEND = "filesystem"; NIX_TIMEOUT = "60"; # seconds STORAGE_PATH = storagePath; diff --git a/ops/modules/oauth2_proxy.nix b/ops/modules/oauth2_proxy.nix deleted file mode 100644 index 07ba8861e7..0000000000 --- a/ops/modules/oauth2_proxy.nix +++ /dev/null @@ -1,52 +0,0 @@ -# Configuration for oauth2_proxy, which is used as a handler for nginx -# auth-request setups. -# -# This module exports a helper function at -# `config.services.depot.oauth2_proxy.withAuth` that can be wrapped -# around nginx server configuration blocks to configure their -# authentication setup. -{ config, depot, pkgs, lib, ... }: - -let - description = "OAuth2 proxy to authenticate TVL services"; - cfg = config.services.depot.oauth2_proxy; - configFile = pkgs.writeText "oauth2_proxy.cfg" '' - email_domains = [ "*" ] - http_address = "127.0.0.1:${toString cfg.port}" - provider = "keycloak-oidc" - client_id = "oauth2-proxy" - oidc_issuer_url = "https://auth.tvl.fyi/auth/realms/TVL" - reverse_proxy = true - set_xauthrequest = true - ''; -in { - options.services.depot.oauth2_proxy = { - enable = lib.mkEnableOption description; - - port = lib.mkOption { - description = "Port to listen on"; - type = lib.types.int; - default = 2884; # "auth" - }; - - secretsFile = lib.mkOption { - type = lib.types.str; - description = "EnvironmentFile from which to load secrets"; - default = "/run/agenix/oauth2_proxy"; - }; - }; - - config = lib.mkIf cfg.enable { - systemd.services.oauth2_proxy = { - inherit description; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - Restart = "always"; - DynamicUser = true; - EnvironmentFile = cfg.secretsFile; - ExecStart = "${pkgs.oauth2_proxy}/bin/oauth2-proxy --config ${configFile}"; - }; - }; - }; -} diff --git a/ops/modules/open_eid.nix b/ops/modules/open_eid.nix new file mode 100644 index 0000000000..fa577f0f57 --- /dev/null +++ b/ops/modules/open_eid.nix @@ -0,0 +1,54 @@ +# NixOS module to configure the Estonian e-ID software. +{ pkgs, ... }: + +{ + services.pcscd.enable = true; + + # Tell p11-kit to load/proxy opensc-pkcs11.so, providing all available slots + # (PIN1 for authentication/decryption, PIN2 for signing). + environment.etc."pkcs11/modules/opensc-pkcs11".text = '' + module: ${pkgs.opensc}/lib/opensc-pkcs11.so + ''; + + # Configure Firefox (in case users set `programs.firefox.enable = true;`) + programs.firefox = { + # Allow a possibly installed "Web eID" extension to do native messaging with + # the "web-eid-app" native component. + # Users not using `programs.firefox.enable` can override their firefox + # derivation, by setting `extraNativeMessagingHosts = [ pkgs.web-eid-app ]`. + nativeMessagingHosts.packages = [ pkgs.web-eid-app ]; + # Configure Firefox to load smartcards via p11kit-proxy. + # Users not using `programs.firefox.enable` can override their firefox + # derivation, by setting + # `extraPolicies.SecurityDevices.p11-kit-proxy "${pkgs.p11-kit}/lib/p11-kit-proxy.so"`. + policies.SecurityDevices.p11-kit-proxy = "${pkgs.p11-kit}/lib/p11-kit-proxy.so"; + }; + + # Chromium users need a symlink to their (slightly different) .json file + # in the native messaging hosts' manifest file location. + environment.etc."chromium/native-messaging-hosts/eu.webeid.json".source = "${pkgs.web-eid-app}/share/web-eid/eu.webeid.json"; + environment.etc."opt/chrome/native-messaging-hosts/eu.webeid.json".source = "${pkgs.web-eid-app}/share/web-eid/eu.webeid.json"; + + environment.systemPackages = with pkgs; [ + libdigidocpp.bin # provides digidoc-tool(1) + qdigidoc + + # Wrapper script to tell to Chrome/Chromium to use p11-kit-proxy to load + # security devices, so they can be used for TLS client auth. + # Each user needs to run this themselves, it does not work on a system level + # due to a bug in Chromium: + # + # https://bugs.chromium.org/p/chromium/issues/detail?id=16387 + # + # Firefox users can just set + # extraPolicies.SecurityDevices.p11-kit-proxy "${pkgs.p11-kit}/lib/p11-kit-proxy.so"; + # when overriding the firefox derivation. + (pkgs.writeShellScriptBin "setup-browser-eid" '' + NSSDB="''${HOME}/.pki/nssdb" + mkdir -p ''${NSSDB} + + ${pkgs.nssTools}/bin/modutil -force -dbdir sql:$NSSDB -add p11-kit-proxy \ + -libfile ${pkgs.p11-kit}/lib/p11-kit-proxy.so + '') + ]; +} diff --git a/ops/modules/owothia.nix b/ops/modules/owothia.nix index b2a77cddc2..b9746c1720 100644 --- a/ops/modules/owothia.nix +++ b/ops/modules/owothia.nix @@ -4,14 +4,15 @@ let cfg = config.services.depot.owothia; description = "owothia - i'm a service owo"; -in { +in +{ options.services.depot.owothia = { enable = lib.mkEnableOption description; secretsFile = lib.mkOption { type = lib.types.str; description = "File path from which systemd should read secrets"; - default = "/run/agenix/owothia"; + default = config.age.secretsDir + "/owothia"; }; owoChance = lib.mkOption { diff --git a/ops/modules/panettone.nix b/ops/modules/panettone.nix index 11e934ec2e..e23dd028ab 100644 --- a/ops/modules/panettone.nix +++ b/ops/modules/panettone.nix @@ -2,7 +2,8 @@ let cfg = config.services.depot.panettone; -in { +in +{ options.services.depot.panettone = with lib; { enable = mkEnableOption "Panettone issue tracker"; @@ -36,7 +37,7 @@ in { by systemd's EnvironmentFile ''; type = types.str; - default = "/run/agenix/panettone"; + default = config.age.secretsDir + "/panettone"; }; irccatHost = mkOption { @@ -62,23 +63,26 @@ in { assertion = cfg.dbHost != "localhost" || config.services.postgresql.enable; message = "Panettone requires a postgresql database"; - } { - assertion = - cfg.dbHost != "localhost" || config.services.postgresql.enableTCPIP; - message = "Panettone can only connect to the postgresql database over TCP"; - } { - assertion = - cfg.dbHost != "localhost" || (lib.any - (user: user.name == cfg.dbUser) - config.services.postgresql.ensureUsers); - message = "Panettone requires a database user"; - } { - assertion = - cfg.dbHost != "localhost" || (lib.any - (db: db == cfg.dbName) - config.services.postgresql.ensureDatabases); - message = "Panettone requires a database"; - }]; + } + { + assertion = + cfg.dbHost != "localhost" || config.services.postgresql.enableTCPIP; + message = "Panettone can only connect to the postgresql database over TCP"; + } + { + assertion = + cfg.dbHost != "localhost" || (lib.any + (user: user.name == cfg.dbUser) + config.services.postgresql.ensureUsers); + message = "Panettone requires a database user"; + } + { + assertion = + cfg.dbHost != "localhost" || (lib.any + (db: db == cfg.dbName) + config.services.postgresql.ensureDatabases); + message = "Panettone requires a database"; + }]; systemd.services.panettone = { wantedBy = [ "multi-user.target" ]; @@ -100,5 +104,16 @@ in { ISSUECHANNEL = cfg.irccatChannel; }; }; + + systemd.services.panettone-fixer = { + description = "Restart panettone regularly to work around b/225"; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.systemd}/bin/systemctl restart panettone"; + serviceConfig.Type = "oneshot"; + + # We don't exactly know how frequently this occurs, but + # _probably_ not more than hourly. + startAt = "hourly"; + }; }; } diff --git a/ops/modules/paroxysm.nix b/ops/modules/paroxysm.nix index cd9cd3866e..070e7623db 100644 --- a/ops/modules/paroxysm.nix +++ b/ops/modules/paroxysm.nix @@ -3,7 +3,8 @@ let cfg = config.services.depot.paroxysm; description = "TVL's majestic IRC bot"; -in { +in +{ options.services.depot.paroxysm.enable = lib.mkEnableOption description; config = lib.mkIf cfg.enable { diff --git a/ops/modules/quassel.nix b/ops/modules/quassel.nix index 9c8692629a..6acb0615f4 100644 --- a/ops/modules/quassel.nix +++ b/ops/modules/quassel.nix @@ -8,7 +8,8 @@ let enableDaemon = true; withKDE = false; }; -in { +in +{ options.services.depot.quassel = with lib; { enable = mkEnableOption "Quassel IRC daemon"; @@ -42,6 +43,8 @@ in { }; config = with lib; mkIf cfg.enable { + networking.firewall.allowedTCPPorts = [ cfg.port ]; + systemd.services.quassel = { description = "Quassel IRC daemon"; wantedBy = [ "multi-user.target" ]; @@ -52,7 +55,7 @@ in { "--port=${toString cfg.port}" "--configdir=/var/lib/quassel" "--require-ssl" - "--ssl-cert=/var/lib/acme/${cfg.acmeHost}/full.pem" + "--ssl-cert=$CREDENTIALS_DIRECTORY/quassel.pem" "--loglevel=${cfg.logLevel}" ]; @@ -61,6 +64,10 @@ in { User = "quassel"; Group = "quassel"; StateDirectory = "quassel"; + + # Avoid trouble with the ACME file permissions by using the + # systemd credentials feature. + LoadCredential = "quassel.pem:/var/lib/acme/${cfg.acmeHost}/full.pem"; }; }; @@ -70,7 +77,7 @@ in { group = "quassel"; }; - groups.quassel = {}; + groups.quassel = { }; }; }; } diff --git a/ops/modules/restic.nix b/ops/modules/restic.nix index 1aacf68973..8695396035 100644 --- a/ops/modules/restic.nix +++ b/ops/modules/restic.nix @@ -14,7 +14,8 @@ let inherit default; type = lib.types.str; }; -in { +in +{ options.services.depot.restic = { enable = lib.mkEnableOption description; bucketEndpoint = mkStringOption "objects.dc-sto1.glesys.net"; diff --git a/ops/modules/smtprelay.nix b/ops/modules/smtprelay.nix index 106593fe39..f6ce262175 100644 --- a/ops/modules/smtprelay.nix +++ b/ops/modules/smtprelay.nix @@ -27,8 +27,9 @@ let prepareArgs = args: concatStringsSep " " (attrValues (mapAttrs (key: value: "-${key} \"${toString value}\"") - (args // overrideArgs))); -in { + (args // overrideArgs))); +in +{ options.services.depot.smtprelay = { enable = mkEnableOption description; @@ -39,7 +40,7 @@ in { secretsFile = mkOption { type = types.str; - default = "/run/agenix/smtprelay"; + default = config.age.secretsDir + "/smtprelay"; }; }; diff --git a/ops/modules/sourcegraph.nix b/ops/modules/sourcegraph.nix index a72cd75d47..cbf836ab64 100644 --- a/ops/modules/sourcegraph.nix +++ b/ops/modules/sourcegraph.nix @@ -4,7 +4,8 @@ let cfg = config.services.depot.sourcegraph; -in { +in +{ options.services.depot.sourcegraph = with lib; { enable = mkEnableOption "SourceGraph code search engine"; @@ -34,7 +35,7 @@ in { }; virtualisation.oci-containers.containers.sourcegraph = { - image = "sourcegraph/server:3.31.2"; + image = "sourcegraph/server:3.40.0"; ports = [ "127.0.0.1:${toString cfg.port}:7080" @@ -51,7 +52,8 @@ in { # Sourcegraph needs a higher nofile limit, it logs warnings # otherwise (unclear whether it actually affects the service). extraOptions = [ - "--ulimit" "nofile=10000:10000" + "--ulimit" + "nofile=10000:10000" ]; }; }; diff --git a/ops/modules/tvl-buildkite.nix b/ops/modules/tvl-buildkite.nix index aaeb5a0f75..3c6d88404f 100644 --- a/ops/modules/tvl-buildkite.nix +++ b/ops/modules/tvl-buildkite.nix @@ -13,7 +13,7 @@ let # All Buildkite hooks are actually besadii, but it's being invoked # with different names. - buildkiteHooks = pkgs.runCommandNoCC "buildkite-hooks" {} '' + buildkiteHooks = pkgs.runCommand "buildkite-hooks" { } '' mkdir -p $out/bin ln -s ${besadiiWithConfig "post-command"} $out/bin/post-command ''; @@ -22,7 +22,8 @@ let echo 'username=buildkite' echo "password=$(jq -r '.gerritPassword' /run/agenix/buildkite-besadii-config)" ''; -in { +in +{ options.services.depot.buildkite = { enable = lib.mkEnableOption description; agentCount = lib.mkOption { @@ -33,39 +34,47 @@ in { config = lib.mkIf cfg.enable { # Run the Buildkite agents using the default upstream module. - services.buildkite-agents = builtins.listToAttrs (map (n: rec { - name = "whitby-${toString n}"; - value = { - inherit name; - enable = true; - tokenPath = "/run/agenix/buildkite-agent-token"; - hooks.post-command = "${buildkiteHooks}/bin/post-command"; + services.buildkite-agents = builtins.listToAttrs (map + (n: rec { + name = "whitby-${toString n}"; + value = { + inherit name; + enable = true; + tokenPath = config.age.secretsDir + "/buildkite-agent-token"; + privateSshKeyPath = config.age.secretsDir + "/buildkite-private-key"; + hooks.post-command = "${buildkiteHooks}/bin/post-command"; + hooks.environment = '' + export PATH=$PATH:/run/wrappers/bin + ''; - runtimePackages = with pkgs; [ - bash - coreutils - credentialHelper - curl - git - gnutar - gzip - jq - nix - ]; - }; - }) agents); + runtimePackages = with pkgs; [ + bash + coreutils + credentialHelper + curl + git + gnutar + gzip + jq + nix + ]; + }; + }) + agents); # Set up a group for all Buildkite agent users users = { - groups.buildkite-agents = {}; - users = builtins.listToAttrs (map (n: rec { - name = "buildkite-agent-whitby-${toString n}"; - value = { - isSystemUser = true; - group = lib.mkForce "buildkite-agents"; - extraGroups = [ name "docker" ]; - }; - }) agents); + groups.buildkite-agents = { }; + users = builtins.listToAttrs (map + (n: rec { + name = "buildkite-agent-whitby-${toString n}"; + value = { + isSystemUser = true; + group = lib.mkForce "buildkite-agents"; + extraGroups = [ name "docker" ]; + }; + }) + agents); }; }; } diff --git a/ops/modules/tvl-cache.nix b/ops/modules/tvl-cache.nix index 4d574821df..683818d103 100644 --- a/ops/modules/tvl-cache.nix +++ b/ops/modules/tvl-cache.nix @@ -6,12 +6,12 @@ }; config = lib.mkIf config.tvl.cache.enable { - nix = { - binaryCachePublicKeys = [ + nix.settings = { + trusted-public-keys = [ "cache.tvl.su:kjc6KOMupXc1vHVufJUoDUYeLzbwSr9abcAKdn/U1Jk=" ]; - binaryCaches = [ + substituters = [ "https://cache.tvl.su" ]; }; diff --git a/ops/modules/tvl-headscale.nix b/ops/modules/tvl-headscale.nix new file mode 100644 index 0000000000..a07021c788 --- /dev/null +++ b/ops/modules/tvl-headscale.nix @@ -0,0 +1,62 @@ +# Configuration for the coordination server for net.tvl.fyi, a +# tailscale network run using headscale. +# +# All TVL members can join this network, which provides several exit +# nodes through which traffic can be routed. +# +# The coordination server is currently run on sanduny.tvl.su. It is +# managed manually, ping somebody with access ... for access. +# +# Servers should join using approximately this command: +# tailscale up --login-server https://net.tvl.fyi --accept-dns=false --advertise-exit-node +# +# Clients should join using approximately this command: +# tailscale up --login-server https://net.tvl.fyi --accept-dns=false +{ config, pkgs, ... }: + +{ + # TODO(tazjin): run embedded DERP server + services.headscale = { + enable = true; + port = 4725; # hscl + + settings = { + server_url = "https://net.tvl.fyi"; + dns_config.nameservers = [ + "8.8.8.8" + "1.1.1.1" + "77.88.8.8" + ]; + + # TLS is handled by nginx + tls_cert_path = null; + tls_key_path = null; + }; + }; + + environment.systemPackages = [ pkgs.headscale ]; # admin CLI + + services.nginx.virtualHosts."net.tvl.fyi" = { + serverName = "net.tvl.fyi"; + enableACME = true; + forceSSL = true; + + # See https://github.com/juanfont/headscale/blob/v0.22.3/docs/reverse-proxy.md#nginx + extraConfig = '' + location / { + proxy_pass http://localhost:${toString config.services.headscale.port}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $server_name; + proxy_redirect http:// https://; + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + } + ''; + }; + +} diff --git a/ops/modules/tvl-slapd/default.nix b/ops/modules/tvl-slapd/default.nix index dbcf139338..c08cd30f16 100644 --- a/ops/modules/tvl-slapd/default.nix +++ b/ops/modules/tvl-slapd/default.nix @@ -26,7 +26,8 @@ let inherit (depot.ops) users; -in { +in +{ services.openldap = { enable = true; @@ -34,7 +35,7 @@ in { "olcDatabase={1}mdb".attrs = { objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; olcDatabase = "{1}mdb"; - olcDbDirectory = "/var/lib/openldap"; + olcDbDirectory = "/var/lib/openldap/db"; olcSuffix = "dc=tvl,dc=fyi"; olcAccess = "to * by * read"; olcRootDN = "cn=admin,dc=tvl,dc=fyi"; @@ -43,12 +44,12 @@ in { "cn=module{0}".attrs = { objectClass = "olcModuleList"; - olcModuleLoad = "pw-argon2"; + olcModuleLoad = "argon2"; }; "cn=schema".includes = map (schema: "${pkgs.openldap}/etc/schema/${schema}.ldif") - [ "core" "cosine" "inetorgperson" "nis" ]; + [ "core" "cosine" "inetorgperson" "nis" ]; }; # Contents are immutable at runtime, and adding user accounts etc. diff --git a/ops/modules/tvl-users.nix b/ops/modules/tvl-users.nix new file mode 100644 index 0000000000..ea83b435f4 --- /dev/null +++ b/ops/modules/tvl-users.nix @@ -0,0 +1,83 @@ +# Standard NixOS users for TVL machines, as well as configuration that +# should following along when they are added to a machine. +{ depot, pkgs, ... }: + +{ + users = { + users.tazjin = { + isNormalUser = true; + extraGroups = [ "git" "wheel" ]; + shell = pkgs.fish; + openssh.authorizedKeys.keys = depot.users.tazjin.keys.all; + }; + + users.lukegb = { + isNormalUser = true; + extraGroups = [ "git" "wheel" ]; + openssh.authorizedKeys.keys = depot.users.lukegb.keys.all; + }; + + users.aspen = { + isNormalUser = true; + extraGroups = [ "git" "wheel" ]; + openssh.authorizedKeys.keys = [ depot.users.aspen.keys.whitby ]; + }; + + users.edef = { + isNormalUser = true; + extraGroups = [ "git" ]; + openssh.authorizedKeys.keys = depot.users.edef.keys.all; + }; + + users.qyliss = { + isNormalUser = true; + description = "Alyssa Ross"; + extraGroups = [ "git" ]; + openssh.authorizedKeys.keys = depot.users.qyliss.keys.all; + }; + + users.eta = { + isNormalUser = true; + extraGroups = [ "git" ]; + openssh.authorizedKeys.keys = depot.users.eta.keys.whitby; + }; + + users.cynthia = { + isNormalUser = true; # I'm normal OwO :3 + extraGroups = [ "git" ]; + openssh.authorizedKeys.keys = depot.users.cynthia.keys.all; + }; + + users.firefly = { + isNormalUser = true; + extraGroups = [ "git" ]; + openssh.authorizedKeys.keys = depot.users.firefly.keys.whitby; + }; + + users.sterni = { + isNormalUser = true; + extraGroups = [ "git" "wheel" ]; + openssh.authorizedKeys.keys = depot.users.sterni.keys.all; + }; + + users.flokli = { + isNormalUser = true; + extraGroups = [ "git" "wheel" ]; + openssh.authorizedKeys.keys = depot.users.flokli.keys.all; + }; + }; + + programs.fish.enable = true; + + environment.systemPackages = with pkgs; [ + alacritty.terminfo + foot.terminfo + rxvt-unicode-unwrapped.terminfo + kitty.terminfo + ]; + + security.sudo.extraRules = [{ + groups = [ "wheel" ]; + commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }]; + }]; +} diff --git a/ops/modules/v4l2loopback.nix b/ops/modules/v4l2loopback.nix deleted file mode 100644 index 636b2ff6cf..0000000000 --- a/ops/modules/v4l2loopback.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - boot = { - extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; - kernelModules = [ "v4l2loopback" ]; - extraModprobeConfig = '' - options v4l2loopback exclusive_caps=1 - ''; - }; -} - diff --git a/ops/modules/www/auth.tvl.fyi.nix b/ops/modules/www/auth.tvl.fyi.nix index e0c031bf70..a068f02365 100644 --- a/ops/modules/www/auth.tvl.fyi.nix +++ b/ops/modules/www/auth.tvl.fyi.nix @@ -12,8 +12,12 @@ forceSSL = true; extraConfig = '' + # increase buffer size for large headers + proxy_buffers 8 16k; + proxy_buffer_size 16k; + location / { - proxy_pass http://localhost:${config.services.keycloak.httpPort}; + proxy_pass http://localhost:${toString config.services.keycloak.settings.http-port}; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $host; diff --git a/ops/modules/www/base.nix b/ops/modules/www/base.nix index cfa9bf0bc6..50fceff0fa 100644 --- a/ops/modules/www/base.nix +++ b/ops/modules/www/base.nix @@ -2,6 +2,11 @@ { config = { + security.acme = { + acceptTerms = true; + defaults.email = "letsencrypt@tvl.su"; + }; + services.nginx = { enable = true; enableReload = true; @@ -10,31 +15,27 @@ recommendedGzipSettings = true; recommendedProxySettings = true; + commonHttpConfig = '' + log_format json_combined escape=json + '{' + '"remote_addr":"$remote_addr",' + '"method":"$request_method",' + '"host":"$host",' + '"uri":"$request_uri",' + '"status":$status,' + '"request_size":$request_length,' + '"response_size":$body_bytes_sent,' + '"response_time":$request_time,' + '"referrer":"$http_referer",' + '"user_agent":"$http_user_agent"' + '}'; + + access_log syslog:server=unix:/dev/log,nohostname json_combined; + ''; + appendHttpConfig = '' add_header Permissions-Policy "interest-cohort=()"; ''; }; - - # NixOS 20.03 broke nginx and I can't be bothered to debug it - # anymore, all solution attempts have failed, so here's a - # brute-force fix. - # - # TODO(tazjin): Find a link to the upstream issue and see if - # they've sorted it after ~20.09 - systemd.services.fix-nginx = { - script = "${pkgs.coreutils}/bin/chown -f -R nginx: /var/spool/nginx /var/cache/nginx"; - - serviceConfig = { - User = "root"; - Type = "oneshot"; - }; - }; - - systemd.timers.fix-nginx = { - wantedBy = [ "multi-user.target" ]; - timerConfig = { - OnCalendar = "minutely"; - }; - }; }; } diff --git a/ops/modules/www/cl.tvl.fyi.nix b/ops/modules/www/cl.tvl.fyi.nix index 470122c395..36422a6c4e 100644 --- a/ops/modules/www/cl.tvl.fyi.nix +++ b/ops/modules/www/cl.tvl.fyi.nix @@ -24,6 +24,10 @@ # The :443 suffix is a workaround for https://b.tvl.fyi/issues/88. proxy_set_header Host $host:443; } + + location = /robots.txt { + return 200 'User-agent: *\nAllow: /'; + } ''; }; }; diff --git a/ops/modules/www/code.tvl.fyi.nix b/ops/modules/www/code.tvl.fyi.nix index 4c182d34f2..ee0211990d 100644 --- a/ops/modules/www/code.tvl.fyi.nix +++ b/ops/modules/www/code.tvl.fyi.nix @@ -1,4 +1,4 @@ -{ depot, config, ... }: +{ depot, pkgs, config, ... }: { imports = [ @@ -13,16 +13,49 @@ forceSSL = true; extraConfig = '' - # Serve the rendered Tvix component SVG. - # - # TODO(tazjin): Implement a way of serving this dynamically - location = /about/tvix/docs/component-flow.svg { - alias ${depot.tvix.docs.svg}/component-flow.svg; + location = /go-get/tvix/build-go { + alias ${pkgs.writeText "go-import-metadata.html" ''<html><meta name="go-import" content="code.tvl.fyi/tvix/build-go git https://code.tvl.fyi/depot.git:/tvix/build-go.git"></html>''}; + } + + location = /go-get/tvix/castore-go { + alias ${pkgs.writeText "go-import-metadata.html" ''<html><meta name="go-import" content="code.tvl.fyi/tvix/castore-go git https://code.tvl.fyi/depot.git:/tvix/castore-go.git"></html>''}; + } + + location = /go-get/tvix/store-go { + alias ${pkgs.writeText "go-import-metadata.html" ''<html><meta name="go-import" content="code.tvl.fyi/tvix/store-go git https://code.tvl.fyi/depot.git:/tvix/store-go.git"></html>''}; + } + + location = /go-get/tvix/nar-bridge { + alias ${pkgs.writeText "go-import-metadata.html" ''<html><meta name="go-import" content="code.tvl.fyi/tvix/nar-bridge git https://code.tvl.fyi/depot.git:/tvix/nar-bridge.git"></html>''}; + } + + location = /tvix/build-go { + if ($args ~* "/?go-get=1") { + return 302 /go-get/tvix/build-go; + } + } + + location = /tvix/castore-go { + if ($args ~* "/?go-get=1") { + return 302 /go-get/tvix/castore-go; + } + } + + location = /tvix/store-go { + if ($args ~* "/?go-get=1") { + return 302 /go-get/tvix/store-go; + } + } + + location = /tvix/nar-bridge { + if ($args ~* "/?go-get=1") { + return 302 /go-get/tvix/nar-bridge; + } } # Git operations on depot.git hit josh location /depot.git { - proxy_pass http://localhost:${toString config.services.depot.git-serving.joshPort}; + proxy_pass http://127.0.0.1:${toString config.services.depot.josh.port}; } # Git clone operations on '/' should be redirected to josh now. diff --git a/ops/modules/www/grep.tvl.fyi.nix b/ops/modules/www/grep.tvl.fyi.nix new file mode 100644 index 0000000000..93ef5eabd2 --- /dev/null +++ b/ops/modules/www/grep.tvl.fyi.nix @@ -0,0 +1,19 @@ +# Experimental configuration for manually Livegrep. +{ config, ... }: + +{ + imports = [ + ./base.nix + ]; + + config = { + services.nginx.virtualHosts."grep.tvl.fyi" = { + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:${toString config.services.depot.livegrep.port}"; + }; + }; + }; +} diff --git a/ops/modules/www/images.tvl.fyi.nix b/ops/modules/www/images.tvl.fyi.nix deleted file mode 100644 index 7d027b2991..0000000000 --- a/ops/modules/www/images.tvl.fyi.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ config, ... }: - -{ - imports = [ - ./base.nix - ]; - - config = { - services.nginx.virtualHosts."images.tvl.fyi" = { - serverName = "images.tvl.fyi"; - serverAliases = [ "images.tvl.su" ]; - enableACME = true; - forceSSL = true; - - extraConfig = '' - location / { - proxy_pass http://localhost:${toString config.services.depot.nixery.port}; - } - ''; - }; - }; -} diff --git a/ops/modules/www/inbox.tvl.su.nix b/ops/modules/www/inbox.tvl.su.nix new file mode 100644 index 0000000000..38db5d2a8e --- /dev/null +++ b/ops/modules/www/inbox.tvl.su.nix @@ -0,0 +1,31 @@ +{ config, depot, ... }: + +{ + imports = [ + ./base.nix + ]; + + config = { + services.nginx.virtualHosts."inbox.tvl.su" = { + enableACME = true; + forceSSL = true; + + extraConfig = '' + # nginx is incapable of serving a single file at /, hence this hack: + location = / { + index /landing-page; + } + + location = /landing-page { + types { } default_type "text/html; charset=utf-8"; + alias ${depot.web.inbox}; + } + + # rest of requests is proxied to public-inbox-httpd + location / { + proxy_pass http://localhost:${toString config.services.public-inbox.http.port}; + } + ''; + }; + }; +} diff --git a/ops/modules/www/self-redirect.nix b/ops/modules/www/self-redirect.nix new file mode 100644 index 0000000000..5bf1627be9 --- /dev/null +++ b/ops/modules/www/self-redirect.nix @@ -0,0 +1,27 @@ +# Redirect the hostname of a machine to its configuration in a web +# browser. +# +# Works by convention, assuming that the machine has its configuration +# at //ops/machines/${hostname}. +{ config, ... }: + +let + host = "${config.networking.hostName}.${config.networking.domain}"; +in +{ + imports = [ + ./base.nix + ]; + + config.services.nginx.virtualHosts."${host}" = { + serverName = host; + addSSL = true; # SSL is not forced on these redirects + enableACME = true; + + extraConfig = '' + location = / { + return 302 https://at.tvl.fyi/?q=%2F%2Fops%2Fmachines%2F${config.networking.hostName}; + } + ''; + }; +} diff --git a/ops/modules/www/signup.tvl.fyi.nix b/ops/modules/www/signup.tvl.fyi.nix new file mode 100644 index 0000000000..1b193f99a9 --- /dev/null +++ b/ops/modules/www/signup.tvl.fyi.nix @@ -0,0 +1,19 @@ +{ depot, ... }: + +{ + imports = [ + ./base.nix + ]; + + config = { + services.nginx.virtualHosts."signup.tvl.fyi" = { + root = depot.web.pwcrypt; + enableACME = true; + forceSSL = true; + + extraConfig = '' + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + ''; + }; + }; +} diff --git a/ops/modules/www/status.tvl.su.nix b/ops/modules/www/status.tvl.su.nix index 2bb6093c14..7079c60260 100644 --- a/ops/modules/www/status.tvl.su.nix +++ b/ops/modules/www/status.tvl.su.nix @@ -18,7 +18,7 @@ forceSSL = true; locations."/" = { - proxyPass = "http://localhost:${toString config.services.grafana.port}"; + proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; }; }; }; diff --git a/ops/modules/www/tazj.in.nix b/ops/modules/www/tazj.in.nix index 7d658a5ec4..47eefca2a6 100644 --- a/ops/modules/www/tazj.in.nix +++ b/ops/modules/www/tazj.in.nix @@ -11,8 +11,13 @@ enableACME = true; forceSSL = true; root = depot.users.tazjin.homepage; + serverAliases = [ "www.tazj.in" ]; extraConfig = '' + location = /en/rss.xml { + return 301 https://tazj.in/feed.atom; + } + ${depot.users.tazjin.blog.oldRedirects} location /blog/ { alias ${depot.users.tazjin.blog.rendered}/; @@ -24,6 +29,15 @@ try_files $uri $uri.html $uri/ =404; } + location = /predlozhnik { + return 302 https://predlozhnik.ru; + } + + # redirect for easier entry on a TV + location = /tv { + return 302 https://tazj.in/blobs/play.html; + } + # Temporary place for serving static files. location /blobs/ { alias /var/lib/tazjins-blobs/; diff --git a/ops/modules/www/tvix.dev.nix b/ops/modules/www/tvix.dev.nix new file mode 100644 index 0000000000..f884bc30ed --- /dev/null +++ b/ops/modules/www/tvix.dev.nix @@ -0,0 +1,46 @@ +{ depot, ... }: + +{ + imports = [ + ./base.nix + ]; + + config = { + services.nginx.virtualHosts."tvix.dev" = { + serverName = "tvix.dev"; + enableACME = true; + forceSSL = true; + root = depot.tvix.website; + }; + + services.nginx.virtualHosts."bolt.tvix.dev" = { + root = depot.web.tvixbolt; + enableACME = true; + forceSSL = true; + }; + + # old domain, serve redirect + services.nginx.virtualHosts."tvixbolt.tvl.su" = { + enableACME = true; + forceSSL = true; + extraConfig = "return 301 https://bolt.tvix.dev$request_uri;"; + }; + + services.nginx.virtualHosts."docs.tvix.dev" = { + serverName = "docs.tvix.dev"; + enableACME = true; + forceSSL = true; + + extraConfig = '' + location = / { + # until we have a better default page here + return 301 https://docs.tvix.dev/rust/tvix_eval/index.html; + } + + location /rust/ { + alias ${depot.tvix.rust-docs}/; + } + ''; + }; + }; +} diff --git a/ops/modules/www/tvl.fyi.nix b/ops/modules/www/tvl.fyi.nix index f422bb8487..59ee1bc27f 100644 --- a/ops/modules/www/tvl.fyi.nix +++ b/ops/modules/www/tvl.fyi.nix @@ -35,7 +35,11 @@ } location = /blog { - return 302 /; + return 302 /#blog; + } + + location = /blog/ { + return 302 /#blog; } ''; }; diff --git a/ops/modules/www/volgasprint.org.nix b/ops/modules/www/volgasprint.org.nix new file mode 100644 index 0000000000..7e5abe5561 --- /dev/null +++ b/ops/modules/www/volgasprint.org.nix @@ -0,0 +1,15 @@ +{ depot, ... }: + +{ + imports = [ + ./base.nix + ]; + + config = { + services.nginx.virtualHosts."volgasprint.org" = { + enableACME = true; + forceSSL = true; + root = "${depot.web.volgasprint}"; + }; + }; +} diff --git a/ops/modules/www/wigglydonke.rs.nix b/ops/modules/www/wigglydonke.rs.nix index 3d85e4eb98..6440164325 100644 --- a/ops/modules/www/wigglydonke.rs.nix +++ b/ops/modules/www/wigglydonke.rs.nix @@ -9,7 +9,7 @@ services.nginx.virtualHosts."wigglydonke.rs" = { enableACME = true; forceSSL = true; - root = "${depot.path + "/users/grfn/wigglydonke.rs"}"; + root = "${depot.path + "/users/aspen/wigglydonke.rs"}"; }; }; } diff --git a/ops/modules/yandex-cloud.nix b/ops/modules/yandex-cloud.nix new file mode 100644 index 0000000000..cf6d1eb810 --- /dev/null +++ b/ops/modules/yandex-cloud.nix @@ -0,0 +1,78 @@ +# Profile for virtual machines on Yandex Cloud, intended for disk +# images. +# +# https://cloud.yandex.com/en/docs/compute/operations/image-create/custom-image +# +# TODO(tazjin): Upstream to nixpkgs once it works well. +{ config, lib, pkgs, modulesPath, ... }: + +let + cfg = config.virtualisation.yandexCloud; + + # Kernel modules required for interacting with the hypervisor. These + # must be available during stage 1 boot and during normal operation, + # as disks and network do not work without them. + modules = [ + "virtio-net" + "virtio-blk" + "virtio-pci" + "virtiofs" + ]; +in +{ + imports = [ + "${modulesPath}/profiles/headless.nix" + ]; + + options = { + virtualisation.yandexCloud.rootPartitionUuid = with lib; mkOption { + type = types.str; + default = "C55A5EE2-E5FA-485C-B3AE-CC928429AB6B"; + + description = '' + UUID to use for the root partition of the disk image. Yandex + Cloud requires that root partitions are mounted by UUID. + + Most users do not need to set this to a non-default value. + ''; + }; + }; + + config = { + fileSystems."/" = { + device = "/dev/disk/by-uuid/${lib.toLower cfg.rootPartitionUuid}"; + fsType = "ext4"; + autoResize = true; + }; + + boot = { + loader.grub.device = "/dev/vda"; + + initrd.kernelModules = modules; + kernelModules = modules; + kernelParams = [ + # Enable support for the serial console + "console=ttyS0" + ]; + + growPartition = true; + }; + + environment.etc.securetty = { + text = "ttyS0"; + mode = "0644"; + }; + + systemd.services."serial-getty@ttyS0".enable = true; + + services.openssh.enable = true; + + system.build.yandexCloudImage = import (pkgs.path + "/nixos/lib/make-disk-image.nix") { + inherit lib config pkgs; + additionalSpace = "128M"; + format = "qcow2"; + partitionTableType = "legacy+gpt"; + rootGPUID = cfg.rootPartitionUuid; + }; + }; +} diff --git a/ops/mq_cli/Cargo.lock b/ops/mq_cli/Cargo.lock index f418d77c34..18fed3621d 100644 --- a/ops/mq_cli/Cargo.lock +++ b/ops/mq_cli/Cargo.lock @@ -1,159 +1,168 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi", ] [[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.50" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.33.0" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "hermit-abi" -version = "0.1.6" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "libc" -version = "0.2.66" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] -name = "mq" -version = "1.0.0" +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "posix_mq 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", +] + +[[package]] +name = "mq_cli" +version = "3773.0.0" +dependencies = [ + "clap", + "libc", + "nix", + "posix_mq", ] [[package]] name = "nix" -version = "0.16.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", ] [[package]] name = "posix_mq" -version = "0.9.0" +version = "3771.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f462ad79a99ea13f3ef76d9c271956e924183f5aeb67a8649c8c2b6bdd079da8" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "nix", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "unicode-width" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb" -"checksum posix_mq 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13ae339e13cc96902a4597a5aab6b76473093969c55d36ba33f6a7bf3268573f" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/ops/mq_cli/Cargo.toml b/ops/mq_cli/Cargo.toml index b412d88787..816a370759 100644 --- a/ops/mq_cli/Cargo.toml +++ b/ops/mq_cli/Cargo.toml @@ -1,10 +1,14 @@ [package] -name = "mq" -version = "1.0.0" -authors = ["Vincent Ambo <mail@tazj.in>"] +name = "mq_cli" +description = "CLI tool for accessing POSIX message queues (mq_overview(7))" +license = "MIT" +version = "3773.0.0" +authors = ["Vincent Ambo <tazjin@tvl.su>"] +homepage = "https://cs.tvl.fyi/depot/-/tree/ops/mq_cli" +repository = "https://code.tvl.fyi/depot.git:/ops/mq_cli.git" [dependencies] -clap = "2.33" +clap = "2.34" libc = "0.2" -nix = "0.16" -posix_mq = "0.9" +nix = "0.23" +posix_mq = "3771.0.0" diff --git a/ops/mq_cli/README.md b/ops/mq_cli/README.md index e612553e74..1045de896b 100644 --- a/ops/mq_cli/README.md +++ b/ops/mq_cli/README.md @@ -27,5 +27,16 @@ SUBCOMMANDS: send Send a message to a queue ``` +## Development + +Development happens in the [TVL +monorepo](https://cs.tvl.fyi/depot/-/tree/ops/mq_cli). + +Starting from version `3773.0.0`, the version numbers correspond to +_revisions_ of the TVL repository, available as git refs (e.g. +`refs/r/3773`). + +See the TVL documentation for more information about how to contribute +to the codebase. [POSIX message queues]: https://linux.die.net/man/7/mq_overview diff --git a/ops/mq_cli/src/main.rs b/ops/mq_cli/src/main.rs index 55ff006429..927993b486 100644 --- a/ops/mq_cli/src/main.rs +++ b/ops/mq_cli/src/main.rs @@ -1,36 +1,38 @@ extern crate clap; -extern crate posix_mq; extern crate libc; extern crate nix; +extern crate posix_mq; -use clap::{App, SubCommand, Arg, ArgMatches, AppSettings}; -use posix_mq::{Name, Queue, Message}; +use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; +use posix_mq::{Message, Name, Queue}; use std::fs::{read_dir, File}; use std::io::{self, Read, Write}; use std::process::exit; fn run_ls() { - let mqueues = read_dir("/dev/mqueue") - .expect("Could not read message queues"); + let mqueues = read_dir("/dev/mqueue").expect("Could not read message queues"); for queue in mqueues { let path = queue.unwrap().path(); let status = { - let mut file = File::open(&path) - .expect("Could not open queue file"); + let mut file = File::open(&path).expect("Could not open queue file"); let mut content = String::new(); - file.read_to_string(&mut content).expect("Could not read queue file"); + file.read_to_string(&mut content) + .expect("Could not read queue file"); content }; - let queue_name = path.components().last().unwrap() + let queue_name = path + .components() + .last() + .unwrap() .as_os_str() .to_string_lossy(); println!("/{}: {}", queue_name, status) - }; + } } fn run_inspect(queue_name: &str) { @@ -47,8 +49,7 @@ fn run_create(cmd: &ArgMatches) { set_rlimit(rlimit.parse().expect("Invalid rlimit value")); } - let name = Name::new(cmd.value_of("queue").unwrap()) - .expect("Invalid queue name"); + let name = Name::new(cmd.value_of("queue").unwrap()).expect("Invalid queue name"); let max_pending: i64 = cmd.value_of("max-pending").unwrap().parse().unwrap(); let max_size: i64 = cmd.value_of("max-size").unwrap().parse().unwrap(); @@ -56,11 +57,11 @@ fn run_create(cmd: &ArgMatches) { let queue = Queue::create(name, max_pending, max_size * 1024); match queue { - Ok(_) => println!("Queue created successfully"), + Ok(_) => println!("Queue created successfully"), Err(e) => { writeln!(io::stderr(), "Could not create queue: {}", e).ok(); exit(1); - }, + } }; } @@ -120,7 +121,12 @@ fn run_rlimit() { }; if errno != 0 { - writeln!(io::stderr(), "Could not get message queue rlimit: {}", errno).ok(); + writeln!( + io::stderr(), + "Could not get message queue rlimit: {}", + errno + ) + .ok(); } else { println!("Message queue rlimit:"); println!("Current limit: {}", rlimit.rlim_cur); @@ -170,16 +176,20 @@ fn main() { .about("Create a new queue") .arg(&queue_arg) .arg(&rlimit_arg) - .arg(Arg::with_name("max-size") - .help("maximum message size (in kB)") - .long("max-size") - .required(true) - .takes_value(true)) - .arg(Arg::with_name("max-pending") - .help("maximum # of pending messages") - .long("max-pending") - .required(true) - .takes_value(true)); + .arg( + Arg::with_name("max-size") + .help("maximum message size (in kB)") + .long("max-size") + .required(true) + .takes_value(true), + ) + .arg( + Arg::with_name("max-pending") + .help("maximum # of pending messages") + .long("max-pending") + .required(true) + .takes_value(true), + ); let receive = SubCommand::with_name("receive") .about("Receive a message from a queue") @@ -188,9 +198,11 @@ fn main() { let send = SubCommand::with_name("send") .about("Send a message to a queue") .arg(&queue_arg) - .arg(Arg::with_name("message") - .help("the message to send") - .required(true)); + .arg( + Arg::with_name("message") + .help("the message to send") + .required(true), + ); let rlimit = SubCommand::with_name("rlimit") .about("Get the message queue rlimit") @@ -211,13 +223,13 @@ fn main() { match matches.subcommand() { ("ls", _) => run_ls(), ("inspect", Some(cmd)) => run_inspect(cmd.value_of("queue").unwrap()), - ("create", Some(cmd)) => run_create(cmd), + ("create", Some(cmd)) => run_create(cmd), ("receive", Some(cmd)) => run_receive(cmd.value_of("queue").unwrap()), - ("send", Some(cmd)) => run_send( + ("send", Some(cmd)) => run_send( cmd.value_of("queue").unwrap(), - cmd.value_of("message").unwrap() + cmd.value_of("message").unwrap(), ), - ("rlimit", _) => run_rlimit(), + ("rlimit", _) => run_rlimit(), _ => unimplemented!(), } } diff --git a/ops/nixos.nix b/ops/nixos.nix index 66ca188c5b..1442d89b30 100644 --- a/ops/nixos.nix +++ b/ops/nixos.nix @@ -7,10 +7,18 @@ in rec { baseModule = { ... }: { # Ensure that pkgs == third_party.nix nixpkgs.pkgs = depot.third_party.nixpkgs; - nix.nixPath = [ - "nixos=${pkgs.path}" - "nixpkgs=${pkgs.path}" - ]; + nix.nixPath = + let + # Due to nixpkgsBisectPath, pkgs.path is not always in the nix store + nixpkgsStorePath = + if lib.hasPrefix builtins.storeDir (toString pkgs.path) + then builtins.storePath pkgs.path # nixpkgs is already in the store + else pkgs.path; # we need to dump nixpkgs to the store either way + in + [ + ("nixos=" + nixpkgsStorePath) + ("nixpkgs=" + nixpkgsStorePath) + ]; }; nixosFor = configuration: (depot.third_party.nixos { @@ -32,7 +40,10 @@ in rec { (throw "${hostname} is not a known NixOS host") (map nixosFor depot.ops.machines.all-systems)); - rebuild-system = rebuildSystemWith depot.path; + rebuild-system = rebuildSystemWith ( + # HACK: use the string of the original source to avoid copying the whole + # depot into the store just for this + builtins.toString depot.path.origSrc); rebuildSystemWith = depotPath: pkgs.writeShellScriptBin "rebuild-system" '' set -ue @@ -50,5 +61,7 @@ in rec { # Systems that should be built in CI whitbySystem = (nixosFor depot.ops.machines.whitby).system; - meta.targets = [ "whitbySystem" ]; + sandunySystem = (nixosFor depot.ops.machines.sanduny).system; + nixeryDev01System = (nixosFor depot.ops.machines.nixery-01).system; + meta.ci.targets = [ "sandunySystem" "whitbySystem" "nixeryDev01System" ]; } diff --git a/ops/pipelines/depot.nix b/ops/pipelines/depot.nix index b6941ba38a..5eff622671 100644 --- a/ops/pipelines/depot.nix +++ b/ops/pipelines/depot.nix @@ -3,22 +3,14 @@ { depot, pkgs, externalArgs, ... }: let - # Protobuf check step which validates that changes to .proto files - # between revisions don't cause backwards-incompatible or otherwise - # flawed changes. - protoCheck = { - command = "${depot.nix.bufCheck}/bin/ci-buf-check"; - label = ":water_buffalo:"; - }; - pipeline = depot.nix.buildkite.mkPipeline { headBranch = "refs/heads/canon"; drvTargets = depot.ci.targets; - additionalSteps = [ protoCheck ]; - parentTargetMap = if (externalArgs ? parentTargetMap) + parentTargetMap = + if (externalArgs ? parentTargetMap) then builtins.fromJSON (builtins.readFile externalArgs.parentTargetMap) - else {}; + else { }; postBuildSteps = [ # After successful builds, create a gcroot for builds on canon. @@ -40,7 +32,8 @@ let }; drvmap = depot.nix.buildkite.mkDrvmap depot.ci.targets; -in pkgs.runCommandNoCC "depot-pipeline" {} '' +in +pkgs.runCommand "depot-pipeline" { } '' mkdir $out cp -r ${pipeline}/* $out cp ${drvmap} $out/drvmap.json diff --git a/ops/pipelines/static-pipeline.yaml b/ops/pipelines/static-pipeline.yaml index 23a1fba4f2..af4f9d784e 100644 --- a/ops/pipelines/static-pipeline.yaml +++ b/ops/pipelines/static-pipeline.yaml @@ -4,6 +4,8 @@ # If something fails during the creation of the pipeline, the fallback # is executed instead which will simply report an error to Gerrit. --- +env: + BUILDKITE_TOKEN_PATH: /run/agenix/buildkite-graphql-token steps: # Run pipeline for tvl-kit when new commits arrive on canon. Since # it is not part of the depot build tree, this is a useful @@ -15,6 +17,16 @@ steps: build: message: "Verification triggered by ${BUILDKITE_COMMIT}" + # Run pipeline for tvix when new commits arrive on canon. Since + # it is not part of the depot build tree, this is a useful + # verification to ensure we don't break external things (too much). + - trigger: "tvix" + async: true + label: ":fork:" + branches: "refs/heads/canon" + build: + message: "Verification triggered by ${BUILDKITE_COMMIT}" + # Create a revision number for the current commit for builds on # canon. # @@ -23,6 +35,11 @@ steps: # # Revision numbers are defined as the number of commits in the # lineage of HEAD, following only the first parent of merges. + # + # Note that git does not fetch these refs by default, instead + # you'll have to modify your git config using + # `git config --add remote.origin.fetch '+refs/r/*:refs/r/*'`. + # The refs are available after the next `git fetch`. - label: ":git:" branches: "refs/heads/canon" command: | @@ -32,12 +49,14 @@ steps: # Generate & upload dynamic build steps - label: ":llama:" key: "pipeline-gen" + concurrency_group: 'depot-nix-eval' + concurrency: 5 # much more than this and whitby will OOM command: | set -ue if test -n "$${GERRIT_CHANGE_URL-}"; then echo "This is a build of [cl/$$GERRIT_CHANGE_ID]($$GERRIT_CHANGE_URL) (at patchset #$$GERRIT_PATCHSET)" | \ - buildkite-agent annotate + buildkite-agent annotate --context cl-annotation fi # Attempt to fetch a target map from a parent commit on canon, @@ -50,7 +69,11 @@ steps: PIPELINE_ARGS="--arg parentTargetMap tmp/parent-target-map.json" fi - nix-build -A ops.pipelines.depot -o pipeline --show-trace $$PIPELINE_ARGS + nix-build --option restrict-eval true --include "depot=$${PWD}" \ + --include "store=/nix/store" \ + --allowed-uris 'https://' \ + -A ops.pipelines.depot \ + -o pipeline --show-trace $$PIPELINE_ARGS # Steps need to be uploaded in reverse order because pipeline # upload prepends instead of appending. @@ -85,7 +108,7 @@ steps: readonly FAILED_JOBS=$(curl 'https://graphql.buildkite.com/v1' \ --silent \ - -H "Authorization: Bearer $(cat /run/agenix/buildkite-graphql-token)" \ + -H "Authorization: Bearer $(cat ${BUILDKITE_TOKEN_PATH})" \ -d "{\"query\": \"query BuildStatusQuery { build(uuid: \\\"$BUILDKITE_BUILD_ID\\\") { jobs(passed: false) { count } } }\"}" | \ jq -r '.data.build.jobs.count') @@ -95,8 +118,8 @@ steps: exit 1 fi - # After duck, on success, upload and run any post-build steps that - # were output by the dynamic pipeline. + # After duck, on success, upload and run any release steps that were + # output by the dynamic pipeline. - label: ":arrow_heading_down:" depends_on: - step: ":duck:" @@ -106,6 +129,6 @@ steps: buildkite-agent artifact download "pipeline/*" . - find ./pipeline -name 'post-chunk-*.json' | tac | while read chunk; do + find ./pipeline -name 'release-chunk-*.json' | tac | while read chunk; do buildkite-agent pipeline upload $$chunk done diff --git a/ops/posix_mq.rs/Cargo.lock b/ops/posix_mq.rs/Cargo.lock index fdd0086c4d..dc344613d0 100644 --- a/ops/posix_mq.rs/Cargo.lock +++ b/ops/posix_mq.rs/Cargo.lock @@ -1,54 +1,63 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cc" version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] -name = "nix" -version = "0.16.1" +name = "memoffset" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] -name = "posix_mq" -version = "0.9.0" +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", ] [[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +name = "posix_mq" +version = "3771.0.0" +dependencies = [ + "libc", + "nix", +] diff --git a/ops/posix_mq.rs/Cargo.toml b/ops/posix_mq.rs/Cargo.toml index d72e87a3dc..8390b80b86 100644 --- a/ops/posix_mq.rs/Cargo.toml +++ b/ops/posix_mq.rs/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "posix_mq" -version = "0.9.0" -authors = ["Vincent Ambo <mail@tazj.in>"] +version = "3771.0.0" +authors = ["Vincent Ambo <tazjin@tvl.su>"] description = "(Higher-level) Rust bindings to POSIX message queues" license = "MIT" -repository = "https://git.tazj.in/tree/ops/posix_mq.rs" +homepage = "https://cs.tvl.fyi/depot/-/tree/ops/posix_mq.rs" +repository = "https://code.tvl.fyi/depot.git:/ops/posix_mq.rs.git" [dependencies] -nix = "0.16" +nix = "0.23" libc = "0.2" diff --git a/ops/posix_mq.rs/README.md b/ops/posix_mq.rs/README.md index 9370c6c087..800d2221e4 100644 --- a/ops/posix_mq.rs/README.md +++ b/ops/posix_mq.rs/README.md @@ -1,7 +1,6 @@ posix_mq ======== -[![Build Status](https://travis-ci.org/aprilabank/posix_mq.rs.svg?branch=master)](https://travis-ci.org/aprilabank/posix_mq.rs) [![crates.io](https://img.shields.io/crates/v/posix_mq.svg)](https://crates.io/crates/posix_mq) This is a simple, relatively high-level library for the POSIX [message queue API][]. It wraps the lower-level API in a @@ -29,5 +28,17 @@ queue.send(&message).expect("message sending failed"); let result = queue.receive().expect("message receiving failed"); ``` +## Development + +Development happens in the [TVL +monorepo](https://cs.tvl.fyi/depot/-/tree/ops/posix_mq.rs). + +Starting from version `3771.0.0`, the version numbers correspond to +_revisions_ of the TVL repository, available as git refs (e.g. +`refs/r/3771`). + +See the TVL documentation for more information about how to contribute +to the codebase. + [message queue API]: https://linux.die.net/man/7/mq_overview [sister library]: https://github.com/aprilabank/posix_mq.kt diff --git a/ops/posix_mq.rs/src/error.rs b/ops/posix_mq.rs/src/error.rs index 1ef585c01e..bacd2aeb39 100644 --- a/ops/posix_mq.rs/src/error.rs +++ b/ops/posix_mq.rs/src/error.rs @@ -1,8 +1,5 @@ use nix; -use std::error; -use std::fmt; -use std::io; -use std::num; +use std::{error, fmt, io, num}; /// This module implements a simple error type to match the errors that can be thrown from the C /// functions as well as some extra errors resulting from internal validations. @@ -17,7 +14,7 @@ use std::num; /// * ENAMETOOLONG: This crate performs name validation /// /// If an unexpected error is encountered it will be wrapped appropriately and should be reported -/// as a bug on https://github.com/aprilabank/posix_mq.rs +/// as a bug on https://b.tvl.fyi #[derive(Debug)] pub enum Error { @@ -47,13 +44,13 @@ pub enum Error { // Some other unexpected / unknown error occured. This is probably an error from // the nix crate. Bug reports also welcome for this! - UnknownInternalError(Option<nix::Error>), + UnknownInternalError(), } -impl error::Error for Error { - fn description(&self) -> &str { +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use Error::*; - match *self { + f.write_str(match *self { // This error contains more sensible description strings already InvalidQueueName(e) => e, ValueReadingError(_) => "error reading system configuration for message queues", @@ -67,31 +64,44 @@ impl error::Error for Error { QueueNotFound() => "the specified queue could not be found", InsufficientMemory() => "insufficient memory to call queue method", InsufficientSpace() => "insufficient space to call queue method", - ProcessFileDescriptorLimitReached() => - "maximum number of process file descriptors reached", - SystemFileDescriptorLimitReached() => - "maximum number of system file descriptors reached", + ProcessFileDescriptorLimitReached() => { + "maximum number of process file descriptors reached" + } + SystemFileDescriptorLimitReached() => { + "maximum number of system file descriptors reached" + } UnknownForeignError(_) => "unknown foreign error occured: please report a bug!", - UnknownInternalError(_) => "unknown internal error occured: please report a bug!", - } + UnknownInternalError() => "unknown internal error occured: please report a bug!", + }) } } -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Explicitly import this to gain access to Error::description() - use std::error::Error; - f.write_str(self.description()) +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Error::ValueReadingError(e) => Some(e), + Error::UnknownForeignError(e) => Some(e), + _ => None, + } } } /// This from implementation is used to translate errors from the lower-level /// C-calls into sensible Rust errors. -impl From<nix::Error> for Error { - fn from(e: nix::Error) -> Self { - match e { - nix::Error::Sys(e) => match_errno(e), - _ => Error::UnknownInternalError(Some(e)), +impl From<nix::errno::Errno> for Error { + fn from(err: nix::Error) -> Self { + use nix::errno::Errno::*; + match err { + EACCES => Error::PermissionDenied(), + EBADF => Error::InvalidQueueDescriptor(), + EINTR => Error::QueueCallInterrupted(), + EEXIST => Error::QueueAlreadyExists(), + EMFILE => Error::ProcessFileDescriptorLimitReached(), + ENFILE => Error::SystemFileDescriptorLimitReached(), + ENOENT => Error::QueueNotFound(), + ENOMEM => Error::InsufficientMemory(), + ENOSPC => Error::InsufficientSpace(), + _ => Error::UnknownForeignError(err), } } } @@ -107,24 +117,6 @@ impl From<io::Error> for Error { // here because the system is probably seriously broken if those files don't contain numbers. impl From<num::ParseIntError> for Error { fn from(_: num::ParseIntError) -> Self { - Error::UnknownInternalError(None) - } -} - - -fn match_errno(err: nix::errno::Errno) -> Error { - use nix::errno::Errno::*; - - match err { - EACCES => Error::PermissionDenied(), - EBADF => Error::InvalidQueueDescriptor(), - EINTR => Error::QueueCallInterrupted(), - EEXIST => Error::QueueAlreadyExists(), - EMFILE => Error::ProcessFileDescriptorLimitReached(), - ENFILE => Error::SystemFileDescriptorLimitReached(), - ENOENT => Error::QueueNotFound(), - ENOMEM => Error::InsufficientMemory(), - ENOSPC => Error::InsufficientSpace(), - _ => Error::UnknownForeignError(err), + Error::UnknownInternalError() } } diff --git a/ops/posix_mq.rs/src/lib.rs b/ops/posix_mq.rs/src/lib.rs index 057601eccf..ed35fb03be 100644 --- a/ops/posix_mq.rs/src/lib.rs +++ b/ops/posix_mq.rs/src/lib.rs @@ -1,5 +1,5 @@ -extern crate nix; extern crate libc; +extern crate nix; use error::Error; use libc::mqd_t; @@ -8,8 +8,8 @@ use nix::sys::stat; use std::ffi::CString; use std::fs::File; use std::io::Read; -use std::string::ToString; use std::ops::Drop; +use std::string::ToString; pub mod error; @@ -33,16 +33,20 @@ impl Name { // have tried just using '/' as a queue name. if string.len() == 1 { return Err(Error::InvalidQueueName( - "Queue name must be a slash followed by one or more characters" + "Queue name must be a slash followed by one or more characters", )); } if string.len() > 255 { - return Err(Error::InvalidQueueName("Queue name must not exceed 255 characters")); + return Err(Error::InvalidQueueName( + "Queue name must not exceed 255 characters", + )); } if string.matches('/').count() > 1 { - return Err(Error::InvalidQueueName("Queue name can not contain more than one slash")); + return Err(Error::InvalidQueueName( + "Queue name can not contain more than one slash", + )); } // TODO: What error is being thrown away here? Is it possible? @@ -97,16 +101,9 @@ impl Queue { flags }; - let attr = mqueue::MqAttr::new( - 0, max_pending, max_size, 0 - ); + let attr = mqueue::MqAttr::new(0, max_pending, max_size, 0); - let queue_descriptor = mqueue::mq_open( - &name.0, - oflags, - default_mode(), - Some(&attr), - )?; + let queue_descriptor = mqueue::mq_open(&name.0, oflags, default_mode(), Some(&attr))?; Ok(Queue { name, @@ -121,12 +118,7 @@ impl Queue { // No extra flags need to be constructed as the default is to open and fail if the // queue does not exist yet - which is what we want here. let oflags = mqueue::MQ_OFlag::O_RDWR; - let queue_descriptor = mqueue::mq_open( - &name.0, - oflags, - default_mode(), - None, - )?; + let queue_descriptor = mqueue::mq_open(&name.0, oflags, default_mode(), None)?; let attr = mq_getattr(queue_descriptor)?; @@ -151,16 +143,9 @@ impl Queue { let default_pending = read_i64_from_file(MSG_DEFAULT)?; let default_size = read_i64_from_file(MSGSIZE_DEFAULT)?; - let attr = mqueue::MqAttr::new( - 0, default_pending, default_size, 0 - ); + let attr = mqueue::MqAttr::new(0, default_pending, default_size, 0); - let queue_descriptor = mqueue::mq_open( - &name.0, - oflags, - default_mode(), - Some(&attr), - )?; + let queue_descriptor = mqueue::mq_open(&name.0, oflags, default_mode(), Some(&attr))?; let actual_attr = mq_getattr(queue_descriptor)?; @@ -187,11 +172,8 @@ impl Queue { return Err(Error::MessageSizeExceeded()); } - mqueue::mq_send( - self.queue_descriptor, - msg.data.as_ref(), - msg.priority, - ).map_err(|e| e.into()) + mqueue::mq_send(self.queue_descriptor, msg.data.as_ref(), msg.priority) + .map_err(|e| e.into()) } /// Receive a message from the message queue. @@ -200,11 +182,7 @@ impl Queue { let mut data: Vec<u8> = vec![0; self.max_size as usize]; let mut priority: u32 = 0; - let msg_size = mqueue::mq_receive( - self.queue_descriptor, - data.as_mut(), - &mut priority, - )?; + let msg_size = mqueue::mq_receive(self.queue_descriptor, data.as_mut(), &mut priority)?; data.truncate(msg_size); Ok(Message { data, priority }) @@ -261,9 +239,9 @@ fn read_i64_from_file(name: &str) -> Result<i64, Error> { /// To work around it, this method calls the C-function directly. fn mq_getattr(mqd: mqd_t) -> Result<libc::mq_attr, Error> { use std::mem; - let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() }; - let res = unsafe { libc::mq_getattr(mqd, &mut attr) }; + let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit(); + let res = unsafe { libc::mq_getattr(mqd, attr.as_mut_ptr()) }; nix::errno::Errno::result(res) - .map(|_| attr) + .map(|_| unsafe { attr.assume_init() }) .map_err(|e| e.into()) } diff --git a/ops/posix_mq.rs/src/tests.rs b/ops/posix_mq.rs/src/tests.rs index 7a08876aea..1f4ea9a58d 100644 --- a/ops/posix_mq.rs/src/tests.rs +++ b/ops/posix_mq.rs/src/tests.rs @@ -4,8 +4,7 @@ use super::*; fn test_open_delete() { // Simple test with default queue settings let name = Name::new("/test-queue").unwrap(); - let queue = Queue::open_or_create(name) - .expect("Opening queue failed"); + let queue = Queue::open_or_create(name).expect("Opening queue failed"); let message = Message { data: "test-message".as_bytes().to_vec(), diff --git a/ops/secrets/besadii.age b/ops/secrets/besadii.age index b78f02da8f..50c2d1442d 100644 --- a/ops/secrets/besadii.age +++ b/ops/secrets/besadii.age Binary files differdiff --git a/ops/secrets/buildkite-agent-token.age b/ops/secrets/buildkite-agent-token.age index 35e592ee51..66802310bb 100644 --- a/ops/secrets/buildkite-agent-token.age +++ b/ops/secrets/buildkite-agent-token.age Binary files differdiff --git a/ops/secrets/buildkite-graphql-token.age b/ops/secrets/buildkite-graphql-token.age index e1c30b785b..6ebf3efca7 100644 --- a/ops/secrets/buildkite-graphql-token.age +++ b/ops/secrets/buildkite-graphql-token.age @@ -1,15 +1,16 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw eGKM1q69QdToZ9wbtsdAgAfGHOsVrc/IJ4IFbHfoeAA -eogaENxdhqW/2H+FM7SPWgN1UcXPzUTx3tYiVU9K8Rk --> ssh-ed25519 CpJBgQ v00XK32Div5ddrWPdzjv5ZFPECtW14rPv3G6iFvXUFI -OQAJaolWVUiVXTK14b9Q5ZTYR4YQL2e6Ye5TY4Xxq0Y --> ssh-ed25519 aXKGcg ieOvBBSHPSP7k05I5unpRn6+S4K9NfRqwUb5s0XM0js -z8Q+psAM7Zj02M7m3KNNjSTLmiLH9S+nOzQE5xz1nr0 --> ssh-ed25519 OkGqLg OKzXlZJyHE73V36WVZ2KhvFhif3HZtZDjjBBv5g3hyA -ilL9pohUoCXfNi1jLekPx35Iu3dGOBAe1H2JFXrKHTU --> VQDa2-grease 'HsH ^-& -YuO3YgYZ3Q1CjlIayGFg1Y9zplKgzqR0mZeZlyaOJDMHDrWSOaWRPXjFVU/s2EvP -MECrypRbNRaHEdPSY7udi1q5cVBPNj3Dci5uiq9t ---- HKTtOZJq9MSAhr3x1eUhk6yFJU3y7TCPilXPhMNfbwA -10ๆ?๑ืaณฌฅเ๓9๎ฝก4๙bWyำ้ -ญjbจ็nใ๐บ6 Ppีปlว'YธFy๗๗๑ \ No newline at end of file +-> ssh-ed25519 dcsaLw X7cI9stdU1F8M8Mhk/5a4UwU2Ze6rBXuwRDxUTKCTHw +CnksXNl+VEs2CYiucBeIgfpzpA05VshlECkbmTUZSpI +-> ssh-ed25519 zcCuhA 7KOsie4KRM0pPKZk8MeDISuX4tT9MAw/5mehSQcNOE8 +UfbpAlKJVhZOH5j4YIw5CVDen7UebTO/S55sLT9tVyc +-> ssh-ed25519 CpJBgQ EiDs9pCdSnPb4T4HvgF+gdyJ9f5orhtn1OVUp45e3jM +SlMWEzpi/mMlhfBPzVBn6jZknvjWCbRQMLoJEklJV2w +-> ssh-ed25519 aXKGcg kiuat73hEcxKvRZ9Gk115LjB3WVgd0h5KrjMOyTRLzw +CwEmQX6vmi6DnJp/TeYFOSdsfrprHylXAzhnAaQ3aKw +-> ssh-ed25519 OkGqLg R+moPPGckVPXrAnwQXFPqsizUwK+8UlL2VAA1965d1Y +J0sxPR2PDqK3k39dSLOzFQkUUZ5cfYqww6NHQ7E4ql4 +-> lb6ND/-grease !D$d P~ Tj. +HjRsXF0B07o957mq0zRgyHlckismT8UI8KcyFN55ff9FlWpci3+LEcPCb08wtraP +DSRvOi4 +--- AomJrDQJ4VQghgD6b7ItcPNyiu+cDmNQM31FOqYBbEk + 0:เนนXดฎ0bฅ^บ(ม๒:ฐำVฆr%GTฏh์ม>~ทถฟ บq๏กฺ*ผๅ ืชฝ;}$๘ \ No newline at end of file diff --git a/ops/secrets/buildkite-ssh-private-key.age b/ops/secrets/buildkite-ssh-private-key.age new file mode 100644 index 0000000000..c9aa988277 --- /dev/null +++ b/ops/secrets/buildkite-ssh-private-key.age Binary files differdiff --git a/ops/secrets/clbot-ssh.age b/ops/secrets/clbot-ssh.age index ab51ccc68e..c24f8f45d3 100644 --- a/ops/secrets/clbot-ssh.age +++ b/ops/secrets/clbot-ssh.age Binary files differdiff --git a/ops/secrets/clbot.age b/ops/secrets/clbot.age index c44c77f583..2cec1f7f36 100644 --- a/ops/secrets/clbot.age +++ b/ops/secrets/clbot.age @@ -1,14 +1,15 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw sjFTLxJ9JArZ/GU/R/hqRVgX73x3sDO4uNdVrRrZpXE -cbMS1tn4+diLX4Hf1Pe0XBYvJH5G3ueZIIA+3KImq3Y --> ssh-ed25519 CpJBgQ 3yeOIq2DxFqr8NW4VpdaUVoEmwvQayWThPzoMo9UCmY -xLyNilVdqXZ6WjAbT9NDFIssFc4564C/13z4w8WGnpU --> ssh-ed25519 aXKGcg peKlfil+osni6uHra2unBeQM5MBeK9TVmBg3BpozVy0 -KsKJ5yQQFWGbuiANV8uOck3sSIW82v/JKqLEuLJRsAo --> ssh-ed25519 OkGqLg Jo5YHWYNkou8JIBKrSrRJBG1VMdStmDqe/S62hdo+Ac -U5zaBxJ6TKsuaB3vKS7+03vBJLe+nAWMZ6fSlwF+VQs --> 8SA_}x-grease -J/zFiD0MDxVK5FDCv4fmA6sawl8gQZcPg0h1NunSjVnBUPNXx9FZylONpu9M56y8 -Z2JJ ---- bR5Pl8ZiMNPIgx/n6ozwOkikLE9E6GWEK2SVIMUlbvI -gุyฤหx_ๅ๘ใแ้กn๘2๊ uT๔ฯZาฤRำ๔G๒7,iฃตS%ZSแKอQdๆ.`ฏ,y(๐Yn9cฌภ \ No newline at end of file +-> ssh-ed25519 dcsaLw ZkAwxhi/ckHaVTnF7bmzOXhQG3HHqw1CpMe6nQL0rHc +9qnf0AY/inCEvk1VBd4RC3M0kATM/JuIyWxqisjersY +-> ssh-ed25519 zcCuhA o3PRUMcah5zjj39LtDWpgmBPFtHyx1N9WQz++lFrFEI +7K1kZHKfmlV5G/xVbgeOuLAO2iXKqcEyRYm+YfTvURs +-> ssh-ed25519 CpJBgQ pFnL2XmxzppshipadVltN/zSgiRiMh6emu6O8EZTpxI +K/RPjooKVSwqxc2aAUBtdTnkKoZvXDi+2NPB2NPXT9E +-> ssh-ed25519 aXKGcg sTN4w5iMnwxmp/E7OKu5I3pUc695OXBYmfOY8/hs1AM +DguaArDGVn7scD0NrDntgePjN1LFlfrPKfjEd1T9iOI +-> ssh-ed25519 OkGqLg xuRTDdql+UBNW2go+XxkC/FJZa+N/e6Kj/Fjm7MzG3E +KC39o7+WV+d/psN4mYSxeUSHsSCxPWTJgYjY1f1Dd3w +-> J:e-grease +CISPWfdtr4GKDU+lhCFk6B/EVyOmYwDxhChu +--- nwu3QYk6rfvIJWJrTB8RSBsWjS1uok8rSxc9FCzoA9k +WSMrฎ g#MSB๗}A"ึ๚๘จw}คูฏ๓วอ-่ลZแ1ศร๑ooGo8๗าจwรำ \ No newline at end of file diff --git a/ops/secrets/depot-inbox-imap.age b/ops/secrets/depot-inbox-imap.age new file mode 100644 index 0000000000..9bce1845cb --- /dev/null +++ b/ops/secrets/depot-inbox-imap.age @@ -0,0 +1,15 @@ +age-encryption.org/v1 +-> ssh-ed25519 dcsaLw cpeIOVtFcfaHZpIAp495fkQLJoT++h1v6p0crBeuzFM ++zomKCg7UVNl/FlfcZflVPbo48C45uGoGoR1tbetEdk +-> ssh-ed25519 zcCuhA loSmQUCnO0EBaGg+wFYYkXOdLBQ6Z+pPl4Y3oGx6xzw ++RdXNYYtIDDXGr1Z0Mh28psvF9gzg12M3EJTUqmdFtU +-> ssh-ed25519 CpJBgQ 0W0LWu8WW6pQzUhK21CeNDUtW0srwR5gNCRjwTy94B4 +A02F+AyP+DajnVTJakx+0jynYRDix9I/9uZUDPjXpis +-> ssh-ed25519 aXKGcg SVBo2urAYGSYrlj3ieoi9nkrffcZ9ZroCn86pZkn4nI +xQRrLNeNcI9cpQY+X2xfLDoBqLNQixGjaYtMDWtHio4 +-> ssh-ed25519 BXptmQ UKNJPPjIiqPQndZ6/yASSg+5PQIn2N9nUy2hQMREq1Y +X9zM/ji9R3jLOEDGLpIVESjU13VU0e3cTAR1xEMhY5I +-> B-grease Y +vUOYknqY0okoUOKZD/8MpnpwkOU31sszuUZfeSVsuVyUMPEbFjWQT74 +--- ymKMaoUQXFPRc9U0ZvULBEC0Az0ew2oEyHwH/kR9ETI +Eu ซฏญxงแอำe_)zPบๅhำำส๙sฃGเ่ดสBLQ \ No newline at end of file diff --git a/ops/secrets/depot-replica-key.age b/ops/secrets/depot-replica-key.age new file mode 100644 index 0000000000..5e8ce94d5d --- /dev/null +++ b/ops/secrets/depot-replica-key.age Binary files differdiff --git a/ops/secrets/gerrit-autosubmit.age b/ops/secrets/gerrit-autosubmit.age new file mode 100644 index 0000000000..2e04be952d --- /dev/null +++ b/ops/secrets/gerrit-autosubmit.age Binary files differdiff --git a/ops/secrets/gerrit-queue.age b/ops/secrets/gerrit-queue.age deleted file mode 100644 index 68dd1e7e2e..0000000000 --- a/ops/secrets/gerrit-queue.age +++ /dev/null Binary files differdiff --git a/ops/secrets/gerrit-secrets.age b/ops/secrets/gerrit-secrets.age index 02a3c66b53..9ad123d578 100644 --- a/ops/secrets/gerrit-secrets.age +++ b/ops/secrets/gerrit-secrets.age Binary files differdiff --git a/ops/secrets/grafana.age b/ops/secrets/grafana.age index ad503dc32a..eef349d64c 100644 --- a/ops/secrets/grafana.age +++ b/ops/secrets/grafana.age @@ -1,13 +1,16 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw CrJGrkztUpn+XkED1hn4Clr/oBNrer9J+/fdqDhgx18 -VWENh02k4HTkhDS2F219vrCUVuxXFOCPsCW+8eeZHs4 --> ssh-ed25519 CpJBgQ 8Lm14o93CEh/aerPtMiStKYtqF/HdgJD05uRRegLgUs -b0H5XBOe4nepmGzl646Ar0XAazzHAJeTLCCGUVaZyW0 --> ssh-ed25519 aXKGcg SKWLHNM0WeFJoGlOPbI6v7CebdSK3qAmQ6kMW5YbIz4 -kQD7Oh9mQeCXyXzOc1kVI8ShE0J89TzuZBOboaQn7sE --> ssh-ed25519 OkGqLg ablfqKN1GYY3GWGCHGtciRFJwO4e0kbcS75Kaj+elUA -PQPeRVzV/Yi0lxI7U+lNbCpeatymazj7GjQLhmL4YI8 --> gse~-grease -I9X7cHnmfbsnu/4AeVVtTRlbguJDylrAlCOqTOt11Gtg/Ft2fnZZTOmsKo8 ---- 3xk3ls7SR7s394FtfqLwxgUDjTPMjnhLz79ClvIm4pE -ผyF๔zผธฤH๑ุฉูมทใ*Mพศ\ซ26I`koฮธ&baาWvMฃ.ดฎีjใฃมFศ;ZํลNึ*๋Pฒ _J๓c _(Sชjๆdน๏8Fแ \ No newline at end of file +-> ssh-ed25519 dcsaLw 0h55HIHm0kf6LqtI99LFUWBCoERBmpoF+anfnxjhDBU +0bHlgfRABn51BoMwAIjUlaVnCr3ZDXkQPmFOiIV3TvI +-> ssh-ed25519 zcCuhA 0vFMP1qFEiN4MUt+1qQCqtEovmO2d6QHj+KjHBrvqB4 +CUM2MDNPEKpksyCQmfDg/k/CKz7/ckgafw4aj0FLcmE +-> ssh-ed25519 CpJBgQ Y971kTqyElTHpOw4D7mUfkIQFWELOBeuGPUE6bqSrXQ +zt3ju2cqDfQJg9BsSsWcOGfPu5Q4XuIz0k2gasaRCPE +-> ssh-ed25519 aXKGcg eNxh3cCMbxG/u4luhlE2WQVzFMlZIcDKDx4dcpK43hY +HGJZYkWbYA0I7HtArCz9ErXwAAfOBHe20JH1J5Bx904 +-> ssh-ed25519 OkGqLg a1+l3dkThz8LLp7C1D9l7CzdB8Q4hxjNzaY7B6HMSnQ +du3nw0b61TGdF91Mq7C/PpjDlnIIph1dVEIivcDpM7M +-> \gwpw]-grease p#:x#sA ^S5*A/ ZpY +1rTU2Rc5MnpJj8zwOK4yR9HvDPOiKjCKHOURq6ak4SUmEgqqyqoujzRaL4I0cKf0 +zMFTkoKnLXjjLiHyvJWqCGwCRq9veUsTiJ6jqs+y6L+YaT71qDzDXi3YfX2p +--- hraNRaUxkHCnhk6AC/3jyxaAj1gyyIi0Q7cqoupcRrA +ก๛:ถ'!ซ37ซ s+0ป@มใืฏจฟd๊ ?๏!%๏lฌุดภอภ;ล๘๛ม2ขฟห๎กBพ!/gฝุใฑ/ฐ:wuีฏ๒ไ[ฉ~ฅณภั๗pฉFต \ No newline at end of file diff --git a/ops/secrets/irccat.age b/ops/secrets/irccat.age index 5a45efa7cc..2002b15c49 100644 --- a/ops/secrets/irccat.age +++ b/ops/secrets/irccat.age Binary files differdiff --git a/ops/secrets/journaldriver.age b/ops/secrets/journaldriver.age new file mode 100644 index 0000000000..c58773f36b --- /dev/null +++ b/ops/secrets/journaldriver.age Binary files differdiff --git a/ops/secrets/keycloak-db.age b/ops/secrets/keycloak-db.age index 5942bf24c2..54194df183 100644 --- a/ops/secrets/keycloak-db.age +++ b/ops/secrets/keycloak-db.age Binary files differdiff --git a/ops/secrets/mkSecrets.nix b/ops/secrets/mkSecrets.nix index 4e40112b96..c99130835f 100644 --- a/ops/secrets/mkSecrets.nix +++ b/ops/secrets/mkSecrets.nix @@ -22,6 +22,6 @@ in defun [ path (attrs agenixSecret) (attrs any) ] (path: secrets: - depot.nix.readTree.drvTargets - # Import each secret into the Nix store - (builtins.mapAttrs (name: _: "${path}/${name}") secrets)) + depot.nix.readTree.drvTargets + # Import each secret into the Nix store + (builtins.mapAttrs (name: _: "${path}/${name}") secrets)) diff --git a/ops/secrets/nix-cache-priv.age b/ops/secrets/nix-cache-priv.age index 4a16897eb2..0381fb1290 100644 --- a/ops/secrets/nix-cache-priv.age +++ b/ops/secrets/nix-cache-priv.age Binary files differdiff --git a/ops/secrets/nix-cache-pub.age b/ops/secrets/nix-cache-pub.age index 692d869015..ae06f49d69 100644 --- a/ops/secrets/nix-cache-pub.age +++ b/ops/secrets/nix-cache-pub.age @@ -1,13 +1,16 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw 2wWiYCk+TcJdGdiT+YWVvv1FZ28EJYykwseyiZ9pkzs -AMvMQQsWe3nar2TQM+wcyD2PEKlE9PeSx8G2ufJzEzI --> ssh-ed25519 CpJBgQ SpGruCznXleG0wmFMUTGJf7VNGKLEYqeQb/mv+axKxM -SL4MTYEiOFgp6+90Fp3QFnSzFUfMWxNF2OHdH3Q+uy0 --> ssh-ed25519 aXKGcg wWO1kn2tUlBZoMFsO1JrVhyqJCfv1BNhoVfKBwfidmA -A3PAoWzbJWSlIKxGYsUEvuwRbDvRTjZYUdeSi+LQa1M --> ssh-ed25519 OkGqLg 2usxSwcnF2tZbJt6R7M+psTSW2M5HcZgr51t47D01GI -HVGRSasPX9/I9E9oZhhMd6hVK/ga3n/UYzRAe2CjRqI --> /oh-grease v* Qu8SiS 2 -5dc ---- 59MLx4Yl2G9G8QjEp+gOrKBPjCqm/ntgg8guQICu/x0 -ู`เ 8DJฦ]๎sำP๋ฑRwa!โ7k47<i:'?)ฟึะีฉ๔๎ๅูฟSธ}๒Rมop)่_wIKpไ:S5๒0kฝ๙ ฮjํ \ No newline at end of file +-> ssh-ed25519 dcsaLw +jfxfM1YDu5CoYtFeRWtpkUQhmFWn/kNBYsBnie7BVg +XxL9l87hXD0zCUEwbSR9OHSYgpOw89Km5iyxPPnVDGQ +-> ssh-ed25519 zcCuhA VAoDkN2gwErUFE/59V4IF9PbSBSleOjt2gosvYnHxWg +Pf6eh8EfAdATjZIkQfhhqOXuJXIdwIpybITcn+rcutI +-> ssh-ed25519 CpJBgQ C6zIv78gu+wBeAjhmXANegSNqGHnugemXBPQcTimgxg +80109g83Hk+smWuZkTIZJ6VFQqJ+LU1boWKQIH1AHjc +-> ssh-ed25519 aXKGcg lPb+kGr0vuJkQO6VutAm4Yh1CVi/XfqNdGbAh/B7ZRk +h4xb++7I9iv8208oqY0xLruA1r62mepISFcusczdbgs +-> ssh-ed25519 OkGqLg aOHt9OR8JChtYpclkgn9wCFnlayFje7WsMGQb8AqChU +3VRTDMUwFtDcoxGU/wiBzTvS0SB/xOpBG6s+ENvAXVE +-> Kow$7|\-grease +8OGnQnY7gm4vMJRXjnBogA0HRU7hqIxs2sErFc7sV1CUNkZlFjdK8tZomlNwshjc +p18HgtjJnaGhSqg1LyP7cJAo/XnSwDYCeNna/6vdlKBR3JeuOGTmx1NIG/cGSg +--- w+jJplb/J3av+UcltcFf4qSqHoQ8Ol8lH/fFB3051Gw +qIํe:1*`j8๕ฑsบnHcyฮเ7ฃฒศรตๅ(ชใพ.xDธ_}%๓)P,Dๆำ6ซSอ้Hล๊รU9ฐ๋ฌิ0ํ8อิํ\ณ๖' \ No newline at end of file diff --git a/ops/secrets/oauth2_proxy.age b/ops/secrets/oauth2_proxy.age deleted file mode 100644 index baddeef1e3..0000000000 --- a/ops/secrets/oauth2_proxy.age +++ /dev/null @@ -1,14 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 dcsaLw 3vCzURGgzn7i3pZp39oSfYy1F331qBDewFgjocK4/nE -doccb4CZhyrA7jvbuG3i8nowApVGKWfIejJjLeXnb9Q --> ssh-ed25519 CpJBgQ 4KovCGvA0cBvEkhfyantUCny49hTu4L038xj/ZG2lCg -o9iaan7jKGYukS4IiTVLV5YqjiycaWyPXyo3x6k8Jhk --> ssh-ed25519 aXKGcg stGJqj37f0E6S0qJW/r/cYXIoT+l4ERG0c/CMckpS28 -aNP2LcrFe9wLB1dnbJjoUTa8ckpMbR3cJtltDn/8st8 --> ssh-ed25519 OkGqLg UK89eEeI/SOWUaR4jg4rDuKFOkzsf6PgNkcphUCoyj8 -o3WFOhB0B2T1F8mxb5qw25S4r9bYyc4tqwLb/iK0TAY --> ZcBt-grease P*F$|]1G *a9 ^dTv-Whe K`GVU -mwq98CjcnoinoAsGUM2PolGrXBZhs9jbUQB8qEAZ7Qtzd6z6BjGoPGr4bjokZQ08 -RwOx9jBmAAFaW9Ak5JX9RBvxu/IIz6xVmQ8a8ev95tA ---- ShfGC5iYYwDC5fXRkZV9Oh1aHJONbdR1EaAp+lrKWUE -ร๙t~EชVจถ/ึ๕E}_๛H็Rษ7PsSw>ยฝ์ญZoD`n)ทK,T} 'F[ SณKyฮ7m"ะEฟG3ๆ"ฮ๕ตวljๅ๒ู^b[ึมMไlfpX๗Cว๐ฒื]ๅ!N]m๛๖๙ใ gจทพ0ึ๖๚!ฐg๐ฏ1ญะโY ฺX \ No newline at end of file diff --git a/ops/secrets/owothia.age b/ops/secrets/owothia.age index 845252dd1d..177ee61383 100644 --- a/ops/secrets/owothia.age +++ b/ops/secrets/owothia.age @@ -1,15 +1,16 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw ZV01yZa6uSpirIxPgW8fLJ3lI/RRb0tRObGey3zlgGE -cu64HZYAxEL0qbUKcQEGzzQpwkAvXwp6NYYGaoHNwPw --> ssh-ed25519 CpJBgQ +NoCEPUKCscQxZLdjFI5YwWNiQuj8klra4AceYAOR1A -xhNGia9flgRDn2QNsklyotwU7nJ9elXV8jMkT8XfUEA --> ssh-ed25519 aXKGcg MsimFAWS4vN6exoeKA2PVin+82QXzt32oS9iei6f4l4 -i+ph/HZ6a5f9QWorgwt0RFvmV4E4HpGSmkZAqdXhZ68 --> ssh-ed25519 OkGqLg zLXi3YNberKHC7b/La1FdrLgLowjB4wovnXo/ayqeQs -dYIN5zvmbMsN5yjhVrccjwYqXJHV9zcEJCjTnMIs55g --> FlqGql'-grease -g+GgOSpwwnqLywaY4h9wMA2h7buTMM8vYEufiyTOOOSD7ljq1cgBePAoCFluW8UW -8SDabs5WTRYgqqDnzVkx9V3JeIWJrfiKQj9coLZ1Crx5+YRD9r766eGEvHOC5eat -432j ---- V/bZkitOabEh8PO3J8dmv/IgycQOF5CmMvGTsHTdmlo -ฯ๕๕7(ฑtฒNูึำยF๚ทgภสฟZ&ooา,ฦฆฒQ1์(^ไน์ K}Wู14๏ซ)๕D@ืธ๐YภฺYi \ No newline at end of file +-> ssh-ed25519 dcsaLw 8XtdgZ++/ZqmK4j8CO8oiuskTxjvKhWDK7fet5hbqiM +Fs4O1vFtQL1JamnuCMPLzfzRPb90nxfXB6OXkyCMoHo +-> ssh-ed25519 zcCuhA 6PNsPMdRXM77ci+mBQNRxr1oMGDNdlQilpUB0Q5es28 +APw2L/0htM9U0fJ1IUthdkoem/UTM/6NNQrgn4Vmpcs +-> ssh-ed25519 CpJBgQ ed00il0q23M+3KH6hf5fFPaXGUKcz03Bn01jSoKiB1U +jEN0Dk2edJBQreAlNE11sx0cI5u1mfFDT11Ev0KJ+gs +-> ssh-ed25519 aXKGcg NocBhG6QGlWDZhjsA6Sxvjv9Gs+3Pq5gcOqnVdiefBg +HYnqBv0pdPz8bqgZ98VDfYFeKcFNeuJrlOsyWt551Sg +-> ssh-ed25519 OkGqLg e0081m/IkQafXh1gAWUZ2glYG7bklCG/LaUy63rK6gc +G2RNMxCxRnqocYhiq142T8EPZQD8cRHHs7AHKFrMLaU +-> +J}@hPk-grease +406BMfqUt/KjayTopj4dNa4owPZphR6AsBXPurJwU/zV9ipirfW3oEeaprdh4uLg +RHO0bSZQV1uu1YmbXkuwMaVj1cVn2vsDPEv3xG2SRzMoEpAAKaFCBba8 +--- 5ncLI9pS25vz5CebIZjPPDQ5cHISlyRFF55rGgFQnnM +แ$"PKช&Cท\ๅ(ีGภ[ฯ( ฌทD๐ึlวบน8ก4็๎ฎPฦ)ฉตฌนบBขฎิผฃฎ๑c\ฅU:๘สฌ( \ No newline at end of file diff --git a/ops/secrets/panettone.age b/ops/secrets/panettone.age index a8a176fb13..0be42dc0a7 100644 --- a/ops/secrets/panettone.age +++ b/ops/secrets/panettone.age @@ -1,16 +1,15 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw lFE6Oxzl0jaGpmfxEzmvywEyxsmPNfhv+NNR95XGiDI -NJhZ6KFNLcScSR5iNB5IAL4UqWzort+jWypbKQPsxu0 --> ssh-ed25519 CpJBgQ 7sMqCFUdss274yNWtYbXe+l7oevKaR99d6E7c4LWtjg -rqwEyv2dT07qd87suVZxk+8+bmA2W6MFkoG8NktRRbY --> ssh-ed25519 aXKGcg 9/0QlqFKxPVwjwagBTWHdhJXWWYXn0v649ZhmzpUxWc -pMs+PoMRi3FghN2odcBQ9tpE+0Mb/jaErnOnuuoq4sw --> ssh-ed25519 OkGqLg Is/FQ/8s+oq+qThcwOdnAgCrZX/kNBLc0Cwpvi2NMwk -Zf31SwMF/fyBd1d899GPv8Z8A8GSBy5xuG4d8zL9Zz0 --> wyU-grease Dzk;3o # ,q\WtGwI -PoJGe6Xlhl47AhFLxM4HLaEYAqcx9lzodHasyZ1AH0BtdSFYT92cYw/1rSNWheTk -YedxiXNrosw ---- tJE6XbPtWlMYKHItyPlThcnLnmp/9AS1muhfgDosTCk -$; !ุ๓?; -bฒ็H}๙๏ิะรfxฐQลาอคdaแท๊K7ฟค1OUำณ<นกฬ่ ซ็y8ีmfบV~ษJาชฐZฝ๐0ณฌ|tN๘เ[รO๗;๐2;/ณ3)vไGP%ชคํJ0ึY%ุจขd[1ฆk/+ณ - \ No newline at end of file +-> ssh-ed25519 dcsaLw zzUe0JqhICtd/kgZnXFpwaQ1Ma6nqy/hMWaOJpRHmDs +4cR+OnWShG6MpB/u0yfsSxplEch7x7DbygfBiJGxOOs +-> ssh-ed25519 zcCuhA 0RZEYC9IuazO9fROalwoOCIgc0j+rNBP3gw7SKG0yEw +mPRhN0hvccEr1A9ihWAFMH4/24vpBKpxBVq4BKBMmYM +-> ssh-ed25519 CpJBgQ VrmfTtTVxuQmpUxMxtXtCnr8pFyqwtdyLHdbzYrlKlM +kHgEdPmoIOLnGuMF5F5Ol1yZWcactSE4OZI0BSmDN+g +-> ssh-ed25519 aXKGcg On4jwgsH504ZjYRwfw5oAfIDk3wU0+xgd43ryAn9H0I +fayzht1ZPPiFCjuYTdwVtJu2nOUg4wtp5IipOR4oJm8 +-> ssh-ed25519 OkGqLg mubp0xI0fvsKOAUaNaftFkHJ+bxgFHbgjn+A7sR8XVs +X68Zr8HvC4/XPC0AFIA5f1SKu7NSR/23oeX8cW1qfis +-> ?`-grease +hOy2Rwvk6+vXpHWWA49Wp10wKbw9TfsLXw +--- 9MLGx6BVm40C0CSV3bq6dnXrpy3QunBlh2/uO5OisUU +วณG<ีๅมะYืA๗Vsณ๐/-%gช๚.e@,Z๑ๆFWๆถ&ๆ๎ง๓<O๖q@พ>wๅฬQ>-gว'ฉฬ`กถจX๖าฯP8ณx<RNvท9ื#'/)ภฆgฆ๚่m2๕ฉิv๐<,฿7 ๗ใษ้ขะวqฏฆชv็QปทAOฮ-๓ฺ+gๅcส#ตๅฝ๎ข*ขฐeํ -งท)า ๙; \ No newline at end of file diff --git a/ops/secrets/secrets.nix b/ops/secrets/secrets.nix index 53f0d39318..5cbf2bf612 100644 --- a/ops/secrets/secrets.nix +++ b/ops/secrets/secrets.nix @@ -1,10 +1,17 @@ let + flokli = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTVTXOutUZZjXLB0lUSgeKcSY/8mxKkC0ingGK1whD2 flokli" + ]; + tazjin = [ # tverskoy "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1fGWz/gsq+ZeZXjvUrV+pBlanw1c3zJ9kLTax9FWQy" + + # zamalek + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDBRXeb8EuecLHP0bW4zuebXp4KRnXgJTZfeVWXQ1n1R" ]; - grfn = [ + aspen = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMcBGBoWd5pPIIQQP52rcFOQN3wAY0J/+K2fuU6SffjA " ]; @@ -12,26 +19,36 @@ let "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJk+KvgvI2oJTppMASNUfMcMkA2G5ZNt+HnWDzaXKLlo" ]; + sanduny = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOag0XhylaTVhmT6HB8EN2Fv5Ymrc4ZfypOXONUkykTX"; whitby = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNh/w4BSKov0jdz3gKBc98tpoLta5bb87fQXWBhAl2I"; - default.publicKeys = tazjin ++ grfn ++ sterni ++ [ whitby ]; -in { - "besadii.age" = default; - "buildkite-agent-token.age" = default; - "buildkite-graphql-token.age" = default; - "clbot-ssh.age" = default; - "clbot.age" = default; - "gerrit-queue.age" = default; - "gerrit-secrets.age" = default; - "grafana.age" = default; - "irccat.age" = default; - "keycloak-db.age" = default; - "nix-cache-priv.age" = default; - "nix-cache-pub.age" = default; - "oauth2_proxy.age" = default; - "owothia.age" = default; - "panettone.age" = default; - "smtprelay.age" = default; - "tf-glesys.age" = default; - "tf-keycloak.age" = default; + terraform.publicKeys = tazjin ++ aspen ++ sterni ++ flokli; + whitbyDefault.publicKeys = tazjin ++ aspen ++ sterni ++ [ whitby ]; + allDefault.publicKeys = tazjin ++ aspen ++ sterni ++ [ sanduny whitby ]; + sandunyDefault.publicKeys = tazjin ++ aspen ++ sterni ++ [ sanduny ]; +in +{ + "besadii.age" = whitbyDefault; + "buildkite-agent-token.age" = whitbyDefault; + "buildkite-graphql-token.age" = whitbyDefault; + "buildkite-ssh-private-key.age" = whitbyDefault; + "clbot-ssh.age" = whitbyDefault; + "clbot.age" = whitbyDefault; + "depot-inbox-imap.age" = sandunyDefault; + "depot-replica-key.age" = whitbyDefault; + "gerrit-autosubmit.age" = whitbyDefault; + "gerrit-secrets.age" = whitbyDefault; + "grafana.age" = whitbyDefault; + "irccat.age" = whitbyDefault; + "journaldriver.age" = allDefault; + "keycloak-db.age" = whitbyDefault; + "nix-cache-priv.age" = whitbyDefault; + "nix-cache-pub.age" = whitbyDefault; + "owothia.age" = whitbyDefault; + "panettone.age" = whitbyDefault; + "smtprelay.age" = whitbyDefault; + "tf-buildkite.age" = terraform; + "tf-glesys.age" = terraform; + "tf-keycloak.age" = terraform; + "tvl-alerts-bot-telegram-token.age" = whitbyDefault; } diff --git a/ops/secrets/smtprelay.age b/ops/secrets/smtprelay.age index 166d2638e1..62fbaffadf 100644 --- a/ops/secrets/smtprelay.age +++ b/ops/secrets/smtprelay.age @@ -1,14 +1,16 @@ age-encryption.org/v1 --> ssh-ed25519 dcsaLw xcNp0GhoE++itBIAUi+0OIKlLENHGqklq02/YGQbH0A -34OgtbXFlhvjYJQI8zysSKdZiK7FBKn+lunvR1TWYrE --> ssh-ed25519 CpJBgQ RSWDjIWDt3nbVmvOusrkmy8K+A15Fph/ApbbBw5L7VA -mP+nnsLaVkeMAAMJ8nsBq4CAw66lVF87bmvGMmsT55A --> ssh-ed25519 aXKGcg YBiyBkcEWP+5m8fTHPWlGKTfyN92gfhJQkmAxJ3Zei0 -dnnJmSII9wmPJ1jL8s8COPjxoIip4HwWPpmK5jNNlcE --> ssh-ed25519 OkGqLg 1A5xPUHzoN+lXYlwKlbV42JCI1l361IyyllZ2HmxGCc -Mi8igtdp0yFEM6lfiT/PqtA6+KWwqS5EWkmtKS+JBWk --> ]3/,-grease Fj#1m Vq3REqK -+sNTJq8Vdns ---- y1d0IBqYwo/ABm9XOEQG26UA7NtTg+8mg/QLtPyMLwc -OูtตใXOW +]+ฬ7|D|n#ฟpPฅSทa#ๆ}v2bMปฮศ๖vจ?Vุ๛ผ ๙9ฒBหฑฅ}ฃvจM๛๏ -วUvMqค@ภI 5mาNx ฬว \ No newline at end of file +-> ssh-ed25519 dcsaLw CW2Lgm0tSWUDwKSNSX/aLkVzQ/QeEeQgU3NITpz2D0M +F7dA+zWdCz21s443bj9zCz6lBsRlFIxiG+l8CdbuPFk +-> ssh-ed25519 zcCuhA l8rsBoYDwhUB5stbeGXYTQ4Fz745ywXFCOQZn2cMBW0 +TycVcUZjR2TDv5DPC54+RwoU6Fj4QpRUJj1j0HM/JCE +-> ssh-ed25519 CpJBgQ CbwZO5LmSxd0HRYkf+lV+ymFcXSn/49GAPHG4l1I7gw +xSmab5+BnAZF/B0n32xX1qZPdHgfoEMGIuZqlpnISjc +-> ssh-ed25519 aXKGcg Tr+odf9p1RBrQK1guR6ToeN4wG1KLA3jwiPIkgyEjws +TaeCnjiRp8VZoMS5qs+OfVbBc6zudayD693h/eGvVOo +-> ssh-ed25519 OkGqLg Dmnsqz6PKzMd6w4t+l6+EWuia+stPwSEtu00KVuAojo +rZ/i1WJhrCM/ZQTAroRRSjzUVJw2UJlPUe1uHYqSscw +-> w!^Z-grease i86O2 i0.Rch +/zsRadAGYzAY6F/J5m6lMjmojkN7NbY3TbfQbA +--- /rQgwuY9SVGLKeUzY5P6c+sGQ1I1aw5cQxmO46QKDSQ + ้(`ฏฏคU ฌ๙,ใรcผ้|าPๆ็ ฟ9แ@& ซวgM฿ +CHโ3ik๗มฤ3#|ๅึgธMาึณAดgขAึ๚nZ๓วYโtจุ๛ฏฬ2นฑK2 Yฺ \ No newline at end of file diff --git a/ops/secrets/tf-buildkite.age b/ops/secrets/tf-buildkite.age new file mode 100644 index 0000000000..0cf6066fa6 --- /dev/null +++ b/ops/secrets/tf-buildkite.age Binary files differdiff --git a/ops/secrets/tf-glesys.age b/ops/secrets/tf-glesys.age index 53aa5e1acb..4e50454b62 100644 --- a/ops/secrets/tf-glesys.age +++ b/ops/secrets/tf-glesys.age Binary files differdiff --git a/ops/secrets/tf-keycloak.age b/ops/secrets/tf-keycloak.age index ddc477b21a..237b9377bd 100644 --- a/ops/secrets/tf-keycloak.age +++ b/ops/secrets/tf-keycloak.age Binary files differdiff --git a/ops/secrets/tvl-alerts-bot-telegram-token.age b/ops/secrets/tvl-alerts-bot-telegram-token.age new file mode 100644 index 0000000000..e897fedc03 --- /dev/null +++ b/ops/secrets/tvl-alerts-bot-telegram-token.age @@ -0,0 +1,15 @@ +age-encryption.org/v1 +-> ssh-ed25519 dcsaLw JGXCnhez0LnlUV8eOitxizmxw/gV+1taBRhNvwvVcms +qsRTOpifnoc0eorFjd4UlP7O3hkRR3KjDUcImASK0jY +-> ssh-ed25519 zcCuhA KUcyaHcmuqCGtJBzvc2UK17gRrjzuzIxll+TS9Q4nWs +CAJ19ClA9Tqj1fcYySq+K9gdZe6Uv0toZLnhlovr3tM +-> ssh-ed25519 CpJBgQ OAE+u9JuC6KoefjCOTj4NkQElZRe6/EEIAGBN/XelnU +M9MHlKxbEBJ+gACo2FiYqmm1cAoYW31+nP16qnVZ7Zw +-> ssh-ed25519 aXKGcg Ll6v6v5HpUIEuOzjpVsPMmPQMnNkmyB4fz/YwNXfCHU +MmFQy2WkKn5SM0bhe4NNe/lMnneKoOF+Ufq0t0QjNbw +-> ssh-ed25519 OkGqLg PS6KLwat1z2BSQ9sIKDaryVU39EJR+iiAaKSP/KSPk0 +qUQP2f4MFk83zQ9edlSNC8jwpJvmp2xhOysd8rnYzW4 +-> >NI-grease @mOcHT z|%,s- mw^c * +zu0M2pS6v3zehnLg +--- jltBYy9brAtpkEIqPoGmIVe3s5XnWtpa9EmuXlAf91c +tdX2-น"ฤำ#ฦ1ํn'\๘'{Dlw;Pึดะ@ฺฬ{๙฿B !yฃ+x๕หะํWตถฤB:wtูqph \ No newline at end of file diff --git a/ops/terraform/README.md b/ops/terraform/README.md new file mode 100644 index 0000000000..9ff6c23d47 --- /dev/null +++ b/ops/terraform/README.md @@ -0,0 +1,5 @@ +//ops/terraform +=============== + +This folder contains Terraform modules and other related +Terraform-tooling by TVL. diff --git a/ops/terraform/deploy-nixos/README.md b/ops/terraform/deploy-nixos/README.md new file mode 100644 index 0000000000..fd0bd1b442 --- /dev/null +++ b/ops/terraform/deploy-nixos/README.md @@ -0,0 +1,50 @@ +<!-- +SPDX-FileCopyrightText: 2023 The TVL Authors + +SPDX-License-Identifier: MIT +--> + +deploy-nixos +============ + +This is a Terraform module to deploy a NixOS system closure to a +remote machine. + +The system closure must be accessible by Nix-importing the repository +root and building a specific attribute +(e.g. `nix-build -A ops.machines.machine-name`). + +The target machine must be accessible normally over SSH, and an SSH +key must be used for access. + +Notably this module separates the evaluation of the system closure from building +and deploying it, and uses the closure's derivation hash to determine whether a +deploy is necessary. + +## Usage example: + +```terraform +module "deploy_somehost" { + source = "git::https://code.tvl.fyi/depot.git:/ops/terraform/deploy-nixos.git" + attrpath = "ops.nixos.somehost" + target_host = "somehost.tvl.su" + target_user = "someone" + target_user_ssh_key = tls_private_key.somehost.private_key_pem +} +``` + +## Future work + +Several things can be improved about this module, for example: + +* The repository root (relative to which the attribute path is evaluated) could + be made configurable. + +* The remote system closure could be discovered to restore remote system state + after manual deploys on the target (i.e. "stomping" of changes). + +More ideas and contributions are, of course, welcome. + +## Acknowledgements + +Development of this module was sponsored by [Resoptima](https://resoptima.com/). diff --git a/ops/terraform/deploy-nixos/main.tf b/ops/terraform/deploy-nixos/main.tf new file mode 100644 index 0000000000..50278b248e --- /dev/null +++ b/ops/terraform/deploy-nixos/main.tf @@ -0,0 +1,113 @@ +# SPDX-FileCopyrightText: 2023 The TVL Authors +# +# SPDX-License-Identifier: MIT + +# This module deploys a NixOS host by building a system closure +# located at the specified attribute in the current repository. +# +# The closure's derivation path is persisted in the Terraform state to +# determine after Nix evaluation whether the system closure has +# changed and needs to be built/deployed. +# +# The system configuration is then built (or substituted) on the +# machine that runs `terraform apply`, then copied and activated on +# the target machine using `nix-copy-closure`. + +variable "attrpath" { + description = "attribute set path pointing to the NixOS system closure" + type = string +} + +variable "target_host" { + description = "address (IP or hostname) at which the target is reachable" + type = string +} + +variable "entrypoint" { + description = <<EOT + Path to a .nix file (or directory containing `default.nix` file) + that provides the attrset specified in `closure`. + If unset, asks git for the root of the repository. + EOT + type = string + default = "" +} + +variable "target_user" { + description = "username on the target machine" + type = string +} + +variable "target_user_ssh_key" { + description = "SSH key to use for connecting to the target" + type = string + default = "" + sensitive = true +} + +variable "triggers" { + type = map(string) + description = "Triggers for deploy" + default = {} +} + +# Fetch the derivation hash for the NixOS system. +data "external" "nixos_system" { + program = ["${path.module}/nix-eval.sh"] + + query = { + attrpath = var.attrpath + entrypoint = var.entrypoint + } +} + +# Deploy the NixOS configuration if anything changed. +resource "null_resource" "nixos_deploy" { + connection { + type = "ssh" + host = var.target_host + user = var.target_user + private_key = var.target_user_ssh_key + } + + # 1. Wait for SSH to become available. + provisioner "remote-exec" { + inline = ["true"] + } + + # 2. Build NixOS system. + provisioner "local-exec" { + command = "nix-build ${data.external.nixos_system.result.drv} --no-out-link" + } + + # 3. Copy closure to the target. + provisioner "local-exec" { + command = "${path.module}/nixos-copy.sh" + + environment = { + SYSTEM_DRV = data.external.nixos_system.result.drv + TARGET_HOST = var.target_host + DEPLOY_KEY = var.target_user_ssh_key + TARGET_USER = var.target_user + } + } + + # 4. Activate closure on the target. + provisioner "remote-exec" { + inline = [ + "set -eu", + "SYSTEM=$(nix-build ${data.external.nixos_system.result.drv} --no-out-link)", + "sudo nix-env --profile /nix/var/nix/profiles/system --set $SYSTEM", + "sudo $SYSTEM/bin/switch-to-configuration switch", + ] + } + + triggers = merge({ + nixos_drv = data.external.nixos_system.result.drv + target_host = var.target_host + }, var.triggers) +} + +output "nixos_drv" { + value = data.external.nixos_system.result +} diff --git a/ops/terraform/deploy-nixos/nix-eval.sh b/ops/terraform/deploy-nixos/nix-eval.sh new file mode 100755 index 0000000000..65f534180b --- /dev/null +++ b/ops/terraform/deploy-nixos/nix-eval.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 The TVL Authors +# +# SPDX-License-Identifier: MIT +set -ueo pipefail + +# Evaluates a Nix expression. +# +# Receives input parameters as JSON from stdin. +# It expects a dict with the following keys: +# +# - `attrpath`: the attribute.path pointing to the expression to instantiate. +# Required. +# - `entrypoint`: the path to the Nix file to invoke. +# Optional. If omitted, will shell out to git to determine the repo root, +# and Nix will use `default.nix` in there. +# - `argstr_json`: A string JSON-encoding a map containing string keys and +# values which should be passed to Nix as `--argstr $key $value`. +# command line args. Optional. +# - `build`: A boolean (or string being "true" or "false") stating whether the +# expression should also be built/substituted on the machine executing this script. +# +# jq's @sh format takes care of escaping. +eval "$(jq -r '@sh "attrpath=\(.attrpath) && entrypoint=\(.entrypoint) && argstr=\((.argstr_json // "{}"|fromjson) | to_entries | map ("--argstr", .key, .value) | join(" ")) build=\(.build)"')" + +# Evaluate the expression. +[[ -z "$entrypoint" ]] && entrypoint=$(git rev-parse --show-toplevel) +# shellcheck disable=SC2086,SC2154 +drv=$(nix-instantiate -A "${attrpath}" "${entrypoint}" ${argstr}) + +# If `build` is set to true, invoke nix-build on the .drv. +# We need to swallow all stdout, to not garble the JSON printed later. +# shellcheck disable=SC2154 +if [ "${build}" == "true" ]; then + nix-build --no-out-link "${drv}" > /dev/null +fi + +# Determine the output path. +outPath=$(nix show-derivation "${drv}" | jq -r ".\"${drv}\".outputs.out.path") + +# Return a JSON back to stdout. +# It contains the following keys: +# +# - `drv`: the store path of the Derivation that has been instantiated. +# - `outPath`: the output store path. +jq -n --arg drv "$drv" --arg outPath "$outPath" '{"drv":$drv, "outPath":$outPath}' diff --git a/ops/terraform/deploy-nixos/nixos-copy.sh b/ops/terraform/deploy-nixos/nixos-copy.sh new file mode 100755 index 0000000000..6b843c3a49 --- /dev/null +++ b/ops/terraform/deploy-nixos/nixos-copy.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 The TVL Authors +# +# SPDX-License-Identifier: MIT + +# +# Copies a NixOS system to a target host, using the provided key, +# or whatever ambient key is configured if the key is not set. +set -ueo pipefail + +export NIX_SSHOPTS="\ + -o StrictHostKeyChecking=no\ + -o UserKnownHostsFile=/dev/null\ + -o GlobalKnownHostsFile=/dev/null" + +# If DEPLOY_KEY was passed, write it to $scratch/id_deploy +if [ -n "${DEPLOY_KEY-}" ]; then + scratch="$(mktemp -d)" + trap 'rm -rf -- "${scratch}"' EXIT + + echo -n "$DEPLOY_KEY" > $scratch/id_deploy + chmod 0600 $scratch/id_deploy + export NIX_SSHOPTS="$NIX_SSHOPTS -o IdentityFile=$scratch/id_deploy" +fi + +nix-copy-closure \ + --to ${TARGET_USER}@${TARGET_HOST} \ + ${SYSTEM_DRV} \ + --gzip \ + --include-outputs \ + --use-substitutes diff --git a/ops/users/default.nix b/ops/users/default.nix index 4f88e75b65..c54a681dce 100644 --- a/ops/users/default.nix +++ b/ops/users/default.nix @@ -2,6 +2,11 @@ [ { + username = "aaqaishtyaq"; + email = "aaqaishtyaq@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$IpWJeEYTYEsrgGBNQcnbWA$w4+gQmeJlhddeaHvmbpNa3hDVg1BkJESZSVAd2eSOs4"; + } + { username = "adisbladis"; email = "adisbladis@gmail.com"; password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$wdgoLRrUgZuz0Kin9YiNgQ$E40VIgzgpMpylZqkfByTKiWQnerupfuf7LDgOsU8tJA"; @@ -12,6 +17,11 @@ password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$8lefg7+8UPAEh9Ott8zH0A$7YuLRraTC1IgxTNTxFJF03AWmqBS3GX2+vfD4XVTrb0"; } { + username = "aspen"; + email = "root@gws.fyi"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$5NEYPJ19nDITK5sGr4bzhQ$Xzpzth6y4w+HGvioHiYgzqFiwMDx0B7HAh+PVbkRuuk"; + } + { username = "cschilling"; email = "christian.schilling.de@gmail.com"; password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$9VN3IS6ViW5FFbVKWOZI6Q$gZxuYAYk0Opq4E5i8cbcNjfznCQNc+RiP7Xv1CUnrQU"; @@ -52,9 +62,9 @@ password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$TrezbwIY5TKLnJiii0wafQ$K0S2p9I8tiqP907nkgoK6IbG9ia4IuDiylTcIs5pesw"; } { - username = "grfn"; - email = "grfn@gws.fyi"; - password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$5NEYPJ19nDITK5sGr4bzhQ$Xzpzth6y4w+HGvioHiYgzqFiwMDx0B7HAh+PVbkRuuk"; + username = "ghuntley"; + email = "ghuntley@ghuntley.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$ciCuQHeA7csqrFUv7+asgw$7GUC5fLJWWVoHP8DvpA+C1u4+iFdV2E311kwTFwGzaQ"; } { username = "htbf"; @@ -62,11 +72,31 @@ password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$2iVXQQfd26icaIguHJg/CQ$hA9ziqn7kQ06AV6uQxJCGXoG8f+LWmH+nVlk00a1n/c"; } { + username = "IslandUsurper"; + email = "lyle@menteeth.us"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$rNSsa8aYU4qvxeFnADgW1g$Zu6B6Al2usRRNfAKhWXzCAfiTfV3XQb0W6Op5TYN1oI"; + } + { username = "isomer"; email = "isomer@tvl.fyi"; password = "{SSHA}OhWQkPJgH1rRJqYIaMUbbKC4iLEzvCev"; } { + username = "j4m3s"; + email = "james.landrein@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$dMYmo+Uym9irtzAGXB2eNw$69OFcuqCqoLPBXKmmtYaQCquXximpyxsb2Kf8U7GdxM"; + } + { + username = "jfroche"; + email = "jfroche@pyxel.be"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$kA19gDabD1Fjy82olcmnsA$TTbkpAc0WYaA4DT2vc7+NAGXhC4Os1tPqZVpHFkzecE"; + } + { + username = "jrhahn"; + email = "mail.jhahn@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$giiu99hS7CzfsDZgxMNvKg$JiZZnFxOGHZRlUziYd3TkEiUplMz7Emy8fXfyLawPS0"; + } + { username = "kn"; email = "klemens@posteo.de"; password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$CoRZInysud4sduDoMjVOCw$/bdvAvyPO2DPxOcHlBiG2+rbTGF9XAcHUhPurxiIpZM"; @@ -77,6 +107,11 @@ password = "{SSHA}7a85VNhpFElFw+N5xcjgGmt4HnBsaGp4"; } { + username = "noteed"; + email = "noteed@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$rcLfF9xXysSx5sahVQLiMA$EgRgAVXn8+r2Csa3XgIHIEBf3hX4Y58pOHf2eDaBUnA"; + } + { username = "nyanotech"; email = "nyanotechnology@gmail.com"; password = "{SSHA}NIJ2RCRb1+Q4Bs63cyE91VZyiN47DG6y"; @@ -104,6 +139,11 @@ password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$o2OcfhfKOry+UrcmODyQCw$qloaQgoIRDESwaA3yqPxxy8sgLk3mrjYFBbF41elVrM"; } { + username = "talyz"; + email = "kim.lindberger@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$KYgHYsxX/DZDhnxdkzn1/w$L2Yyc2lYAREZP0FD3iX57MB6gzoOCcVmCGDxIsUGAgk"; + } + { username = "tazjin"; email = "tazjin@tvl.su"; password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$wOPEl9D3kSke//oLtbvqrg$j0npwwXgaXQ/emefKUwL59tH8hdmtzbgH2rQzWSmE2Y"; @@ -155,8 +195,38 @@ password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$NQdBVPNwh2ioDq9zWfMusA$2cABJGI8cU2JZirnVU5E5C28sTiePkiOPEAaqNUp/Fk"; } { - username = "zseri"; - email = "zseri.devel@ytrizja.de"; + username = "fogti"; + email = "fogti+devel@ytrizja.de"; password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$wVNkImXloXIkCycnecdFeA$ECAdGdNzUUEq9sFGsIl0jb7AALGsHE+ndWRn6ilSmdE"; } + { + username = "brainrake"; + email = "martonboros@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$f4/ewdyRBQbClL4KzqypHg$6Ql/xkmfIr60Qp1XMaFherqhh4cekLIbsi7KMM6izfE"; + } + { + username = "raitobezarius"; + email = "tvl@lahfa.xyz"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$3NZTBbF5dZssAHC/ktcA/Q$AZxHGG0ycNMOkIxC/ONYbyhNxC9hb6cpWvnsNH8LWZk"; + } + { + username = "hsjobeki"; + email = "hsjobeki@gmail.com"; + password = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$jez9eVa2v0BznIJMOhw+hw$wUbwCS+Bfcjjzr08saQE6NNTPWNXWWaxv+UtBCdYC2s"; + } + { + username = "totikom"; + email = "eugene.lomov@protonmail.com"; + password = "{ARGON2}$argon2id$v=19$m=19456,t=2,p=1$r/EsEGkqCcv8ccjQ84pX7Q$ebpWno7LI1RXkWKBjnkDHZM1gPuPj1LSMoFUsX0j6AU"; + } + { + username = "espes"; + email = "espes@pequalsnp.com"; + password = "{ARGON2}$argon2id$v=19$m=19456,t=2,p=1$eXeFrbNxuKn/JCpQr5VmxA$NtMNBceNg/JtqMfHk/qHxEHsEVsTWmHJbpq4ve/+XYg"; + } + { + username = "caralice"; + email = "tvl@alice-carroll.pet"; + password = "{ARGON2}$argon2id$v=19$m=19456,t=2,p=1$mt/0RzKw4RHxm7ybpMHP5Q$P/SDBMv5si9D98NFO/eZgh2+InlByqYxqAvQWhl+p0c"; + } ] diff --git a/ops/yandex-base-image/default.nix b/ops/yandex-base-image/default.nix new file mode 100644 index 0000000000..3dc4b8f589 --- /dev/null +++ b/ops/yandex-base-image/default.nix @@ -0,0 +1,9 @@ +# Base image for Yandex Cloud VMs. +{ depot, ... }: + +(depot.ops.nixos.nixosFor { + imports = [ + (depot.path.origSrc + ("/ops/modules/yandex-cloud.nix")) + (depot.path.origSrc + ("/ops/modules/tvl-users.nix")) + ]; +}).config.system.build.yandexCloudImage diff --git a/ops/yandex-cloud-rs/.gitignore b/ops/yandex-cloud-rs/.gitignore new file mode 100644 index 0000000000..ab3f21a96e --- /dev/null +++ b/ops/yandex-cloud-rs/.gitignore @@ -0,0 +1,5 @@ +target/ +result/ +# Ignore everything under src (except for lib.rs) +src/* +!src/lib.rs diff --git a/ops/yandex-cloud-rs/Cargo.lock b/ops/yandex-cloud-rs/Cargo.lock new file mode 100644 index 0000000000..0015d43106 --- /dev/null +++ b/ops/yandex-cloud-rs/Cargo.lock @@ -0,0 +1,1368 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "h2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.146" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +dependencies = [ + "autocfg", + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio" +version = "1.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "rustls-native-certs", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "yandex-cloud" +version = "2023.9.4" +dependencies = [ + "prost", + "prost-types", + "tokio", + "tonic", + "tonic-build", + "walkdir", +] diff --git a/ops/yandex-cloud-rs/Cargo.toml b/ops/yandex-cloud-rs/Cargo.toml new file mode 100644 index 0000000000..a72d11d59a --- /dev/null +++ b/ops/yandex-cloud-rs/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "yandex-cloud" +description = "Generated gRPC clients for the Yandex Cloud API" +license = "MIT" +version = "2023.9.4" +edition = "2021" +homepage = "https://cs.tvl.fyi/depot/-/tree/ops/yandex-cloud-rs" +repository = "https://code.tvl.fyi/depot.git:/ops/yandex-cloud-rs.git" +include = [ "/src", "README.md" ] + +[dependencies] +prost = "0.11" +prost-types = "0.11" + +[dependencies.tonic] +version = "0.9" +features = [ "tls", "tls-roots", "gzip" ] + +[build-dependencies] +tonic-build = "0.9" +walkdir = "2.3.3" + +[dev-dependencies] +tokio = "1.28" # check when updating tonic diff --git a/ops/yandex-cloud-rs/README.md b/ops/yandex-cloud-rs/README.md new file mode 100644 index 0000000000..a80fa83163 --- /dev/null +++ b/ops/yandex-cloud-rs/README.md @@ -0,0 +1,49 @@ +yandex-cloud-rs +=============== + +Client library for Yandex Cloud gRPC APIs, as published in their +[GitHub repository][repo]. + +Please see the [online documentation][docs] for user-facing +information, this README is intended for library developers. + +The source code of the library lives [in the TVL repository][code]. + +------------- + +In order to build this library, the gRPC API definitions need to be +fetched from GitHub. By default this is done by Nix (see +`default.nix`), which then injects the location of the API definitions +through the `YANDEX_CLOUD_PROTOS` environment variable. + +The actual code generation happens through the calls in `build.rs`. + +Releases of this library are done from *dirty* trees, meaning that the +version on crates.io should already contain all the generated code. In +order to do this, after bumping the version in `Cargo.toml` and the +API commit in `default.nix`, the following release procedure should be +used: + +``` +# Get rid of all generated source files +find src | grep '.rs$' | grep -v '^src/lib.rs$' | xargs rm + +# Get rid of all old artefacts +cargo clean + +# Verify that a clean build works as intended +cargo build + +# Verify that all documentation builds, and verify that it looks fine: +# +# - Is the version correct (current date)? +# - Are all the services included (i.e. not an accidental empty build)? +cargo doc --open + +# If everything looks fine, release: +cargo publish --allow-dirty +``` + +[repo]: https://github.com/yandex-cloud/cloudapi +[docs]: https://docs.rs/yandex-cloud/latest/yandex_cloud/ +[code]: https://cs.tvl.fyi/depot/-/tree/ops/yandex-cloud-rs diff --git a/ops/yandex-cloud-rs/build.rs b/ops/yandex-cloud-rs/build.rs new file mode 100644 index 0000000000..e9a96ef9df --- /dev/null +++ b/ops/yandex-cloud-rs/build.rs @@ -0,0 +1,43 @@ +use std::path::PathBuf; +use walkdir::{DirEntry, WalkDir}; + +fn proto_files(proto_dir: &str) -> Vec<PathBuf> { + let mut out = vec![]; + + fn is_proto(entry: &DirEntry) -> bool { + entry.file_type().is_file() + && entry + .path() + .extension() + .map(|e| e.to_string_lossy() == "proto") + .unwrap_or(false) + } + + for entry in WalkDir::new(format!("{}/yandex", proto_dir)).into_iter() { + let entry = entry.expect("failed to list proto files"); + + if is_proto(&entry) { + out.push(entry.into_path()) + } + } + + out +} + +fn main() { + if let Some(proto_dir) = option_env!("YANDEX_CLOUD_PROTOS") { + tonic_build::configure() + .build_client(true) + .build_server(false) + .out_dir("src/") + .include_file("includes.rs") + .compile( + &proto_files(proto_dir), + &[ + format!("{}", proto_dir), + format!("{}/third_party/googleapis", proto_dir), + ], + ) + .expect("failed to generate gRPC clients for Yandex Cloud") + } +} diff --git a/ops/yandex-cloud-rs/default.nix b/ops/yandex-cloud-rs/default.nix new file mode 100644 index 0000000000..6a8b263dee --- /dev/null +++ b/ops/yandex-cloud-rs/default.nix @@ -0,0 +1,22 @@ +{ depot, lib, pkgs, ... }: + +let + protoSrc = pkgs.fetchFromGitHub { + owner = "yandex-cloud"; + repo = "cloudapi"; + rev = "b4383be5ebe360bd946e49c8eaf647a73e9c44c0"; + sha256 = "0z4jyw2cylvyrq5ja8pcaqnlf6lf6ximj85hgjag6ckawayk1rzx"; + }; +in +pkgs.rustPlatform.buildRustPackage rec { + name = "yandex-cloud-rs"; + src = depot.third_party.gitignoreSource ./.; + cargoLock.lockFile = ./Cargo.lock; + YANDEX_CLOUD_PROTOS = "${protoSrc}"; + nativeBuildInputs = [ pkgs.protobuf ]; + + # The generated doc comments contain lots of things that rustc + # *thinks* are doctests, but are actually just garbage leading to + # compiler errors. + doCheck = false; +} diff --git a/ops/yandex-cloud-rs/examples/log-write.rs b/ops/yandex-cloud-rs/examples/log-write.rs new file mode 100644 index 0000000000..84d183421a --- /dev/null +++ b/ops/yandex-cloud-rs/examples/log-write.rs @@ -0,0 +1,37 @@ +//! This example uses the Yandex Cloud Logging API to write a log entry. + +use prost_types::Timestamp; +use tonic::transport::channel::Endpoint; +use yandex_cloud::yandex::cloud::logging::v1::destination::Destination; +use yandex_cloud::yandex::cloud::logging::v1::log_ingestion_service_client::LogIngestionServiceClient; +use yandex_cloud::yandex::cloud::logging::v1::Destination as OuterDestination; +use yandex_cloud::yandex::cloud::logging::v1::IncomingLogEntry; +use yandex_cloud::yandex::cloud::logging::v1::WriteRequest; +use yandex_cloud::AuthInterceptor; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let channel = Endpoint::from_static("https://ingester.logging.yandexcloud.net") + .connect() + .await?; + + let mut client = LogIngestionServiceClient::with_interceptor( + channel, + AuthInterceptor::new("YOUR_TOKEN_HERE"), + ); + + let request = WriteRequest { + destination: Some(OuterDestination { + destination: Some(Destination::LogGroupId("YOUR_LOG_GROUP_ID".into())), + }), + entries: vec![IncomingLogEntry { + timestamp: Some(Timestamp::date_time(2023, 04, 24, 23, 44, 30).unwrap()), + message: "test log message".into(), + ..Default::default() + }], + ..Default::default() + }; + + client.write(request).await.unwrap(); + Ok(()) +} diff --git a/ops/yandex-cloud-rs/src/lib.rs b/ops/yandex-cloud-rs/src/lib.rs new file mode 100644 index 0000000000..e7f79c75be --- /dev/null +++ b/ops/yandex-cloud-rs/src/lib.rs @@ -0,0 +1,108 @@ +//! This module provides low-level generated gRPC clients for the +//! Yandex Cloud APIs. +//! +//! The clients are generated using the [tonic][] and [prost][] +//! crates and have default configuration. +//! +//! Documentation present in the protos is retained into the generated +//! Rust types, but for detailed API information you should visit the +//! official Yandex Cloud Documentation pages: +//! +//! * [in English](https://cloud.yandex.com/en-ru/docs/overview/api) +//! * [in Russian](https://cloud.yandex.ru/docs/overview/api) +//! +//! The proto sources are available on the [Yandex Cloud GitHub][protos]. +//! +//! [tonic]: https://docs.rs/tonic/latest/tonic/ +//! [prost]: https://docs.rs/prost/latest/prost/ +//! [protos]: https://github.com/yandex-cloud/cloudapi +//! +//! The majority of user-facing structures can be found in the +//! [`yandex::cloud`] module. +//! +//! ## Usage +//! +//! Typically to use these APIs, you need to provide an authentication +//! credential and an endpoint to connect to. The full list of +//! Yandex's endpoints is [available online][endpoints] and you should +//! look up the service you plan to use and pick the correct endpoint +//! from the list. +//! +//! Authentication is done via an HTTP header using an IAM token, +//! which can be done in Tonic using [interceptors][]. The +//! [`AuthInterceptor`] provided by this crate can be used for that +//! purpose. +//! +//! Full usage examples are [available here][examples]. +//! +//! [endpoints]: https://cloud.yandex.com/en/docs/api-design-guide/concepts/endpoints +//! [interceptors]: https://docs.rs/tonic/latest/tonic/service/trait.Interceptor.html +//! [examples]: https://code.tvl.fyi/tree/ops/yandex-cloud-rs/examples + +use tonic::metadata::{Ascii, MetadataValue}; +use tonic::service::Interceptor; + +/// Publicly re-export some types from tonic which users might need +/// for implementing traits, or for naming concrete client types. +pub mod tonic_exports { + pub use tonic::service::interceptor::InterceptedService; + pub use tonic::transport::Channel; + pub use tonic::transport::Endpoint; + pub use tonic::Status; +} + +/// Helper trait for types or closures that can provide authentication +/// tokens for Yandex Cloud. +pub trait TokenProvider { + /// Fetch a currently valid authentication token for Yandex Cloud. + fn get_token<'a>(&'a mut self) -> Result<&'a str, tonic::Status>; +} + +impl TokenProvider for String { + fn get_token<'a>(&'a mut self) -> Result<&'a str, tonic::Status> { + Ok(self.as_str()) + } +} + +impl TokenProvider for &'static str { + fn get_token(&mut self) -> Result<&'static str, tonic::Status> { + Ok(*self) + } +} + +/// Interceptor for adding authentication headers to gRPC requests. +/// This is constructed with a callable that returns authentication +/// tokens. +/// +/// This callable is responsible for ensuring that the returned tokens +/// are valid at the given time, i.e. it should take care of +/// refreshing and so on. +pub struct AuthInterceptor<T: TokenProvider> { + token_provider: T, +} + +impl<T: TokenProvider> AuthInterceptor<T> { + pub fn new(token_provider: T) -> Self { + Self { token_provider } + } +} + +impl<T: TokenProvider> Interceptor for AuthInterceptor<T> { + fn call( + &mut self, + mut request: tonic::Request<()>, + ) -> Result<tonic::Request<()>, tonic::Status> { + let token: MetadataValue<Ascii> = format!("Bearer {}", self.token_provider.get_token()?) + .try_into() + .map_err(|_| { + tonic::Status::invalid_argument("authorization token contained invalid characters") + })?; + + request.metadata_mut().insert("authorization", token); + + Ok(request) + } +} + +// The rest of this file is generated by the build script at ../build.rs. +include!("includes.rs"); |