Beispiel #1
0
    def __init__(self,
                 name,
                 password,
                 connection,
                 hd_image,
                 base_image=None,
                 xml=None,
                 max_builds=None,
                 notify_on_missing=[],
                 missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10,
                 properties={},
                 locks=None):
        AbstractLatentBuildSlave.__init__(self, name, password, max_builds,
                                          notify_on_missing, missing_timeout,
                                          build_wait_timeout, properties,
                                          locks)

        if not libvirt:
            config.error(
                "The python module 'libvirt' is needed to use a LibVirtSlave")

        self.name = name
        self.connection = connection
        self.image = hd_image
        self.base_image = base_image
        self.xml = xml

        self.cheap_copy = True
        self.graceful_shutdown = False

        self.domain = None

        self.ready = False
        self._find_existing_deferred = self._find_existing_instance()
Beispiel #2
0
    def __init__(self,
                 name,
                 password,
                 flavor,
                 image,
                 os_username,
                 os_password,
                 os_tenant_name,
                 os_auth_url,
                 meta=None,
                 max_builds=None,
                 notify_on_missing=[],
                 missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10,
                 properties={},
                 locks=None):

        if not client or not nce:
            config.error("The python module 'novaclient' is needed  "
                         "to use a OpenStackLatentBuildSlave")

        AbstractLatentBuildSlave.__init__(self, name, password, max_builds,
                                          notify_on_missing, missing_timeout,
                                          build_wait_timeout, properties,
                                          locks)
        self.flavor = flavor
        self.image = image
        self.os_username = os_username
        self.os_password = os_password
        self.os_tenant_name = os_tenant_name
        self.os_auth_url = os_auth_url
        self.meta = meta
Beispiel #3
0
 def __init__(self, name, password, aws_id_file_path, region,
              instance_name):
     if not boto:
         config.error(
             "The python module 'boto' is needed to use EC2 build slaves")
     AbstractLatentBuildSlave.__init__(self,
                                       name,
                                       password,
                                       max_builds=None,
                                       notify_on_missing=[],
                                       missing_timeout=60 * 20,
                                       build_wait_timeout=0,
                                       properties={},
                                       locks=None)
     if not os.path.exists(aws_id_file_path):
         raise ValueError(
             "Please supply your AWS credentials in "
             "the {} file (on two lines).".format(aws_id_file_path))
     with open(aws_id_file_path, "r") as aws_credentials_file:
         access_key_id = aws_credentials_file.readline().strip()
         secret_key = aws_credentials_file.readline().strip()
     self.conn = boto.ec2.connect_to_region(
         region,
         aws_access_key_id=access_key_id,
         aws_secret_access_key=secret_key)
     self.instance = self.conn.get_only_instances(
         filters={"tag:Name": instance_name})[0]
Beispiel #4
0
    def __init__(self, name, password, connection, hd_image, base_image=None, xml=None, max_builds=None, notify_on_missing=None,
                 missing_timeout=60 * 20, build_wait_timeout=60 * 10, properties=None, locks=None):
        if notify_on_missing is None:
            notify_on_missing = []
        if properties is None:
            properties = {}

        AbstractLatentBuildSlave.__init__(self, name, password, max_builds, notify_on_missing,
                                          missing_timeout, build_wait_timeout, properties, locks)

        if not libvirt:
            config.error("The python module 'libvirt' is needed to use a LibVirtSlave")

        self.name = name
        self.connection = connection
        self.image = hd_image
        self.base_image = base_image
        self.xml = xml

        self.cheap_copy = True
        self.graceful_shutdown = False

        self.domain = None

        self.ready = False
        self._find_existing_deferred = self._find_existing_instance()
