stratos-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vanson Lim <v...@cisco.com>
Subject Openstack Availability zone settings in partition definition not working
Date Sun, 20 Sep 2015 05:29:42 GMT
Stratos developers,

I found an issue where defining an availability "zone" property in a partition has no affect
on controlling the placement of a VM launched 
under openstack.

The code which builds the template (iaas.initialize) used by jclouds is executed only once
before stratos appends the availability zone 
properties to the iaas datastructure.

The problem is in the buildIaas() call shown below:

https://github.com/apache/stratos/blob/92ff7e9b5800d578a37d6aa82551d60fbdd66529/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/openstack/OpenstackPartitionValidator.java


The issue also exists in the cloudstack, ec2, gce and docker variants of this function.

        @Override
             public IaasProvider validate(Partition partition, Properties properties) throws
InvalidPartitionException {
                 try {
                     // validate the existence of the zone and hosts properties.
                     if (properties.containsKey(Scope.region.toString())) {
                         String region = properties.getProperty(Scope.region.toString());

                         if (iaasProvider.getImage() != null && !iaasProvider.getImage().contains(region))
{

                             String msg = "Invalid partition detected, invalid region: [partition-id]
" + partition.getId() +
                                     " [region] " + region;
                             log.error(msg);
                             throw new InvalidPartitionException(msg);
                         }

                         iaas.isValidRegion(region);

                         IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
        *                Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);*
        updatedIaas.setIaasProvider(updatedIaasProvider);

                         if (properties.containsKey(Scope.zone.toString())) {
                             String zone = properties.getProperty(Scope.zone.toString());
                             iaas.isValidZone(region, zone);

        updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
        *                    updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);*
        updatedIaas.setIaasProvider(updatedIaasProvider);
                         }

                         updateOtherProperties(updatedIaasProvider, properties);
                         return updatedIaasProvider;
                     } else {

                         return iaasProvider;
                     }
                 } catch (Exception e) {
                     String msg = "Invalid partition detected: [partition-id] " + partition.getId()
+ e.getMessage();
                     log.error(msg, e);
                     throw new InvalidPartitionException(msg, e);
                 }
             }


             private void updateOtherProperties(IaasProvider updatedIaasProvider,
                                                Properties properties) {
                 Iaas updatedIaas;
                 try {
        *            updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);*

                     for (Object property : properties.keySet()) {
                         if (property instanceof String) {
                             String key = (String) property;
                             updatedIaasProvider.setProperty(key,
                                     properties.getProperty(key));
                             if (log.isDebugEnabled()) {
                                 log.debug("Added property " + key
                                         + " to the IaasProvider.");
                             }
                         }
                     }
        *            updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);*
                     updatedIaas.setIaasProvider(updatedIaasProvider);
                 } catch (InvalidIaasProviderException ignore) {
                 }

             }



        buidIaas() calls getIaas() under the covers and only initializes the compute template
the first time it is called.   buildIaas() is
        called a second time after the availability_zone property is set, and then a third/fourth
time in updateOtherProperties().

        As show below,   getIaas() only calls iaas.initilize() the first time it's called.

            public class CloudControllerServiceUtil {

            ...
                 public static Iaas buildIaas(IaasProvider iaasProvider) throws InvalidIaasProviderException
{
                     return iaasProvider.getIaas();
                 }
            ....

            public class IaasProvider implements Serializable {
            ....
                 public Iaas getIaas() {
                     if (iaas == null) {
                         synchronized (IaasProvider.this) {
                             if (iaas == null) {
                                 try {
                                     iaas = CloudControllerUtil.createIaasInstance(this);
                                     iaas.initialize();
                                 } catch (InvalidIaasProviderException e) {
                                     throw new RuntimeException("Could not create IaaS instance",
e);
                                 }
                             }
                         }
                     }
                     return iaas;
                 }
            ....

        I propose the attached diffs to define buildIaas() such that it forces the iaas datastructure
to be reinitialized,  if this looks
        okay, I'll see about getting this pushed upstream.
        I've also validated this on my openstack setup.


        Regards,

        -Vanson


Mime
View raw message