/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.imageservercontroller.impl; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.imageservercontroller.ImageServerConf; import com.emc.storageos.networkcontroller.SSHDialog; import com.emc.storageos.networkcontroller.SSHPrompt; import com.emc.storageos.networkcontroller.SSHSession; import com.emc.storageos.networkcontroller.exceptions.NetworkDeviceControllerException; public class ImageServerDialog extends SSHDialog { private static final Logger logger = LoggerFactory .getLogger(ImageServerDialog.class); public static void main(String[] args) { ImageServerDialog d = null; try { ImageServerConf imageServerConf = new ImageServerConf(); imageServerConf.setImageServerIp("<IP>"); imageServerConf.setImageServerUser("root"); imageServerConf.setImageServerPassword("<password>"); imageServerConf.setTftpbootDir("/opt/tftpboot/"); imageServerConf.setImageServerSecondIp("<IP>"); imageServerConf.setImageServerHttpPort("44491"); imageServerConf.setImageDir("images"); SSHSession session = new SSHSession(); session.connect(imageServerConf.getImageServerIp(), imageServerConf.getSshPort(), imageServerConf.getImageServerUser(), imageServerConf.getImageServerPassword()); d = new ImageServerDialog(session, imageServerConf.getSshTimeoutMs()); d.init(); d.cd("/tmp"); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (d != null && d.isConnected()) { d.close(); } } System.out.println("exit"); System.exit(0); } private static final Logger log = LoggerFactory.getLogger(ImageServerDialog.class); private SSHPrompt[] prompts = { SSHPrompt.LINUX_CUSTOM_PROMPT }; private static final String PROMPT = ImageServerDialogProperties.getString("PROMPT"); public ImageServerDialog(SSHSession session, Integer defaultTimeout) { super(session, defaultTimeout); } /** * Since prompt is not known, setup a custom one. */ public void init() { StringBuilder buf = new StringBuilder(); // set custom prompt. String command = String.format(ImageServerDialogProperties.getString("cmd.promptChange"), PROMPT); try { sendWaitFor(command, defaultTimeout, prompts, buf); } catch (NetworkDeviceControllerException e) { // re-try, cut the timeout in half log.error("timeout when trying to connect to image server: {}", e.getMessage()); log.info("let's retry"); sendWaitFor(command, defaultTimeout / 2, prompts, buf); log.info("retry worked"); } // set command line length to a 1000 chars command = String.format(ImageServerDialogProperties.getString("cmd.termLength"), 1000); sendWaitFor(command, defaultTimeout, prompts, buf); } /** * Close connection. */ public void close() { send("exit"); this.getSession().disconnect(); } /** * Is the connection open. * * @return */ public boolean isConnected() { return this.getSession().isConnected(); } /** * Start process with nohup command. * * @param cmd */ public void nohup(String cmd) { send(String.format(ImageServerDialogProperties.getString("cmd.nohup"), cmd)); // have to sleep a little to skip output after nohup command try { Thread.sleep(1000); } catch (InterruptedException e) { // ignore } } /** * Kill process by PID. * * @param pid */ public void kill(String pid) { send(String.format(ImageServerDialogProperties.getString("cmd.kill"), pid)); // have to sleep a little to skip output after kill command try { Thread.sleep(1000); } catch (InterruptedException e) { // ignore } } private static final Pattern p = Pattern.compile("(\\d+)(/)"); /** * Returns PID of the process listening on the given port, null if no * process. * * @param port * @return */ public String getServerPid(String port) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.getServerPid"), port); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); String lines = cleanOutput(buf); if (lines.trim().equals("")) { return null; } Matcher m = p.matcher(lines); if (m.find()) { return m.group(1); } return null; } /** * cd command in linux. * * @param dir */ public void cd(String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.cd"), dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Returns file content using the 'cat' command. * * @param filePath * @return */ public String readFile(String filePath) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.readFile"), filePath); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); int from = command.length() + 1; int to = buf.indexOf(PROMPT) - 2; if (to <= from) { return ""; // empty file } return buf.substring(from, to); } /** * Removes '\r' from the end of every line. * * @param str * @return */ private String stripOffCR(String str) { String[] arr = str.split("\n"); StringBuilder buf = new StringBuilder(); for (String s : arr) { if (s.endsWith("\r")) { buf.append(s.substring(0, s.length() - 1)); } else { buf.append(s); } buf.append("\n"); } return buf.toString(); } /** * Write file using echo command. * * @param filePath * @param content */ public void writeFile(String filePath, String content) { StringBuilder buf = new StringBuilder(); String newContent = stripOffCR(content); String[] lines = newContent.split("\n"); String cmd = null; for (String line : lines) { if (cmd == null) { // first time cmd = String.format(ImageServerDialogProperties.getString("cmd.writeFile"), line, filePath); } else { cmd = String.format(ImageServerDialogProperties.getString("cmd.writeFile.append"), line, filePath); } sendWaitFor(cmd, defaultTimeout, prompts, buf); } } /** * Executes 'wget' command. Return true if successful. * * @param url * @param fileName * @param timeout * @return */ public boolean wget(String url, String fileName, int timeout) { boolean result = false; StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.wget"), url, "'" + fileName+ "'"); sendWaitFor(command, timeout, prompts, buf); log.debug(buf.toString()); String[] lines = getLines(buf); String regex = ".*" + fileName + ".* saved .*"; for (String line : lines) { if (Pattern.matches(regex, line)) { result = true; } } if (!result) { log.warn(buf.toString()); } return result; } /** * Executes 'mkdir -p' command. * * @param dir */ public void mkdir(String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.mkdir"), dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Mounts an ISO file using 'mount' command. * * @param iso * @param dir */ public void mount(String iso, String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.mount"), "'" + iso+ "'", dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Remove file or directory using 'rm -rf' command. No error if file or * directory don't exist. * * @param fileOrDir */ public void rm(String fileOrDir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.rm"), fileOrDir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Copies directory. * * @param fromDir * @param toDir */ public void cpDir(String fromDir, String toDir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.cpDir"), fromDir, toDir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Change permissions on a directory. * * @param permissions * @param dir */ public void chmodDir(String permissions, String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.chmodDir"), permissions, dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Change permissions on a file. * * @param permissions * @param file */ public void chmodFile(String permissions, String file) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.chmodFile"), permissions, file); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Executes 'umount' command. * * @param dir */ public void umount(String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.umount"), dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); } /** * Return true if file exists. * * @param filePath * @return */ public boolean fileExists(String filePath) { boolean result = false; StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.fileExists"), filePath); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); String[] lines = getLines(buf); for (String line : lines) { if (line.trim().equals("1")) { result = true; break; } if (line.trim().equals("0")) { result = false; break; } } return result; } /** * Return true if directory exists. * * @param dir * @return */ public boolean directoryExists(String dir) { boolean result = false; StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.directoryExists"), dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); String[] lines = getLines(buf); for (String line : lines) { if (line.trim().equals("1")) { result = true; break; } if (line.trim().equals("0")) { result = false; break; } } return result; } public String[] lsDir(String dir) { StringBuilder buf = new StringBuilder(); String command = String.format(ImageServerDialogProperties.getString("cmd.lsDir"), dir); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); String files = cleanOutput(buf); return files.split("\n"); } /** * Expectation here is that the command is less than 80 characters and is * terminated by new line! * * @param command * @return output of the command (empty string if no output) */ public String execCommand(String command) { StringBuilder buf = new StringBuilder(); sendWaitFor(command, defaultTimeout, prompts, buf); log.debug(buf.toString()); return cleanOutput(buf); } /** * Remove the first and last lines. * * @param buf * @return */ private String cleanOutput(StringBuilder buf) { StringBuilder result = new StringBuilder(); String[] lines = getLines(buf); for (int i = 1; i < lines.length - 1; i++) { if (i > 1) { result.append('\n'); } result.append(lines[i]); } return result.toString(); } }