xva-store v1

This commit is contained in:
Mohamedox
2019-09-18 10:55:22 +02:00
parent 027dfd262f
commit 9272524264
9 changed files with 91 additions and 39 deletions

View File

@@ -20,7 +20,8 @@ class XoServerCloud {
}
async load() {
const getResourceCatalog = ({ hub } = {}) => this._getCatalog({ hub })
const getResourceCatalog = ({ filters } = {}) =>
this._getCatalog({ filters })
getResourceCatalog.description =
"Get the list of user's available resources"
getResourceCatalog.permission = 'admin'
@@ -67,8 +68,8 @@ class XoServerCloud {
// ----------------------------------------------------------------
async _getCatalog({ hub } = {}) {
const catalog = await this._updater.call('getResourceCatalog', { hub })
async _getCatalog({ filters } = {}) {
const catalog = await this._updater.call('getResourceCatalog', { filters })
if (!catalog) {
throw new Error('cannot get catalog')
@@ -79,8 +80,8 @@ class XoServerCloud {
// ----------------------------------------------------------------
async _getNamespaces({ hub } = {}) {
const catalog = await this._getCatalog({ hub })
async _getNamespaces() {
const catalog = await this._getCatalog()
if (!catalog._namespaces) {
throw new Error('cannot get namespaces')
@@ -108,7 +109,9 @@ class XoServerCloud {
// ----------------------------------------------------------------
async _getNamespaceCatalog(namespace, hub) {
const namespaceCatalog = (await this._getCatalog({ hub }))[namespace]
const namespaceCatalog = (await this._getCatalog({ filters: { hub } }))[
namespace
]
if (!namespaceCatalog) {
throw new Error(`cannot get catalog: ${namespace} not registered`)
@@ -120,12 +123,12 @@ class XoServerCloud {
// ----------------------------------------------------------------
async _requestResource(namespace, id, version, hub) {
const _namespace = (await this._getNamespaces({ hub }))[namespace]
const _namespace = (await this._getNamespaces())[namespace]
const { _token: token } = await this._getNamespaceCatalog(namespace, hub)
if (!hub && (!_namespace || !_namespace.registered)) {
throw new Error(`cannot get resource: ${namespace} not registered`)
}
const { _token: token } = await this._getNamespaceCatalog(namespace, hub)
// 2018-03-20 Extra check: getResourceDownloadToken seems to be called without a token in some cases
if (token === undefined) {
@@ -136,8 +139,6 @@ class XoServerCloud {
token,
id,
version,
namespace,
hub,
})
if (!downloadToken) {

View File

@@ -2146,6 +2146,9 @@ const messages = {
// Hub
hubPage: 'Hub',
hubInstallXva: 'Install',
hubSuccessfulInstallMsg: 'VM installed successfuly',
hubVmNoAvailableMsg: 'No VMs available ',
hubNoDefaultSrMessage: "There's no default SR for {pool} pool",
hubCreateXva: 'Create',
hubDeployXva: 'Deploy',
hubSortBy: 'Sort by',

View File

@@ -58,3 +58,7 @@ export const setHomeVmIdsSelection = createAction(
'SET_HOME_VM_IDS_SELECTION',
homeVmIdsSelection => homeVmIdsSelection
)
export const setHubInstallLoadingState = createAction(
'SET_HUB_INSTALL_LOADING_STATE',
hubInstallLoadingState => hubInstallLoadingState
)

View File

@@ -92,6 +92,15 @@ export default {
homeVmIdsSelection,
}),
// This state is used temporarily to keep loading state in hub
hubInstallLoadingState: combineActionHandlers(
{},
{
[actions.setHubInstallLoadingState]: (_, hubInstallLoadingState) =>
hubInstallLoadingState,
}
),
objects: combineActionHandlers(
{
all: {}, // Mutable for performance!

View File

@@ -345,8 +345,8 @@ export const subscribeRoles = createSubscription(
export const subscribeIpPools = createSubscription(() => _call('ipPool.getAll'))
export const subscribeResourceCatalog = ({ hub }) =>
createSubscription(() => _call('cloud.getResourceCatalog', { hub }))
export const subscribeResourceCatalog = ({ filters } = {}) =>
createSubscription(() => _call('cloud.getResourceCatalog', { filters }))
const getNotificationCookie = () => {
const notificationCookie = cookies.get(
@@ -2896,8 +2896,8 @@ export const fixHostNotInXosanNetwork = (xosanSr, host) =>
// XOSAN packs -----------------------------------------------------------------
export const getResourceCatalog = ({ hub } = {}) =>
_call('cloud.getResourceCatalog', { hub: Boolean(hub) })
export const getResourceCatalog = ({ filters } = {}) =>
_call('cloud.getResourceCatalog', { filters })
export const getAllResourceCatalog = () => _call('cloud.getAllResourceCatalog')
@@ -2909,7 +2909,7 @@ const downloadAndInstallXosanPack = (pack, pool, { version }) =>
})
export const downloadAndInstallResource = ({ namespace, id, version, sr }) =>
_call('resource.downloadAndInstallResource', {
_call('hub.downloadAndInstallResource', {
namespace,
id,
version,

View File

@@ -6,7 +6,7 @@ import React from 'react'
import { Container, Col, Row } from 'grid'
import { addSubscriptions } from 'utils'
import { injectState, provideState } from 'reaclette'
import { map, mapValues, orderBy } from 'lodash'
import { isEmpty, map, mapValues, orderBy } from 'lodash'
import { subscribeResourceCatalog } from 'xo'
import Resource from './resource'
@@ -29,7 +29,7 @@ const HEADER = (
export default decorate([
addSubscriptions({
catalog: subscribeResourceCatalog({ hub: true }),
catalog: subscribeResourceCatalog({ filters: { hub: true } }),
}),
provideState({
initialState: () => ({
@@ -52,18 +52,24 @@ export default decorate([
}),
injectState,
({ state: { resources } }) => (
<Page
header={HEADER}
title='hubPage'
formatTitle
className='background-page'
>
<Page header={HEADER} title='hubPage' formatTitle>
<Row>
{map(resources, (info, namespace) => (
<Col key={namespace} mediumSize={3}>
<Resource className='card-style' namespace={namespace} {...info} />
</Col>
))}
{isEmpty(resources) ? (
<h2 className='text-muted'>
&nbsp; {_('hubVmNoAvailableMsg')}
<Icon icon='alarm' color='yellow' />
</h2>
) : (
map(resources, (info, namespace) => (
<Col key={namespace} mediumSize={3}>
<Resource
className='card-style'
namespace={namespace}
{...info}
/>
</Col>
))
)}
</Row>
</Page>
),

View File

@@ -5,6 +5,7 @@ import Icon from 'icon'
import React from 'react'
import Tooltip from 'tooltip'
import { Container } from 'grid'
import { error } from 'notification'
import { SelectPool } from 'select-objects'
import { injectState, provideState } from 'reaclette'
@@ -14,13 +15,26 @@ export default decorate([
pools: multi ? [] : undefined,
}),
effects: {
handlePools(_, pools) {
this.props.onChange({
pools,
pool: pools,
})
return {
pools,
handlePools(__, pools) {
let noDefaultSrPool
for (const pool of pools) {
if (pool.default_SR === undefined) {
noDefaultSrPool = pool
}
}
if (noDefaultSrPool) {
error(
'Error',
_('hubNoDefaultSrMessage', { pool: noDefaultSrPool.name_label })
)
} else {
this.props.onChange({
pools,
pool: pools,
})
return {
pools,
}
}
},
},

View File

@@ -36,6 +36,7 @@ export default decorate([
return {
templates: getTemplates,
pools: getPools,
hubInstallLoadingState: state => state.hubInstallLoadingState,
}
}),
provideState({
@@ -46,7 +47,12 @@ export default decorate([
effects: {
initialize: () => {},
async install(__, { name, namespace, id, version }) {
const { isFromSources, installPoolPredicate } = this.state
const { setHubInstallLoadingState } = this.props
const {
isFromSources,
hubInstallLoadingState,
installPoolPredicate,
} = this.state
if (isFromSources) {
subscribeAlert()
} else {
@@ -70,7 +76,10 @@ export default decorate([
},
})
this.state.loading = true
setHubInstallLoadingState({
...hubInstallLoadingState,
[id]: true,
})
for (const pool of resourceParams.pools) {
try {
await downloadAndInstallResource({
@@ -79,12 +88,15 @@ export default decorate([
version,
sr: pool.default_SR,
})
success('XVA import', 'XVA installed successfuly')
success('XVA import', _('hubSuccessfulInstallMsg'))
} catch (_error) {
error('Error', _error.message)
}
}
this.state.loading = false
setHubInstallLoadingState({
...hubInstallLoadingState,
[id]: false,
})
}
},
async create(__, { name }) {
@@ -160,6 +172,8 @@ export default decorate([
poolName: ({ pool }) => pool && pool.name_label,
installedTemplates: (_, { id, templates }) =>
filter(templates, ['other.xva_id', id]),
installLoadingState: (_, { hubInstallLoadingState, id }) =>
hubInstallLoadingState[id],
isTemplateInstalledOnAllPools: ({ installedTemplates }, { pools }) => {
let _isTemplateInstalledOnAllPools = true
if (isEmpty(installedTemplates)) {
@@ -251,6 +265,7 @@ export default decorate([
handler={effects.install}
icon={'add'}
size='meduim'
pending={state.installLoadingState}
>
{_('hubInstallXva')}
</ActionButton>