~danwent/nova/qmanager

« back to all changes in this revision

Viewing changes to nova/virt/driver.py

  • Committer: Dan Wendlandt
  • Date: 2011-08-23 03:31:24 UTC
  • mfrom: (1343.1.133 nova)
  • Revision ID: dan@nicira.com-20110823033124-mgfx108h423trjmy
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
class ComputeDriver(object):
63
63
    """Base class for compute drivers.
64
64
 
65
 
    Lots of documentation is currently on fake.py.
 
65
    The interface to this class talks in terms of 'instances' (Amazon EC2 and
 
66
    internal Nova terminology), by which we mean 'running virtual machine'
 
67
    (XenAPI terminology) or domain (Xen or libvirt terminology).
 
68
 
 
69
    An instance has an ID, which is the identifier chosen by Nova to represent
 
70
    the instance further up the stack.  This is unfortunately also called a
 
71
    'name' elsewhere.  As far as this layer is concerned, 'instance ID' and
 
72
    'instance name' are synonyms.
 
73
 
 
74
    Note that the instance ID or name is not human-readable or
 
75
    customer-controlled -- it's an internal ID chosen by Nova.  At the
 
76
    nova.virt layer, instances do not have human-readable names at all -- such
 
77
    things are only known higher up the stack.
 
78
 
 
79
    Most virtualization platforms will also have their own identity schemes,
 
80
    to uniquely identify a VM or domain.  These IDs must stay internal to the
 
81
    platform-specific layer, and never escape the connection interface.  The
 
82
    platform-specific layer is responsible for keeping track of which instance
 
83
    ID maps to which platform-specific ID, and vice versa.
 
84
 
 
85
    In contrast, the list_disks and list_interfaces calls may return
 
86
    platform-specific IDs.  These identify a specific virtual disk or specific
 
87
    virtual network interface, and these IDs are opaque to the rest of Nova.
 
88
 
 
89
    Some methods here take an instance of nova.compute.service.Instance.  This
 
90
    is the datastructure used by nova.compute to store details regarding an
 
91
    instance, and pass them into this layer.  This layer is responsible for
 
92
    translating that generic datastructure into terms that are specific to the
 
93
    virtualization platform.
 
94
 
66
95
    """
67
96
 
68
97
    def init_host(self, host):
69
 
        """Adopt existing VM's running here"""
 
98
        """Initialize anything that is necessary for the driver to function,
 
99
        including catching up with currently running VM's on the given host."""
70
100
        # TODO(Vek): Need to pass context in for access to auth_token
71
101
        raise NotImplementedError()
72
102
 
74
104
        """Get the current status of an instance, by name (not ID!)
75
105
 
76
106
        Returns a dict containing:
 
107
 
77
108
        :state:           the running state, one of the power_state codes
78
109
        :max_mem:         (int) the maximum memory in KBytes allowed
79
110
        :mem:             (int) the memory in KBytes used by the domain
84
115
        raise NotImplementedError()
85
116
 
86
117
    def list_instances(self):
 
118
        """
 
119
        Return the names of all the instances known to the virtualization
 
120
        layer, as a list.
 
121
        """
87
122
        # TODO(Vek): Need to pass context in for access to auth_token
88
123
        raise NotImplementedError()
89
124
 
94
129
 
95
130
    def spawn(self, context, instance,
96
131
              network_info=None, block_device_info=None):
97
 
        """Launch a VM for the specified instance"""
 
132
        """
 
133
        Create a new instance/VM/domain on the virtualization platform.
 
134
 
 
135
        Once this successfully completes, the instance should be
 
136
        running (power_state.RUNNING).
 
137
 
 
138
        If this fails, any partial instance should be completely
 
139
        cleaned up, and the virtualization platform should be in the state
 
140
        that it was before this call began.
 
141
 
 
142
        :param context: security context
 
143
        :param instance: Instance of {nova.compute.service.Instance}.
 
144
                         This function should use the data there to guide
 
145
                         the creation of the new instance.
 
146
        :param network_info:
 
147
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
 
148
        :param block_device_info:
 
149
        """
98
150
        raise NotImplementedError()
99
151
 
100
152
    def destroy(self, instance, network_info, cleanup=True):
101
153
        """Destroy (shutdown and delete) the specified instance.
102
154
 
103
155
        The given parameter is an instance of nova.compute.service.Instance,
104
 
        and so the instance is being specified as instance.name.
105
 
 
106
 
        The work will be done asynchronously.  This function returns a