Beispiel #5
0
    def __init__(self, name, password,
                 flavor,
                 os_username,
                 os_password,
                 os_tenant_name,
                 os_auth_url,
                 block_devices=None,
                 image=None,
                 meta=None,
                 # Have a nova_args parameter to allow passing things directly
                 # to novaclient v1.1.
                 nova_args=None,
                 **kwargs):

        if not client or not nce:
            config.error("The python module 'novaclient' is needed  "
                         "to use a OpenStackLatentBuildSlave")

        if not block_devices and not image:
            raise ValueError('One of block_devices or image must be given')

        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)

        self.flavor = flavor
        self.os_username = os_username
        self.os_password = os_password
        self.os_tenant_name = os_tenant_name
        self.os_auth_url = os_auth_url
        if block_devices is not None:
            self.block_devices = [self._parseBlockDevice(bd) for bd in block_devices]
        else:
            self.block_devices = None
        self.image = image
        self.meta = meta
        self.nova_args = nova_args if nova_args is not None else {}
Beispiel #6
0
    def __init__(self, name, password,
                 flavor,
                 image,
                 os_username,
                 os_password,
                 os_tenant_name,
                 os_auth_url,
                 meta=None,
                 max_builds=None, notify_on_missing=[], missing_timeout=60*20,
                 build_wait_timeout=60*10, properties={}, locks=None):

        if not client or not nce:
            config.error("The python module 'novaclient' is needed  "
                         "to use a OpenStackLatentBuildSlave")

        AbstractLatentBuildSlave.__init__(
            self, name, password, max_builds, notify_on_missing,
            missing_timeout, build_wait_timeout, properties, locks)
        self.flavor = flavor
        self.image = image
        self.os_username = os_username
        self.os_password = os_password
        self.os_tenant_name = os_tenant_name
        self.os_auth_url = os_auth_url
        self.meta = meta
    def __init__(self, name, password, ssh_host, username, key_path, host_key_file=os.path.expanduser("~/.ssh/known_hosts"), **kwargs):
        """
        Creates a new SSH latent build slave with the given parameters.
        """
        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)
        self.client = SSHClient()
        self.client.load_system_host_keys(host_key_file)

        self.hostname = ssh_host
        self.username = username
        self.key_path = key_path
        self.started = False
    def __init__(self, name, password, hostname, username,
                 command, key_path=None, **kwargs):
        """
        Creates a new SSH latent build slave with the given parameters.
        """
        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)
        self.client = SSHClient()
        self.client.load_system_host_keys()

        self.hostname = hostname
        self.username = username
        self.command = command
        self.key_path = key_path

        self.started = False
Beispiel #9
0
    def __init__(
        self,
        name,
        password,
        flavor,
        os_username,
        os_password,
        os_tenant_name,
        os_auth_url,
        block_devices=None,
        image=None,
        meta=None,
        max_builds=None,
        notify_on_missing=[],
        missing_timeout=60 * 20,
        build_wait_timeout=60 * 10,
        properties={},
        locks=None,
        # Have a nova_args parameter to allow passing things directly
        # to novaclient v1.1.
        nova_args=None):

        if not client or not nce:
            config.error("The python module 'novaclient' is needed  "
                         "to use a OpenStackLatentBuildSlave")

        if not block_devices and not image:
            raise ValueError('One of block_devices or image must be given')

        AbstractLatentBuildSlave.__init__(self, name, password, max_builds,
                                          notify_on_missing, missing_timeout,
                                          build_wait_timeout, properties,
                                          locks)
        self.flavor = flavor
        self.os_username = os_username
        self.os_password = os_password
        self.os_tenant_name = os_tenant_name
        self.os_auth_url = os_auth_url
        if block_devices is not None:
            self.block_devices = [
                self._parseBlockDevice(bd) for bd in block_devices
            ]
        else:
            self.block_devices = None
        self.image = image
        self.meta = meta
        self.nova_args = nova_args if nova_args is not None else {}
    def __init__(self, name, password, droplet_name, token, region, image,
                 size_slug, backups=False,
                 max_builds=None, notify_on_missing=[], missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10, properties={}, locks=None):

        build_wait_timeout = 60*10 # FIXME:  Wait for Docker to start?
        AbstractLatentBuildSlave.__init__(
            self, name, password, max_builds, notify_on_missing,
            missing_timeout, build_wait_timeout, properties, locks)

        self.token = token
        self.name = name
        self.region=region
        self.image=image
        self.size_slug=size_slug
        self.backups=backups

        self.mgr = digitalocean.Manager(token=token)
