Support user-defined diagnostics attribution (#635)

* Switch to flakehub

* Diagnostics: support user-defined attribution.

Allows a user to specify an additional value to associate their diagnostics with that value. nix-installer doesn't generate or store these values, and most users have no need for it.

* Respond to feedback
This commit is contained in:
Graham Christensen 2023-09-20 14:23:23 -04:00 committed by GitHub
parent 1c103edb90
commit 60e5fff623
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 70 additions and 30 deletions

View file

@ -465,6 +465,7 @@ Here is a table of the [diagnostic data we collect][diagnosticdata]:
| `is_ci` | Whether the installer is being used in CI (e.g. GitHub Actions). |
| `action` | Either `Install` or `Uninstall`. |
| `status` | One of `Success`, `Failure`, `Pending`, or `Cancelled`. |
| `attribution` | Optionally defined by the user, associate the diagnostics of this run to the provided value. |
| `failure_chain` | A high level description of what the failure was, if any. For example: `Command("diskutil")` if the command `diskutil list` failed. |
To disable diagnostic reporting, set the diagnostics URL to an empty string by passing `--diagnostic-endpoint=""` or setting `NIX_INSTALLER_DIAGNOSTIC_ENDPOINT=""`.

View file

@ -8,17 +8,15 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1693549280,
"narHash": "sha256-Se0ceJDij5fJvucwTpuDZyuQOWnJfP/hX3XzTBuAzXg=",
"owner": "nix-community",
"repo": "fenix",
"rev": "5b116a689c22ed2495c2b0f857539519a2951ce2",
"type": "github"
"revCount": 1584,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/nix-community/fenix/0.1.1584%2Brev-5b116a689c22ed2495c2b0f857539519a2951ce2/018a4fce-4088-7e9a-bbab-7a39da8de2ff/source.tar.gz"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
"type": "tarball",
"url": "https://flakehub.com/f/nix-community/fenix/0.1.1584.tar.gz"
}
},
"flake-compat": {
@ -37,6 +35,22 @@
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
@ -75,23 +89,21 @@
},
"nix": {
"inputs": {
"flake-compat": "flake-compat_2",
"lowdown-src": "lowdown-src",
"nixpkgs": "nixpkgs",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1674678482,
"narHash": "sha256-MtVatZVsV+dtjdD4AC4bztrnDFas+WZYHzQMt41FwzU=",
"owner": "nixos",
"repo": "nix",
"rev": "435a16b5556f4171b4204a3f65c9dedf215f168c",
"type": "github"
"narHash": "sha256-QMYAkdtU+g9HlZKtoJ+AI6TbWzzovKGnPZJHfZdclc8=",
"rev": "a212300a1d9f9c7b0daf19c00c87fc50480f54f4",
"revCount": 14727,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/NixOS/nix/2.17.0/018a1daf-2c87-7730-8fc0-4885c5d8eff7/source.tar.gz"
},
"original": {
"owner": "nixos",
"ref": "2.13.2",
"repo": "nix",
"type": "github"
"type": "tarball",
"url": "https://flakehub.com/f/NixOS/nix/2.17.0.tar.gz"
}
},
"nixpkgs": {
@ -128,18 +140,15 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1693500674,
"narHash": "sha256-HDlg/j0Et+D8NWayNOsdvZrJ+nA4h3muXQxIMUlpDXo=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "da938d190e2335209df6806ddcb982634e51918c",
"type": "github"
"narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=",
"rev": "970a59bd19eff3752ce552935687100c46e820a5",
"revCount": 526521,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.526521%2Brev-970a59bd19eff3752ce552935687100c46e820a5/018aabed-d05c-7478-b3db-bed61902efec/source.tar.gz"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.0.tar.gz"
}
},
"root": {

View file

@ -2,10 +2,10 @@
description = "The Determinate Nix Installer";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.0.tar.gz";
fenix = {
url = "github:nix-community/fenix";
url = "https://flakehub.com/f/nix-community/fenix/0.1.1584.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
@ -15,7 +15,7 @@
};
nix = {
url = "github:nixos/nix/2.13.2";
url = "https://flakehub.com/f/NixOS/nix/2.17.0.tar.gz";
# Omitting `inputs.nixpkgs.follows = "nixpkgs";` on purpose
};

View file

@ -156,6 +156,7 @@ impl Planner for MyPlanner {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
Ok(nix_installer::diagnostics::DiagnosticData::new(
self.common.diagnostic_attribution.clone(),
self.common.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -34,6 +34,7 @@ pub enum DiagnosticAction {
/// A report sent to an endpoint
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct DiagnosticReport {
pub attribution: Option<String>,
pub version: String,
pub planner: String,
pub configured_settings: Vec<String>,
@ -50,6 +51,7 @@ pub struct DiagnosticReport {
/// A preparation of data to be sent to the `endpoint`.
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Default)]
pub struct DiagnosticData {
attribution: Option<String>,
version: String,
planner: String,
configured_settings: Vec<String>,
@ -65,6 +67,7 @@ pub struct DiagnosticData {
impl DiagnosticData {
pub fn new(
attribution: Option<String>,
endpoint: Option<String>,
planner: String,
configured_settings: Vec<String>,
@ -81,6 +84,7 @@ impl DiagnosticData {
let is_ci = is_ci::cached()
|| std::env::var("NIX_INSTALLER_CI").unwrap_or_else(|_| "0".into()) == "1";
Ok(Self {
attribution,
endpoint,
version: env!("CARGO_PKG_VERSION").into(),
planner,
@ -131,6 +135,7 @@ impl DiagnosticData {
pub fn report(&self, action: DiagnosticAction, status: DiagnosticStatus) -> DiagnosticReport {
let Self {
attribution,
version,
planner,
configured_settings,
@ -143,6 +148,7 @@ impl DiagnosticData {
failure_chain,
} = self;
DiagnosticReport {
attribution: attribution.clone(),
version: version.clone(),
planner: planner.clone(),
configured_settings: configured_settings.clone(),

View file

@ -129,6 +129,7 @@ impl Planner for Linux {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
Ok(crate::diagnostics::DiagnosticData::new(
self.settings.diagnostic_attribution.clone(),
self.settings.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -210,6 +210,7 @@ impl Planner for Macos {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
Ok(crate::diagnostics::DiagnosticData::new(
self.settings.diagnostic_attribution.clone(),
self.settings.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -72,6 +72,7 @@ impl Planner for MyPlanner {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
Ok(nix_installer::diagnostics::DiagnosticData::new(
self.common.diagnostic_attribution.clone(),
self.common.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -262,6 +262,7 @@ impl Planner for Ostree {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
Ok(crate::diagnostics::DiagnosticData::new(
self.settings.diagnostic_attribution.clone(),
self.settings.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -388,6 +388,7 @@ impl Planner for SteamDeck {
#[cfg(feature = "diagnostics")]
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
Ok(crate::diagnostics::DiagnosticData::new(
self.settings.diagnostic_attribution.clone(),
self.settings.diagnostic_endpoint.clone(),
self.typetag_name().into(),
self.configured_settings()

View file

@ -205,12 +205,26 @@ pub struct CommonSettings {
)]
pub force: bool,
#[cfg(feature = "diagnostics")]
/// Relate the install diagnostic to a specific value
#[cfg_attr(
feature = "cli",
clap(
long,
default_value = None,
env = "NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION",
global = true
)
)]
pub diagnostic_attribution: Option<String>,
#[cfg(feature = "diagnostics")]
/// The URL or file path for an installation diagnostic to be sent
///
/// Sample of the data sent:
///
/// {
/// "attribution": null,
/// "version": "0.4.0",
/// "planner": "linux",
/// "configured_settings": [ "modify_profile" ],
@ -301,6 +315,8 @@ impl CommonSettings {
force: false,
ssl_cert_file: Default::default(),
#[cfg(feature = "diagnostics")]
diagnostic_attribution: None,
#[cfg(feature = "diagnostics")]
diagnostic_endpoint: Some("https://install.determinate.systems/nix/diagnostic".into()),
})
}
@ -319,6 +335,8 @@ impl CommonSettings {
extra_conf,
force,
ssl_cert_file,
#[cfg(feature = "diagnostics")]
diagnostic_attribution: _,
#[cfg(feature = "diagnostics")]
diagnostic_endpoint,
} = self;