parent
5ba170bf1f
commit
08ddfe0649
@ -3,6 +3,7 @@
|
|||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
- [SR/Disk] Disable actions on unmanaged VDIs [#3988](https://github.com/vatesfr/xen-orchestra/issues/3988) (PR [#4000](https://github.com/vatesfr/xen-orchestra/pull/4000))
|
- [SR/Disk] Disable actions on unmanaged VDIs [#3988](https://github.com/vatesfr/xen-orchestra/issues/3988) (PR [#4000](https://github.com/vatesfr/xen-orchestra/pull/4000))
|
||||||
|
- [Pool] Specify automatic networks on a Pool [#3916](https://github.com/vatesfr/xen-orchestra/issues/3916) (PR [#3958](https://github.com/vatesfr/xen-orchestra/pull/3958))
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
@ -85,34 +85,35 @@ createBonded.description =
|
|||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export async function set({
|
export async function set({
|
||||||
network,
|
automatic,
|
||||||
|
defaultIsLocked,
|
||||||
name_description: nameDescription,
|
name_description: nameDescription,
|
||||||
name_label: nameLabel,
|
name_label: nameLabel,
|
||||||
defaultIsLocked,
|
network,
|
||||||
id,
|
|
||||||
}) {
|
}) {
|
||||||
await this.getXapi(network).setNetworkProperties(network._xapiId, {
|
await this.getXapi(network).setNetworkProperties(network._xapiId, {
|
||||||
|
automatic,
|
||||||
|
defaultIsLocked,
|
||||||
nameDescription,
|
nameDescription,
|
||||||
nameLabel,
|
nameLabel,
|
||||||
defaultIsLocked,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
set.params = {
|
set.params = {
|
||||||
id: {
|
automatic: {
|
||||||
type: 'string',
|
type: 'boolean',
|
||||||
|
optional: true,
|
||||||
},
|
},
|
||||||
name_label: {
|
defaultIsLocked: {
|
||||||
type: 'string',
|
type: 'boolean',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
name_description: {
|
name_description: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
defaultIsLocked: {
|
name_label: {
|
||||||
type: 'boolean',
|
type: 'string',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -578,6 +578,7 @@ const TRANSFORMS = {
|
|||||||
|
|
||||||
network(obj) {
|
network(obj) {
|
||||||
return {
|
return {
|
||||||
|
automatic: obj.other_config?.automatic === 'true',
|
||||||
bridge: obj.bridge,
|
bridge: obj.bridge,
|
||||||
defaultIsLocked: obj.default_locking_mode === 'disabled',
|
defaultIsLocked: obj.default_locking_mode === 'disabled',
|
||||||
MTU: +obj.MTU,
|
MTU: +obj.MTU,
|
||||||
|
@ -305,17 +305,23 @@ export default class Xapi extends XapiBase {
|
|||||||
|
|
||||||
async setNetworkProperties(
|
async setNetworkProperties(
|
||||||
id,
|
id,
|
||||||
{ nameLabel, nameDescription, defaultIsLocked }
|
{ automatic, defaultIsLocked, nameDescription, nameLabel }
|
||||||
) {
|
) {
|
||||||
let defaultLockingMode
|
let defaultLockingMode
|
||||||
if (defaultIsLocked != null) {
|
if (defaultIsLocked != null) {
|
||||||
defaultLockingMode = defaultIsLocked ? 'disabled' : 'unlocked'
|
defaultLockingMode = defaultIsLocked ? 'disabled' : 'unlocked'
|
||||||
}
|
}
|
||||||
await this._setObjectProperties(this.getObject(id), {
|
const network = this.getObject(id)
|
||||||
nameLabel,
|
await Promise.all([
|
||||||
nameDescription,
|
this._setObjectProperties(network, {
|
||||||
defaultLockingMode,
|
defaultLockingMode,
|
||||||
})
|
nameDescription,
|
||||||
|
nameLabel,
|
||||||
|
}),
|
||||||
|
this._updateObjectMapProperty(network, 'other_config', {
|
||||||
|
automatic: automatic === undefined ? undefined : automatic ? 'true' : null,
|
||||||
|
}),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================
|
// =================================================================
|
||||||
|
@ -733,6 +733,7 @@ const messages = {
|
|||||||
memoryLeftTooltip: '{used}% used ({free} free)',
|
memoryLeftTooltip: '{used}% used ({free} free)',
|
||||||
// ----- Pool network tab -----
|
// ----- Pool network tab -----
|
||||||
pif: 'PIF',
|
pif: 'PIF',
|
||||||
|
poolNetworkAutomatic: 'Automatic',
|
||||||
poolNetworkNameLabel: 'Name',
|
poolNetworkNameLabel: 'Name',
|
||||||
poolNetworkDescription: 'Description',
|
poolNetworkDescription: 'Description',
|
||||||
poolNetworkPif: 'PIFs',
|
poolNetworkPif: 'PIFs',
|
||||||
|
@ -81,6 +81,7 @@ import {
|
|||||||
resolveResourceSet,
|
resolveResourceSet,
|
||||||
} from 'utils'
|
} from 'utils'
|
||||||
import {
|
import {
|
||||||
|
createFilter,
|
||||||
createSelector,
|
createSelector,
|
||||||
createGetObject,
|
createGetObject,
|
||||||
createGetObjectsOfType,
|
createGetObjectsOfType,
|
||||||
@ -485,20 +486,19 @@ export default class NewVm extends BaseComponent {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const VIFs = []
|
let VIFs = []
|
||||||
|
const defaultNetworkIds = this._getDefaultNetworkIds(template)
|
||||||
forEach(template.VIFs, vifId => {
|
forEach(template.VIFs, vifId => {
|
||||||
const vif = getObject(storeState, vifId, resourceSet)
|
const vif = getObject(storeState, vifId, resourceSet)
|
||||||
VIFs.push({
|
VIFs.push({
|
||||||
network:
|
network:
|
||||||
pool || isInResourceSet(vif.$network)
|
pool || isInResourceSet(vif.$network)
|
||||||
? vif.$network
|
? vif.$network
|
||||||
: this._getDefaultNetworkId(template),
|
: defaultNetworkIds[0],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if (VIFs.length === 0) {
|
if (VIFs.length === 0) {
|
||||||
VIFs.push({
|
VIFs = defaultNetworkIds.map(id => ({ network: id }))
|
||||||
network: this._getDefaultNetworkId(template),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
const name_label =
|
const name_label =
|
||||||
state.name_label === '' || !state.name_labelHasChanged
|
state.name_label === '' || !state.name_labelHasChanged
|
||||||
@ -631,21 +631,38 @@ export default class NewVm extends BaseComponent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_getDefaultNetworkId = template => {
|
|
||||||
|
_getAutomaticNetworks = createSelector(
|
||||||
|
createFilter(this._getPoolNetworks, [network => network.automatic]),
|
||||||
|
networks => networks.map(_ => _.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
_getDefaultNetworkIds = template => {
|
||||||
if (template === undefined) {
|
if (template === undefined) {
|
||||||
return
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const network =
|
if (this.props.pool === undefined) {
|
||||||
this.props.pool === undefined
|
const network = find(
|
||||||
? find(this._getResolvedResourceSet().objectsByType.network, {
|
this._getResolvedResourceSet().objectsByType.network,
|
||||||
$pool: template.$pool,
|
{
|
||||||
})
|
$pool: template.$pool,
|
||||||
: find(this._getPoolNetworks(), network => {
|
}
|
||||||
const pif = getObject(store.getState(), network.PIFs[0])
|
)
|
||||||
return pif && pif.management
|
return network !== undefined ? [network.id] : []
|
||||||
})
|
}
|
||||||
return network && network.id
|
|
||||||
|
const automaticNetworks = this._getAutomaticNetworks()
|
||||||
|
if (automaticNetworks.length !== 0) {
|
||||||
|
return automaticNetworks
|
||||||
|
}
|
||||||
|
|
||||||
|
const network = find(this._getPoolNetworks(), network => {
|
||||||
|
const pif = getObject(store.getState(), network.PIFs[0])
|
||||||
|
return pif && pif.management
|
||||||
|
})
|
||||||
|
|
||||||
|
return network !== undefined ? [network.id] : []
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildVmsNameTemplate = createSelector(
|
_buildVmsNameTemplate = createSelector(
|
||||||
@ -788,9 +805,7 @@ export default class NewVm extends BaseComponent {
|
|||||||
this._setState({
|
this._setState({
|
||||||
VIFs: [
|
VIFs: [
|
||||||
...state.VIFs,
|
...state.VIFs,
|
||||||
{
|
{ network: this._getDefaultNetworkIds(state.template)[0] },
|
||||||
network: this._getDefaultNetworkId(state.template),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,21 @@ class Name extends Component {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class AutomaticNetwork extends Component {
|
||||||
|
_editAutomaticNetwork = automatic =>
|
||||||
|
editNetwork(this.props.network, { automatic })
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { network } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Toggle onChange={this._editAutomaticNetwork} value={network.automatic} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
class Description extends Component {
|
class Description extends Component {
|
||||||
_editDescription = value =>
|
_editDescription = value =>
|
||||||
editNetwork(this.props.network, { name_description: value })
|
editNetwork(this.props.network, { name_description: value })
|
||||||
@ -343,6 +358,10 @@ const NETWORKS_COLUMNS = [
|
|||||||
itemRenderer: network =>
|
itemRenderer: network =>
|
||||||
!isEmpty(network.PIFs) && <PifsItem network={network} />,
|
!isEmpty(network.PIFs) && <PifsItem network={network} />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: _('poolNetworkAutomatic'),
|
||||||
|
itemRenderer: network => <AutomaticNetwork network={network} />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
itemRenderer: network => <NetworkActions network={network} />,
|
itemRenderer: network => <NetworkActions network={network} />,
|
||||||
|
Loading…
Reference in New Issue
Block a user