/* * Copyright (c) 2013 Technische Universitat Wien (TUW), Distributed Systems Group. http://dsg.tuwien.ac.at * * This work was partially supported by the European Commission in terms of the CELAR FP7 project (FP7-ICT-2011-8 #317790), http://www.celarcloud.eu/ * * 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 at.ac.tuwien.dsg.cloud.salsa.cloudconnector.openstack; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jclouds.ContextBuilder; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.NovaApiMetadata; import org.jclouds.openstack.nova.v2_0.domain.Address; import org.jclouds.openstack.nova.v2_0.domain.Image; import org.jclouds.openstack.nova.v2_0.domain.Server; import org.jclouds.openstack.nova.v2_0.domain.Server.Status; import org.jclouds.openstack.nova.v2_0.domain.ServerCreated; import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi; import org.jclouds.openstack.nova.v2_0.features.ImageApi; import org.jclouds.openstack.nova.v2_0.features.ServerApi; import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.v2_0.domain.Resource; import org.slf4j.Logger; import at.ac.tuwien.dsg.cloud.salsa.cloudconnector.CloudInterface; import at.ac.tuwien.dsg.cloud.salsa.cloudconnector.InstanceDescription; import at.ac.tuwien.dsg.cloud.salsa.cloudconnector.ServiceDeployerException; import at.ac.tuwien.dsg.cloud.salsa.cloudconnector.VMStates; import com.google.common.collect.FluentIterable; import com.google.common.collect.Multimap; import com.google.common.io.Closeables; public class OpenStackJcloud implements CloudInterface, Cloneable { //private final NovaApi novaApi; //private final Set<String> zones; Logger LOGGER; NovaApi client; ServerApi serverApi; VolumeApi volumeApi; String keyName; final String region = "myregion"; Map<String, String> mapFlavorName = new HashMap<>(); public OpenStackJcloud(Logger logger, String endpoint, String tenant, String username, String password, String keyName) { //logger.info(Configuration.getCloudAPIType()+" "+Configuration.getCloudUser()+" "+Configuration.getCloudPassword()+" "+Configuration.getCloudAPIEndpoint()); this.LOGGER = logger; this.keyName = keyName; // ComputeServiceContext context = ContextBuilder.newBuilder("openstack-nova") // .credentials(tenant + ":" + username, password) // .endpoint(endpoint) // // .modules(modules) // //.buildApi(NovaApi.class); // .buildView(ComputeServiceContext.class); //client = (NovaApi) context.unwrap(NovaApiMetadata.contextToken(null)).getApi(); client = ContextBuilder.newBuilder("openstack-nova") .endpoint(endpoint) .credentials(tenant + ":" + username, password) //.modules(modules) .buildApi(NovaApi.class); serverApi = client.getServerApiForZone(region); for (Resource flavor : client.getFlavorApiForZone(region).list().concat()) { // System.out.println( flavor.getId()+" "+flavor.getName()); mapFlavorName.put(flavor.getName(), flavor.getId()); } } @Override public String launchInstance(String instanceName, String imageId, List<String> securityGroups, String sshKeyName, String userData, String instType, int minInst, int maxInst) throws ServiceDeployerException { LOGGER.debug("Jclouds Openstack Connector for node name: " + instanceName + ", imageId: " + imageId + ", instanceType: " + instType + "sshKeyName: " + sshKeyName); CreateServerOptions createNodeOptions = new CreateServerOptions(); createNodeOptions.userData(userData.getBytes()); createNodeOptions.keyPairName(this.keyName); LOGGER.debug("Jclouds Openstack - Prepare creation"); ServerCreated serverCreated = serverApi.create(instanceName, imageId, instType, createNodeOptions); // instance type is m1.small as default int maxtry = 20; int tryee = 0; LOGGER.debug("Jclouds Openstack - CREATED"); LOGGER.debug("Jclouds Openstack - CREATED. ID = " + serverCreated.getId()); while (getIpInstance(serverCreated.getId()) == null) { //serverApi.get(serverCreated.getId()).getStatus() != Status.ACTIVE){ try { LOGGER.debug("Server " + serverCreated.getId() + " is not started.. wait 5 secs"); Thread.sleep(5000); tryee += 1; if (tryee >= maxtry) { return serverCreated.getId(); } } catch (InterruptedException e) { LOGGER.error(e.toString()); } } return serverCreated.getId(); } @Override public InstanceDescription getInstanceDescriptionByID(String instanceID) { Server server = serverApi.get(instanceID); Multimap<String, Address> map = server.getAddresses(); List<Address> PA = (List<Address>) map.get("private"); String privateIp = ""; if (!PA.isEmpty()) { privateIp = PA.get(0).getAddr(); } InstanceDescription des = new InstanceDescription(instanceID, privateIp, ""); Status status = server.getStatus(); switch (status) { case ACTIVE: des.setState(VMStates.Running); break; case BUILD: des.setState(VMStates.Prolog); break; case ERROR: des.setState(VMStates.Failed); break; case STOPPED: des.setState(VMStates.Terminated); break; case UNKNOWN: des.setState(VMStates.Unknown); break; default: des.setState(VMStates.Unknown); break; } return des; } @Override public void removeInstance(String instanceToTerminateID) throws ServiceDeployerException { serverApi.delete(instanceToTerminateID); } public void listImages() { try { ImageApi imageApi = client.getImageApiForZone(region); FluentIterable<? extends Image> images = imageApi.listInDetail().concat(); PrintWriter f0 = new PrintWriter(new FileWriter("/tmp/dsg_openstack_images.txt")); for (Image image : images) { System.out.println("\t" + image); f0.println(image); } f0.close(); } catch (Exception e) { } } public void listServers() { for (Server server : serverApi.listInDetail().concat()) { System.out.println(" " + server); } } public void printServerInfo(String id) { System.out.println("IPv4: " + serverApi.get(id).getAccessIPv4()); System.out.println("IPv6: " + serverApi.get(id).getAccessIPv6()); System.out.println("hostid: " + serverApi.get(id).getHostId()); System.out.println("status: " + serverApi.get(id).getStatus()); System.out.println("IPv4: " + serverApi.get(id).getAddresses()); Multimap<String, Address> map = serverApi.get(id).getAddresses(); List<Address> PA = (List<Address>) map.get("private"); PA.get(0).getAddr(); } private String getIpInstance(String instanceId) { LOGGER.debug("getIpInstance 1"); Server server = serverApi.get(instanceId); LOGGER.debug("getIpInstance 2"); Multimap<String, Address> map = server.getAddresses(); if (map.isEmpty()) { return null; } LOGGER.debug("getIpInstance 3"); List<Address> PA = (List<Address>) map.get("private"); if (PA.isEmpty()) { return null; } LOGGER.debug("getIpInstance 4"); return PA.get(0).getAddr(); } public void close() throws IOException { Closeables.close(client, true); } }