Index: boto/boto/ec2/instance.py =================================================================== --- boto.orig/boto/ec2/instance.py +++ boto/boto/ec2/instance.py @@ -15,7 +15,7 @@ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. @@ -33,6 +33,29 @@ from boto.ec2.networkinterface import Ne from boto.ec2.group import Group import base64 + +class InstanceState(object): + """ + """ + def __init__(self, code=0, name=None): + self.code = code + self.name = name + + def __repr__(self): + return '%s(%d)' % (self.name, self.code) + + def startElement(self, name, attrs, connection): + pass + + def endElement(self, name, value, connection): + if name == 'code': + self.code = int(value) + elif name == 'name': + self.name = value + else: + setattr(self, name, value) + + class Reservation(EC2Object): """ Represents a Reservation response object. @@ -44,7 +67,6 @@ class Reservation(EC2Object): :ivar instances: A list of Instance objects launched in this Reservation. """ - def __init__(self, connection=None): EC2Object.__init__(self, connection) self.id = None @@ -76,7 +98,8 @@ class Reservation(EC2Object): def stop_all(self): for instance in self.instances: instance.stop() - + + class Instance(TaggedEC2Object): """ Represents an instance. @@ -86,8 +109,13 @@ class Instance(TaggedEC2Object): groups associated with the instance. :ivar public_dns_name: The public dns name of the instance. :ivar private_dns_name: The private dns name of the instance. - :ivar state: The string representation of the instances current state. - :ivar state_code: An integer representation of the instances current state. + :ivar state: The string representation of the instance's current state. + :ivar state_code: An integer representation of the instance's + current state. + :ivar previous_state: The string representation of the instance's + previous state. + :ivar previous_state_code: An integer representation of the + instance's current state. :ivar key_name: The name of the SSH key associated with the instance. :ivar instance_type: The type of instance (e.g. m1.small). :ivar launch_time: The time the instance was launched. @@ -116,18 +144,14 @@ class Instance(TaggedEC2Object): :ivar interfaces: List of Elastic Network Interfaces associated with this instance. """ - + def __init__(self, connection=None): TaggedEC2Object.__init__(self, connection) self.id = None self.dns_name = None self.public_dns_name = None self.private_dns_name = None - self.state = None - self.state_code = None self.key_name = None - self.shutdown_state = None - self.previous_state = None self.instance_type = None self.launch_time = None self.image_id = None @@ -158,10 +182,32 @@ class Instance(TaggedEC2Object): self.hypervisor = None self.virtualization_type = None self.architecture = None + self._previous_state = None + self._state = InstanceState() def __repr__(self): return 'Instance:%s' % self.id + @property + def state(self): + return self._state.name + + @property + def state_code(self): + return self._state.code + + @property + def previous_state(self): + if self._previous_state: + return self._previous_state.name + return None + + @property + def previous_state_code(self): + if self._previous_state: + return self._previous_state.code + return 0 + def startElement(self, name, attrs, connection): retval = TaggedEC2Object.startElement(self, name, attrs, connection) if retval is not None: @@ -187,6 +233,13 @@ class Instance(TaggedEC2Object): elif name == 'iamInstanceProfile': self.instance_profile = SubParse('iamInstanceProfile') return self.instance_profile + elif name == 'currentState': + return self._state + elif name == 'previousState': + self._previous_state = InstanceState() + return self._previous_state + elif name == 'instanceState': + return self._state return None def endElement(self, name, value, connection): @@ -203,8 +256,6 @@ class Instance(TaggedEC2Object): self.key_name = value elif name == 'amiLaunchIndex': self.ami_launch_index = value - elif name == 'shutdownState': - self.shutdown_state = value elif name == 'previousState': self.previous_state = value elif name == 'name': @@ -310,7 +361,7 @@ class Instance(TaggedEC2Object): :type force: bool :param force: Forces the instance to stop - + :rtype: list :return: A list of the instances stopped """ @@ -411,6 +462,7 @@ class Instance(TaggedEC2Object): """ return self.connection.reset_instance_attribute(self.id, attribute) + class ConsoleOutput: def __init__(self, parent=None): @@ -432,10 +484,12 @@ class ConsoleOutput: else: setattr(self, name, value) + class InstanceAttribute(dict): ValidValues = ['instanceType', 'kernel', 'ramdisk', 'userData', - 'disableApiTermination', 'instanceInitiatedShutdownBehavior', + 'disableApiTermination', + 'instanceInitiatedShutdownBehavior', 'rootDeviceName', 'blockDeviceMapping', 'sourceDestCheck', 'groupSet'] @@ -465,6 +519,7 @@ class InstanceAttribute(dict): elif name in self.ValidValues: self[name] = self._current_value + class SubParse(dict): def __init__(self, section, parent=None): @@ -477,4 +532,3 @@ class SubParse(dict): def endElement(self, name, value, connection): if name != self.section: self[name] = value -