Skip to content

Commit

Permalink
Update links to API code about hard-coded allowed transitions (#2387)
Browse files Browse the repository at this point in the history
* update links to API code about hard-coded allowed transitions

* update links for instance reboot and stop

* middle ground: including rebooting in stop but not reboot list

* make sure disk is detachable in mock api
  • Loading branch information
david-crespo authored Aug 20, 2024
1 parent 6a005a0 commit f53bb38
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
39 changes: 29 additions & 10 deletions app/api/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,31 @@ export const genName = (...parts: [string, ...string[]]) => {
}

const instanceActions: Record<string, InstanceState[]> = {
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/src/app/instance.rs#L1960-L1963
start: ['stopped'],
reboot: ['running'],
stop: ['running', 'starting'],

// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/instance.rs#L865
delete: ['stopped', 'failed'],
// https://github.com/oxidecomputer/omicron/blob/9eff6a4/nexus/db-queries/src/db/datastore/disk.rs#L310-L314

// reboot and stop are kind of weird!
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/src/app/instance.rs#L790-L798
// https://github.com/oxidecomputer/propolis/blob/b278193/bin/propolis-server/src/lib/vm/request_queue.rs
// https://github.com/oxidecomputer/console/pull/2387#discussion_r1722368236
reboot: ['running'], // technically rebooting allowed but too weird to say it
stop: ['running', 'starting', 'rebooting'],

// NoVmm maps to to Stopped:
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-model/src/instance_state.rs#L55

// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/disk.rs#L323-L327
detachDisk: ['creating', 'stopped', 'failed'],
// https://github.com/oxidecomputer/omicron/blob/a7c7a67/nexus/db-queries/src/db/datastore/disk.rs#L183-L184
// only Creating and NoVmm
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/disk.rs#L185-L188
attachDisk: ['creating', 'stopped'],
// https://github.com/oxidecomputer/omicron/blob/8f0cbf0/nexus/db-queries/src/db/datastore/network_interface.rs#L482
// primary nic: https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/network_interface.rs#L761-L765
// non-primary: https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/network_interface.rs#L806-L810
updateNic: ['stopped'],
// https://github.com/oxidecomputer/omicron/blob/ebcc2acd/nexus/src/app/instance.rs#L1648-L1676
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/src/app/instance.rs#L1520-L1522
serialConsole: ['running', 'rebooting', 'migrating', 'repairing'],
}

Expand All @@ -123,12 +137,17 @@ export function instanceTransitioning({ runState }: Instance) {
}

const diskActions: Record<string, DiskState['state'][]> = {
// https://github.com/oxidecomputer/omicron/blob/4970c71e/nexus/db-queries/src/db/datastore/disk.rs#L578-L582.
delete: ['detached', 'creating', 'faulted'],
// TODO: link to API source
// this is a weird one because the list of states is dynamic and it includes
// 'creating' in the unwind of the disk create saga, but does not include
// 'creating' in the disk delete saga, which is what we care about
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/src/app/sagas/disk_delete.rs?plain=1#L110
delete: ['detached', 'faulted'],
// TODO: link to API source. It's hard to determine from the saga code what the rule is here.
snapshot: ['attached', 'detached'],
// https://github.com/oxidecomputer/omicron/blob/4970c71e/nexus/db-queries/src/db/datastore/disk.rs#L169-L172
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/disk.rs#L173-L176
attach: ['creating', 'detached'],
// https://github.com/oxidecomputer/omicron/blob/6dd9802/nexus/db-queries/src/db/datastore/disk.rs#L313-L314
detach: ['attached'],
}

export const diskCan = R.mapValues(diskActions, (states) => {
Expand Down
2 changes: 2 additions & 0 deletions app/pages/project/instances/instance/tabs/StorageTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export function StorageTab() {
},
},
{
// don't bother checking disk state: assume that if it is showing up
// in this list, it can be detached
label: 'Detach',
disabled: !instanceCan.detachDisk({ runState: instance.runState }) && (
<>
Expand Down
12 changes: 9 additions & 3 deletions mock-api/msw/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
} from '@oxide/api'

import { json, makeHandlers, type Json } from '~/api/__generated__/msw-handlers'
import { validateIp } from '~/util/str'
import { instanceCan } from '~/api/util'
import { commaSeries, validateIp } from '~/util/str'
import { GiB } from '~/util/units'

import { genCumulativeI64Data } from '../metrics'
Expand Down Expand Up @@ -557,10 +558,15 @@ export const handlers = makeHandlers({
},
instanceDiskDetach({ body, path, query: projectParams }) {
const instance = lookup.instance({ ...path, ...projectParams })
if (instance.run_state !== 'stopped') {
throw 'Cannot detach disk from instance that is not stopped'
if (!instanceCan.detachDisk({ runState: instance.run_state })) {
const states = commaSeries(instanceCan.detachDisk.states, 'or')
throw `Can only detach disk from instance that is ${states}`
}
const disk = lookup.disk({ ...projectParams, disk: body.disk })
if (!diskCan.detach(disk)) {
const states = commaSeries(diskCan.detach.states, 'or')
throw `Can only detach disk that is ${states}`
}
disk.state = { state: 'detached' }
return disk
},
Expand Down

0 comments on commit f53bb38

Please sign in to comment.