Beispiel #11
0
    def __init__(self, name, password, connection, hd_image, base_image=None, xml=None,
                 **kwargs):
        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)
        if not libvirt:
            config.error("The python module 'libvirt' is needed to use a LibVirtSlave")

        self.connection = connection
        self.image = hd_image
        self.base_image = base_image
        self.xml = xml

        self.cheap_copy = True
        self.graceful_shutdown = False

        self.domain = None

        self.ready = False
        self._find_existing_deferred = self._find_existing_instance()
Beispiel #12
0
    def __init__(self, name, password,
                 flavor,
                 os_username,
                 os_password,
                 os_tenant_name,
                 os_auth_url,
                 block_devices=None,
                 image=None,
                 meta=None,
                 max_builds=None, notify_on_missing=None, missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10, properties=None, locks=None,
                 # Have a nova_args parameter to allow passing things directly
                 # to novaclient v1.1.
                 nova_args=None):

        if not client or not nce:
            config.error("The python module 'novaclient' is needed  "
                         "to use a OpenStackLatentBuildSlave")

        if not block_devices and not image:
            raise ValueError('One of block_devices or image must be given')

        if notify_on_missing is None:
            notify_on_missing = []

        if properties is None:
            properties = {}

        AbstractLatentBuildSlave.__init__(
            self, name, password, max_builds, notify_on_missing,
            missing_timeout, build_wait_timeout, properties, locks)
        self.flavor = flavor
        self.os_username = os_username
        self.os_password = os_password
        self.os_tenant_name = os_tenant_name
        self.os_auth_url = os_auth_url
        if block_devices is not None:
            self.block_devices = [self._parseBlockDevice(bd) for bd in block_devices]
        else:
            self.block_devices = None
        self.image = image
        self.meta = meta
        self.nova_args = nova_args if nova_args is not None else {}
Beispiel #13
0
    def canStartBuild(self):
        if not self.ready:
            log.msg("Not accepting builds as existing domains not iterated")
            return False

        if self.domain and not self.isConnected():
            log.msg("Not accepting builds as existing domain but slave not connected")
            return False

        return AbstractLatentBuildSlave.canStartBuild(self)
Beispiel #14
0
    def canStartBuild(self):
        if not self.ready:
            log.msg("Not accepting builds as existing domains not iterated")
            return False

        if self.domain and not self.isConnected():
            log.msg("Not accepting builds as existing domain but slave not connected")
            return False

        return AbstractLatentBuildSlave.canStartBuild(self)