107
 
        task that allows the caller to detect when it is complete.
108
156
 
109
157
        If the instance is not found (for example if networking failed), this
110
158
        function should still succeed.  It's probably a good idea to log a
111
159
        warning in that case.
112
160
 
 
161
        :param instance: Instance of {nova.compute.service.Instance} and so
 
162
                         the instance is being specified as instance.name.
 
163
        :param network_info:
 
164
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
 
165
        :param cleanup:
 
166
 
113
167
        """
114
168
        # TODO(Vek): Need to pass context in for access to auth_token
115
169
        raise NotImplementedError()
116
170
 
117
171
    def reboot(self, instance, network_info):
118
 
        """Reboot specified VM"""
 
172
        """Reboot the specified instance.
 
173
 
 
174
        :param instance: Instance of {nova.compute.service.Instance} and so
 
175
                         the instance is being specified as instance.name.
 
176
        :param network_info:
 
177
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
 
178
        """
119
179
        # TODO(Vek): Need to pass context in for access to auth_token
120
180
        raise NotImplementedError()
121
181
 
140
200
        raise NotImplementedError()
141
201
 
142
202
    def get_host_ip_addr(self):
 
203
        """
 
204
        Retrieves the IP address of the dom0
 
205
        """
143
206
        # TODO(Vek): Need to pass context in for access to auth_token
144
207
        raise NotImplementedError()
145
208
 
146
209
    def attach_volume(self, context, instance_id, volume_id, mountpoint):
 
210
        """Attach the disk at device_path to the instance at mountpoint"""
147
211
        raise NotImplementedError()
148
212
 
149
213
    def detach_volume(self, context, instance_id, volume_id):
 
214
        """Detach the disk attached to the instance at mountpoint"""
150
215
        raise NotImplementedError()
151
216
 
152
 
    def compare_cpu(self, context, cpu_info):
 
217
    def compare_cpu(self, cpu_info):
 
218
        """Compares given cpu info against host
 
219
 
 
220
        Before attempting to migrate a VM to this host,
 
221
        compare_cpu is called to ensure that the VM will
 
222
        actually run here.
 
223
 
 
224
        :param cpu_info: (str) JSON structure describing the source CPU.
 
225
        :returns: None if migration is acceptable
 
226
        :raises: :py:class:`~nova.exception.InvalidCPUInfo` if migration
 
227
                 is not acceptable.
 
228
        """
153
229
        raise NotImplementedError()
154
230
 
155
231
    def migrate_disk_and_power_off(self, instance, dest):
156
 
        """Transfers the VHD of a running instance to another host, then shuts
157
 
        off the instance copies over the COW disk"""
 
232
        """
 
233
        Transfers the disk of a running instance in multiple phases, turning
 
234
        off the instance before the end.
 
235
        """
158
236
        # TODO(Vek): Need to pass context in for access to auth_token
159
237
        raise NotImplementedError()
160
238
 
161
239
    def snapshot(self, context, instance, image_id):
162
 
        """Create snapshot from a running VM instance."""
 
240
        """
 
241
        Snapshots the specified instance.
 
242
 
 
243
        The given parameter is an instance of nova.compute.service.Instance,
 
244
        and so the instance is being specified as instance.name.
 
245
 
 
246
        The second parameter is the name of the snapshot.
 
247
        """
163
248
        raise NotImplementedError()
164
249
 
165
250
    def finish_migration(self, context, instance, disk_info, network_info,
166
251
                         resize_instance):
167
 
        """Completes a resize, turning on the migrated instance"""
 
252
        """Completes a resize, turning on the migrated instance
 
253
 
 
254
        :param network_info:
 
255
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
 
256
        """
168
257
        raise NotImplementedError()
169
258
 
170
259
    def revert_migration(self, instance):
173
262
        raise NotImplementedError()
174
263
 
175
264
    def pause(self, instance, callback):
176
 
        """Pause VM instance"""
 
265
        """Pause the specified instance."""
177
266
        # TODO(Vek): Need to pass context in for access to auth_token
178
267
        raise NotImplementedError()
179
268
 
218
307
                       post_method, recover_method):
219
308
        """Spawning live_migration operation for distributing high-load.
220
309
 
221
 
        :params ctxt: security context
222
 
        :params instance_ref:
 
310
        :param ctxt: security context
 
311
        :param instance_ref:
223
312
            nova.db.sqlalchemy.models.Instance object
224
313
            instance object that is migrated.
225
 
        :params dest: destination host
226
 
        :params post_method:
 
