-
Notifications
You must be signed in to change notification settings - Fork 64
Store "last allocated IP" in BlueprintSledConfig
#9550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: john/blippy-sled-subnet-checks
Are you sure you want to change the base?
Store "last allocated IP" in BlueprintSledConfig
#9550
Conversation
| @@ -0,0 +1,59 @@ | |||
| -- Working with INET values in SQL is "fun". | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This migration query is quite horrifying IMO. I would love suggestions to make it less so.
common/src/address.rs
Outdated
| // to assume that addresses in this subnet are available. | ||
| pub const SLED_RESERVED_ADDRESSES: u16 = 32; | ||
|
|
||
| static_assertions::const_assert_eq!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this because I was concerned some places for the new field semantically wanted to use RSS_RESERVED_ADDRESSES and others were using SLED_RESERVED_ADDRESSES, and those mixed uses only worked if they both had the same value. With the switch to the newtype, I don't think that's true anymore (because it enforces a minimum, and if RSS_RESERVED_ADDRESSES went higher that would be fine), so I just took this back out.
| BlueprintSledConfig { | ||
| state: SledState::Active, | ||
| subnet: Ipv6Subnet::new(Ipv6Addr::LOCALHOST), | ||
| last_allocated_ip_subnet_offset: RSS_RESERVED_ADDRESSES, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is used in a lot of tests and the connection feels pretty non-obvious, I wonder if we could document this better somehow? Maybe another constant (TESTING_INITIAL_LAST_ALLOCATED_IP_SUBNET_OFFSET is maybe long...) with a comment about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't love another constant; we already have both RSS_RESERVED_ADDRESSES and SLED_RESERVED_ADDRESSES that both mean "the starting point of what Reconfigurator can use". I think we only have two because SLED_RESERVED_ADDRESSES is supposed to be for special IPs like "gz" and "switch zone", except RSS stomps all over it when assigning zone IPs.
I did briefly consider making this a newtype instead of a raw u16; then these could all be something like LastAllocatedIpOffset::initial(). Would that be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's too bad to have a third constant, in that they're all right near each other, documented together, and have static asserts. In fact, I wouldn't define this one to be 32 -- I'd define it as the value of that other constant explicitly. More like an alias.
A different type with a named constructor would also work. You don't need a separate type to make it a free function... but then it may as well be a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with a newtype in 27a7e0d - what do you think?
schema/crdb/dbinit.sql
Outdated
| subnet INET NOT NULL, | ||
|
|
||
| -- the last allocated IP within `subnet` used by the blueprint | ||
| last_allocated_ip_subnet_offset INT4 NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about a constraint between 0 and 65K?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 61502ee
| -- Final arg to `substr()`: this trims off the leading | ||
| -- `::` in the `::NNNN` we produced above. | ||
| 3), | ||
| -- Final args to `lpad()`: this ensure we always have | ||
| -- exactly 4 hex digits, left padding with 0 if needed. | ||
| 4, '0') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These seem aligned weirdly for the functions that they're arguments to?
| SELECT ('x' || | ||
| lpad( | ||
| substr( | ||
| -- bitwise & the IP with a /112 hostmask, which | ||
| -- squishes this IP down to the string '::NNNN', | ||
| -- where there will be 1-4 hex-valued X characters. | ||
| host(primary_service_ip & hostmask('::/112')), | ||
| -- Final arg to `substr()`: this trims off the leading | ||
| -- `::` in the `::NNNN` we produced above. | ||
| 3), | ||
| -- Final args to `lpad()`: this ensure we always have | ||
| -- exactly 4 hex digits, left padding with 0 if needed. | ||
| 4, '0') | ||
| -- We concatenated a literal 'x' prefix onto the front of the | ||
| -- `NNNN` value we just produced, which causes `bit(16)` to | ||
| -- interpret it as a 16-bit hex value (which it is!). Then | ||
| -- convert that bitstring into an integer. | ||
| )::bit(16)::int AS final_hextet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChatGPT tells me and I've casually confirmed that you can treat inet values as integers. So this works in dogfood to compute the offset for a given row:
root@[fd00:1122:3344:10b::3]:32221/omicron> select sled_id,primary_service_ip,((primary_service_ip & hostmask('::/112')) - '::'::inet) as offset from bp_omicron_zone where blueprint_id = '01155c9f-f124-41b1-aafd-0bc132d22598';
sled_id | primary_service_ip | offset
---------------------------------------+------------------------+---------
b886b58a-1e3f-4be1-b9f2-0c2e66c6bc88 | fd00:1122:3344:106::c | 12
0c7011f7-a4bf-4daf-90cc-1c2410103300 | fd00:1122:3344:2::1 | 1
f15774c1-b8e5-434f-a493-ec43f96cba06 | fd00:1122:3344:105::28 | 40
...
7b862eb6-7f50-4c2f-b9a6-0d12ac913d3c | fd00:1122:3344:101::45 | 69
f15774c1-b8e5-434f-a493-ec43f96cba06 | fd00:1122:3344:105::22 | 34
b886b58a-1e3f-4be1-b9f2-0c2e66c6bc88 | fd00:1122:3344:106::d | 13
(698 rows)
Assuming I did the right thing, maybe that could clean a bunch of this up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... yeah that's way better. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in 8d55a7d
This PR is large-ish but very boilerplatey. This is a prerequisite for the planner work to avoid reading expunged zones @smklein pointed out in #9521 (comment).
We add a
last_allocated_ip_subnet_offsetfield toBlueprintSledConfig, along with alast_allocated_ip()method that adds the offset to the sled's subnet. The rest is fallout of using that field:Staged on top of #9549.