Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php |
— | — | @@ -350,6 +350,7 @@ |
351 | 351 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancestate' ) ); |
352 | 352 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancetype' ) ); |
353 | 353 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceip' ) ); |
| 354 | + $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancepublicip' ) ); |
354 | 355 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroups' ) ); |
355 | 356 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-availabilityzone' ) ); |
356 | 357 | $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-imageid' ) ); |
— | — | @@ -361,7 +362,7 @@ |
362 | 363 | if ( ! in_array( $project, $userProjects ) ) { |
363 | 364 | continue; |
364 | 365 | } |
365 | | - $instanceName = (string)$instance->getInstanceName(); |
| 366 | + $instanceName = $instance->getInstanceName(); |
366 | 367 | $instanceName = htmlentities( $instanceName ); |
367 | 368 | $title = Title::newFromText( $instanceName, NS_VM ); |
368 | 369 | $instanceNameLink = $sk->link( $title, $instanceName, array(), array(), array() ); |
— | — | @@ -369,7 +370,14 @@ |
370 | 371 | $instanceOut .= Html::element( 'td', array(), $instance->getInstanceId() ); |
371 | 372 | $instanceOut .= Html::element( 'td', array(), $instance->getInstanceState() ); |
372 | 373 | $instanceOut .= Html::element( 'td', array(), $instance->getInstanceType() ); |
373 | | - $instanceOut .= Html::element( 'td', array(), $instance->getInstancePrivateIP() ); |
| 374 | + $privateip = $instance->getInstancePrivateIP(); |
| 375 | + $publicip = $instance->getInstancePublicIP(); |
| 376 | + $instanceOut .= Html::element( 'td', array(), $privateip ); |
| 377 | + if ( $privateip != $publicip ) { |
| 378 | + $instanceOut .= Html::element( 'td', array(), $publicip ); |
| 379 | + } else { |
| 380 | + $instanceOut .= Html::element( 'td', array(), '' ); |
| 381 | + } |
374 | 382 | $groupsOut = ''; |
375 | 383 | foreach ( $instance->getSecurityGroups() as $group ) { |
376 | 384 | $groupsOut .= Html::element( 'li', array(), $group ); |
— | — | @@ -452,7 +460,7 @@ |
453 | 461 | |
454 | 462 | if ( $host ) { |
455 | 463 | $title = Title::newFromText( $wgOut->getPageTitle() ); |
456 | | - $job = new OpenStackNovaHostJob( $title, array( 'instanceid' => (string)$instance->getInstanceId() ) ); |
| 464 | + $job = new OpenStackNovaHostJob( $title, array( 'instanceid' => $instance->getInstanceId() ) ); |
457 | 465 | $job->insert(); |
458 | 466 | $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-createdinstance', array(), |
459 | 467 | $instance->getInstanceID(), $instance->getImageId(), |
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php |
— | — | @@ -79,6 +79,7 @@ |
80 | 80 | 'openstackmanager-instancestate' => 'Instance State', |
81 | 81 | 'openstackmanager-instancetype' => 'Instance Type', |
82 | 82 | 'openstackmanager-instanceip' => 'Instance IP', |
| 83 | + 'openstackmanager-instancepublicip' => 'Instance Floating IP', |
83 | 84 | 'openstackmanager-securitygroups' => 'Security Groups', |
84 | 85 | 'openstackmanager-availabilityzone' => 'Availability Zone', |
85 | 86 | 'openstackmanager-imageid' => 'Image ID', |
Index: trunk/extensions/OpenStackManager/OpenStackNovaInstance.php |
— | — | @@ -42,14 +42,14 @@ |
43 | 43 | * @return |
44 | 44 | */ |
45 | 45 | function getReservationId() { |
46 | | - return $this->instance->reservationId; |
| 46 | + return (string)$this->instance->reservationId; |
47 | 47 | } |
48 | 48 | |
49 | 49 | /** |
50 | 50 | * @return |
51 | 51 | */ |
52 | 52 | function getInstanceId() { |
53 | | - return $this->instance->instancesSet->item->instanceId; |
| 53 | + return (string)$this->instance->instancesSet->item->instanceId; |
54 | 54 | } |
55 | 55 | |
56 | 56 | /** |
— | — | @@ -57,7 +57,7 @@ |
58 | 58 | */ |
59 | 59 | function getInstancePrivateIP() { |
60 | 60 | # Though this is unintuitive, privateDnsName is the private IP |
61 | | - return $this->instance->instancesSet->item->privateDnsName; |
| 61 | + return (string)$this->instance->instancesSet->item->privateDnsName; |
62 | 62 | } |
63 | 63 | |
64 | 64 | /** |
— | — | @@ -65,56 +65,56 @@ |
66 | 66 | */ |
67 | 67 | function getInstancePublicIP() { |
68 | 68 | # Though this is unintuitive, privateDnsName is the private IP |
69 | | - return $this->instance->instancesSet->item->dnsName; |
| 69 | + return (string)$this->instance->instancesSet->item->dnsName; |
70 | 70 | } |
71 | 71 | |
72 | 72 | /** |
73 | 73 | * @return |
74 | 74 | */ |
75 | 75 | function getInstanceName() { |
76 | | - return $this->instance->instancesSet->item->displayName; |
| 76 | + return (string)$this->instance->instancesSet->item->displayName; |
77 | 77 | } |
78 | 78 | |
79 | 79 | /** |
80 | 80 | * @return |
81 | 81 | */ |
82 | 82 | function getInstanceState() { |
83 | | - return $this->instance->instancesSet->item->instanceState->name; |
| 83 | + return (string)$this->instance->instancesSet->item->instanceState->name; |
84 | 84 | } |
85 | 85 | |
86 | 86 | /** |
87 | 87 | * @return |
88 | 88 | */ |
89 | 89 | function getInstanceType() { |
90 | | - return $this->instance->instancesSet->item->instanceType; |
| 90 | + return (string)$this->instance->instancesSet->item->instanceType; |
91 | 91 | } |
92 | 92 | |
93 | 93 | /** |
94 | 94 | * @return |
95 | 95 | */ |
96 | 96 | function getImageId() { |
97 | | - return $this->instance->instancesSet->item->imageId; |
| 97 | + return (string)$this->instance->instancesSet->item->imageId; |
98 | 98 | } |
99 | 99 | |
100 | 100 | /** |
101 | 101 | * @return |
102 | 102 | */ |
103 | 103 | function getKeyName() { |
104 | | - return $this->instance->instancesSet->item->keyName; |
| 104 | + return (string)$this->instance->instancesSet->item->keyName; |
105 | 105 | } |
106 | 106 | |
107 | 107 | /** |
108 | 108 | * @return |
109 | 109 | */ |
110 | 110 | function getOwner() { |
111 | | - return $this->instance->ownerId; |
| 111 | + return (string)$this->instance->ownerId; |
112 | 112 | } |
113 | 113 | |
114 | 114 | /** |
115 | 115 | * @return |
116 | 116 | */ |
117 | 117 | function getAvailabilityZone() { |
118 | | - return $this->instance->instancesSet->item->placement->availabilityZone; |
| 118 | + return (string)$this->instance->instancesSet->item->placement->availabilityZone; |
119 | 119 | } |
120 | 120 | |
121 | 121 | /** |
— | — | @@ -122,7 +122,7 @@ |
123 | 123 | */ |
124 | 124 | function getRegion() { |
125 | 125 | # NOTE: This is non-existant in openstack for now |
126 | | - return $this->instance->instancesSet->item->region; |
| 126 | + return (string)$this->instance->instancesSet->item->region; |
127 | 127 | } |
128 | 128 | |
129 | 129 | /** |
— | — | @@ -131,7 +131,7 @@ |
132 | 132 | function getSecurityGroups() { |
133 | 133 | $groups = array(); |
134 | 134 | foreach ( $this->instance->groupSet->item as $group ) { |
135 | | - $groups[] = $group->groupId; |
| 135 | + $groups[] = (string)$group->groupId; |
136 | 136 | } |
137 | 137 | return $groups; |
138 | 138 | } |
— | — | @@ -140,7 +140,7 @@ |
141 | 141 | * @return |
142 | 142 | */ |
143 | 143 | function getLaunchTime() { |
144 | | - return $this->instance->instancesSet->item->launchTime; |
| 144 | + return (string)$this->instance->instancesSet->item->launchTime; |
145 | 145 | } |
146 | 146 | |
147 | 147 | } |
Index: trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php |
— | — | @@ -16,14 +16,14 @@ |
17 | 17 | * @return |
18 | 18 | */ |
19 | 19 | function getKeyName() { |
20 | | - return $this->keypair->keyName; |
| 20 | + return (string)$this->keypair->keyName; |
21 | 21 | } |
22 | 22 | |
23 | 23 | /** |
24 | 24 | * @return |
25 | 25 | */ |
26 | 26 | function getKeyFingerprint() { |
27 | | - return $this->keypair->keyFingerprint; |
| 27 | + return (string)$this->keypair->keyFingerprint; |
28 | 28 | } |
29 | 29 | |
30 | 30 | } |
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroupRule.php |
— | — | @@ -17,21 +17,21 @@ |
18 | 18 | * |
19 | 19 | */ |
20 | 20 | function getToPort() { |
21 | | - return $this->rule->toPort; |
| 21 | + return (string)$this->rule->toPort; |
22 | 22 | } |
23 | 23 | |
24 | 24 | /** |
25 | 25 | * @return |
26 | 26 | */ |
27 | 27 | function getFromPort() { |
28 | | - return $this->rule->fromPort; |
| 28 | + return (string)$this->rule->fromPort; |
29 | 29 | } |
30 | 30 | |
31 | 31 | /** |
32 | 32 | * @return |
33 | 33 | */ |
34 | 34 | function getIPProtocol() { |
35 | | - return $this->rule->ipProtocol; |
| 35 | + return (string)$this->rule->ipProtocol; |
36 | 36 | } |
37 | 37 | |
38 | 38 | /** |
— | — | @@ -40,7 +40,7 @@ |
41 | 41 | function getIPRanges() { |
42 | 42 | $ranges = array(); |
43 | 43 | foreach ( $this->rule->ipRanges->item as $iprange ) { |
44 | | - $ranges[] = $iprange->cidrIp; |
| 44 | + $ranges[] = (string)$iprange->cidrIp; |
45 | 45 | } |
46 | 46 | return $ranges; |
47 | 47 | } |
— | — | @@ -52,8 +52,8 @@ |
53 | 53 | $groups = array(); |
54 | 54 | foreach ( $this->rule->groups->item as $group ) { |
55 | 55 | $properties = array(); |
56 | | - $properties['groupname'] = $group->groupName; |
57 | | - $properties['project'] = $group->userId; |
| 56 | + $properties['groupname'] = (string)$group->groupName; |
| 57 | + $properties['project'] = (string)$group->userId; |
58 | 58 | $groups[] = $properties; |
59 | 59 | } |
60 | 60 | return $groups; |
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php |
— | — | @@ -173,6 +173,8 @@ |
174 | 174 | * @return null|OpenStackNovaInstance |
175 | 175 | */ |
176 | 176 | function createInstance( $instanceName, $image, $key, $instanceType, $availabilityZone, $groups ) { |
| 177 | + global $wgOpenStackManagerInstanceUserData; |
| 178 | + |
177 | 179 | # 1, 1 is min and max number of instances to create. |
178 | 180 | # We never want to make more than one at a time. |
179 | 181 | $options = array(); |
— | — | @@ -182,6 +184,48 @@ |
183 | 185 | $options['InstanceType'] = $instanceType; |
184 | 186 | $options['Placement.AvailabilityZone'] = $availabilityZone; |
185 | 187 | $options['DisplayName'] = $instanceName; |
| 188 | + if ( $wgOpenStackManagerInstanceUserData ) { |
| 189 | + $random_hash = md5(date('r', time())); |
| 190 | + $endl = $this->getLineEnding(); |
| 191 | + $boundary = '===============' . $random_hash .'=='; |
| 192 | + $userdata = 'Content-Type: multipart/mixed; boundary="' . $boundary .'"' . $endl; |
| 193 | + $userdata .= 'MIME-Version: 1.0' . $endl; |
| 194 | + $boundary = '--' . $boundary; |
| 195 | + $userdata .= $endl; |
| 196 | + $userdata .= $boundary; |
| 197 | + if ( $wgOpenStackManagerInstanceUserData['cloud-config'] ) { |
| 198 | + $userdata .= $endl . $this->getAttachmentMime( Spyc::YAMLDump( $wgOpenStackManagerInstanceUserData['cloud-config'] ), 'text/cloud-config', 'cloud-config.txt' ); |
| 199 | + $userdata .= $endl . $boundary; |
| 200 | + } |
| 201 | + if ( $wgOpenStackManagerInstanceUserData['scripts'] ) { |
| 202 | + $i = 0; |
| 203 | + foreach ( $wgOpenStackManagerInstanceUserData['scripts'] as $script ) { |
| 204 | + $stat = @stat( $script ); |
| 205 | + if ( ! $stat ) { |
| 206 | + continue; |
| 207 | + } |
| 208 | + $scripttext = file_get_contents( $script ); |
| 209 | + $userdata .= $endl . $this->getAttachmentMime( $scripttext, 'text/x-shellscript', 'wiki-script-' . $i . '.sh' ); |
| 210 | + $userdata .= $endl . $boundary; |
| 211 | + $i = $i + 1; |
| 212 | + } |
| 213 | + } |
| 214 | + if ( $wgOpenStackManagerInstanceUserData['upstarts'] ) { |
| 215 | + $i = 0; |
| 216 | + foreach ( $wgOpenStackManagerInstanceUserData['upstarts'] as $upstart ) { |
| 217 | + $stat = @stat( $upstart ); |
| 218 | + if ( ! $stat ) { |
| 219 | + continue; |
| 220 | + } |
| 221 | + $upstarttext = file_get_contents( $upstart ); |
| 222 | + $userdata .= $endl . $this->getAttachmentMime( $upstarttext, 'text/upstart-job', 'wiki-upstart-config-' . $i . '.conf' ); |
| 223 | + $userdata .= $endl . $boundary; |
| 224 | + $i = $i + 1; |
| 225 | + } |
| 226 | + } |
| 227 | + $userdata .= '--'; |
| 228 | + $options['UserData'] = base64_encode( $userdata ); |
| 229 | + } |
186 | 230 | if ( count( $groups ) > 1 ) { |
187 | 231 | $options['SecurityGroup'] = $groups; |
188 | 232 | } else if ( count( $groups ) == 1 ) { |
— | — | @@ -198,6 +242,25 @@ |
199 | 243 | return $instance; |
200 | 244 | } |
201 | 245 | |
| 246 | + function getAttachmentMime( $attachmenttext, $mimetype, $filename ) { |
| 247 | + $endl = $this->getLineEnding(); |
| 248 | + $attachment = 'Content-Type: ' . $mimetype . '; charset="us-ascii"'. $endl; |
| 249 | + $attachment .= 'MIME-Version: 1.0' . $endl; |
| 250 | + $attachment .= 'Content-Transfer-Encoding: 7bit' . $endl; |
| 251 | + $attachment .= 'Content-Disposition: attachment; filename="' . $filename . '"' . $endl; |
| 252 | + $attachment .= $endl; |
| 253 | + $attachment .= $attachmenttext; |
| 254 | + return $attachment; |
| 255 | + } |
| 256 | + |
| 257 | + function getLineEnding() { |
| 258 | + if ( wfIsWindows() ) { |
| 259 | + return "\r\n"; |
| 260 | + } else { |
| 261 | + return "\n"; |
| 262 | + } |
| 263 | + } |
| 264 | + |
202 | 265 | /** |
203 | 266 | * @param $instanceId |
204 | 267 | * @return |
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php |
— | — | @@ -21,21 +21,21 @@ |
22 | 22 | * @return |
23 | 23 | */ |
24 | 24 | function getGroupName() { |
25 | | - return $this->group->groupName; |
| 25 | + return (string)$this->group->groupName; |
26 | 26 | } |
27 | 27 | |
28 | 28 | /** |
29 | 29 | * @return |
30 | 30 | */ |
31 | 31 | function getGroupDescription() { |
32 | | - return $this->group->groupDescription; |
| 32 | + return (string)$this->group->groupDescription; |
33 | 33 | } |
34 | 34 | |
35 | 35 | /** |
36 | 36 | * @return |
37 | 37 | */ |
38 | 38 | function getOwner() { |
39 | | - return $this->group->ownerId; |
| 39 | + return (string)$this->group->ownerId; |
40 | 40 | } |
41 | 41 | |
42 | 42 | /** |
Index: trunk/extensions/OpenStackManager/OpenStackNovaAddress.php |
— | — | @@ -29,7 +29,7 @@ |
30 | 30 | * @return |
31 | 31 | */ |
32 | 32 | function getPublicIP() { |
33 | | - return $this->address->publicIp; |
| 33 | + return (string)$this->address->publicIp; |
34 | 34 | } |
35 | 35 | |
36 | 36 | /** |
Index: trunk/extensions/OpenStackManager/OpenStackManager.php |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | 'path' => __FILE__, |
23 | 23 | 'name' => 'OpenStackManager', |
24 | 24 | 'author' => 'Ryan Lane', |
25 | | - 'version' => '1.0', |
| 25 | + 'version' => '1.1', |
26 | 26 | 'url' => 'http://mediawiki.org/wiki/Extension:OpenStackManager', |
27 | 27 | 'descriptionmsg' => 'openstackmanager-desc', |
28 | 28 | ); |
— | — | @@ -61,6 +61,11 @@ |
62 | 62 | 'availableclasses' => array(), |
63 | 63 | 'availablevariables' => array(), |
64 | 64 | ); |
| 65 | +$wgOpenStackManagerInstanceUserData = array( |
| 66 | + 'cloud-config' => array(), |
| 67 | + 'scripts' => array(), |
| 68 | + 'upstarts' => array(), |
| 69 | + ); |
65 | 70 | |
66 | 71 | $dir = dirname( __FILE__ ) . '/'; |
67 | 72 | |