parent
837dc3028d
commit
9e9a81a5ce
27 changed files with 255 additions and 512 deletions
@ -1,93 +0,0 @@ |
||||
import { useContext } from 'react'; |
||||
|
||||
import { Box } from '@mui/material'; |
||||
import { styled } from '@mui/material/styles'; |
||||
import { BodyText, HeaderText } from '../Text'; |
||||
import { Panel, InnerPanel, InnerPanelHeader } from '../Panels'; |
||||
import SharedStorageHost from './FileSystemsHost'; |
||||
import periodicFetch from '../../lib/fetchers/periodicFetch'; |
||||
import { AnvilContext } from '../AnvilContext'; |
||||
import Spinner from '../Spinner'; |
||||
import { LARGE_MOBILE_BREAKPOINT } from '../../lib/consts/DEFAULT_THEME'; |
||||
|
||||
const PREFIX = 'SharedStorage'; |
||||
|
||||
const classes = { |
||||
header: `${PREFIX}-header`, |
||||
root: `${PREFIX}-root`, |
||||
}; |
||||
|
||||
const StyledDiv = styled('div')(({ theme }) => ({ |
||||
[`& .${classes.header}`]: { |
||||
paddingTop: '.1em', |
||||
paddingRight: '.7em', |
||||
}, |
||||
|
||||
[`& .${classes.root}`]: { |
||||
overflow: 'auto', |
||||
height: '78vh', |
||||
paddingLeft: '.3em', |
||||
[theme.breakpoints.down(LARGE_MOBILE_BREAKPOINT)]: { |
||||
height: '100%', |
||||
}, |
||||
}, |
||||
})); |
||||
|
||||
const SharedStorage = ({ anvil }: { anvil: AnvilListItem[] }): JSX.Element => { |
||||
const { uuid } = useContext(AnvilContext); |
||||
const { data, isLoading } = periodicFetch<{ |
||||
file_systems: AnvilFileSystem[]; |
||||
}>( |
||||
`${process.env.NEXT_PUBLIC_API_URL}/get_shared_storage?anvil_uuid=${uuid}`, |
||||
); |
||||
return ( |
||||
<Panel> |
||||
<StyledDiv> |
||||
<HeaderText text="Shared Storage" /> |
||||
{!isLoading ? ( |
||||
<Box className={classes.root}> |
||||
{data?.file_systems && |
||||
data.file_systems.map( |
||||
(fs: AnvilFileSystem): JSX.Element => ( |
||||
<InnerPanel key={fs.mount_point}> |
||||
<InnerPanelHeader> |
||||
<Box |
||||
display="flex" |
||||
width="100%" |
||||
className={classes.header} |
||||
> |
||||
<Box> |
||||
<BodyText text={fs.mount_point} /> |
||||
</Box> |
||||
</Box> |
||||
</InnerPanelHeader> |
||||
{fs?.hosts && |
||||
fs.hosts.map( |
||||
( |
||||
host: AnvilFileSystemHost, |
||||
index: number, |
||||
): JSX.Element => ( |
||||
<SharedStorageHost |
||||
host={{ |
||||
...host, |
||||
...anvil[ |
||||
anvil.findIndex((a) => a.anvil_uuid === uuid) |
||||
].hosts[index], |
||||
}} |
||||
key={fs.hosts[index].free} |
||||
/> |
||||
), |
||||
)} |
||||
</InnerPanel> |
||||
), |
||||
)} |
||||
</Box> |
||||
) : ( |
||||
<Spinner /> |
||||
)} |
||||
</StyledDiv> |
||||
</Panel> |
||||
); |
||||
}; |
||||
|
||||
export default SharedStorage; |
@ -1,87 +0,0 @@ |
||||
import { Box } from '@mui/material'; |
||||
import { styled } from '@mui/material/styles'; |
||||
import * as prettyBytes from 'pretty-bytes'; |
||||
import { AllocationBar } from '../Bars'; |
||||
import { BodyText } from '../Text'; |
||||
import Decorator from '../Decorator'; |
||||
|
||||
const PREFIX = 'SharedStorageHost'; |
||||
|
||||
const classes = { |
||||
fs: `${PREFIX}-fs`, |
||||
bar: `${PREFIX}-bar`, |
||||
decoratorBox: `${PREFIX}-decoratorBox`, |
||||
}; |
||||
|
||||
const StyledDiv = styled('div')(() => ({ |
||||
[`& .${classes.fs}`]: { |
||||
paddingLeft: '.7em', |
||||
paddingRight: '.7em', |
||||
paddingTop: '1.2em', |
||||
}, |
||||
|
||||
[`& .${classes.bar}`]: { |
||||
paddingLeft: '.7em', |
||||
paddingRight: '.7em', |
||||
}, |
||||
|
||||
[`& .${classes.decoratorBox}`]: { |
||||
paddingRight: '.3em', |
||||
}, |
||||
})); |
||||
|
||||
const SharedStorageHost = ({ |
||||
host, |
||||
}: { |
||||
host: AnvilFileSystemHost; |
||||
}): JSX.Element => ( |
||||
<StyledDiv> |
||||
<Box display="flex" width="100%" className={classes.fs}> |
||||
<Box flexGrow={1}> |
||||
<BodyText text={host.host_name || 'Not Available'} /> |
||||
</Box> |
||||
<Box className={classes.decoratorBox}> |
||||
<Decorator colour={host.is_mounted ? 'ok' : 'error'} /> |
||||
</Box> |
||||
<Box> |
||||
<BodyText text={host.is_mounted ? 'Mounted' : 'Not Mounted'} /> |
||||
</Box> |
||||
</Box> |
||||
{host.is_mounted && ( |
||||
<> |
||||
<Box display="flex" width="100%" className={classes.fs}> |
||||
<Box flexGrow={1}> |
||||
<BodyText |
||||
text={`Used: ${prettyBytes.default(host.total - host.free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
<Box> |
||||
<BodyText |
||||
text={`Free: ${prettyBytes.default(host.free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
</Box> |
||||
<Box display="flex" width="100%" className={classes.bar}> |
||||
<Box flexGrow={1}> |
||||
<AllocationBar |
||||
allocated={((host.total - host.free) / host.total) * 100} |
||||
/> |
||||
</Box> |
||||
</Box> |
||||
<Box display="flex" justifyContent="center" width="100%"> |
||||
<BodyText |
||||
text={`Total Storage: ${prettyBytes.default(host.total, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Box> |
||||
</> |
||||
)} |
||||
</StyledDiv> |
||||
); |
||||
|
||||
export default SharedStorageHost; |
@ -1,3 +0,0 @@ |
||||
import SharedStorage from './FileSystems'; |
||||
|
||||
export default SharedStorage; |
@ -1,53 +0,0 @@ |
||||
import { Grid } from '@mui/material'; |
||||
import * as prettyBytes from 'pretty-bytes'; |
||||
import { useMemo } from 'react'; |
||||
|
||||
import { AllocationBar } from './Bars'; |
||||
import { Panel } from './Panels'; |
||||
import periodicFetch from '../lib/fetchers/periodicFetch'; |
||||
import Spinner from './Spinner'; |
||||
import { HeaderText, BodyText } from './Text'; |
||||
|
||||
// TODO: need to be removed or revised because it's likely unused.
|
||||
const Storage = ({ uuid }: { uuid: string }): JSX.Element => { |
||||
const { data: { free = 0, total = 0 } = {}, isLoading } = |
||||
periodicFetch<AnvilMemory>( |
||||
`${process.env.NEXT_PUBLIC_API_URL}/get_memory?anvil_uuid=${uuid}`, |
||||
); |
||||
|
||||
const contentLayoutElement = useMemo( |
||||
() => ( |
||||
<Grid container alignItems="center" justifyContent="space-around"> |
||||
<Grid item xs={12}> |
||||
<HeaderText text="Storage Resync" /> |
||||
</Grid> |
||||
<Grid item xs={5}> |
||||
<BodyText |
||||
text={`Allocated: ${prettyBytes.default(total - free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Grid> |
||||
<Grid item xs={4}> |
||||
<BodyText |
||||
text={`Free: ${prettyBytes.default(free, { |
||||
binary: true, |
||||
})}`}
|
||||
/> |
||||
</Grid> |
||||
<Grid item xs={10}> |
||||
<AllocationBar allocated={((total - free) / total) * 100} /> |
||||
</Grid> |
||||
</Grid> |
||||
), |
||||
[free, total], |
||||
); |
||||
const contentAreaElement = useMemo( |
||||
() => (isLoading ? <Spinner /> : contentLayoutElement), |
||||
[contentLayoutElement, isLoading], |
||||
); |
||||
|
||||
return <Panel>{contentAreaElement}</Panel>; |
||||
}; |
||||
|
||||
export default Storage; |
@ -0,0 +1,88 @@ |
||||
type AnvilCPU = { |
||||
allocated: number; |
||||
cores: number; |
||||
threads: number; |
||||
}; |
||||
|
||||
type AnvilMemory = { |
||||
allocated: string; |
||||
reserved: string; |
||||
total: string; |
||||
}; |
||||
|
||||
type AnvilNetworkBondLink = { |
||||
link_name: string; |
||||
link_uuid: string; |
||||
link_speed: number; |
||||
link_state: 'optimal' | 'degraded' | 'down'; |
||||
is_active: boolean; |
||||
}; |
||||
|
||||
type AnvilNetworkHostBond = { |
||||
bond_name: string; |
||||
bond_uuid: string; |
||||
links: AnvilNetworkBondLink[]; |
||||
}; |
||||
|
||||
type AnvilNetworkHosts = { |
||||
host_name: string; |
||||
host_uuid: string; |
||||
bonds: AnvilNetworkHostBond[]; |
||||
}; |
||||
|
||||
type AnvilNetwork = { |
||||
hosts: AnvilNetworkHosts[]; |
||||
}; |
||||
|
||||
type AnvilServer = { |
||||
anvilName: string; |
||||
anvilUUID: string; |
||||
serverName: string; |
||||
serverUUID: string; |
||||
serverState: |
||||
| 'running' |
||||
| 'idle' |
||||
| 'paused' |
||||
| 'in shutdown' |
||||
| 'shut off' |
||||
| 'crashed' |
||||
| 'pmsuspended' |
||||
| 'migrating'; |
||||
serverHostUUID: string; |
||||
}; |
||||
|
||||
type AnvilServers = AnvilServer[]; |
||||
|
||||
type AnvilSharedStorageGroup = { |
||||
storage_group_free: string; |
||||
storage_group_name: string; |
||||
storage_group_total: string; |
||||
storage_group_uuid: string; |
||||
}; |
||||
|
||||
type AnvilSharedStorage = { |
||||
storage_groups: AnvilSharedStorageGroup[]; |
||||
}; |
||||
|
||||
type AnvilStatusHost = { |
||||
state: 'offline' | 'booted' | 'crmd' | 'in_ccm' | 'online'; |
||||
host_uuid: string; |
||||
host_name: string; |
||||
state_percent: number; |
||||
state_message: string; |
||||
removable: boolean; |
||||
}; |
||||
|
||||
type AnvilStatus = { |
||||
anvil_state: 'optimal' | 'not_ready' | 'degraded'; |
||||
hosts: AnvilStatusHost[]; |
||||
}; |
||||
|
||||
type AnvilListItem = { |
||||
anvil_name: string; |
||||
anvil_uuid: string; |
||||
} & AnvilStatus; |
||||
|
||||
type AnvilList = { |
||||
anvils: AnvilListItem[]; |
||||
}; |
@ -1,5 +0,0 @@ |
||||
declare type AnvilCPU = { |
||||
cores: number; |
||||
threads: number; |
||||
allocated: number; |
||||
}; |
@ -1,16 +0,0 @@ |
||||
declare type AnvilFileSystemHost = { |
||||
host_uuid: string; |
||||
host_name: string; |
||||
is_mounted: boolean; |
||||
total: number; |
||||
free: number; |
||||
}; |
||||
|
||||
declare type AnvilFileSystem = { |
||||
mount_point: string; |
||||
hosts: Array<AnvilFileSystemHost>; |
||||
}; |
||||
|
||||
declare type AnvilFileSystems = { |
||||
file_systems: Array<AnvilFileSystem>; |
||||
}; |
@ -1,8 +0,0 @@ |
||||
declare type AnvilListItem = { |
||||
anvil_name: string; |
||||
anvil_uuid: string; |
||||
} & AnvilStatus; |
||||
|
||||
declare type AnvilList = { |
||||
anvils: Array<AnvilListItem>; |
||||
}; |
@ -1,6 +0,0 @@ |
||||
declare type AnvilMemory = { |
||||
allocated: number; |
||||
free: number; |
||||
reserved: number; |
||||
total: number; |
||||
}; |
@ -1,45 +0,0 @@ |
||||
declare type AnvilNetworkBondLink = { |
||||
link_name: string; |
||||
link_uuid: string; |
||||
link_speed: number; |
||||
link_state: 'optimal' | 'degraded' | 'down'; |
||||
is_active: boolean; |
||||
}; |
||||
|
||||
declare type AnvilNetworkHostBond = { |
||||
bond_name: string; |
||||
bond_uuid: string; |
||||
links: Array<AnvilNetworkBondLink>; |
||||
}; |
||||
|
||||
declare type AnvilNetworkHosts = { |
||||
host_name: string; |
||||
host_uuid: string; |
||||
bonds: Array<AnvilNetworkHostBond>; |
||||
}; |
||||
|
||||
declare type AnvilNetwork = { |
||||
hosts: Array<AnvilNetworkHosts>; |
||||
}; |
||||
|
||||
declare type ProcessedBond = { |
||||
bond_name: string; |
||||
bond_uuid: string; |
||||
bond_speed: number; |
||||
bond_state: 'optimal' | 'degraded' | 'down'; |
||||
hosts: Array<{ |
||||
host_name: string; |
||||
host_uuid: string; |
||||
link: { |
||||
link_name: string; |
||||
link_uuid: string; |
||||
link_speed: number; |
||||
link_state: 'optimal' | 'degraded' | 'down'; |
||||
is_active: boolean; |
||||
}; |
||||
}>; |
||||
}; |
||||
|
||||
declare type ProcessedNetwork = { |
||||
bonds: Array<ProcessedBond>; |
||||
}; |
@ -1,18 +0,0 @@ |
||||
declare type AnvilServer = { |
||||
server_name: string; |
||||
server_uuid: string; |
||||
server_state: |
||||
| 'running' |
||||
| 'idle' |
||||
| 'paused' |
||||
| 'in shutdown' |
||||
| 'shut off' |
||||
| 'crashed' |
||||
| 'pmsuspended' |
||||
| 'migrating'; |
||||
server_host_uuid: string; |
||||
}; |
||||
|
||||
declare type AnvilServers = { |
||||
servers: Array<AnvilServer>; |
||||
}; |
@ -1,10 +0,0 @@ |
||||
declare type AnvilSharedStorageGroup = { |
||||
storage_group_name: string; |
||||
storage_group_uuid: string; |
||||
storage_group_total: number; |
||||
storage_group_free: number; |
||||
}; |
||||
|
||||
declare type AnvilSharedStorage = { |
||||
storage_groups: Array<AnvilSharedStorageGroup>; |
||||
}; |
@ -1,13 +0,0 @@ |
||||
declare type AnvilStatusHost = { |
||||
state: 'offline' | 'booted' | 'crmd' | 'in_ccm' | 'online'; |
||||
host_uuid: string; |
||||
host_name: string; |
||||
state_percent: number; |
||||
state_message: string; |
||||
removable: boolean; |
||||
}; |
||||
|
||||
declare type AnvilStatus = { |
||||
anvil_state: 'optimal' | 'not_ready' | 'degraded'; |
||||
hosts: Array<AnvilStatusHost>; |
||||
}; |
@ -0,0 +1,21 @@ |
||||
type ProcessedBond = { |
||||
bond_name: string; |
||||
bond_uuid: string; |
||||
bond_speed: number; |
||||
bond_state: 'optimal' | 'degraded' | 'down'; |
||||
hosts: Array<{ |
||||
host_name: string; |
||||
host_uuid: string; |
||||
link: { |
||||
link_name: string; |
||||
link_uuid: string; |
||||
link_speed: number; |
||||
link_state: 'optimal' | 'degraded' | 'down'; |
||||
is_active: boolean; |
||||
}; |
||||
}>; |
||||
}; |
||||
|
||||
type ProcessedNetwork = { |
||||
bonds: ProcessedBond[]; |
||||
}; |
Loading…
Reference in new issue