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

Reply via email to