314
        :param dest: destination host
 
315
        :param post_method:
227
316
            post operation method.
228
317
            expected nova.compute.manager.post_live_migration.
229
 
        :params recover_method:
 
318
        :param recover_method:
230
319
            recovery method when any exception occurs.
231
320
            expected nova.compute.manager.recover_live_migration.
232
321
 
235
324
        raise NotImplementedError()
236
325
 
237
326
    def refresh_security_group_rules(self, security_group_id):
 
327
        """This method is called after a change to security groups.
 
328
 
 
329
        All security groups and their associated rules live in the datastore,
 
330
        and calling this method should apply the updated rules to instances
 
331
        running the specified security group.
 
332
 
 
333
        An error should be raised if the operation cannot complete.
 
334
 
 
335
        """
238
336
        # TODO(Vek): Need to pass context in for access to auth_token
239
337
        raise NotImplementedError()
240
338
 
241
339
    def refresh_security_group_members(self, security_group_id):
 
340
        """This method is called when a security group is added to an instance.
 
341
 
 
342
        This message is sent to the virtualization drivers on hosts that are
 
343
        running an instance that belongs to a security group that has a rule
 
344
        that references the security group identified by `security_group_id`.
 
345
        It is the responsiblity of this method to make sure any rules
 
346
        that authorize traffic flow with members of the security group are
 
347
        updated and any new members can communicate, and any removed members
 
348
        cannot.
 
349
 
 
350
        Scenario:
 
351
            * we are running on host 'H0' and we have an instance 'i-0'.
 
352
            * instance 'i-0' is a member of security group 'speaks-b'
 
353
            * group 'speaks-b' has an ingress rule that authorizes group 'b'
 
354
            * another host 'H1' runs an instance 'i-1'
 
355
            * instance 'i-1' is a member of security group 'b'
 
356
 
 
357
            When 'i-1' launches or terminates we will recieve the message
 
358
            to update members of group 'b', at which time we will make
 
359
            any changes needed to the rules for instance 'i-0' to allow
 
360
            or deny traffic coming from 'i-1', depending on if it is being
 
361
            added or removed from the group.
 
362
 
 
363
        In this scenario, 'i-1' could just as easily have been running on our
 
364
        host 'H0' and this method would still have been called.  The point was
 
365
        that this method isn't called on the host where instances of that
 
366
        group are running (as is the case with
 
367
        :method:`refresh_security_group_rules`) but is called where references
 
368
        are made to authorizing those instances.
 
369
 
 
370
        An error should be raised if the operation cannot complete.
 
371
 
 
372
        """
242
373
        # TODO(Vek): Need to pass context in for access to auth_token
243
374
        raise NotImplementedError()
244
375
 
245
376
    def refresh_provider_fw_rules(self, security_group_id):
246
 
        """See: nova/virt/fake.py for docs."""
 
377
        """This triggers a firewall update based on database changes.
 
378
 
 
379
        When this is called, rules have either been added or removed from the
 
380
        datastore.  You can retrieve rules with
 
381
        :method:`nova.db.api.provider_fw_rule_get_all`.
 
382
 
 
383
        Provider rules take precedence over security group rules.  If an IP
 
384
        would be allowed by a security group ingress rule, but blocked by
 
385
        a provider rule, then packets from the IP are dropped.  This includes
 
386
        intra-project traffic in the case of the allow_project_net_traffic
 
387
        flag for the libvirt-derived classes.
 
388
 
 
389
        """
247
390
        # TODO(Vek): Need to pass context in for access to auth_token
248
391
        raise NotImplementedError()
249
392
 
284
427
        raise NotImplementedError()
285
428
 
286
429
    def set_admin_password(self, context, instance_id, new_pass=None):
287
 
        """Set the root/admin password for an instance on this server."""
 
430
        """
 
431
        Set the root password on the specified instance.
 
432
 
 
433
        The first parameter is an instance of nova.compute.service.Instance,
 
434
        and so the instance is being specified as instance.name. The second
 
435
        parameter is the value of the new password.
 
436
        """
288
437
        raise NotImplementedError()
289
438
 
290
439
    def inject_file(self, instance, b64_path, b64_contents):
291
 
        """Create a file on the VM instance. The file path and contents
292
 
        should be base64-encoded.
 
440
        """
 
441
        Writes a file on the specified instance.
 
442
 
 
443
        The first parameter is an instance of nova.compute.service.Instance,
 
444
        and so the instance is being specified as instance.name. The second
 
