All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclouds.aws.ec2.compute.functions.ImageParser Maven / Gradle / Ivy

The newest version!
/**
 *
 * Copyright (C) 2010 Cloud Conscious, LLC. 
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ====================================================================
 */

package org.jclouds.aws.ec2.compute.functions;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrNull;

import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.jclouds.aws.ec2.domain.Image.Architecture;
import org.jclouds.aws.ec2.domain.Image.ImageType;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.logging.Logger;
import org.jclouds.rest.annotations.Provider;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;

/**
 * @author Adrian Cole
 */
@Singleton
public class ImageParser implements Function {
   @Resource
   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
   protected Logger logger = Logger.NULL;

   // nebula/ubuntu-karmic
   // nebula/karmic-large
   public static final Pattern NEBULA_PATTERN = Pattern.compile("nebula/(ubuntu-)?(.*)(-.*)?");

   // 137112412989/amzn-ami-0.9.7-beta.i386-ebs
   // 137112412989/amzn-ami-0.9.7-beta.x86_64-ebs
   // amzn-ami-us-east-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml
   // amzn-ami-us-east-1/amzn-ami-0.9.7-beta.i386.manifest.xml
   public static final Pattern AMZN_PATTERN = Pattern
         .compile(".*/amzn-ami-(.*)\\.(i386|x86_64)(-ebs|\\.manifest.xml)?");

   public static final Pattern CANONICAL_PATTERN = Pattern.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?");

   // ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml
   public static final Pattern RIGHTSCALE_PATTERN = Pattern
         .compile("[^/]*/([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");

   // ex 411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha
   // 411009282317/RightImage_Windows_2008_x64_v5.5.5
   public static final Pattern RIGHTIMAGE_PATTERN = Pattern
         .compile("[^/]*/RightImage[_ ]([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");

   private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
   private final Supplier> locations;

   private final Supplier defaultLocation;
   private final String provider;
   private final Map> osVersionMap;

   @Inject
   ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
         Map> osVersionMap, @Memoized Supplier> locations,
         Supplier defaultLocation, @Provider String provider) {
      this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
      this.locations = checkNotNull(locations, "locations");
      this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
      this.provider = checkNotNull(provider, "provider");
      this.osVersionMap = checkNotNull(osVersionMap, "utils");
   }

   @Override
   public Image apply(final org.jclouds.aws.ec2.domain.Image from) {
      if (from.getImageType() != ImageType.MACHINE) {
         logger.trace("skipping as not a machine image(%s)", from.getId());
         return null;
      }
      ImageBuilder builder = new ImageBuilder();
      builder.providerId(from.getId());
      builder.id(from.getRegion() + "/" + from.getId());
      builder.description(from.getDescription() != null ? from.getDescription() : from.getImageLocation());
      builder.userMetadata(ImmutableMap. of("owner", from.getImageOwnerId(), "rootDeviceType", from
            .getRootDeviceType().toString()));

      OsFamily osFamily = parseOsFamilyOrNull(provider, from.getImageLocation());
      String osName = null;
      String osArch = from.getVirtualizationType();
      String osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, from.getImageLocation(),
            osVersionMap);
      String osDescription = from.getImageLocation();
      boolean is64Bit = from.getArchitecture() == Architecture.X86_64;
      try {
         Matcher matcher = getMatcherAndFind(from.getImageLocation());
         if (matcher.pattern() == AMZN_PATTERN) {
            osFamily = OsFamily.AMZN_LINUX;
            osVersion = matcher.group(1);
            builder.version(osVersion);
         } else if (matcher.pattern() == NEBULA_PATTERN) {
            osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(2), osVersionMap);
         } else {
            osFamily = OsFamily.fromValue(matcher.group(1));
            osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(2), osVersionMap);
            builder.version(matcher.group(3).replace(".manifest.xml", ""));
         }
      } catch (IllegalArgumentException e) {
         logger.debug("<< didn't match os(%s)", from.getImageLocation());
      } catch (NoSuchElementException e) {
         logger.debug("<< didn't match at all(%s)", from.getImageLocation());
      }

      builder.defaultCredentials(credentialProvider.execute(from));

      try {
         builder.location(Iterables.find(locations.get(), new Predicate() {

            @Override
            public boolean apply(Location input) {
               return input.getId().equals(from.getRegion());
            }

         }));
      } catch (NoSuchElementException e) {
         System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from.getId(), locations);
         builder.location(new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(), defaultLocation
               .get().getParent()));
      }
      builder.operatingSystem(new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit));
      return builder.build();
   }

   /**
    * 
    * @throws NoSuchElementException
    *            if no configured matcher matches the manifest.
    */
   private Matcher getMatcherAndFind(String manifest) {
      for (Pattern pattern : new Pattern[] { AMZN_PATTERN, NEBULA_PATTERN, CANONICAL_PATTERN, RIGHTIMAGE_PATTERN,
            RIGHTSCALE_PATTERN }) {
         Matcher matcher = pattern.matcher(manifest);
         if (matcher.find())
            return matcher;
      }
      throw new NoSuchElementException(manifest);
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy