forked from lix-project/lix-installer
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:
parent
1c103edb90
commit
60e5fff623
|
@ -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). |
|
| `is_ci` | Whether the installer is being used in CI (e.g. GitHub Actions). |
|
||||||
| `action` | Either `Install` or `Uninstall`. |
|
| `action` | Either `Install` or `Uninstall`. |
|
||||||
| `status` | One of `Success`, `Failure`, `Pending`, or `Cancelled`. |
|
| `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. |
|
| `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=""`.
|
To disable diagnostic reporting, set the diagnostics URL to an empty string by passing `--diagnostic-endpoint=""` or setting `NIX_INSTALLER_DIAGNOSTIC_ENDPOINT=""`.
|
||||||
|
|
63
flake.lock
63
flake.lock
|
@ -8,17 +8,15 @@
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693549280,
|
|
||||||
"narHash": "sha256-Se0ceJDij5fJvucwTpuDZyuQOWnJfP/hX3XzTBuAzXg=",
|
"narHash": "sha256-Se0ceJDij5fJvucwTpuDZyuQOWnJfP/hX3XzTBuAzXg=",
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "5b116a689c22ed2495c2b0f857539519a2951ce2",
|
"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": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"type": "tarball",
|
||||||
"repo": "fenix",
|
"url": "https://flakehub.com/f/nix-community/fenix/0.1.1584.tar.gz"
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
|
@ -37,6 +35,22 @@
|
||||||
"type": "github"
|
"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": {
|
"lowdown-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
@ -75,23 +89,21 @@
|
||||||
},
|
},
|
||||||
"nix": {
|
"nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat_2",
|
||||||
"lowdown-src": "lowdown-src",
|
"lowdown-src": "lowdown-src",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
"nixpkgs-regression": "nixpkgs-regression"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1674678482,
|
"narHash": "sha256-QMYAkdtU+g9HlZKtoJ+AI6TbWzzovKGnPZJHfZdclc8=",
|
||||||
"narHash": "sha256-MtVatZVsV+dtjdD4AC4bztrnDFas+WZYHzQMt41FwzU=",
|
"rev": "a212300a1d9f9c7b0daf19c00c87fc50480f54f4",
|
||||||
"owner": "nixos",
|
"revCount": 14727,
|
||||||
"repo": "nix",
|
"type": "tarball",
|
||||||
"rev": "435a16b5556f4171b4204a3f65c9dedf215f168c",
|
"url": "https://api.flakehub.com/f/pinned/NixOS/nix/2.17.0/018a1daf-2c87-7730-8fc0-4885c5d8eff7/source.tar.gz"
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"type": "tarball",
|
||||||
"ref": "2.13.2",
|
"url": "https://flakehub.com/f/NixOS/nix/2.17.0.tar.gz"
|
||||||
"repo": "nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
|
@ -128,18 +140,15 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693500674,
|
"narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=",
|
||||||
"narHash": "sha256-HDlg/j0Et+D8NWayNOsdvZrJ+nA4h3muXQxIMUlpDXo=",
|
"rev": "970a59bd19eff3752ce552935687100c46e820a5",
|
||||||
"owner": "nixos",
|
"revCount": 526521,
|
||||||
"repo": "nixpkgs",
|
"type": "tarball",
|
||||||
"rev": "da938d190e2335209df6806ddcb982634e51918c",
|
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.526521%2Brev-970a59bd19eff3752ce552935687100c46e820a5/018aabed-d05c-7478-b3db-bed61902efec/source.tar.gz"
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"type": "tarball",
|
||||||
"ref": "nixpkgs-unstable",
|
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.0.tar.gz"
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
description = "The Determinate Nix Installer";
|
description = "The Determinate Nix Installer";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.0.tar.gz";
|
||||||
|
|
||||||
fenix = {
|
fenix = {
|
||||||
url = "github:nix-community/fenix";
|
url = "https://flakehub.com/f/nix-community/fenix/0.1.1584.tar.gz";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
nix = {
|
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
|
# Omitting `inputs.nixpkgs.follows = "nixpkgs";` on purpose
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ impl Planner for MyPlanner {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(nix_installer::diagnostics::DiagnosticData::new(
|
Ok(nix_installer::diagnostics::DiagnosticData::new(
|
||||||
|
self.common.diagnostic_attribution.clone(),
|
||||||
self.common.diagnostic_endpoint.clone(),
|
self.common.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub enum DiagnosticAction {
|
||||||
/// A report sent to an endpoint
|
/// A report sent to an endpoint
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct DiagnosticReport {
|
pub struct DiagnosticReport {
|
||||||
|
pub attribution: Option<String>,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub planner: String,
|
pub planner: String,
|
||||||
pub configured_settings: Vec<String>,
|
pub configured_settings: Vec<String>,
|
||||||
|
@ -50,6 +51,7 @@ pub struct DiagnosticReport {
|
||||||
/// A preparation of data to be sent to the `endpoint`.
|
/// A preparation of data to be sent to the `endpoint`.
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Default)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Default)]
|
||||||
pub struct DiagnosticData {
|
pub struct DiagnosticData {
|
||||||
|
attribution: Option<String>,
|
||||||
version: String,
|
version: String,
|
||||||
planner: String,
|
planner: String,
|
||||||
configured_settings: Vec<String>,
|
configured_settings: Vec<String>,
|
||||||
|
@ -65,6 +67,7 @@ pub struct DiagnosticData {
|
||||||
|
|
||||||
impl DiagnosticData {
|
impl DiagnosticData {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
attribution: Option<String>,
|
||||||
endpoint: Option<String>,
|
endpoint: Option<String>,
|
||||||
planner: String,
|
planner: String,
|
||||||
configured_settings: Vec<String>,
|
configured_settings: Vec<String>,
|
||||||
|
@ -81,6 +84,7 @@ impl DiagnosticData {
|
||||||
let is_ci = is_ci::cached()
|
let is_ci = is_ci::cached()
|
||||||
|| std::env::var("NIX_INSTALLER_CI").unwrap_or_else(|_| "0".into()) == "1";
|
|| std::env::var("NIX_INSTALLER_CI").unwrap_or_else(|_| "0".into()) == "1";
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
attribution,
|
||||||
endpoint,
|
endpoint,
|
||||||
version: env!("CARGO_PKG_VERSION").into(),
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
planner,
|
planner,
|
||||||
|
@ -131,6 +135,7 @@ impl DiagnosticData {
|
||||||
|
|
||||||
pub fn report(&self, action: DiagnosticAction, status: DiagnosticStatus) -> DiagnosticReport {
|
pub fn report(&self, action: DiagnosticAction, status: DiagnosticStatus) -> DiagnosticReport {
|
||||||
let Self {
|
let Self {
|
||||||
|
attribution,
|
||||||
version,
|
version,
|
||||||
planner,
|
planner,
|
||||||
configured_settings,
|
configured_settings,
|
||||||
|
@ -143,6 +148,7 @@ impl DiagnosticData {
|
||||||
failure_chain,
|
failure_chain,
|
||||||
} = self;
|
} = self;
|
||||||
DiagnosticReport {
|
DiagnosticReport {
|
||||||
|
attribution: attribution.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
planner: planner.clone(),
|
planner: planner.clone(),
|
||||||
configured_settings: configured_settings.clone(),
|
configured_settings: configured_settings.clone(),
|
||||||
|
|
|
@ -129,6 +129,7 @@ impl Planner for Linux {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(crate::diagnostics::DiagnosticData::new(
|
Ok(crate::diagnostics::DiagnosticData::new(
|
||||||
|
self.settings.diagnostic_attribution.clone(),
|
||||||
self.settings.diagnostic_endpoint.clone(),
|
self.settings.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -210,6 +210,7 @@ impl Planner for Macos {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(crate::diagnostics::DiagnosticData::new(
|
Ok(crate::diagnostics::DiagnosticData::new(
|
||||||
|
self.settings.diagnostic_attribution.clone(),
|
||||||
self.settings.diagnostic_endpoint.clone(),
|
self.settings.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -72,6 +72,7 @@ impl Planner for MyPlanner {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<nix_installer::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(nix_installer::diagnostics::DiagnosticData::new(
|
Ok(nix_installer::diagnostics::DiagnosticData::new(
|
||||||
|
self.common.diagnostic_attribution.clone(),
|
||||||
self.common.diagnostic_endpoint.clone(),
|
self.common.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -262,6 +262,7 @@ impl Planner for Ostree {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(crate::diagnostics::DiagnosticData::new(
|
Ok(crate::diagnostics::DiagnosticData::new(
|
||||||
|
self.settings.diagnostic_attribution.clone(),
|
||||||
self.settings.diagnostic_endpoint.clone(),
|
self.settings.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -388,6 +388,7 @@ impl Planner for SteamDeck {
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
async fn diagnostic_data(&self) -> Result<crate::diagnostics::DiagnosticData, PlannerError> {
|
||||||
Ok(crate::diagnostics::DiagnosticData::new(
|
Ok(crate::diagnostics::DiagnosticData::new(
|
||||||
|
self.settings.diagnostic_attribution.clone(),
|
||||||
self.settings.diagnostic_endpoint.clone(),
|
self.settings.diagnostic_endpoint.clone(),
|
||||||
self.typetag_name().into(),
|
self.typetag_name().into(),
|
||||||
self.configured_settings()
|
self.configured_settings()
|
||||||
|
|
|
@ -205,12 +205,26 @@ pub struct CommonSettings {
|
||||||
)]
|
)]
|
||||||
pub force: bool,
|
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")]
|
#[cfg(feature = "diagnostics")]
|
||||||
/// The URL or file path for an installation diagnostic to be sent
|
/// The URL or file path for an installation diagnostic to be sent
|
||||||
///
|
///
|
||||||
/// Sample of the data sent:
|
/// Sample of the data sent:
|
||||||
///
|
///
|
||||||
/// {
|
/// {
|
||||||
|
/// "attribution": null,
|
||||||
/// "version": "0.4.0",
|
/// "version": "0.4.0",
|
||||||
/// "planner": "linux",
|
/// "planner": "linux",
|
||||||
/// "configured_settings": [ "modify_profile" ],
|
/// "configured_settings": [ "modify_profile" ],
|
||||||
|
@ -301,6 +315,8 @@ impl CommonSettings {
|
||||||
force: false,
|
force: false,
|
||||||
ssl_cert_file: Default::default(),
|
ssl_cert_file: Default::default(),
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
|
diagnostic_attribution: None,
|
||||||
|
#[cfg(feature = "diagnostics")]
|
||||||
diagnostic_endpoint: Some("https://install.determinate.systems/nix/diagnostic".into()),
|
diagnostic_endpoint: Some("https://install.determinate.systems/nix/diagnostic".into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -319,6 +335,8 @@ impl CommonSettings {
|
||||||
extra_conf,
|
extra_conf,
|
||||||
force,
|
force,
|
||||||
ssl_cert_file,
|
ssl_cert_file,
|
||||||
|
#[cfg(feature = "diagnostics")]
|
||||||
|
diagnostic_attribution: _,
|
||||||
#[cfg(feature = "diagnostics")]
|
#[cfg(feature = "diagnostics")]
|
||||||
diagnostic_endpoint,
|
diagnostic_endpoint,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
Loading…
Reference in a new issue