/* * 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.stratuslab; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.UUID; import org.apache.commons.io.FileUtils; 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; public class StratusLabConnector implements CloudInterface{ private Logger logger; private final String DIVIDE_STR="_0_"; private int check_retry=20; private int check_inteval=1000; private ArrayList<String> env = new ArrayList<String>(); private String bindir; private String config_file = "/tmp/stratus-user.cnf"; private String public_key_file; public static void main(String[] args) { String resource = StratusLabConnector.class.getResource("stratuslab-client").getFile(); String bin = resource + "/bin"; String python = resource + "/lib/stratuslab/python"; System.out.println(bin); System.out.println(python); } public StratusLabConnector(Logger logger, String endpoint, String pdisk_endpoint, String username, String password, String user_public_key_file, String client_path) { //String resource = StratusLabConnector.class.getResource("/stratuslab-client").getFile(); this.logger = logger; this.env.add("PYTHONPATH=" + client_path + "/lib/stratuslab/python"); this.bindir = client_path + "/bin"; this.public_key_file = user_public_key_file; File f = new File(config_file); if (!f.exists()) { try { String content = "[default] \n"; content += "endpoint = " + endpoint + "\n"; content += "pdisk_endpoint = " + pdisk_endpoint + "\n"; content += "username = " + username + "\n"; content += "password = " + password + "\n"; content += "user_public_key_file = " + user_public_key_file + "\n"; f.createNewFile(); FileWriter fw = new FileWriter(f.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.write(content); bw.close(); System.out.println("Wrote stratuslab config file: " + config_file); } catch (IOException e) { e.printStackTrace(); } } } private String runStratusCommand(String command){ Process p; String re = ""; try { String cmdTotal = bindir+"/"+command + " -c "+ config_file; p = Runtime.getRuntime().exec( cmdTotal, env.toArray(new String[env.size()])); //p = Runtime.getRuntime().exec("sh -c "+ bindir+command+"", env); //String[]cmd = {"sh","-c", bindir+command}; //p = Runtime.getRuntime().exec(cmd, env); p.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line = reader.readLine(); while (line != null) { line = reader.readLine(); re += line + "\n"; } logger.debug("Execute cmd: "+command); logger.debug("Exit value : "+p.exitValue()); } catch (Exception e) { logger.error(e.toString()); } return re; } public InstanceDescription getInstanceDescriptionByID(String instanceID) { // This command will return one and only one line, if instance is existed // e.g: 799 Running 1 1572864 0 134.158.75.104 service123_0_deployID int step = 0; String instanceDes=""; String instanceDesRaw = ""; while (step <check_retry && instanceDes.equals("")){ instanceDesRaw=runStratusCommand("stratus-describe-instance -n"); Scanner scanner = new Scanner(instanceDesRaw); while (scanner.hasNextLine()) { String line = scanner.nextLine(); if (!line.trim().equals("") && line.replaceAll("\\s+", " ").split(" ")[0].equals(instanceID)){ instanceDes = line.replaceAll("\\s+", " "); System.out.println("FOUND: "+instanceDes); break; } } scanner.close(); if (instanceDes.trim().equals("")){ // not update yet, retry try { System.out.println("Sleep: "+instanceDes); Thread.sleep(check_inteval); } catch (Exception e) {} } step++; } if (instanceDes.trim().equals("")) { logger.warn("Not fould Instance: " + instanceID); return null; } try { String ip = instanceDes.split(" ")[5]; InstanceDescription id = new InstanceDescription(instanceID, ip, ip); String stateStr =instanceDes.split(" ")[1]; id.setState(VMStates.fromString(stateStr)); logger.info("\n\nFound instance " + instanceID + " " + id.getPrivateIp() + " " + id.getPublicIp()); return id; } catch (Exception e) { logger.error(e.toString()); return null; } } /* * Note: sshKeyName is the file of publickey */ public String launchInstance(String instanceName, String imageId, List<String> securityGroups, String sshKeyName, String userData, String instType, int minInst, int maxInst) throws ServiceDeployerException { logger.debug("Launching instance with TAGs: \n" + securityGroups); try { // put userData to tmp file String tmpUserDataFile = "/tmp/user_data_stratus_"+UUID.randomUUID().toString(); FileUtils.writeStringToFile(new File(tmpUserDataFile), userData); String cmd[] = { this.bindir+"/stratus-run-instance", "--quiet", "-t", instType, "--cloud-init", "ssh,"+this.public_key_file+"#x-shellscript,"+tmpUserDataFile, "-c", this.config_file, imageId }; // result should be: ID, IP (e.g. "323, 134.158.75.215") StringBuilder builder = new StringBuilder(); for(String s : cmd) { builder.append(s+" "); } logger.debug("Stratus cmd: " + builder.toString()); String result[] = ProcessUtils.execGetOutput(cmd,this.env.toArray(new String[env.size()])).split(","); if (result.length > 1){ return result[0].trim(); // the Stratuslab ID of new VM } else { logger.error("Cannot create Stratuslab instance"); return ""; } } catch (Exception e){ logger.error(e.toString()); } return null; } public void removeInstance(String instanceToTerminateID) throws ServiceDeployerException { runStratusCommand("stratus-kill-instance " + instanceToTerminateID); } public String getInstance(UUID deployID) throws ServiceDeployerException { String instanceDes=runStratusCommand("stratus-describe-instance -n | grep "+deployID.toString()).replaceAll("\\s+", " "); return instanceDes.split(" ")[0]; } public List<String> getSecurityGroups(String instanceID) throws ServiceDeployerException { String instanceDes=runStratusCommand("stratus-describe-instance "+instanceID).replaceAll("\\s+", " "); List<String> lst = new ArrayList<String>(); lst.add(instanceDes.split(" ")[7]); // attract serviceID return lst; } }