Skip to content

Loading…

feature: specify VPC subnet in addnode command #391

Open
wants to merge 2 commits into from

2 participants

@nitecoder

This adds a simple fix to the problem of not being able to specify different zones in addnode when using VPC. The problem is that subnets are zone-specific and addnodes did not have an option to change the cluster-wide subnet setting.

This is related to issue #390

dmitry-adchemy added some commits
@dmitry-adchemy dmitry-adchemy Add option to specify subnet on addnode command. This allows -z optio…
…n to be used with VPC clusters to choose a different zone than that specified in the cluster config.
f1bbab9
@dmitry-adchemy dmitry-adchemy fix style nags 467cd93
@nitecoder nitecoder changed the title from feature: specify subnet addnode (#390) to feature: specify subnet addnode
@nitecoder nitecoder changed the title from feature: specify subnet addnode to feature: specify VPC subnet in addnode command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 10, 2014
  1. @dmitry-adchemy

    Add option to specify subnet on addnode command. This allows -z optio…

    dmitry-adchemy committed
    …n to be used with VPC clusters to choose a different zone than that specified in the cluster config.
  2. @dmitry-adchemy

    fix style nags

    dmitry-adchemy committed
Showing with 38 additions and 16 deletions.
  1. +32 −15 starcluster/cluster.py
  2. +6 −1 starcluster/commands/addnode.py
View
47 starcluster/cluster.py
@@ -178,7 +178,8 @@ def add_node(self, cluster_name, alias=None, no_create=False,
def add_nodes(self, cluster_name, num_nodes, aliases=None, no_create=False,
image_id=None, instance_type=None, zone=None,
- placement_group=None, spot_bid=None):
+ placement_group=None, spot_bid=None,
+ subnet_id=None):
"""
Add one or more nodes to cluster
"""
@@ -186,7 +187,8 @@ def add_nodes(self, cluster_name, num_nodes, aliases=None, no_create=False,
return cl.add_nodes(num_nodes, aliases=aliases, image_id=image_id,
instance_type=instance_type, zone=zone,
placement_group=placement_group, spot_bid=spot_bid,
- no_create=no_create)
+ no_create=no_create,
+ subnet_id=subnet_id)
def remove_node(self, cluster_name, alias=None, terminate=True,
force=False):
@@ -434,7 +436,7 @@ def __init__(self,
self._cluster_group = None
self._placement_group = None
- self._subnet = None
+ self._subnet = {}
self._zone = None
self._master = None
self._nodes = []
@@ -634,9 +636,18 @@ def _security_group(self):
@property
def subnet(self):
- if not self._subnet and self.subnet_id:
- self._subnet = self.ec2.get_subnet(self.subnet_id)
- return self._subnet
+ return self.get_subnet(self.subnet_id)
+
+ def get_subnet(self, subnet_id=None):
+ """Return either default subnet or subnet by the specified id.
+ Caches the subnet objects to avoid redundant ec2 lookups"""
+ subnet_id = subnet_id or self.subnet_id
+ if subnet_id:
+ found = self._subnet.get(subnet_id, None)
+ if found is None:
+ found = self.ec2.get_subnet(subnet_id)
+ self._subnet[subnet_id] = found
+ return found
@property
def cluster_group(self):
@@ -913,7 +924,7 @@ def _get_cluster_userdata(self, aliases):
def create_nodes(self, aliases, image_id=None, instance_type=None,
zone=None, placement_group=None, spot_bid=None,
- force_flat=False):
+ force_flat=False, subnet_id=None):
"""
Convenience method for requesting instances with this cluster's
settings. All settings (kwargs) except force_flat default to cluster
@@ -946,19 +957,22 @@ def create_nodes(self, aliases, image_id=None, instance_type=None,
placement=zone or getattr(self.zone, 'name', None),
user_data=user_data,
placement_group=placement_group)
- if self.subnet_id:
+
+ subnet_id = subnet_id or self.subnet_id
+ if subnet_id:
netif = self.ec2.get_network_spec(
device_index=0, associate_public_ip_address=self.public_ips,
- subnet_id=self.subnet_id, groups=[self.cluster_group.id])
+ subnet_id=subnet_id, groups=[self.cluster_group.id])
kwargs.update(
network_interfaces=self.ec2.get_network_collection(netif))
else:
kwargs.update(security_groups=[cluster_sg])
+
resvs = []
if spot_bid:
security_group_id = self.cluster_group.id
for alias in aliases:
- if not self.subnet_id:
+ if not subnet_id:
kwargs['security_group_ids'] = [security_group_id]
kwargs['user_data'] = self._get_cluster_userdata([alias])
resvs.extend(self.ec2.request_instances(image_id, **kwargs))
@@ -997,7 +1011,7 @@ def add_node(self, alias=None, no_create=False, image_id=None,
def add_nodes(self, num_nodes, aliases=None, image_id=None,
instance_type=None, zone=None, placement_group=None,
- spot_bid=None, no_create=False):
+ spot_bid=None, no_create=False, subnet_id=None):
"""
Add new nodes to this cluster
@@ -1016,12 +1030,14 @@ def add_nodes(self, num_nodes, aliases=None, image_id=None,
raise exception.ClusterValidationError(
"worker nodes cannot have master as an alias")
if not no_create:
- if self.subnet:
- ip_count = self.subnet.available_ip_address_count
+ # Why is this even here? Shouldn't it be down in self.create_nodes?
+ subnet = self.get_subnet(subnet_id)
+ if subnet:
+ ip_count = subnet.available_ip_address_count
if ip_count < len(aliases):
raise exception.ClusterValidationError(
"Not enough IP addresses available in %s (%d)" %
- (self.subnet.id, ip_count))
+ (subnet.id, ip_count))
for node in running_pending:
if node.alias in aliases:
raise exception.ClusterValidationError(
@@ -1030,7 +1046,8 @@ def add_nodes(self, num_nodes, aliases=None, image_id=None,
resp = self.create_nodes(aliases, image_id=image_id,
instance_type=instance_type, zone=zone,
placement_group=placement_group,
- spot_bid=spot_bid)
+ spot_bid=spot_bid,
+ subnet_id=subnet_id)
if spot_bid or self.spot_bid:
self.ec2.wait_for_propagation(spot_requests=resp)
else:
View
7 starcluster/commands/addnode.py
@@ -97,6 +97,10 @@ def addopts(self, parser):
"-x", "--no-create", dest="no_create", action="store_true",
default=False, help="do not launch new EC2 instances when "
"adding nodes (use existing instances instead)")
+ parser.add_option(
+ "-N", "--subnet-id", dest="subnet_id", action="store",
+ type="string", default=None,
+ help=("Launch the new nodes into this VPC subnet"))
def execute(self, args):
if len(args) != 1:
@@ -125,4 +129,5 @@ def execute(self, args):
image_id=self.opts.image_id,
instance_type=self.opts.instance_type,
zone=self.opts.zone, spot_bid=self.opts.spot_bid,
- no_create=self.opts.no_create)
+ no_create=self.opts.no_create,
+ subnet_id=self.opts.subnet_id)
Something went wrong with that request. Please try again.