Beispiel #15
0
    def __init__(self, name, password, instance_type, ami=None,
                 valid_ami_owners=None, valid_ami_location_regex=None,
                 elastic_ip=None, identifier=None, secret_identifier=None,
                 aws_id_file_path=None, user_data=None, region=None,
                 keypair_name='latent_buildbot_slave',
                 security_name='latent_buildbot_slave',
                 max_builds=None, notify_on_missing=[], missing_timeout=60 * 20,
                 build_wait_timeout=60 * 10, properties={}, locks=None,
                 spot_instance=False, max_spot_price=1.6, volumes=[],
                 placement=None, price_multiplier=1.2, tags={}, retry=1,
                 retry_price_adjustment=1, product_description='Linux/UNIX'):

        if not boto:
            config.error("The python module 'boto' is needed to use a "
                         "EC2LatentBuildSlave")

        AbstractLatentBuildSlave.__init__(
            self, name, password, max_builds, notify_on_missing,
            missing_timeout, build_wait_timeout, properties, locks)
        if not ((ami is not None) ^
                (valid_ami_owners is not None or
                 valid_ami_location_regex is not None)):
            raise ValueError(
                'You must provide either a specific ami, or one or both of '
                'valid_ami_location_regex and valid_ami_owners')
        self.ami = ami
        if valid_ami_owners is not None:
            if isinstance(valid_ami_owners, (int, long)):
                valid_ami_owners = (valid_ami_owners,)
            else:
                for element in valid_ami_owners:
                    if not isinstance(element, (int, long)):
                        raise ValueError(
                            'valid_ami_owners should be int or iterable '
                            'of ints', element)
        if valid_ami_location_regex is not None:
            if not isinstance(valid_ami_location_regex, basestring):
                raise ValueError(
                    'valid_ami_location_regex should be a string')
            else:
                # verify that regex will compile
                re.compile(valid_ami_location_regex)
        self.valid_ami_owners = valid_ami_owners
        self.valid_ami_location_regex = valid_ami_location_regex
        self.instance_type = instance_type
        self.keypair_name = keypair_name
        self.security_name = security_name
        self.user_data = user_data
        self.spot_instance = spot_instance
        self.max_spot_price = max_spot_price
        self.volumes = volumes
        self.price_multiplier = price_multiplier
        self.retry_price_adjustment = retry_price_adjustment
        self.retry = retry
        self.attempt = 1
        self.product_description = product_description
        if None not in [placement, region]:
            self.placement = '%s%s' % (region, placement)
        else:
            self.placement = None
        if identifier is None:
            assert secret_identifier is None, (
                'supply both or neither of identifier, secret_identifier')
            if aws_id_file_path is None:
                home = os.environ['HOME']
                aws_id_file_path = os.path.join(home, '.ec2', 'aws_id')
            if not os.path.exists(aws_id_file_path):
                raise ValueError(
                    "Please supply your AWS access key identifier and secret "
                    "access key identifier either when instantiating this %s "
                    "or in the %s file (on two lines).\n" %
                    (self.__class__.__name__, aws_id_file_path))
            with open(aws_id_file_path, 'r') as aws_file:
                identifier = aws_file.readline().strip()
                secret_identifier = aws_file.readline().strip()
        else:
            assert aws_id_file_path is None, \
                'if you supply the identifier and secret_identifier, ' \
                'do not specify the aws_id_file_path'
            assert secret_identifier is not None, \
                'supply both or neither of identifier, secret_identifier'

        region_found = None

        # Make the EC2 connection.
        if region is not None:
            for r in boto.ec2.regions(aws_access_key_id=identifier,
                                      aws_secret_access_key=secret_identifier):

                if r.name == region:
                    region_found = r

            if region_found is not None:
                self.conn = boto.ec2.connect_to_region(region,
                                                       aws_access_key_id=identifier,
                                                       aws_secret_access_key=secret_identifier)
            else:
                raise ValueError(
                    'The specified region does not exist: {0}'.format(region))

        else:
            self.conn = boto.connect_ec2(identifier, secret_identifier)

        # Make a keypair
        #
        # We currently discard the keypair data because we don't need it.
        # If we do need it in the future, we will always recreate the keypairs
        # because there is no way to
        # programmatically retrieve the private key component, unless we
        # generate it and store it on the filesystem, which is an unnecessary
        # usage requirement.
        try:
            key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
            assert key_pair
            # key_pair.delete() # would be used to recreate
        except boto.exception.EC2ResponseError, e:
            if 'InvalidKeyPair.NotFound' not in e.body:
                if 'AuthFailure' in e.body:
                    print ('POSSIBLE CAUSES OF ERROR:\n'
                           '  Did you sign up for EC2?\n'
                           '  Did you put a credit card number in your AWS '
                           'account?\n'
                           'Please doublecheck before reporting a problem.\n')
                raise
            # make one; we would always do this, and stash the result, if we
            # needed the key (for instance, to SSH to the box).  We'd then
            # use paramiko to use the key to connect.
            self.conn.create_key_pair(keypair_name)
Beispiel #16
0
    def __init__(self,
                 name,
                 password,
                 instance_type,
                 ami=None,
                 valid_ami_owners=None,
                 valid_ami_location_regex=None,
                 elastic_ip=None,
                 identifier=None,
                 secret_identifier=None,
                 aws_id_file_path=None,
                 user_data=None,
                 region=None,
                 keypair_name='latent_buildbot_slave',
                 security_name='latent_buildbot_slave',
                 spot_instance=False,
                 max_spot_price=1.6,
                 volumes=None,
                 placement=None,
                 price_multiplier=1.2,
                 tags=None,
                 retry=1,
                 retry_price_adjustment=1,
                 product_description='Linux/UNIX',
                 **kwargs):

        if not boto:
            config.error("The python module 'boto' is needed to use a "
                         "EC2LatentBuildSlave")

        if volumes is None:
            volumes = []

        if tags is None:
            tags = {}

        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)

        if not ((ami is not None) ^ (valid_ami_owners is not None
                                     or valid_ami_location_regex is not None)):
            raise ValueError(
                'You must provide either a specific ami, or one or both of '
                'valid_ami_location_regex and valid_ami_owners')
        self.ami = ami
        if valid_ami_owners is not None:
            if isinstance(valid_ami_owners, (int, long)):
                valid_ami_owners = (valid_ami_owners, )
            else:
                for element in valid_ami_owners:
                    if not isinstance(element, (int, long)):
                        raise ValueError(
                            'valid_ami_owners should be int or iterable '
                            'of ints', element)
        if valid_ami_location_regex is not None:
            if not isinstance(valid_ami_location_regex, basestring):
                raise ValueError('valid_ami_location_regex should be a string')
            else:
                # verify that regex will compile
                re.compile(valid_ami_location_regex)
        self.valid_ami_owners = valid_ami_owners
        self.valid_ami_location_regex = valid_ami_location_regex
        self.instance_type = instance_type
        self.keypair_name = keypair_name
        self.security_name = security_name
        self.user_data = user_data
        self.spot_instance = spot_instance
        self.max_spot_price = max_spot_price
        self.volumes = volumes
        self.price_multiplier = price_multiplier
        self.retry_price_adjustment = retry_price_adjustment
        self.retry = retry
        self.attempt = 1
        self.product_description = product_description
        if None not in [placement, region]:
            self.placement = '%s%s' % (region, placement)
        else:
            self.placement = None
        if identifier is None:
            assert secret_identifier is None, (
                'supply both or neither of identifier, secret_identifier')
            if aws_id_file_path is None:
                home = os.environ['HOME']
                aws_id_file_path = os.path.join(home, '.ec2', 'aws_id')
            if not os.path.exists(aws_id_file_path):
                raise ValueError(
                    "Please supply your AWS access key identifier and secret "
                    "access key identifier either when instantiating this %s "
                    "or in the %s file (on two lines).\n" %
                    (self.__class__.__name__, aws_id_file_path))
            with open(aws_id_file_path, 'r') as aws_file:
                identifier = aws_file.readline().strip()
                secret_identifier = aws_file.readline().strip()
        else:
            assert aws_id_file_path is None, \
                'if you supply the identifier and secret_identifier, ' \
                'do not specify the aws_id_file_path'
            assert secret_identifier is not None, \
                'supply both or neither of identifier, secret_identifier'

        region_found = None

        # Make the EC2 connection.
        if region is not None:
            for r in boto.ec2.regions(aws_access_key_id=identifier,
                                      aws_secret_access_key=secret_identifier):

                if r.name == region:
                    region_found = r

            if region_found is not None:
                self.conn = boto.ec2.connect_to_region(
                    region,
                    aws_access_key_id=identifier,
                    aws_secret_access_key=secret_identifier)
            else:
                raise ValueError('The specified region does not exist: ' +
                                 region)

        else:
            self.conn = boto.connect_ec2(identifier, secret_identifier)

        # Make a keypair
        #
        # We currently discard the keypair data because we don't need it.
        # If we do need it in the future, we will always recreate the keypairs
        # because there is no way to
        # programmatically retrieve the private key component, unless we
        # generate it and store it on the filesystem, which is an unnecessary
        # usage requirement.
        try:
            key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
            assert key_pair
            # key_pair.delete() # would be used to recreate
        except boto.exception.EC2ResponseError, e:
            if 'InvalidKeyPair.NotFound' not in e.body:
                if 'AuthFailure' in e.body:
                    print('POSSIBLE CAUSES OF ERROR:\n'
                          '  Did you sign up for EC2?\n'
                          '  Did you put a credit card number in your AWS '
                          'account?\n'
                          'Please doublecheck before reporting a problem.\n')
                raise
            # make one; we would always do this, and stash the result, if we
            # needed the key (for instance, to SSH to the box).  We'd then
            # use paramiko to use the key to connect.
            self.conn.create_key_pair(keypair_name)
