[pkg-eucalyptus-commits] [SCM] managing cloud instances for Eucalyptus branch, master, updated. 3.0.0-alpha3-257-g1da8e3a
Garrett Holmstrom
gholms at fedoraproject.org
Sun Jun 16 02:29:57 UTC 2013
The following commit has been merged in the master branch:
commit a629896e58b3e9c5726f92659d34f104008a4cf4
Merge: f5745102324e9bf91aeb4849c8c6254eeacad844 97495528e6f5b345ffff9e9030e56ec4472a7143
Author: Garrett Holmstrom <gholms at fedoraproject.org>
Date: Sat Nov 3 21:14:35 2012 -0700
Merge branch 'master' into requestbuilder
Conflicts:
euca2ools/__init__.py
euca2ools/commands/euca/createkeypair.py
euca2ools/commands/euca/describeaddresses.py
euca2ools/commands/euca/describeimageattribute.py
euca2ools/commands/euca/describeimages.py
euca2ools/commands/euca/describeinstances.py
euca2ools/commands/euca/getpassword.py
euca2ools/commands/euca/register.py
setup.py
diff --combined euca2ools/commands/bundle/bundleimage.py
index 0408ecf,7b278ac..7b278ac
--- a/euca2ools/commands/bundle/bundleimage.py
+++ b/euca2ools/commands/bundle/bundleimage.py
@@@ -34,6 -34,7 +34,7 @@@ import euca2ools.commands.eucacomman
from boto.roboto.param import Param
import euca2ools.bundler
from euca2ools.exceptions import NotFoundError, CommandFailed
+ import sys
class BundleImage(euca2ools.commands.eucacommand.EucaCommand):
@@@ -81,7 -82,7 +82,7 @@@
Param(name='target_arch',
short_name='r', long_name='arch',
optional=True, ptype='string', default='x86_64',
- choices=['i386', 'x86_64'],
+ choices=['i386', 'x86_64', 'armhf'],
doc='Target architecture for the image.'),
Param(name='batch', long_name='batch',
optional=True, ptype='boolean',
@@@ -89,13 -90,12 +90,12 @@@
def get_block_devs(self):
mapping_str = self.block_device_mapping
- mapping = []
+ mapping = {}
mapping_pairs = mapping_str.split(',')
for m in mapping_pairs:
m_parts = m.split('=')
if len(m_parts) > 1:
- mapping.append(m_parts[0])
- mapping.append(m_parts[1])
+ mapping[m_parts[0]] = m_parts[1]
return mapping
def add_product_codes(self):
diff --combined euca2ools/commands/bundle/bundleupload.py
index f6b0e16,d9c0a5c..fe5c85f
--- a/euca2ools/commands/bundle/bundleupload.py
+++ b/euca2ools/commands/bundle/bundleupload.py
@@@ -36,8 -36,8 +36,8 @@@ import o
import euca2ools.commands.eucacommand
from boto.roboto.param import Param
from boto.exception import S3ResponseError, S3CreateError
-from euca2ools.commands.euca.uploadbundle import UploadBundle
-from euca2ools.commands.euca.bundleimage import BundleImage
+from euca2ools.commands.bundle.uploadbundle import UploadBundle
+from euca2ools.commands.bundle.bundleimage import BundleImage
import euca2ools.bundler
from euca2ools.exceptions import NotFoundError, CommandFailed
@@@ -86,7 -86,7 +86,7 @@@ class BundleUpload(UploadBundle, Bundle
Param(name='target_arch',
short_name='r', long_name='arch',
optional=True, ptype='string', default='x86_64',
- choices=['i386', 'x86_64'],
+ choices=['i386', 'x86_64', 'armhf'],
doc='Target architecture for the image.'),
Param(name='acl', long_name='acl',
optional=True, ptype='string', default='ec2-bundle-read',
diff --combined euca2ools/commands/bundle/bundlevol.py
index cfc1873,f6452d0..f6452d0
--- a/euca2ools/commands/bundle/bundlevol.py
+++ b/euca2ools/commands/bundle/bundlevol.py
@@@ -40,14 -40,15 +40,15 @@@ import euca2ools.bundle
import euca2ools.metadata
from euca2ools.exceptions import *
- MAX_IMAGE_SIZE = 1024 * 10
+ IMAGE_MAX_SIZE_IN_MB = euca2ools.bundler.IMAGE_MAX_SIZE / 1024 // 1024
class BundleVol(euca2ools.commands.eucacommand.EucaCommand):
-
Description = 'Bundles an image for use with Eucalyptus or Amazon EC2.'
Options = [Param(name='size', short_name='s', long_name='size',
- optional=True, ptype='integer', default=MAX_IMAGE_SIZE,
- doc='Size of the image in MB(max=%d).' % MAX_IMAGE_SIZE),
+ optional=True, ptype='integer',
+ default=IMAGE_MAX_SIZE_IN_MB,
+ doc=('Size of the image in MB (default: {0}; recommended '
+ 'maximum: {0})').format(IMAGE_MAX_SIZE_IN_MB)),
Param(name='user', short_name='u', long_name='user',
optional=True, ptype='string',
doc="""User ID (12-digit) of the user who is
@@@ -98,7 -99,7 +99,7 @@@
Param(name='target_architecture',
short_name='r', long_name='arch',
optional=True, ptype='string', default='x86_64',
- choices=['i386', 'x86_64'],
+ choices=['i386', 'x86_64', 'armhf'],
doc='Target architecture for the image'),
Param(name='volume_path', long_name='volume',
optional=True, ptype='dir', default='/',
@@@ -120,11 -121,6 +121,6 @@@
print 'Must be superuser to execute this command.'
sys.exit()
- def check_image_size(self, size):
- if size > MAX_IMAGE_SIZE:
- msg = 'Image Size is too large (Max = %d MB)' % MAX_IMAGE_SIZE
- self.display_error_and_exit(msg)
-
def parse_excludes(self, excludes_string):
excludes = []
if excludes_string:
@@@ -175,7 -171,7 +171,7 @@@
ancestor_ami_ids)
- def add_product_codes(self, product_code_string, product_codes):
+ def add_product_codes(self, product_code_string, product_codes=None):
if not product_codes:
product_codes = []
product_code_values = product_code_string.split(',')
@@@ -225,9 -221,6 +221,6 @@@
else:
self.fstab_path = 'new'
self.check_root()
- if self.size > MAX_IMAGE_SIZE:
- msg = 'Image Size is too large (Max = %d MB)' % MAX_IMAGE_SIZE
- self.display_error_and_exit(msg)
self.volume_path = os.path.normpath(self.volume_path)
noex='EUCA_BUNDLE_VOL_EMPTY_EXCLUDES'
@@@ -245,7 -238,7 +238,7 @@@
ancestor_ami_ids) = self.get_instance_metadata(self.ramdisk_id,
self.kernel_id,
self.block_device_mapping)
- if self.product_codes:
+ if self.product_codes and isinstance(self.product_codes, basestring):
self.product_codes = self.add_product_codes(self.product_codes)
try:
diff --combined euca2ools/commands/bundle/deletebundle.py
index 56c1c1b,5f6201b..5f6201b
--- a/euca2ools/commands/bundle/deletebundle.py
+++ b/euca2ools/commands/bundle/deletebundle.py
@@@ -36,6 -36,7 +36,7 @@@ from boto.roboto.param import Para
import os
import sys
import textwrap
+ import time
from xml.dom import minidom
from boto.exception import S3ResponseError, S3CreateError
from boto.s3.key import Key
@@@ -178,8 -179,15 +179,15 @@@ class DeleteBundle(euca2ools.commands.e
directory = os.path.abspath('/tmp')
if not self.manifest_path and not self.prefix:
- print 'Neither manifestpath nor prefix was specified.'
- print 'All manifest data in bucket will be deleted.'
+ print 'Neither a manifestpath nor a prefix was specified.'
+ print 'All bundles in bucket', self.bucket, 'will be deleted.'
+ print ('If this is not what you want, press Ctrl+C in the next '
+ '10 seconds'),
+ for __ in range(10):
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ time.sleep(1)
+ print
bucket_instance = self.ensure_bucket(self.bucket)
manifests = None
diff --combined euca2ools/commands/euca/createkeypair.py
index 668b967,ec98b22..d5e5335
--- a/euca2ools/commands/euca/createkeypair.py
+++ b/euca2ools/commands/euca/createkeypair.py
@@@ -1,6 -1,6 +1,6 @@@
# Software License Agreement (BSD License)
#
-# Copyright (c) 2009-2011, Eucalyptus Systems, Inc.
+# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
@@@ -27,15 -27,50 +27,24 @@@
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: Neil Soman neil at eucalyptus.com
-# Mitch Garnaat mgarnaat at eucalyptus.com
-
-import euca2ools.commands.eucacommand
-from boto.roboto.param import Param
-from os import chmod
-from stat import *
-
-class CreateKeyPair(euca2ools.commands.eucacommand.EucaCommand):
-
- Description = 'Creates a new key pair for use with instances'
- Options = [Param(name='filename', short_name='f',
- long_name='filename', ptype='string',
- doc='Filename to save the private key to. Default ' +
- 'action is to overwite the file.',
- optional=True)]
-
- Args = [Param(name='keypair_name', ptype='string',
- doc='unique name for a keypair to be created',
- cardinality=1, optional=False)]
-
- def display_fingerprint(self, keypair):
- print 'KEYPAIR\t%s\t%s' % (keypair.name, keypair.fingerprint)
-
- def display_keypair(self, keypair):
- print keypair.material
-
- def save_keypair_to_file(self, keypair):
- keyfile = open(self.filename, 'w')
- keyfile.write(keypair.material)
- keyfile.close()
-
- chmod(self.filename, S_IRUSR|S_IWUSR)
-
- def main(self):
- conn = self.make_connection_cli()
- return self.make_request_cli(conn, 'create_key_pair',
- key_name=self.keypair_name)
- def main_cli(self):
- keypair = self.main()
- self.display_fingerprint(keypair)
- if self.filename != None:
- self.save_keypair_to_file(keypair)
++import os
+from requestbuilder import Arg
+from . import EucalyptusRequest
+
+class CreateKeyPair(EucalyptusRequest):
+ Description = 'Create a new SSH key pair for use with instances'
- Args = [Arg('KeyName', metavar='KEYPAIR', help='name of the new key pair')]
++ Args = [Arg('KeyName', metavar='KEYPAIR', help='name of the new key pair'),
++ Arg('-f', '--filename', metavar='FILE', route_to=None,
++ help='file name to save the private key to')]
+
+ def print_result(self, result):
+ print self.tabify(('KEYPAIR', result['keyName'],
+ result['keyFingerprint']))
- print result['keyMaterial']
++ if self.args.get('filename'):
++ prev_umask = os.umask(0o077)
++ with open(self.args['filename'], 'w') as privkeyfile:
++ privkeyfile.write(result['keyMaterial'])
++ os.umask(prev_umask)
+ else:
- self.display_keypair(keypair)
++ print result['keyMaterial']
diff --combined euca2ools/commands/euca/describeimages.py
index de68717,c421e90..2d7970c
--- a/euca2ools/commands/euca/describeimages.py
+++ b/euca2ools/commands/euca/describeimages.py
@@@ -1,6 -1,6 +1,6 @@@
# Software License Agreement (BSD License)
#
-# Copyright (c) 2009-2011, Eucalyptus Systems, Inc.
+# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
@@@ -27,122 -27,159 +27,122 @@@
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: Neil Soman neil at eucalyptus.com
-# Mitch Garnaat mgarnaat at eucalyptus.com
-
-import euca2ools.commands.eucacommand
-from boto.roboto.param import Param
-class DescribeImages(euca2ools.commands.eucacommand.EucaCommand):
-
- APIVersion = '2010-08-31'
- Description = 'Shows information about machine images.'
- Options = [Param(name='all', short_name='a', long_name='all',
- optional=True, ptype='boolean', default=False,
- doc='Show all images that the user has access to.'),
- Param(name='owner', short_name='o', long_name='owner',
- optional=True, ptype='string', cardinality='*',
- doc="""Show only images owned by the user.
- Valid values: account ID|self|amazon"""),
- Param(name='executable_by',
- short_name='x', long_name='executable-by',
- optional=True, ptype='string', cardinality='*',
- doc="""Show only images for which user has
- explicit launch permissions.
- Valid values: account ID|self|all""")]
- Args = [Param(name='image', ptype='string',
- cardinality='+', optional=True)]
- Filters = [Param(name='architecture', ptype='string',
- doc='Image architecture. Valid values are i386 | x86_64 | armhf'),
- Param(name='block-device-mapping.delete-on-termination',
- ptype='boolean',
- doc="""Whether the Amazon EBS volume is deleted on
- instance termination."""),
- Param(name='block-device-mapping.device-name', ptype='string',
- doc="""Device name (e.g., /dev/sdh) for an Amazon EBS volume
- mapped to the image."""),
- Param(name='block-device-mapping.snapshot-id', ptype='string',
- doc="""Snapshot ID for an Amazon EBS volume mapped
- to the image."""),
- Param(name='block-device-mapping.volume-size', ptype='integer',
- doc="""Volume size for an Amazon EBS volume mapped
- to the image."""),
- Param(name='description', ptype='string',
- doc='Description of the AMI'),
- Param(name='hypervisor', ptype='string',
- doc="""Hypervisor type of the image.
- Valid values are ovm | xen."""),
- Param(name='image-id', ptype='string',
- doc='ID of the imageID'),
- Param(name='image-type', ptype='string',
- doc="""Type of the image.
- Valid values are machine | kernel | ramdisk"""),
- Param(name='is-public', ptype='boolean',
- doc='Whether the image is public.'),
- Param(name='kernel-id', ptype='string',
- doc='Kernel ID.'),
- Param(name='manifest-location', ptype='string',
- doc='Location of the image manifest.'),
- Param(name='name', ptype='string',
- doc='Name of the AMI.'),
- Param(name='owner-alias', ptype='string',
- doc="""AWS account alias (e.g., amazon or self) or
- AWS account ID that owns the AMI."""),
- Param(name='owner-id', ptype='string',
- doc='AWS account ID of the image owner.'),
- Param(name='platform', ptype='string',
- doc="""Use windows if you have Windows based AMIs;
- otherwise leave blank."""),
- Param(name='product-code', ptype='string',
- doc='Product code associated with the AMI.'),
- Param(name='ramdisk-id', ptype='string',
- doc='The ramdisk ID.'),
- Param(name='root-device-name', ptype='string',
- doc='Root device name of the AMI (e.g., /dev/sda1).'),
- Param(name='root-device-type', ptype='string',
- doc="""Root device type the AMI uses.
- Valid Values: ebs | instance-store."""),
- Param(name='state', ptype='string',
- doc="""State of the image.
- Valid values: available | pending | failed."""),
- Param(name='state-reason-code', ptype='string',
- doc='Reason code for the state change.'),
- Param(name='state-reason-message', ptype='string',
- doc='Message for the state change.'),
- Param(name='tag-key', ptype='string',
- doc='Key of a tag assigned to the resource.'),
- Param(name='tag-value', ptype='string',
- doc='Value of a tag assigned to the resource.'),
- Param(name='tag:key', ptype='string',
- doc="""Filters the results based on a specific
- tag/value combination."""),
- Param(name='virtualization-type', ptype='string',
- doc="""Virtualization type of the image.
- Valid values: paravirtual | hvm""")]
-
- def display_images(self, images):
- for image in images:
- image_string = '%s\t%s\t%s\t%s' % (image.id, image.location,
- image.ownerId, image.state)
- if image.is_public:
- image_string += '\tpublic'
- else:
- image_string += '\tprivate'
+from requestbuilder import Arg, Filter, GenericTagFilter
+from . import EucalyptusRequest
- image_string += '\t%s' % ','.join(image.product_codes)
+class DescribeImages(EucalyptusRequest):
+ Description = '''\
+ Show information about images
- for i in [image.architecture, image.type, image.kernel_id,
- image.ramdisk_id, image.platform,
- image.root_device_type]:
- image_string += '\t%s' % (('' if i == None else i))
+ By default, only images the caller owns and images for which the caller
+ has explicit launch permissions are shown.'''
- print 'IMAGE\t%s' % image_string
- if image.block_device_mapping:
- block_dev_mapping = image.block_device_mapping
- if image.root_device_type == 'ebs':
- block_dev_string = '%s\t%s\t%s' \
- % (block_dev_mapping.current_name,
- block_dev_mapping.current_value.snapshot_id,
- block_dev_mapping.current_value.size)
- print 'BLOCKDEVICEMAPPING\t%s' % block_dev_string
+ APIVersion = '2010-08-31'
+ Args = [Arg('ImageId', metavar='IMAGE', nargs='*',
+ help='limit results to one or more images'),
+ Arg('-a', '--all', action='store_true', route_to=None,
+ help='describe all images'),
+ Arg('-o', '--owner', dest='Owner', metavar='ACCOUNT',
+ action='append',
+ help='describe images owned by the specified owner'),
+ Arg('-x', '--executable-by', dest='ExecutableBy',
+ metavar='ACCOUNT', action='append',
+ help='''describe images for which the specified entity has
+ explicit launch permissions''')]
- Filters = [Filter('architecture', choices=('i386', 'x86_64'),
++ Filters = [Filter('architecture', choices=('i386', 'x86_64', 'armhf'),
+ help='image architecture'),
+ Filter('block-device-mapping.delete-on-termination',
+ help='''whether a volume is deleted upon instance
+ termination'''),
+ Filter('block-device-mapping.device-name',
+ help='device name for a volume mapped to the image'),
+ Filter('block-device-mapping.snapshot-id',
+ help='snapshot ID for a volume mapped to the image'),
+ Filter('block-device-mapping.volume-size',
+ help='volume size for a volume mapped to the image'),
+ Filter('description', help='image description'),
+ Filter('image-id'),
+ Filter('image-type', choices=('machine', 'kernel', 'ramdisk'),
+ help='image type ("machine", "kernel", or "ramdisk")'),
+ Filter('is-public', help='whether the image is public'),
+ Filter('kernel-id'),
+ Filter('manifest-location'),
+ Filter('name'),
+ Filter('owner-alias', help="image owner's account alias"),
+ Filter('owner-id', help="image owner's account ID"),
+ Filter('platform', help='"windows" for Windows images'),
+ Filter('product-code',
+ help='product code associated with the image'),
+ Filter('product-code.type', choices=('devpay', 'marketplace'),
+ help='type of product code associated with the image'),
+ Filter('ramdisk-id'),
+ Filter('root-device-name'),
+ Filter('root-device-type', choices=('ebs', 'instance-store'),
+ help='root device type ("ebs" or "instance-store")'),
+ Filter('state', choices=('available', 'pending', 'failed'),
+ help='''image state ("available", "pending", or
+ "failed")'''),
+ Filter('state-reason-code',
+ help='reason code for the most recent state change'),
+ Filter('state-reason-message',
+ help='message for the most recent state change'),
+ Filter('tag-key', help='key of a tag assigned to the image'),
+ Filter('tag-value',
+ help='value of a tag assigned to the image'),
+ GenericTagFilter('tag:KEY',
+ help='specific tag key/value combination'),
+ Filter('virtualization-type', choices=('paravirtual', 'hvm'),
+ help='virtualization type ("paravirtual" or "hvm")'),
+ Filter('hypervisor', choices=('ovm', 'xen'),
+ help='image\'s hypervisor type ("ovm" or "xen")')]
+ ListDelims = ['imagesSet', 'blockDeviceMapping', 'tagSet']
def main(self):
- if self.all and (self.owner or self.executable_by or self.image):
- msg = '-a cannot be combined with owner, launch, or image list'
- self.display_error_and_exit(msg)
-
- # if you specify "-a" then it means return ALL images
- if self.all:
- self.executable_by = []
- self.owner = []
-
- conn = self.make_connection_cli()
- if (self.executable_by or self.owner or self.image or self.all):
- images = self.make_request_cli(conn, 'get_all_images',
- image_ids=self.image,
- owners=self.owner,
- executable_by=self.executable_by)
- else:
- owned = self.make_request_cli(conn, 'get_all_images',
- image_ids = None, owners = ("self",), executable_by = None)
- launchable = self.make_request_cli(conn, 'get_all_images',
- image_ids = None, owners = None, executable_by = ("self"))
+ if not any(self.args.get(item) for item in ('all', 'ImageId',
+ 'ExecutableBy', 'Owner')):
+ # Default to owned images and images with explicit launch perms
+ self.params = {'Owner': 'self'}
+ owned = self.send()
+ self.params = {'ExecutableBy': 'self'}
+ executable = self.send()
+ self.params = None
+ owned['imagesSet'] = (owned.get( 'imagesSet', []) +
+ executable.get('imagesSet', []))
+ return owned
+ if self.args['all']:
+ if self.args.get('ImageId'):
+ self._cli_parser.error('argument -a/--all: not allowed with '
+ 'a list of images')
+ if self.args.get('ExecutableBy'):
+ self._cli_parser.error('argument -a/--all: not allowed with '
+ 'argument -x/--executable-by')
+ if self.args.get('Owner'):
+ self._cli_parser.error('argument -a/--all: not allowed with '
+ 'argument -o/--owner')
+ return self.send()
- seen = { }
- images = [ ]
- for image in owned:
- seen[image.id] = True
- images.append(image)
- for image in launchable:
- if image.id not in seen:
- images.append(image)
+ def print_result(self, result):
+ for image in result.get('imagesSet', []):
+ self.print_image(image)
- return images
+ def print_image(self, image):
+ print self.tabify(('IMAGE', image.get('imageId'),
+ image.get('imageLocation'),
+ image.get('imageOwnerAlias') or image.get('imageOwnerId'),
+ image.get('imageState'),
+ ('public' if image.get('isPublic') == 'true' else 'private'),
+ image.get('architecture'), image.get('imageType'),
+ image.get('kernelId'), image.get('ramdiskId'),
+ image.get('platform'), image.get('rootDeviceType'),
+ image.get('virtualizationType'), image.get('hypervisor')))
+ for mapping in image.get('blockDeviceMapping', []):
+ self.print_blockdevice_mapping(mapping)
+ for tag in image.get('tagSet', []):
+ self.print_resource_tag(tag, image.get('imageId'))
- def main_cli(self):
- images = self.main()
- self.display_images(images)
+ def print_blockdevice_mapping(self, mapping):
+ print self.tabify(('BLOCKDEVICEMAPPING', mapping.get('deviceName'),
+ mapping.get('ebs', {}).get('snapshotId'),
+ mapping.get('ebs', {}).get('volumeSize'),
+ mapping.get('ebs', {}).get('deleteOnTermination')))
diff --combined euca2ools/commands/euca/getpassword.py
index bbd4522,66a90f9..960ca89
--- a/euca2ools/commands/euca/getpassword.py
+++ b/euca2ools/commands/euca/getpassword.py
@@@ -1,6 -1,6 +1,6 @@@
# Software License Agreement (BSD License)
#
-# Copyright (c) 20092011, Eucalyptus Systems, Inc.
+# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
@@@ -27,25 -27,47 +27,29 @@@
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: Neil Soman neil at eucalyptus.com
-# Mitch Garnaat mgarnaat at eucalyptus.com
-
-import euca2ools.commands.eucacommand
-import euca2ools.bundler
-import sys
-from boto.roboto.param import Param
-class GetPassword(euca2ools.commands.eucacommand.EucaCommand):
+import base64
+from M2Crypto import RSA
+from requestbuilder import Arg
+from .argtypes import file_contents
+from .getpassworddata import GetPasswordData
- Description = """Retrieves decrypts the administrator password
- for a Windows instance."""
- Options = [Param(name='privatekey',
- short_name='k', long_name='priv-launch-key',
- ptype='file', optional=False,
- doc="""The file that contains the private key
- used to launch the instance.""")]
- Args = [Param(name='instance_id', ptype='string', optional=False,
- doc='unique identifier for the Windows instance')]
+class GetPassword(GetPasswordData):
+ Action = 'GetPasswordData'
+ Description = '''Retrieve the administrator password for an instance
+ running Windows'''
+ Args = [Arg('-k', '--priv-launch-key', metavar='PRIVKEY',
+ type=file_contents, required=True, route_to=None,
+ help='''file containing the private key corresponding to the
+ key pair supplied at instance launch time''')]
- def main(self):
- conn = self.make_connection_cli()
+ def print_result(self, result):
- pwdata = result['passwordData']
+ try:
- pd = self.make_request_cli(conn, 'get_password_data',
- instance_id=self.instance_id)
++ pwdata = result['passwordData']
+ except AttributeError:
- # The reply didn't contain a passwordData element. Boto doesn't
- # handle this since EC2 always includes one, even if it is empty.
- return None
- if pd:
- # TODO - this is actually in the bundler
- # TODO validate file?
- return euca2ools.bundler.Bundler(self).decrypt_string(
- pd, self.privatekey, encoded=True)
- else:
- return None
-
- def main_cli(self):
- pw = self.main()
- if pw:
- print pw
- else:
- sys.exit('no password found for this instance')
++ # The reply didn't contain a passwordData element.
++ raise AttributeError('no password data found for this instance')
+ privkey = RSA.load_key_string(self.args['priv_launch_key'])
+ password = privkey.private_decrypt(base64.b64decode(pwdata),
+ RSA.pkcs1_padding)
+ print password
diff --combined euca2ools/commands/eustore/installimage.py
index b2ef8e4,e15415d..d2f8e42
--- a/euca2ools/commands/eustore/installimage.py
+++ b/euca2ools/commands/eustore/installimage.py
@@@ -36,6 -36,7 +36,7 @@@ import o
import sys
import tarfile
import hashlib
+ import re
import zlib
import tempfile
import urllib2
@@@ -47,8 -48,8 +48,8 @@@ from boto.s3.connection import Locatio
import euca2ools.bundler
import euca2ools.commands.eustore
import euca2ools.utils
-from euca2ools.commands.euca.bundleimage import BundleImage
-from euca2ools.commands.euca.uploadbundle import UploadBundle
+from euca2ools.commands.bundle.bundleimage import BundleImage
+from euca2ools.commands.bundle.uploadbundle import UploadBundle
from euca2ools.commands.euca.register import Register
from euca2ools.exceptions import NotFoundError, CommandFailed
@@@ -164,7 -165,7 +165,7 @@@ class InstallImage(AWSQueryRequest)
print type+": "+name+" is already installed on the cloud, skipping installation of another one."
return True
else:
- answer = raw_input(type+": "+name+" is already installed on ths cloud. Would you like to use it intead?(y/N)")
+ answer = raw_input(type + ": " + name + " is already installed on this cloud. Would you like to use it instead? (y/N)")
if (answer=='y' or answer=='Y'):
return True
return False
@@@ -268,14 -269,15 +269,15 @@@
if not(kernel_dir) and (os.path.dirname(path) != tar_root):
continue;
if not name.startswith('.'):
- if name.startswith('vmlin'):
+ # Note that vmlinuz is not always at the beginning of the filename
+ if name.find('vmlinu') != -1:
print "Bundling/uploading kernel"
if prefix:
name = prefix+name
kernel_id = self.bundleFile(path, name, description, arch, 'true', None)
kernel_found = True
print kernel_id
- elif name.startswith('initrd'):
+ elif re.match(".*(initr(d|amfs)|loader).*", name):
print "Bundling/uploading ramdisk"
if prefix:
name = prefix+name
diff --combined setup.py
index c7148d4,89433ab..e1d2633
--- a/setup.py
+++ b/setup.py
@@@ -31,13 -31,39 +31,39 @@@
# Author: Neil Soman neil at eucalyptus.com
# Mitch Garnaat mgarnaat at eucalyptus.com
- try:
- from setuptools import setup
- except ImportError:
- from distutils.core import setup
+ from distutils.core import setup
+ from distutils.command.build_scripts import build_scripts
+ from distutils.command.install_scripts import install_scripts
+ import os.path
from euca2ools import __version__
+ # Cheap hack: install symlinks separately from regular files.
+ # cmd.copy_tree accepts a preserve_symlinks option, but when we call
+ # ``setup.py install'' more than once the method fails when it encounters
+ # symlinks that are already there.
+
+ class build_scripts_except_symlinks(build_scripts):
+ '''Like build_scripts, but ignoring symlinks'''
+ def copy_scripts(self):
+ orig_scripts = self.scripts
+ self.scripts = [script for script in self.scripts
+ if not os.path.islink(script)]
+ build_scripts.copy_scripts(self)
+ self.scripts = orig_scripts
+
+ class install_scripts_and_symlinks(install_scripts):
+ '''Like install_scripts, but also replicating nonexistent symlinks'''
+ def run(self):
+ install_scripts.run(self)
+ # Replicate symlinks if they don't exist
+ for script in self.distribution.scripts:
+ if os.path.islink(script):
+ target = os.readlink(script)
+ newlink = os.path.join(self.install_dir, os.path.basename(script))
+ if not os.path.exists(newlink):
+ os.symlink(target, newlink)
+
setup(name = "euca2ools",
version = __version__,
description = "Elastic Utility Computing Architecture Command Line Tools",
@@@ -169,12 -195,11 +195,12 @@@
"bin/eustore-install-image"],
url = "http://open.eucalyptus.com",
packages = ["euca2ools", "euca2ools.nc", "euca2ools.commands",
- "euca2ools.commands.euca", "euca2ools.commands.euare",
- "euca2ools.commands.eustore"],
+ "euca2ools.commands.bundle", "euca2ools.commands.euca",
+ "euca2ools.commands.euare", "euca2ools.commands.eustore",
+ "euca2ools.commands.walrus"],
license = 'BSD (Simplified)',
platforms = 'Posix; MacOS X; Windows',
- classifiers = ['Development Status :: 5 - Production/Stable',
+ classifiers = ['Development Status :: 2 - Pre-Alpha',
'Intended Audience :: Users',
'License :: OSI Approved :: Simplified BSD License',
'Operating System :: OS Independent',
@@@ -183,4 -208,5 +209,5 @@@
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Topic :: Internet'],
- )
+ cmdclass = {'build_scripts': build_scripts_except_symlinks,
+ 'install_scripts': install_scripts_and_symlinks})
--
managing cloud instances for Eucalyptus
More information about the pkg-eucalyptus-commits
mailing list