445
        parameter is the base64-encoded path to which the file is to be
 
446
        written on the instance; the third is the contents of the file, also
 
447
        base64-encoded.
293
448
        """
294
449
        # TODO(Vek): Need to pass context in for access to auth_token
295
450
        raise NotImplementedError()
296
451
 
297
452
    def agent_update(self, instance, url, md5hash):
298
 
        """Update agent on the VM instance."""
 
453
        """
 
454
        Update agent on the specified instance.
 
455
 
 
456
        The first parameter is an instance of nova.compute.service.Instance,
 
457
        and so the instance is being specified as instance.name. The second
 
458
        parameter is the URL of the agent to be fetched and updated on the
 
459
        instance; the third is the md5 hash of the file for verification
 
460
        purposes.
 
461
        """
299
462
        # TODO(Vek): Need to pass context in for access to auth_token
300
463
        raise NotImplementedError()
301
464
 
322
485
        """Plugs in VIFs to networks."""
323
486
        # TODO(Vek): Need to pass context in for access to auth_token
324
487
        raise NotImplementedError()
 
488
 
 
489
    def update_host_status(self):
 
490
        """Refresh host stats"""
 
491
        raise NotImplementedError()
 
492
 
 
493
    def get_host_stats(self, refresh=False):
 
494
        """Return currently known host stats"""
 
495
        raise NotImplementedError()
 
496
 
 
497
    def list_disks(self, instance_name):
 
498
        """
 
499
        Return the IDs of all the virtual disks attached to the specified
 
500
        instance, as a list.  These IDs are opaque to the caller (they are
 
501
        only useful for giving back to this layer as a parameter to
 
502
        disk_stats).  These IDs only need to be unique for a given instance.
 
503
 
 
504
        Note that this function takes an instance ID.
 
505
        """
 
506
        raise NotImplementedError()
 
507
 
 
508
    def list_interfaces(self, instance_name):
 
509
        """
 
510
        Return the IDs of all the virtual network interfaces attached to the
 
511
        specified instance, as a list.  These IDs are opaque to the caller
 
512
        (they are only useful for giving back to this layer as a parameter to
 
513
        interface_stats).  These IDs only need to be unique for a given
 
514
        instance.
 
515
 
 
516
        Note that this function takes an instance ID.
 
517
        """
 
518
        raise NotImplementedError()
 
519
 
 
520
    def resize(self, instance, flavor):
 
521
        """
 
522
        Resizes/Migrates the specified instance.
 
523
 
 
524
        The flavor parameter determines whether or not the instance RAM and
 
525
        disk space are modified, and if so, to what size.
 
526
        """
 
527
        raise NotImplementedError()
 
528
 
 
529
    def block_stats(self, instance_name, disk_id):
 
530
        """
 
531
        Return performance counters associated with the given disk_id on the
 
532
        given instance_name.  These are returned as [rd_req, rd_bytes, wr_req,
 
533
        wr_bytes, errs], where rd indicates read, wr indicates write, req is
 
534
        the total number of I/O requests made, bytes is the total number of
 
535
        bytes transferred, and errs is the number of requests held up due to a
 
536
        full pipeline.
 
537
 
 
538
        All counters are long integers.
 
539
 
 
540
        This method is optional.  On some platforms (e.g. XenAPI) performance
 
541
        statistics can be retrieved directly in aggregate form, without Nova
 
542
        having to do the aggregation.  On those platforms, this method is
 
543
        unused.
 
544
 
 
545
        Note that this function takes an instance ID.
 
546
        """
 
547
        raise NotImplementedError()
 
548
 
 
549
    def interface_stats(self, instance_name, iface_id):
 
550
        """
 
551
        Return performance counters associated with the given iface_id on the
 
552
        given instance_id.  These are returned as [rx_bytes, rx_packets,
 
553
        rx_errs, rx_drop, tx_bytes, tx_packets, tx_errs, tx_drop], where rx
 
554
        indicates receive, tx indicates transmit, bytes and packets indicate
 
555
        the total number of bytes or packets transferred, and errs and dropped
 
556
        is the total number of packets failed / dropped.
 
557
 
 
558
        All counters are long integers.
 
559
 
 
560
        This method is optional.  On some platforms (e.g. XenAPI) performance
 
561
        statistics can be retrieved directly in aggregate form, without Nova
 
562
        having to do the aggregation.  On those platforms, this method is
 
563
        unused.
 
564
 
 
565
        Note that this function takes an instance ID.
 
566
        """
 
567
        raise NotImplementedError()