Merge pull request #103 from DeterminateSystems/fh-cache-under-determinate
Drop the assertion around the netrc under dnixd
This commit is contained in:
commit
7c6bd9387c
|
@ -1,5 +1,5 @@
|
||||||
use crate::env::Environment;
|
use crate::env::Environment;
|
||||||
use crate::error::{self, Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use attic::cache::CacheName;
|
use attic::cache::CacheName;
|
||||||
use attic::nix_store::{NixStore, StorePath};
|
use attic::nix_store::{NixStore, StorePath};
|
||||||
|
@ -32,28 +32,16 @@ pub struct State {
|
||||||
pub async fn init_cache(
|
pub async fn init_cache(
|
||||||
environment: Environment,
|
environment: Environment,
|
||||||
flakehub_api_server: &Url,
|
flakehub_api_server: &Url,
|
||||||
flakehub_api_server_netrc: &Path,
|
|
||||||
flakehub_cache_server: &Url,
|
flakehub_cache_server: &Url,
|
||||||
flakehub_flake_name: Option<String>,
|
flakehub_flake_name: Option<String>,
|
||||||
store: Arc<NixStore>,
|
store: Arc<NixStore>,
|
||||||
using_dnixd: bool,
|
auth_method: &super::FlakeHubAuthSource,
|
||||||
) -> Result<State> {
|
) -> Result<State> {
|
||||||
if using_dnixd {
|
|
||||||
let dnixd_state_dir: &Path = Path::new(&crate::DETERMINATE_STATE_DIR);
|
|
||||||
let expected_netrc_path = dnixd_state_dir.join("netrc");
|
|
||||||
if flakehub_api_server_netrc != expected_netrc_path {
|
|
||||||
let err = format!("flakehub-api-server-netrc was ({}), expected ({}) since determinate-nixd is available", flakehub_api_server_netrc.display(), expected_netrc_path.display());
|
|
||||||
return Err(error::Error::Config(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Parse netrc to get the credentials for api.flakehub.com.
|
// Parse netrc to get the credentials for api.flakehub.com.
|
||||||
let netrc = {
|
let netrc = {
|
||||||
let mut netrc_file = File::open(flakehub_api_server_netrc).await.map_err(|e| {
|
let netrc_path = auth_method.as_path_buf();
|
||||||
Error::Internal(format!(
|
let mut netrc_file = File::open(&netrc_path).await.map_err(|e| {
|
||||||
"Failed to open {}: {}",
|
Error::Internal(format!("Failed to open {}: {}", netrc_path.display(), e))
|
||||||
flakehub_api_server_netrc.display(),
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
let mut netrc_contents = String::new();
|
let mut netrc_contents = String::new();
|
||||||
netrc_file
|
netrc_file
|
||||||
|
@ -62,7 +50,7 @@ pub async fn init_cache(
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Internal(format!(
|
Error::Internal(format!(
|
||||||
"Failed to read {} contents: {}",
|
"Failed to read {} contents: {}",
|
||||||
flakehub_api_server_netrc.display(),
|
netrc_path.display(),
|
||||||
e
|
e
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
@ -99,7 +87,7 @@ pub async fn init_cache(
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !using_dnixd {
|
if let super::FlakeHubAuthSource::Netrc(netrc_path) = auth_method {
|
||||||
// Append an entry for the FlakeHub cache server to netrc.
|
// Append an entry for the FlakeHub cache server to netrc.
|
||||||
if !netrc
|
if !netrc
|
||||||
.machines
|
.machines
|
||||||
|
@ -109,12 +97,12 @@ pub async fn init_cache(
|
||||||
let mut netrc_file = tokio::fs::OpenOptions::new()
|
let mut netrc_file = tokio::fs::OpenOptions::new()
|
||||||
.create(false)
|
.create(false)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(flakehub_api_server_netrc)
|
.open(netrc_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Internal(format!(
|
Error::Internal(format!(
|
||||||
"Failed to open {} for appending: {}",
|
"Failed to open {} for appending: {}",
|
||||||
flakehub_api_server_netrc.display(),
|
netrc_path.display(),
|
||||||
e
|
e
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
@ -131,7 +119,7 @@ pub async fn init_cache(
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Internal(format!(
|
Error::Internal(format!(
|
||||||
"Failed to write credentials to {}: {}",
|
"Failed to write credentials to {}: {}",
|
||||||
flakehub_api_server_netrc.display(),
|
netrc_path.display(),
|
||||||
e
|
e
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
@ -149,23 +137,25 @@ pub async fn init_cache(
|
||||||
|
|
||||||
// Periodically refresh JWT in GitHub Actions environment
|
// Periodically refresh JWT in GitHub Actions environment
|
||||||
if environment.is_github_actions() {
|
if environment.is_github_actions() {
|
||||||
// NOTE(cole-h): This is a workaround -- at the time of writing, GitHub Actions JWTs are only
|
if let super::FlakeHubAuthSource::Netrc(path) = auth_method {
|
||||||
// valid for 5 minutes after being issued. FlakeHub uses these JWTs for authentication, which
|
// NOTE(cole-h): This is a workaround -- at the time of writing, GitHub Actions JWTs are only
|
||||||
// means that after those 5 minutes have passed and the token is expired, FlakeHub (and by
|
// valid for 5 minutes after being issued. FlakeHub uses these JWTs for authentication, which
|
||||||
// extension FlakeHub Cache) will no longer allow requests using this token. However, GitHub
|
// means that after those 5 minutes have passed and the token is expired, FlakeHub (and by
|
||||||
// gives us a way to repeatedly request new tokens, so we utilize that and refresh the token
|
// extension FlakeHub Cache) will no longer allow requests using this token. However, GitHub
|
||||||
// every 2 minutes (less than half of the lifetime of the token).
|
// gives us a way to repeatedly request new tokens, so we utilize that and refresh the token
|
||||||
let netrc_path_clone = flakehub_api_server_netrc.to_path_buf();
|
// every 2 minutes (less than half of the lifetime of the token).
|
||||||
let initial_github_jwt_clone = flakehub_password.clone();
|
let netrc_path_clone = path.to_path_buf();
|
||||||
let flakehub_cache_server_clone = flakehub_cache_server.to_string();
|
let initial_github_jwt_clone = flakehub_password.clone();
|
||||||
let api_clone = api.clone();
|
let flakehub_cache_server_clone = flakehub_cache_server.to_string();
|
||||||
|
let api_clone = api.clone();
|
||||||
|
|
||||||
tokio::task::spawn(refresh_github_actions_jwt_worker(
|
tokio::task::spawn(refresh_github_actions_jwt_worker(
|
||||||
netrc_path_clone,
|
netrc_path_clone,
|
||||||
initial_github_jwt_clone,
|
initial_github_jwt_clone,
|
||||||
flakehub_cache_server_clone,
|
flakehub_cache_server_clone,
|
||||||
api_clone,
|
api_clone,
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the cache UUID for this project.
|
// Get the cache UUID for this project.
|
||||||
|
|
|
@ -23,7 +23,7 @@ mod telemetry;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs::{self, create_dir_all};
|
use std::fs::create_dir_all;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -59,13 +59,6 @@ type State = Arc<StateInner>;
|
||||||
/// GitHub Actions-powered Nix binary cache
|
/// GitHub Actions-powered Nix binary cache
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// JSON file containing credentials.
|
|
||||||
///
|
|
||||||
/// If this is not specified, credentials will be loaded
|
|
||||||
/// from the environment.
|
|
||||||
#[arg(short = 'c', long)]
|
|
||||||
credentials_file: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// Address to listen on.
|
/// Address to listen on.
|
||||||
///
|
///
|
||||||
/// FIXME: IPv6
|
/// FIXME: IPv6
|
||||||
|
@ -193,6 +186,26 @@ struct StateInner {
|
||||||
original_paths: Option<Mutex<HashSet<PathBuf>>>,
|
original_paths: Option<Mutex<HashSet<PathBuf>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) enum FlakeHubAuthSource {
|
||||||
|
DeterminateNixd,
|
||||||
|
Netrc(PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlakeHubAuthSource {
|
||||||
|
pub(crate) fn as_path_buf(&self) -> PathBuf {
|
||||||
|
match &self {
|
||||||
|
Self::Netrc(path) => path.clone(),
|
||||||
|
Self::DeterminateNixd => {
|
||||||
|
let mut path = PathBuf::from(DETERMINATE_STATE_DIR);
|
||||||
|
path.push("netrc");
|
||||||
|
|
||||||
|
path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn main_cli() -> Result<()> {
|
async fn main_cli() -> Result<()> {
|
||||||
let guard = init_logging()?;
|
let guard = init_logging()?;
|
||||||
let _tracing_guard = guard.appender_guard;
|
let _tracing_guard = guard.appender_guard;
|
||||||
|
@ -231,20 +244,23 @@ async fn main_cli() -> Result<()> {
|
||||||
|
|
||||||
let narinfo_negative_cache = Arc::new(RwLock::new(HashSet::new()));
|
let narinfo_negative_cache = Arc::new(RwLock::new(HashSet::new()));
|
||||||
|
|
||||||
|
let auth_method: FlakeHubAuthSource = match (args.flakehub_api_server_netrc, dnixd_available) {
|
||||||
|
(None, true) => FlakeHubAuthSource::DeterminateNixd,
|
||||||
|
(Some(_), true) => {
|
||||||
|
tracing::info!("Ignoring the user-specified --flakehub-api-server-netrc, in favor of the determinate-nixd netrc");
|
||||||
|
FlakeHubAuthSource::DeterminateNixd
|
||||||
|
}
|
||||||
|
(Some(path), false) => FlakeHubAuthSource::Netrc(path),
|
||||||
|
(None, false) => {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"--flakehub-api-server-netrc is required when determinate-nixd is unavailable"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let flakehub_state = if args.use_flakehub {
|
let flakehub_state = if args.use_flakehub {
|
||||||
let flakehub_cache_server = args.flakehub_cache_server;
|
let flakehub_cache_server = args.flakehub_cache_server;
|
||||||
|
|
||||||
let flakehub_api_server_netrc = if dnixd_available {
|
|
||||||
let dnixd_netrc_path = PathBuf::from(DETERMINATE_STATE_DIR).join("netrc");
|
|
||||||
args.flakehub_api_server_netrc.unwrap_or(dnixd_netrc_path)
|
|
||||||
} else {
|
|
||||||
args.flakehub_api_server_netrc.ok_or_else(|| {
|
|
||||||
anyhow!(
|
|
||||||
"--flakehub-api-server-netrc is required when determinate-nixd is unavailable"
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
let flakehub_api_server = &args.flakehub_api_server;
|
let flakehub_api_server = &args.flakehub_api_server;
|
||||||
|
|
||||||
let flakehub_flake_name = args.flakehub_flake_name;
|
let flakehub_flake_name = args.flakehub_flake_name;
|
||||||
|
@ -252,22 +268,21 @@ async fn main_cli() -> Result<()> {
|
||||||
match flakehub::init_cache(
|
match flakehub::init_cache(
|
||||||
environment,
|
environment,
|
||||||
flakehub_api_server,
|
flakehub_api_server,
|
||||||
&flakehub_api_server_netrc,
|
|
||||||
&flakehub_cache_server,
|
&flakehub_cache_server,
|
||||||
flakehub_flake_name,
|
flakehub_flake_name,
|
||||||
store.clone(),
|
store.clone(),
|
||||||
dnixd_available,
|
&auth_method,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(state) => {
|
Ok(state) => {
|
||||||
if !dnixd_available {
|
if let FlakeHubAuthSource::Netrc(ref path) = auth_method {
|
||||||
nix_conf
|
nix_conf
|
||||||
.write_all(
|
.write_all(
|
||||||
format!(
|
format!(
|
||||||
"extra-substituters = {}?trusted=1\nnetrc-file = {}\n",
|
"extra-substituters = {}?trusted=1\nnetrc-file = {}\n",
|
||||||
&flakehub_cache_server,
|
&flakehub_cache_server,
|
||||||
flakehub_api_server_netrc.display()
|
path.display()
|
||||||
)
|
)
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
|
@ -290,26 +305,10 @@ async fn main_cli() -> Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let gha_cache = if args.use_gha_cache {
|
let gha_cache = if args.use_gha_cache {
|
||||||
let credentials = if let Some(credentials_file) = &args.credentials_file {
|
tracing::info!("Loading credentials from environment");
|
||||||
tracing::info!("Loading credentials from {:?}", credentials_file);
|
|
||||||
let bytes = fs::read(credentials_file).with_context(|| {
|
|
||||||
format!(
|
|
||||||
"Failed to read credentials file '{}'",
|
|
||||||
credentials_file.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
serde_json::from_slice(&bytes).with_context(|| {
|
let credentials = Credentials::load_from_env()
|
||||||
format!(
|
.with_context(|| "Failed to load credentials from environment (see README.md)")?;
|
||||||
"Failed to deserialize credentials file '{}'",
|
|
||||||
credentials_file.display()
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
} else {
|
|
||||||
tracing::info!("Loading credentials from environment");
|
|
||||||
Credentials::load_from_env()
|
|
||||||
.with_context(|| "Failed to load credentials from environment (see README.md)")?
|
|
||||||
};
|
|
||||||
|
|
||||||
let gha_cache = gha::GhaCache::new(
|
let gha_cache = gha::GhaCache::new(
|
||||||
credentials,
|
credentials,
|
||||||
|
|
Loading…
Reference in a new issue