Beispiel #17
0
    def __init__(self, name, password, instance_type, ami=None,
                 valid_ami_owners=None, valid_ami_location_regex=None,
                 elastic_ip=None, identifier=None, secret_identifier=None,
                 aws_id_file_path=None, user_data=None, region=None,
                 keypair_name='latent_buildbot_slave',
                 security_name='latent_buildbot_slave',
                 spot_instance=False, max_spot_price=1.6, volumes=None,
                 placement=None, price_multiplier=1.2, tags=None, retry=1,
                 retry_price_adjustment=1, product_description='Linux/UNIX',
                 **kwargs):

        if not boto:
            config.error("The python module 'boto' is needed to use a "
                         "EC2LatentBuildSlave")

        if volumes is None:
            volumes = []

        if tags is None:
            tags = {}

        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)

        if not ((ami is not None) ^
                (valid_ami_owners is not None or
                 valid_ami_location_regex is not None)):
            raise ValueError(
                'You must provide either a specific ami, or one or both of '
                'valid_ami_location_regex and valid_ami_owners')
        self.ami = ami
        if valid_ami_owners is not None:
            if isinstance(valid_ami_owners, (int, long)):
                valid_ami_owners = (valid_ami_owners,)
            else:
                for element in valid_ami_owners:
                    if not isinstance(element, (int, long)):
                        raise ValueError(
                            'valid_ami_owners should be int or iterable '
                            'of ints', element)
        if valid_ami_location_regex is not None:
            if not isinstance(valid_ami_location_regex, basestring):
                raise ValueError(
                    'valid_ami_location_regex should be a string')
            else:
                # verify that regex will compile
                re.compile(valid_ami_location_regex)
        self.valid_ami_owners = valid_ami_owners
        self.valid_ami_location_regex = valid_ami_location_regex
        self.instance_type = instance_type
        self.keypair_name = keypair_name
        self.security_name = security_name
        self.user_data = user_data
        self.spot_instance = spot_instance
        self.max_spot_price = max_spot_price
        self.volumes = volumes
        self.price_multiplier = price_multiplier
        self.retry_price_adjustment = retry_price_adjustment
        self.retry = retry
        self.attempt = 1
        self.product_description = product_description
        if None not in [placement, region]:
            self.placement = '%s%s' % (region, placement)
        else:
            self.placement = None
        if identifier is None:
            assert secret_identifier is None, (
                'supply both or neither of identifier, secret_identifier')
            if aws_id_file_path is None:
                home = os.environ['HOME']
                default_path = os.path.join(home, '.ec2', 'aws_id')
                if os.path.exists(default_path):
                    aws_id_file_path = default_path
            if aws_id_file_path:
                log.msg('WARNING: EC2LatentBuildSlave is using deprecated '
                        'aws_id file')
                with open(aws_id_file_path, 'r') as aws_file:
                    identifier = aws_file.readline().strip()
                    secret_identifier = aws_file.readline().strip()
        else:
            assert aws_id_file_path is None, \
                'if you supply the identifier and secret_identifier, ' \
                'do not specify the aws_id_file_path'
            assert secret_identifier is not None, \
                'supply both or neither of identifier, secret_identifier'

        region_found = None

        # Make the EC2 connection.
        if region is not None:
            for r in boto.ec2.regions(aws_access_key_id=identifier,
                                      aws_secret_access_key=secret_identifier):

                if r.name == region:
                    region_found = r

            if region_found is not None:
                self.conn = boto.ec2.connect_to_region(region,
                                                       aws_access_key_id=identifier,
                                                       aws_secret_access_key=secret_identifier)
            else:
                raise ValueError(
                    'The specified region does not exist: ' + region)

        else:
            self.conn = boto.connect_ec2(identifier, secret_identifier)

        # Make a keypair
        #
        # We currently discard the keypair data because we don't need it.
        # If we do need it in the future, we will always recreate the keypairs
        # because there is no way to
        # programmatically retrieve the private key component, unless we
        # generate it and store it on the filesystem, which is an unnecessary
        # usage requirement.
        try:
            key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
            assert key_pair
            # key_pair.delete() # would be used to recreate
        except boto.exception.EC2ResponseError as e:
            if 'InvalidKeyPair.NotFound' not in e.body:
                if 'AuthFailure' in e.body:
                    log.msg('POSSIBLE CAUSES OF ERROR:\n'
                            '  Did you supply your AWS credentials?\n'
                            '  Did you sign up for EC2?\n'
                            '  Did you put a credit card number in your AWS '
                            'account?\n'
                            'Please doublecheck before reporting a problem.\n')
                raise
            # make one; we would always do this, and stash the result, if we
            # needed the key (for instance, to SSH to the box).  We'd then
            # use paramiko to use the key to connect.
            self.conn.create_key_pair(keypair_name)

        # create security group
        try:
            group = self.conn.get_all_security_groups(security_name)[0]
            assert group
        except boto.exception.EC2ResponseError as e:
            if 'InvalidGroup.NotFound' in e.body:
                self.security_group = self.conn.create_security_group(
                    security_name,
                    'Authorization to access the buildbot instance.')
                # Authorize the master as necessary
                # TODO this is where we'd open the hole to do the reverse pb
                # connect to the buildbot
                # ip = urllib.urlopen(
                #     'http://checkip.amazonaws.com').read().strip()
                # self.security_group.authorize('tcp', 22, 22, '%s/32' % ip)
                # self.security_group.authorize('tcp', 80, 80, '%s/32' % ip)
            else:
                raise

        # get the image
        if self.ami is not None:
            self.image = self.conn.get_image(self.ami)
        else:
            # verify we have access to at least one acceptable image
            discard = self.get_image()
            assert discard

        # get the specified elastic IP, if any
        if elastic_ip is not None:
            elastic_ip = self.conn.get_all_addresses([elastic_ip])[0]
        self.elastic_ip = elastic_ip
        self.tags = tags
