Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
b78ff98
[nexus] Split Nexus configuration (package vs runtime)
smklein Jun 8, 2022
cca5795
Merge branch 'main' into nexus-argsplit
smklein Jun 8, 2022
fccc15c
Ensure postgres config was just a rename
smklein Jun 8, 2022
2443215
Merge branch 'main' into nexus-argsplit
smklein Jun 8, 2022
a077bd4
review feedback
smklein Jun 8, 2022
f91cea1
Merge branch 'main' into nexus-argsplit
smklein Jun 8, 2022
d16eda2
DNS client
smklein Jun 8, 2022
8db30b7
Add concurrency
smklein Jun 8, 2022
3a0c6ba
comment
smklein Jun 8, 2022
33b3e02
fmt
smklein Jun 8, 2022
3eb57dc
lockfile
smklein Jun 8, 2022
39aa9ff
Merge branch 'main' into nexus-argsplit
smklein Jun 15, 2022
dd04a67
s/runtime/deployment
smklein Jun 15, 2022
63b6379
Merge branch 'nexus-argsplit' into dns-client
smklein Jun 15, 2022
e1dc941
[nexus][sled-agent] Generate rack ID in RSS, plumb it through Nexus
smklein Jun 15, 2022
a4309ac
need rack_id in the test config too
smklein Jun 15, 2022
02f592d
Merge branch 'main' into nexus-argsplit
smklein Jun 20, 2022
ff2d7b9
[internal-dns] Avoid 'picking ports'
smklein Jun 20, 2022
a261155
Merge branch 'nexus-argsplit' into dns-client
smklein Jun 20, 2022
6cc7864
Merge branch 'fix-internal-dns-api' into dns-client
smklein Jun 20, 2022
2a035a5
Changes from rss-handoff
smklein Jun 20, 2022
e84faaf
Merge branch 'dns-client' into rack-id
smklein Jun 20, 2022
c3a49bb
[nexus] Add a new user for background tasks
smklein Jun 20, 2022
5440cbf
[rss] Set DNS records during RSS initialization
smklein Jun 20, 2022
3e1495f
[oximeter] Rely on dynamically set arguments within Oximeter
smklein Jun 20, 2022
5d330bc
fix import
smklein Jun 20, 2022
130ffa0
okay not THAT dynamic just yet
smklein Jun 20, 2022
7ceb8fa
[nexus] Populate rack during initialization
smklein Jun 21, 2022
5188880
[nexus] Add tests for rack endpoints
smklein Jun 21, 2022
1e0b8fe
Merge branch 'main' into nexus-argsplit
smklein Jun 21, 2022
da4a2b8
Merge branch 'nexus-argsplit' into fix-internal-dns-api
smklein Jun 21, 2022
d7b10cf
Merge branch 'fix-internal-dns-api' into dns-client
smklein Jun 21, 2022
bb9a3af
Merge branch 'dns-client' into rack-id
smklein Jun 21, 2022
fed4a3d
Merge branch 'rack-id' into background-work-user
smklein Jun 21, 2022
6f75649
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 21, 2022
c7ea709
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 21, 2022
5c00d54
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 21, 2022
4df23c2
jgallagher feedback
smklein Jun 21, 2022
71f3aac
Merge branch 'fix-internal-dns-api' into dns-client
smklein Jun 21, 2022
5556d5f
Patch tests
smklein Jun 21, 2022
226fd94
Merge branch 'fix-internal-dns-api' into dns-client
smklein Jun 21, 2022
6126e41
merge
smklein Jun 21, 2022
b01bffd
Merge branch 'dns-client' into rack-id
smklein Jun 21, 2022
d09c8d5
Merge branch 'rack-id' into background-work-user
smklein Jun 21, 2022
d764d2a
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 21, 2022
ad0ddce
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 21, 2022
d4cbe41
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 21, 2022
e4f434f
Merge branch 'main' into nexus-argsplit
smklein Jun 21, 2022
62fccb2
Merge branch 'nexus-argsplit' into fix-internal-dns-api
smklein Jun 21, 2022
1905985
Merge branch 'fix-internal-dns-api' into dns-client
smklein Jun 21, 2022
1a0b61b
Merge branch 'dns-client' into rack-id
smklein Jun 21, 2022
f5ee394
Merge branch 'rack-id' into background-work-user
smklein Jun 21, 2022
588fe8f
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 21, 2022
fed243d
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 21, 2022
a6b5240
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 21, 2022
d6e3c9d
background-work -> service-balancer
smklein Jun 22, 2022
fd8286a
Merge branch 'main' into dns-client
smklein Jun 22, 2022
bed0269
Merge branch 'dns-client' into rack-id
smklein Jun 22, 2022
ef6072d
Merge branch 'rack-id' into background-work-user
smklein Jun 22, 2022
4c53d4a
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 22, 2022
05da5db
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 22, 2022
83eb272
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 22, 2022
b959c39
Merge branch 'main' into dns-client
smklein Jun 23, 2022
470da8b
review feedback
smklein Jun 24, 2022
a23a036
Merge branch 'dns-client' into rack-id
smklein Jun 24, 2022
56d2e1c
Merge branch 'rack-id' into background-work-user
smklein Jun 24, 2022
155fd10
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 24, 2022
b5916e0
merge
smklein Jun 24, 2022
3bd9f7a
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 24, 2022
b8a3ffc
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 24, 2022
13b9825
Merge branch 'main' into dns-client
smklein Jun 24, 2022
e1a912f
Merge branch 'dns-client' into rack-id
smklein Jun 24, 2022
28d87f5
Merge branch 'rack-id' into background-work-user
smklein Jun 24, 2022
f7c897a
Merge branch 'background-work-user' into rss-set-dns
smklein Jun 24, 2022
bf687b9
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 24, 2022
40a2433
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 24, 2022
364efb3
rack ID to test interfaces
smklein Jun 24, 2022
f1b6e20
Merge branch 'main' into rss-set-dns
smklein Jun 26, 2022
756114d
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 26, 2022
ba5275f
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 26, 2022
debe96d
Merge branch 'main' into rss-set-dns
smklein Jun 26, 2022
b24dd68
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 26, 2022
a7bd0d5
Merge branch 'main' into rss-set-dns
smklein Jun 27, 2022
ea84b79
Merge branch 'rss-set-dns' into oximeter-resolves-nexus-address
smklein Jun 27, 2022
91656e8
Merge branch 'oximeter-resolves-nexus-address' into rack-populate
smklein Jun 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions nexus/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::config;
use crate::context::OpContext;
use crate::db;
use crate::populate::populate_start;
use crate::populate::PopulateArgs;
use crate::populate::PopulateStatus;
use crate::saga_interface::SagaContext;
use anyhow::anyhow;
Expand Down Expand Up @@ -55,15 +56,12 @@ pub struct Nexus {
/// uuid for this nexus instance.
id: Uuid,

/// uuid for this rack (TODO should also be in persistent storage)
/// uuid for this rack
rack_id: Uuid,

/// general server log
log: Logger,

/// cached rack identity metadata
api_rack_identity: db::model::RackIdentity,

/// persistent storage for resources in the control plane
db_datastore: Arc<db::DataStore>,

Expand Down Expand Up @@ -140,14 +138,18 @@ impl Nexus {
authn::Context::internal_db_init(),
Arc::clone(&db_datastore),
);
let populate_status =
populate_start(populate_ctx, Arc::clone(&db_datastore));

let populate_args = PopulateArgs::new(rack_id);
let populate_status = populate_start(
populate_ctx,
Arc::clone(&db_datastore),
populate_args,
);

let nexus = Nexus {
id: config.deployment.id,
rack_id,
log: log.new(o!()),
api_rack_identity: db::model::RackIdentity::new(rack_id),
db_datastore: Arc::clone(&db_datastore),
authz: Arc::clone(&authz),
sec_client: Arc::clone(&sec_client),
Expand Down
56 changes: 22 additions & 34 deletions nexus/src/app/rack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,47 @@
use crate::authz;
use crate::context::OpContext;
use crate::db;
use crate::db::lookup::LookupPath;
use crate::internal_api::params::ServicePutRequest;
use futures::future::ready;
use futures::StreamExt;
use omicron_common::api::external::DataPageParams;
use omicron_common::api::external::Error;
use omicron_common::api::external::ListResult;
use omicron_common::api::external::ListResultVec;
use omicron_common::api::external::LookupResult;
use omicron_common::api::external::LookupType;
use omicron_common::api::external::ResourceType;
use uuid::Uuid;

impl super::Nexus {
pub(crate) fn as_rack(&self) -> db::model::Rack {
db::model::Rack {
identity: self.api_rack_identity.clone(),
initialized: true,
tuf_base_url: None,
}
}

pub async fn racks_list(
&self,
opctx: &OpContext,
pagparams: &DataPageParams<'_, Uuid>,
) -> ListResult<db::model::Rack> {
opctx.authorize(authz::Action::Read, &authz::FLEET).await?;

if let Some(marker) = pagparams.marker {
if *marker >= self.rack_id {
return Ok(futures::stream::empty().boxed());
}
}

Ok(futures::stream::once(ready(Ok(self.as_rack()))).boxed())
) -> ListResultVec<db::model::Rack> {
self.db_datastore.rack_list(&opctx, pagparams).await
}

pub async fn rack_lookup(
&self,
opctx: &OpContext,
rack_id: &Uuid,
) -> LookupResult<db::model::Rack> {
let authz_rack = authz::Rack::new(
authz::FLEET,
*rack_id,
LookupType::ById(*rack_id),
);
opctx.authorize(authz::Action::Read, &authz_rack).await?;
let (.., db_rack) = LookupPath::new(opctx, &self.db_datastore)
.rack_id(*rack_id)
.fetch()
.await?;
Ok(db_rack)
}

if *rack_id == self.rack_id {
Ok(self.as_rack())
} else {
Err(Error::not_found_by_id(ResourceType::Rack, rack_id))
}
/// Ensures that a rack exists in the DB.
///
/// If the rack already exists, this function is a no-op.
pub async fn rack_insert(
&self,
opctx: &OpContext,
rack_id: Uuid,
) -> Result<(), Error> {
self.datastore()
.rack_insert(opctx, &db::model::Rack::new(rack_id))
.await?;
Ok(())
}

/// Marks the rack as initialized with a set of services.
Expand Down
7 changes: 7 additions & 0 deletions nexus/src/app/test_interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use uuid::Uuid;
/// Exposes additional [`Nexus`] interfaces for use by the test suite
#[async_trait]
pub trait TestInterfaces {
/// Access the Rack ID of the currently executing Nexus.
fn rack_id(&self) -> Uuid;

/// Returns the SledAgentClient for an Instance from its id. We may also
/// want to split this up into instance_lookup_by_id() and instance_sled(),
/// but after all it's a test suite special to begin with.
Expand All @@ -39,6 +42,10 @@ pub trait TestInterfaces {

#[async_trait]
impl TestInterfaces for super::Nexus {
fn rack_id(&self) -> Uuid {
self.rack_id
}

async fn instance_sled_by_id(
&self,
id: &Uuid,
Expand Down
25 changes: 16 additions & 9 deletions nexus/src/app/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ use tokio::io::AsyncWriteExt;
static BASE_ARTIFACT_DIR: &str = "/var/tmp/oxide_artifacts";

impl super::Nexus {
fn tuf_base_url(&self) -> Option<String> {
self.updates_config.as_ref().map(|c| {
let rack = self.as_rack();
async fn tuf_base_url(
&self,
opctx: &OpContext,
) -> Result<Option<String>, Error> {
let rack = self.rack_lookup(opctx, &self.rack_id).await?;

Ok(self.updates_config.as_ref().map(|c| {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this predates this change, but it seems weird to me that the updates_url is hanging off the rack object. I think we want to avoid Omicron assuming that "the rack" == "the whole control plane". But since this was already like this, maybe just file a separate issue?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I understand correctly for this issue, what object should the updates_url be attached to?

I thought the intent back in #717 was to allow this to be toggled at a rack-wide level (all sleds on a rack must use the same update source, effectively).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect us to have global-looking config in the database for something like that. I'm thinking of the multi-rack case. Shouldn't all Sleds in one instance of Omicron use the same updates URL? Different racks in the same AZ or even Region probably shouldn't be using different updates URLs.

Of course we're deferring multi-rack for the MVP. But conflating "rack" with "the whole control plane" now will make it a lot harder to untangle later what's really rack-level vs. control-plane-level. And it doesn't seem much harder to just have a table of global config.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rack.tuf_base_url.unwrap_or_else(|| c.default_base_url.clone())
})
}))
}

pub async fn updates_refresh_metadata(
Expand All @@ -42,10 +46,11 @@ impl super::Nexus {
message: "updates system not configured".into(),
}
})?;
let base_url =
self.tuf_base_url().ok_or_else(|| Error::InvalidRequest {
let base_url = self.tuf_base_url(opctx).await?.ok_or_else(|| {
Error::InvalidRequest {
message: "updates system not configured".into(),
})?;
}
})?;
let trusted_root = tokio::fs::read(&updates_config.trusted_root)
.await
.map_err(|e| Error::InternalError {
Expand Down Expand Up @@ -129,8 +134,10 @@ impl super::Nexus {
artifact: UpdateArtifact,
) -> Result<Vec<u8>, Error> {
let mut base_url =
self.tuf_base_url().ok_or_else(|| Error::InvalidRequest {
message: "updates system not configured".into(),
self.tuf_base_url(opctx).await?.ok_or_else(|| {
Error::InvalidRequest {
message: "updates system not configured".into(),
}
})?;
if !base_url.ends_with('/') {
base_url.push('/');
Expand Down
14 changes: 14 additions & 0 deletions nexus/src/db/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ impl DataStore {
Ok(self.pool.pool())
}

pub async fn rack_list(
&self,
opctx: &OpContext,
pagparams: &DataPageParams<'_, Uuid>,
) -> ListResultVec<Rack> {
opctx.authorize(authz::Action::Read, &authz::FLEET).await?;
use db::schema::rack::dsl;
paginated(dsl::rack, dsl::id, pagparams)
.select(Rack::as_select())
.load_async(self.pool_authorized(opctx).await?)
.await
.map_err(|e| public_error_from_diesel_pool(e, ErrorHandler::Server))
}

/// Stores a new rack in the database.
///
/// This function is a no-op if the rack already exists.
Expand Down
10 changes: 6 additions & 4 deletions nexus/src/external_api/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3252,13 +3252,15 @@ async fn hardware_racks_get(
let query = query_params.into_inner();
let handler = async {
let opctx = OpContext::for_external_api(&rqctx).await?;
let rack_stream = nexus
let racks = nexus
.racks_list(&opctx, &data_page_params_for(&rqctx, &query)?)
.await?;
let view_list = to_list::<db::model::Rack, Rack>(rack_stream).await;
.await?
.into_iter()
.map(|r| r.into())
.collect();
Ok(HttpResponseOk(ScanById::results_page(
&query,
view_list,
racks,
&|_, rack: &Rack| rack.identity.id,
)?))
};
Expand Down
Loading