mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-09-10 22:14:48 -05:00
feat(@xen-orchestra/rest-api): expose POST srs/:id/vdis (#8984)
This commit is contained in:
@@ -84,6 +84,23 @@ export interface Xapi {
|
||||
pool_emergencyShutdown(): Promise<void>
|
||||
resumeVm(id: XoVm['id']): Promise<void>
|
||||
unpauseVm(id: XoVm['id']): Promise<void>
|
||||
SR_importVdi(
|
||||
ref: XenApiSr['$ref'],
|
||||
stream: Readable,
|
||||
opts?: {
|
||||
format?: SUPPORTED_VDI_FORMAT
|
||||
name_description?: XoVdi['name_description']
|
||||
name_label?: XoVdi['name_label']
|
||||
other_config?: XoVdi['other_config']
|
||||
read_only?: boolean
|
||||
sharable?: boolean
|
||||
SR?: XenApiSr['$ref']
|
||||
tags?: XoVdi['tags']
|
||||
type?: XoVdi['type']
|
||||
virtual_size?: XoVdi['size']
|
||||
xenstore_data?: Record<string, string>
|
||||
}
|
||||
): Promise<XenApiVdi['$ref']>
|
||||
startVm(
|
||||
id: XoVm['id'],
|
||||
opts?: {
|
||||
|
||||
@@ -3,6 +3,10 @@ export const vdiIds = [
|
||||
'/rest/v0/vdis/771d5baf-4364-42f9-8c92-8e5fe08b332a',
|
||||
]
|
||||
|
||||
export const vdiId = {
|
||||
id: '5e13f673-760e-41be-826e-620d16b7f43b',
|
||||
}
|
||||
|
||||
export const partialVdis = [
|
||||
{
|
||||
type: 'VDI',
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Example, Get, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa'
|
||||
import { Example, Get, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa'
|
||||
import { inject } from 'inversify'
|
||||
import { provide } from 'inversify-binding-decorators'
|
||||
import { Request as ExRequest } from 'express'
|
||||
import type { XoAlarm, XoSr } from '@vates/types'
|
||||
import { SUPPORTED_VDI_FORMAT, XenApiVdi, XoVdi, type XoAlarm, type XoSr } from '@vates/types'
|
||||
|
||||
import { AlarmService } from '../alarms/alarm.service.mjs'
|
||||
import { BASE_URL } from '../index.mjs'
|
||||
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs'
|
||||
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs'
|
||||
import { notFoundResp, unauthorizedResp, type Unbrand } from '../open-api/common/response.common.mjs'
|
||||
import { createdResp, notFoundResp, unauthorizedResp, type Unbrand } from '../open-api/common/response.common.mjs'
|
||||
import { partialSrs, sr, srIds } from '../open-api/oa-examples/sr.oa-example.mjs'
|
||||
import { vdiId } from '../open-api/oa-examples/vdi.oa-example.mjs'
|
||||
import { RestApi } from '../rest-api/rest-api.mjs'
|
||||
import type { SendObjects } from '../helpers/helper.type.mjs'
|
||||
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs'
|
||||
@@ -79,4 +81,42 @@ export class SrController extends XapiXoController<XoSr> {
|
||||
|
||||
return this.sendObjects(Object.values(alarms), req, 'alarms')
|
||||
}
|
||||
|
||||
/**
|
||||
* Import an exported VDI
|
||||
* @example id "c4284e12-37c9-7967-b9e8-83ef229c3e03"
|
||||
* @example name_label "VDI_foo_import"
|
||||
* @example name_description "VDI imported by the REST API"
|
||||
* @example raw true
|
||||
*/
|
||||
@Example(vdiId)
|
||||
@Post('{id}/vdis')
|
||||
@Tags('vdis')
|
||||
@SuccessResponse(createdResp.status, 'VDI imported')
|
||||
@Response(notFoundResp.status, notFoundResp.description)
|
||||
async srImportVdi(
|
||||
@Request() req: ExRequest & { length?: number },
|
||||
@Path() id: string,
|
||||
@Query() name_label?: string,
|
||||
@Query() name_description?: string,
|
||||
@Query() raw?: boolean
|
||||
): Promise<{ id: Unbrand<XoVdi>['id'] }> {
|
||||
const xapiSr = this.getXapiObject(id as XoSr['id'])
|
||||
const xapi = xapiSr.$xapi
|
||||
|
||||
if (req.headers['content-length'] !== undefined) {
|
||||
req.length = +req.headers['content-length']
|
||||
}
|
||||
|
||||
const vdiRef = await xapi.SR_importVdi(xapiSr.$ref, req, {
|
||||
format: raw ? SUPPORTED_VDI_FORMAT.raw : SUPPORTED_VDI_FORMAT.vhd,
|
||||
name_label,
|
||||
name_description,
|
||||
})
|
||||
const vdiId = await xapi.getField<XenApiVdi, 'uuid'>('VDI', vdiRef, 'uuid')
|
||||
|
||||
this.setHeader('Location', `${BASE_URL}/vdis/${vdiId}`)
|
||||
|
||||
return { id: vdiId }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/srs/{id}/vdis": {
|
||||
"post": {
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/octet-stream": {
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/docs/swagger.json": {
|
||||
"get": {
|
||||
"operationId": "swaggerSpec",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
- `DELETE /rest/v0/vdis/<vdi-id>` (PR [#8961](https://github.com/vatesfr/xen-orchestra/pull/8961))
|
||||
- `DELETE /rest/v0/vdi-snapshots/<vdi-snapshot-id>` (PR [#8961](https://github.com/vatesfr/xen-orchestra/pull/8961))
|
||||
- `POST /rest/v0/tasks/<task-id>/actions/abort` (PR [#8908](https://github.com/vatesfr/xen-orchestra/pull/8908))
|
||||
- `POST /rest/v0/srs/<sr-id>/vdis` (PR [#8984](https://github.com/vatesfr/xen-orchestra/pull/8984))
|
||||
- `GET /rest/v0/vdis/<vdi-id>.(raw|vhd)` (PR [#8923](http://github.com/vatesfr/xen-orchestra/pull/8923))
|
||||
- `GET /rest/v0/vdi-snapshots/<vdi-snapshot-id>.(raw|vhd)` (PR [#8923](http://github.com/vatesfr/xen-orchestra/pull/8923))
|
||||
- `GET /rest/v0/vms/<vm-id>.(xva|ova)` (PR [#8929](https://github.com/vatesfr/xen-orchestra/pull/8929))
|
||||
|
||||
@@ -12,7 +12,6 @@ import cloneDeep from 'lodash/cloneDeep.js'
|
||||
import path from 'node:path'
|
||||
import pick from 'lodash/pick.js'
|
||||
import * as CM from 'complex-matcher'
|
||||
import { VDI_FORMAT_RAW, VDI_FORMAT_VHD } from '@xen-orchestra/xapi'
|
||||
|
||||
import { getUserPublicProperties, isAlarm } from '../utils.mjs'
|
||||
import { compileXoJsonSchema } from './_xoJsonSchema.mjs'
|
||||
@@ -1016,23 +1015,6 @@ export default class RestApi {
|
||||
})
|
||||
)
|
||||
|
||||
api.post(
|
||||
'/:collection(srs)/:object/vdis',
|
||||
wrap(async (req, res) => {
|
||||
const sr = req.xapiObject
|
||||
req.length = ifDef(req.headers['content-length'], Number)
|
||||
|
||||
const { name_label, name_description, raw } = req.query
|
||||
const vdiRef = await sr.$importVdi(req, {
|
||||
format: raw !== undefined ? VDI_FORMAT_RAW : VDI_FORMAT_VHD,
|
||||
name_label,
|
||||
name_description,
|
||||
})
|
||||
|
||||
res.end(await sr.$xapi.getField('VDI', vdiRef, 'uuid'))
|
||||
})
|
||||
)
|
||||
|
||||
setupRestApi(express, app)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user