Beispiel #18
0
    def __init__(self,
                 name,
                 password,
                 instance_type,
                 ami=None,
                 valid_ami_owners=None,
                 valid_ami_location_regex=None,
                 elastic_ip=None,
                 identifier=None,
                 secret_identifier=None,
                 aws_id_file_path=None,
                 user_data=None,
                 region=None,
                 keypair_name='latent_buildbot_slave',
                 security_name='latent_buildbot_slave',
                 spot_instance=False,
                 max_spot_price=1.6,
                 volumes=None,
                 placement=None,
                 subnet_id=None,
                 price_multiplier=1.2,
                 tags=None,
                 retry=1,
                 retry_price_adjustment=1,
                 product_description='Linux/UNIX',
                 **kwargs):

        if not boto:
            config.error("The python module 'boto' is needed to use a "
                         "EC2LatentBuildSlave")

        if volumes is None:
            volumes = []

        if tags is None:
            tags = {}

        AbstractLatentBuildSlave.__init__(self, name, password, **kwargs)

        if not ((ami is not None) ^ (valid_ami_owners is not None
                                     or valid_ami_location_regex is not None)):
            raise ValueError(
                'You must provide either a specific ami, or one or both of '
                'valid_ami_location_regex and valid_ami_owners')
        self.ami = ami
        if valid_ami_owners is not None:
            if isinstance(valid_ami_owners, (int, long)):
                valid_ami_owners = (valid_ami_owners, )
            else:
                for element in valid_ami_owners:
                    if not isinstance(element, (int, long)):
                        raise ValueError(
                            'valid_ami_owners should be int or iterable '
                            'of ints', element)
        if valid_ami_location_regex is not None:
            if not isinstance(valid_ami_location_regex, basestring):
                raise ValueError('valid_ami_location_regex should be a string')
            else:
                # verify that regex will compile
                re.compile(valid_ami_location_regex)
        self.valid_ami_owners = valid_ami_owners
        self.valid_ami_location_regex = valid_ami_location_regex
        self.instance_type = instance_type
        self.keypair_name = keypair_name
        self.security_name = security_name
        self.user_data = user_data
        self.spot_instance = spot_instance
        self.max_spot_price = max_spot_price
        self.volumes = volumes
        self.price_multiplier = price_multiplier
        self.retry_price_adjustment = retry_price_adjustment
        self.retry = retry
        self.attempt = 1
        self.product_description = product_description
        if None not in [placement, region]:
            self.placement = '%s%s' % (region, placement)
        else:
            self.placement = None
        if identifier is None:
            assert secret_identifier is None, (
                'supply both or neither of identifier, secret_identifier')
            if aws_id_file_path is None:
                home = os.environ['HOME']
                default_path = os.path.join(home, '.ec2', 'aws_id')
                if os.path.exists(default_path):
                    aws_id_file_path = default_path
            if aws_id_file_path:
                log.msg('WARNING: EC2LatentBuildSlave is using deprecated '
                        'aws_id file')
                with open(aws_id_file_path, 'r') as aws_file:
                    identifier = aws_file.readline().strip()
                    secret_identifier = aws_file.readline().strip()
        else:
            assert aws_id_file_path is None, \
                'if you supply the identifier and secret_identifier, ' \
                'do not specify the aws_id_file_path'
            assert secret_identifier is not None, \
                'supply both or neither of identifier, secret_identifier'

        region_found = None

        # Make the EC2 connection.
        if region is not None:
            for r in boto.ec2.regions(aws_access_key_id=identifier,
                                      aws_secret_access_key=secret_identifier):

                if r.name == region:
                    region_found = r

            if region_found is not None:
                self.conn = boto.ec2.connect_to_region(
                    region,
                    aws_access_key_id=identifier,
                    aws_secret_access_key=secret_identifier)
                if subnet_id is not None:
                    self.vpc_api_conn = boto.vpc.VPCConnection(
                        region=region_found,
                        aws_access_key_id=identifier,
                        aws_secret_access_key=secret_identifier)
            else:
                raise ValueError('The specified region does not exist: ' +
                                 region)

        else:
            self.conn = boto.connect_ec2(identifier, secret_identifier)

        # Make a keypair
        #
        # We currently discard the keypair data because we don't need it.
        # If we do need it in the future, we will always recreate the keypairs
        # because there is no way to
        # programmatically retrieve the private key component, unless we
        # generate it and store it on the filesystem, which is an unnecessary
        # usage requirement.
        try:
            key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
            assert key_pair
            # key_pair.delete() # would be used to recreate
        except boto.exception.EC2ResponseError as e:
            if 'InvalidKeyPair.NotFound' not in e.body:
                if 'AuthFailure' in e.body:
                    log.msg('POSSIBLE CAUSES OF ERROR:\n'
                            '  Did you supply your AWS credentials?\n'
                            '  Did you sign up for EC2?\n'
                            '  Did you put a credit card number in your AWS '
                            'account?\n'
                            'Please doublecheck before reporting a problem.\n')
                raise
            # make one; we would always do this, and stash the result, if we
            # needed the key (for instance, to SSH to the box).  We'd then
            # use paramiko to use the key to connect.
            self.conn.create_key_pair(keypair_name)

        # create security group
        try:
            group = self.conn.get_all_security_groups(security_name)[0]
            assert group
        except boto.exception.EC2ResponseError as e:
            if 'InvalidGroup.NotFound' in e.body:
                self.security_group = self.conn.create_security_group(
                    security_name,
                    'Authorization to access the buildbot instance.')
                # Authorize the master as necessary
                # TODO this is where we'd open the hole to do the reverse pb
                # connect to the buildbot
                # ip = urllib.urlopen(
                #     'http://checkip.amazonaws.com').read().strip()
                # self.security_group.authorize('tcp', 22, 22, '%s/32' % ip)
                # self.security_group.authorize('tcp', 80, 80, '%s/32' % ip)
            else:
                raise

        # get the image
        if self.ami is not None:
            self.image = self.conn.get_image(self.ami)
        else:
            # verify we have access to at least one acceptable image
            discard = self.get_image()
            assert discard

        # get the specified elastic IP, if any
        if elastic_ip is not None:
            elastic_ip = self.conn.get_all_addresses([elastic_ip])[0]
        self.elastic_ip = elastic_ip
        # Make sure the subnet id is valid on the onset, else the vpc subnet does not exist and is invalid
        if subnet_id is not None:
            assert self.vpc_api_conn.get_all_subnets([subnet_id])[0]
        self.subnet_id = subnet_id
        self.tags = tags