Skip to content

Commit

Permalink
error handling during initial data population needs work (#985)
Browse files Browse the repository at this point in the history
  • Loading branch information
davepacheco authored May 2, 2022
1 parent efd5610 commit d2bf956
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 54 deletions.
34 changes: 19 additions & 15 deletions nexus/src/db/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2326,16 +2326,17 @@ impl DataStore {
})
.collect::<Vec<UserBuiltin>>();

// TODO: This should probably be removed when we can switch
// "test-privileged" and "test-unprivileged" to normal silo users rather
// than built-in users.
debug!(opctx.log, "creating silo_user entries for built-in users");

for builtin_user in &builtin_users {
self.silo_user_create(SiloUser::new(
*SILO_ID,
builtin_user.identity.id, /* silo user id */
))
.await?;
}

info!(opctx.log, "created silo_user entries for built-in users");

debug!(opctx.log, "attempting to create built-in users");
Expand Down Expand Up @@ -2512,23 +2513,27 @@ impl DataStore {
})
}

// NOTE: This function is only used for testing and for initial population
// of built-in users as silo users. The error handling here assumes (1)
// that the caller expects no user input error from the database, and (2)
// that if a Silo user with the same id already exists in the database,
// that's not an error (it's assumed to be the same user).
pub async fn silo_user_create(
&self,
silo_user: SiloUser,
) -> CreateResult<SiloUser> {
) -> Result<(), Error> {
use db::schema::silo_user::dsl;

diesel::insert_into(dsl::silo_user)
let _ = diesel::insert_into(dsl::silo_user)
.values(silo_user)
.returning(SiloUser::as_returning())
.get_result_async(self.pool())
.on_conflict(dsl::id)
.do_nothing()
.execute_async(self.pool())
.await
.map_err(|e| {
Error::internal_error(&format!(
"error creating silo user: {:?}",
e
))
})
public_error_from_diesel_pool(e, ErrorHandler::Server)
})?;
Ok(())
}

/// Load built-in silos into the database
Expand Down Expand Up @@ -2983,7 +2988,7 @@ mod test {
datastore.session_create(&opctx, session.clone()).await.unwrap();

// Associate silo with user
let silo_user = datastore
datastore
.silo_user_create(SiloUser::new(*SILO_ID, silo_user_id))
.await
.unwrap();
Expand All @@ -2993,7 +2998,7 @@ mod test {
.fetch()
.await
.unwrap();
assert_eq!(silo_user.silo_id, db_silo_user.silo_id,);
assert_eq!(*SILO_ID, db_silo_user.silo_id);

// fetch the one we just created
let (.., fetched) = LookupPath::new(&opctx, &datastore)
Expand Down Expand Up @@ -3481,11 +3486,10 @@ mod test {

// Create a new Silo user so that we can lookup their keys.
let silo_user_id = Uuid::new_v4();
let silo_user = datastore
datastore
.silo_user_create(SiloUser::new(*SILO_ID, silo_user_id))
.await
.unwrap();
assert_eq!(silo_user.id(), silo_user_id);

let (.., authz_user) = LookupPath::new(&opctx, &datastore)
.silo_user_id(silo_user_id)
Expand Down
10 changes: 10 additions & 0 deletions nexus/src/db/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ impl Pool {
Pool { pool }
}

pub fn new_failfast(db_config: &DbConfig) -> Self {
let manager =
ConnectionManager::<DbConnection>::new(&db_config.url.url());
let pool = bb8::Builder::new()
.connection_customizer(Box::new(DisallowFullTableScans {}))
.connection_timeout(std::time::Duration::from_millis(1))
.build_unchecked(manager);
Pool { pool }
}

/// Returns a reference to the underlying pool.
pub fn pool(&self) -> &bb8::Pool<ConnectionManager<DbConnection>> {
&self.pool
Expand Down
4 changes: 2 additions & 2 deletions nexus/src/nexus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub trait TestInterfaces {
&self,
silo_id: Uuid,
silo_user_id: Uuid,
) -> CreateResult<SiloUser>;
) -> Result<(), Error>;
}

pub static BASE_ARTIFACT_DIR: &str = "/var/tmp/oxide_artifacts";
Expand Down Expand Up @@ -3980,7 +3980,7 @@ impl TestInterfaces for Nexus {
&self,
silo_id: Uuid,
silo_user_id: Uuid,
) -> CreateResult<SiloUser> {
) -> Result<(), Error> {
let silo_user = SiloUser::new(silo_id, silo_user_id);
Ok(self.db_datastore.silo_user_create(silo_user).await?)
}
Expand Down
Loading

0 comments on commit d2bf956

Please sign in to comment.