Ryan Lane has uploaded a new change for review.
https://gerrit.wikimedia.org/r/68126
Change subject: WORK IN PROGRESS: Add resize support
......................................................................
WORK IN PROGRESS: Add resize support
Adds a new action with three subactions to Special:NovaInstance:
resize/resize
resize/confirm
resize/revert
When a user resizes an instance, it'll go into the VERIFY_RESIZE
state. At that point, confirm resize and revert resize actions
will be available.
TODO: Update code to use task output from change 65269
TODO: Add the rest of the qqq
TODO: Add api actions
Change-Id: Ia74f1b2ca85f488260eff2f7ba764e9a7885114d
---
M OpenStackManager.i18n.php
M OpenStackManagerEvent.php
M nova/OpenStackNovaController.php
M special/SpecialNovaInstance.php
4 files changed, 305 insertions(+), 33 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/OpenStackManager
refs/changes/26/68126/1
diff --git a/OpenStackManager.i18n.php b/OpenStackManager.i18n.php
index d60f6cb..205df68 100644
--- a/OpenStackManager.i18n.php
+++ b/OpenStackManager.i18n.php
@@ -52,6 +52,9 @@
'openstackmanager-modify' => 'modify',
'openstackmanager-rename' => 'rename',
'openstackmanager-reboot' => 'reboot',
+ 'openstackmanager-resize' => 'resize',
+ 'openstackmanager-confirmresize' => 'confirm resize',
+ 'openstackmanager-revertresize' => 'revert resize',
'openstackmanager-actions' => 'Actions',
'openstackmanager-notloggedin' => 'Login required',
'openstackmanager-mustbeloggedin' => 'You must be logged in to perform
this action.',
@@ -116,6 +119,21 @@
'openstackmanager-rebootinstancequestion' => 'Are you sure you wish to
reboot instance "$1"?',
'openstackmanager-rebootedinstance' => 'Rebooted instance $1.',
'openstackmanager-rebootinstancefailed' => 'Failed to reboot instance
$1.',
+ 'openstackmanager-resizeinstance' => 'Resize instance',
+ 'openstackmanager-resizeinstancewithname' => 'Resize instance $1 ($2)',
+ 'openstackmanager-confirmresizeinstance' => 'Confirm resize instance',
+ 'openstackmanager-confirmresizeinstancewithname' => 'Confirm resize of
instance $1 ($2)',
+ 'openstackmanager-confirmresizeinstancequestion' => 'Are you sure you
wish to confirm the resize of instance "$1"?',
+ 'openstackmanager-revertresizeinstance' => 'Revert resize instance',
+ 'openstackmanager-revertresizeinstancewithname' => 'Revert resize of
instance $1 ($2)',
+ 'openstackmanager-revertresizeinstancequestion' => 'Are you sure you
wish to revert the resize of instance "$1"?',
+ 'openstackmanager-resizedinstance' => 'Resizing instance $1.',
+ 'openstackmanager-resizeinstancefailed' => 'Failed to resize instance
$1.',
+ 'openstackmanager-confirmresizedinstance' => 'Confirmed resize of
instance $1.',
+ 'openstackmanager-confirmresizeinstancefailed' => 'Failed to confirm
resize of instance $1.',
+ 'openstackmanager-revertresizedinstance' => 'Reverting resize of
instance $1.',
+ 'openstackmanager-revertresizeinstancefailed' => 'Failed to revert
resize of instance $1.',
+ 'openstackmanager-instancenotresized' => 'Instance is not in the
resized state.',
'openstackmanager-launchtime' => 'Launch time',
'openstackmanager-createinstance' => 'Add instance',
@@ -427,10 +445,11 @@
'action-manageproject' => 'manage OpenStack projects and roles',
'right-loginviashell' => 'Login via shell',
- 'notification-osm-instance-deleted' => '$1 {{GENDER:$1|deleted}}
instance \'$3\' in project [[$2]]',
- 'notification-osm-instance-build-completed' => '$1 {{GENDER:$1|built}}
instance \'$3\' in project [[$2]]',
- 'notification-osm-instance-reboot-completed' => '$1
{{GENDER:$1|rebooted}} instance \'$3\' in project [[$2]]',
- 'notification-osm-projectmember-added' => '$1 {{GENDER:$1|added}} you
to project [[$2]]',
+ 'notification-osm-instance-deleted' => '$1 deleted instance \'$3\' in
project [[$2]]',
+ 'notification-osm-instance-resized' => '$1 resized instance \'$3\' in
project [[$2]]',
+ 'notification-osm-instance-build-completed' => '$1 built instance
\'$3\' in project [[$2]]',
+ 'notification-osm-instance-reboot-completed' => '$1 rebooted instance
\'$3\' in project [[$2]]',
+ 'notification-osm-projectmember-added' => '$1 added you to project
[[$2]]',
'echo-category-title-osm-instance-deleted' => 'Deletes an instance from
a project I\'m an admin on.',
'echo-category-title-osm-instance-build-completed' => 'Builds an
instance on a project I\'m an admin on.',
'echo-category-title-osm-instance-reboot-completed' => 'Reboots an
instance.',
@@ -502,6 +521,9 @@
'openstackmanager-modify' => '{{Identical|Modify}}',
'openstackmanager-rename' => '{{Identical|Rename}}',
'openstackmanager-reboot' => 'Used as action link text in
Special:NovaInstance.',
+ 'openstackmanager-resize' => 'Used as action link text in
Special:NovaInstance.',
+ 'openstackmanager-confirmresize' => 'Used as action link text in
Special:NovaInstance.',
+ 'openstackmanager-revertresize' => 'Used as action link text in
Special:NovaInstance.',
'openstackmanager-actions' => 'Used as column header of tables in
several Special pages.
{{Identical|Action}}',
'openstackmanager-notloggedin' => 'Used as page title in Special:Nova.
diff --git a/OpenStackManagerEvent.php b/OpenStackManagerEvent.php
index bb0faa9..610500c 100644
--- a/OpenStackManagerEvent.php
+++ b/OpenStackManagerEvent.php
@@ -14,6 +14,20 @@
}
}
+ public static function createResizeEvent( $instanceName, $project,
$user ) {
+ if ( class_exists( 'EchoEvent' ) ) {
+ EchoEvent::create( array(
+ 'type' => 'osm-instance-resized',
+ 'title' => Title::newFromText( $project,
NS_NOVA_RESOURCE ),
+ 'agent' => $user,
+ 'extra' => array(
+ 'instanceName' => $instanceName,
+ 'projectName' => $project
+ )
+ ) );
+ }
+ }
+
/**
* Store the event information in a DB table. We'll get this back out
in the maintenance/onInstanceActionCompletion.php script.
* @param $type string
diff --git a/nova/OpenStackNovaController.php b/nova/OpenStackNovaController.php
index 830d418..a25e957 100644
--- a/nova/OpenStackNovaController.php
+++ b/nova/OpenStackNovaController.php
@@ -588,7 +588,7 @@
/**
* Reboots an instance
*
- * @param type
+ * @param string instanceid
* @param string $type
* @return boolean
*/
@@ -613,6 +613,46 @@
return $limits;
}
+ /**
+ * Resize an instance
+ *
+ * @param instanceid
+ * @param string $type
+ * @return boolean
+ */
+ function resizeInstance( $instanceid, $type ) {
+ $instanceid = urlencode( $instanceid );
+ $data = array( 'resize' => array( 'flavorRef' => $type ) );
+ $ret = $this->restCall( 'compute', '/servers/' . $instanceid .
'/action', 'POST', $data );
+ return ( $ret['code'] === 202 );
+ }
+
+ /**
+ * Confirm the resize of an instance
+ *
+ * @param instanceid
+ * @return boolean
+ */
+ function confirmResizeInstance( $instanceid ) {
+ $instanceid = urlencode( $instanceid );
+ $data = array( 'confirmResize' => null );
+ $ret = $this->restCall( 'compute', '/servers/' . $instanceid .
'/action', 'POST', $data );
+ return ( $ret['code'] === 204 );
+ }
+
+ /**
+ * Revert the resize of an instance
+ *
+ * @param instanceid
+ * @return boolean
+ */
+ function revertResizeInstance( $instanceid ) {
+ $instanceid = urlencode( $instanceid );
+ $data = array( 'revertResize' => null );
+ $ret = $this->restCall( 'compute', '/servers/' . $instanceid .
'/action', 'POST', $data );
+ return ( $ret['code'] === 202 );
+ }
+
function authenticate( $username, $password ) {
global $wgAuth;
global $wgMemc;
diff --git a/special/SpecialNovaInstance.php b/special/SpecialNovaInstance.php
index fa767be..e9e4d76 100644
--- a/special/SpecialNovaInstance.php
+++ b/special/SpecialNovaInstance.php
@@ -73,6 +73,12 @@
return;
}
$this->rebootInstance();
+ } elseif ( $action === "resize" ) {
+ if ( ! $this->userLDAP->inProject( $project ) ) {
+ $this->notInProject( $project );
+ return;
+ }
+ $this->resizeInstance();
} elseif ( $action === "consoleoutput" ) {
if ( ! $this->userLDAP->inProject( $project ) ) {
$this->notInProject( $project );
@@ -91,7 +97,6 @@
*/
function createInstance() {
global $wgOpenStackManagerPuppetOptions;
- global $wgOpenStackManagerInstanceBannedInstanceTypes;
global $wgOpenStackManagerInstanceDefaultImage;
global $wgOpenStackManagerInstanceBannedImages;
@@ -114,29 +119,7 @@
'name' => 'instancename',
);
- $instanceTypes = $this->userNova->getInstanceTypes();
- $instanceType_keys = array();
- foreach ( $instanceTypes as $instanceType ) {
- $instanceTypeName =
$instanceType->getInstanceTypeName();
- if ( in_array( $instanceTypeName,
$wgOpenStackManagerInstanceBannedInstanceTypes ) ) {
- continue;
- }
- $instanceTypeId = $instanceType->getInstanceTypeId();
- $cpus = $instanceType->getNumberOfCPUs();
- $ram = $instanceType->getMemorySize();
- $root_storage = $instanceType->getRootStorageSize();
- $storage = $instanceType->getStorageSize();
- // @todo FIXME: Hard coded parentheses.
- $instanceLabel = $instanceTypeName . ' (' . $this->msg(
'openstackmanager-instancetypelabel', $cpus, $ram, $root_storage, $storage
)->text() . ')';
- $instanceType_keys[$instanceLabel] = $instanceTypeId;
- }
- $instanceInfo['instanceType'] = array(
- 'type' => 'select',
- 'label-message' => 'openstackmanager-instancetype',
- 'section' => 'info',
- 'options' => $instanceType_keys,
- 'name' => 'instanceType',
- );
+ $instanceInfo['instancetype'] = $this->getInstanceTypeInput();
$instanceInfo['region'] = array(
'type' => 'hidden',
@@ -437,8 +420,97 @@
);
$instanceForm = new HTMLForm( $instanceInfo,
'openstackmanager-novainstance' );
$instanceForm->setTitle( SpecialPage::getTitleFor(
'NovaInstance' ) );
- $instanceForm->setSubmitID(
'novainstance-form-deleteinstancesubmit' );
+ $instanceForm->setSubmitID(
'novainstance-form-rebootinstancesubmit' );
$instanceForm->setSubmitCallback( array( $this,
'tryRebootSubmit' ) );
+ $instanceForm->show();
+
+ return true;
+ }
+
+ /**
+ * Handle ?action=resize
+ * @return bool
+ */
+ function resizeInstance() {
+ $this->setHeaders();
+
+ $project = $this->getRequest()->getText( 'project' );
+ $region = $this->getRequest()->getText( 'region' );
+ $subaction = $this->getRequest()->getText( 'subaction' );
+ if ( ! $this->userLDAP->inRole( 'projectadmin', $project ) ) {
+ $this->notInRole( 'projectadmin', $project );
+ return false;
+ }
+ $instanceosid = $this->getRequest()->getText( 'instanceid' );
+ $instance = $this->userNova->getInstance( $instanceosid );
+ if ( !$instance ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-nonexistanthost' );
+ return false;
+ }
+ $instanceid = $instance->getInstanceId();
+ $instancename = $instance->getInstanceName();
+ $instancestate = $instance->getInstanceState();
+ if ( $subaction !== 'resize' && $instancestate !== 'resized' ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-instancenotresized' );
+ return false;
+ }
+ if ( ! $this->getRequest()->wasPosted() ) {
+ if ( $subaction === "confirm" ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-confirmresizeinstancequestion', $instance->getInstanceId() );
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-confirmresizeinstancewithname',
+
$instanceid, $instancename ) );
+ } else if ( $subaction === "revert" ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-revertresizeinstancequestion', $instance->getInstanceId() );
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-revertresizeinstancewithname',
+
$instanceid, $instancename ) );
+ } else {
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-resizeinstancewithname',
+
$instanceid, $instancename ) );
+ }
+ } else {
+ if ( $subaction === "confirm" ) {
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-confirmresizeinstance' ) );
+ } else if ( $subaction === "revert" ) {
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-revertresizeinstance' ) );
+ } else {
+ $this->getOutput()->setPagetitle( $this->msg(
'openstackmanager-resizeinstance' ) );
+ }
+ }
+
+ $instanceInfo = array();
+ $instanceInfo['instanceid'] = array(
+ 'type' => 'hidden',
+ 'default' => $instanceosid,
+ 'name' => 'instanceid',
+ );
+ if ( $subaction == 'resize' ) {
+ $instanceInfo['instancetype'] =
$this->getInstanceTypeInput();
+ }
+
+ $instanceInfo['project'] = array(
+ 'type' => 'hidden',
+ 'default' => $project,
+ 'name' => 'project',
+ );
+ $instanceInfo['region'] = array(
+ 'type' => 'hidden',
+ 'default' => $region,
+ 'name' => 'region',
+ );
+ $instanceInfo['action'] = array(
+ 'type' => 'hidden',
+ 'default' => 'resize',
+ 'name' => 'action',
+ );
+ $instanceInfo['subaction'] = array(
+ 'type' => 'hidden',
+ 'default' => $subaction,
+ 'name' => 'subaction',
+ );
+ $instanceForm = new HTMLForm( $instanceInfo,
'openstackmanager-novainstance' );
+ $instanceForm->setTitle( SpecialPage::getTitleFor(
'NovaInstance' ) );
+ $instanceForm->setSubmitID(
'novainstance-form-resizeinstancesubmit' );
+ $instanceForm->setSubmitCallback( array( $this,
'tryResizeSubmit' ) );
$instanceForm->show();
return true;
@@ -572,6 +644,45 @@
null,
$instanceDataAttributes
);
+ if ( $instance->getInstanceState() == "resized"
) {
+ $actions[] = $this->createActionLink(
+
'openstackmanager-confirmresize',
+ array(
+ 'action' => 'resize',
+ 'subaction' =>
'confirm',
+ 'instanceid' =>
$instance->getInstanceOSId(),
+ 'project' =>
$projectName,
+ 'region' => $region
+ ),
+ null,
+ $instanceDataAttributes
+ );
+ $actions[] = $this->createActionLink(
+ 'openstackmanager-revertresize',
+ array(
+ 'action' => 'resize',
+ 'subaction' => 'revert',
+ 'instanceid' =>
$instance->getInstanceOSId(),
+ 'project' =>
$projectName,
+ 'region' => $region
+ ),
+ null,
+ $instanceDataAttributes
+ );
+ } else {
+ $actions[] = $this->createActionLink(
+ 'openstackmanager-resize',
+ array(
+ 'action' => 'resize',
+ 'subaction' => 'resize',
+ 'instanceid' =>
$instance->getInstanceOSId(),
+ 'project' =>
$projectName,
+ 'region' => $region
+ ),
+ null,
+ $instanceDataAttributes
+ );
+ }
$actions[] = $this->createActionLink(
'openstackmanager-configure',
array(
@@ -614,7 +725,7 @@
$this->getOutput()->addWikiMsg(
'openstackmanager-invaliddomain' );
return true;
}
- $instance = $this->userNova->createInstance(
$formData['instancename'], $formData['imageType'], '',
$formData['instanceType'], $formData['groups'] );
+ $instance = $this->userNova->createInstance(
$formData['instancename'], $formData['imageType'], '',
$formData['instancetype'], $formData['groups'] );
if ( $instance ) {
// In essex it seems attributes from extensions aren't
returned. So,
// for now we need to work around this by fetching the
instance again.
@@ -699,12 +810,69 @@
*/
function tryRebootSubmit( $formData, $entryPoint = 'internal' ) {
$instanceid = $formData['instanceid'];
+ $instance = $this->userNova->getInstance( $instanceid );
+ if ( ! $instance ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-nonexistanthost' );
+ return true;
+ }
+ $instancename = $instance->getInstanceName();
$success = $this->userNova->rebootInstance( $instanceid );
if ( $success ) {
OpenStackManagerEvent::storeEventInfo( 'reboot',
$this->getUser(), $this->userNova->getInstance( $instanceid ),
$formData['project'] );
- $this->getOutput()->addWikiMsg(
'openstackmanager-rebootedinstance', $instanceid );
+ $this->getOutput()->addWikiMsg(
'openstackmanager-rebootedinstance', $instancename );
} else {
- $this->getOutput()->addWikiMsg(
'openstackmanager-rebootinstancefailed', $instanceid );
+ $this->getOutput()->addWikiMsg(
'openstackmanager-rebootinstancefailed', $instancename );
+ }
+
+ $out = '<br />';
+ $out .= Linker::link(
+ $this->getTitle(),
+ $this->msg( 'openstackmanager-backinstancelist'
)->escaped()
+ );
+
+ $this->getOutput()->addHTML( $out );
+ return true;
+ }
+
+ /**
+ * @param $formData
+ * @param string $entryPoint
+ * @return bool
+ */
+ function tryResizeSubmit( $formData, $entryPoint = 'internal' ) {
+ $instanceid = $formData['instanceid'];
+ $instance = $this->userNova->getInstance( $instanceid );
+ if ( ! $instance ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-nonexistanthost' );
+ return true;
+ }
+ $instancename = $instance->getInstanceName();
+ if ( isset( $formData['instancetype'] ) ) {
+ $type = $formData['instancetype'];
+ }
+ $subaction = $formData['subaction'];
+ if ( $subaction === "resize" ) {
+ $success = $this->userNova->resizeInstance(
$instanceid, $type );
+ if ( $success ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-resizedinstance', $instancename );
+ } else {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-resizeinstancefailed', $instancename );
+ }
+ } else if ( $subaction === "confirm" ) {
+ $success = $this->userNova->confirmResizeInstance(
$instanceid );
+ if ( $success ) {
+ OpenStackManagerEvent::createResizeEvent(
$instancename, $formData['project'], $this->getUser() );
+ $this->getOutput()->addWikiMsg(
'openstackmanager-confirmresizedinstance', $instancename );
+ } else {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-confirmresizeinstancefailed', $instancename );
+ }
+ } else if ( $subaction === "revert" ) {
+ $success = $this->userNova->revertResizeInstance(
$instanceid );
+ if ( $success ) {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-revertresizedinstance', $instancename );
+ } else {
+ $this->getOutput()->addWikiMsg(
'openstackmanager-revertresizeinstancefailed', $instancename );
+ }
}
$out = '<br />';
@@ -849,4 +1017,32 @@
}
#### End of Puppet related methods ################################
+
+ function getInstanceTypeInput() {
+ global $wgOpenStackManagerInstanceBannedInstanceTypes;
+
+ $instanceTypes = $this->userNova->getInstanceTypes();
+ $instanceType_keys = array();
+ foreach ( $instanceTypes as $instanceType ) {
+ $instanceTypeName =
$instanceType->getInstanceTypeName();
+ if ( in_array( $instanceTypeName,
$wgOpenStackManagerInstanceBannedInstanceTypes ) ) {
+ continue;
+ }
+ $instanceTypeId = $instanceType->getInstanceTypeId();
+ $cpus = $instanceType->getNumberOfCPUs();
+ $ram = $instanceType->getMemorySize();
+ $root_storage = $instanceType->getRootStorageSize();
+ $storage = $instanceType->getStorageSize();
+ // @todo FIXME: Hard coded parentheses.
+ $instanceLabel = $instanceTypeName . ' (' . $this->msg(
'openstackmanager-instancetypelabel', $cpus, $ram, $root_storage, $storage
)->text() . ')';
+ $instanceType_keys[$instanceLabel] = $instanceTypeId;
+ }
+ return array(
+ 'type' => 'select',
+ 'label-message' => 'openstackmanager-instancetype',
+ 'section' => 'info',
+ 'options' => $instanceType_keys,
+ 'name' => 'instancetype',
+ );
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/68126
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia74f1b2ca85f488260eff2f7ba764e9a7885114d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/OpenStackManager
Gerrit-Branch: master
Gerrit-Owner: Ryan Lane <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits