org.jenkinsci.plugins.os_ci.model.Product.java Source code

Java tutorial

Introduction

Here is the source code for org.jenkinsci.plugins.os_ci.model.Product.java

Source

package org.jenkinsci.plugins.os_ci.model;

import com.google.common.base.Joiner;
import hudson.FilePath;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.os_ci.exceptions.OsCiPluginException;
import org.jenkinsci.plugins.os_ci.exceptions.ProductDeployPluginException;
import org.jenkinsci.plugins.os_ci.model.Openstack.DeployParmeters;
import org.jenkinsci.plugins.os_ci.model.Openstack.FloatingIP;
import org.jenkinsci.plugins.os_ci.model.Openstack.StackDetails;
import org.jenkinsci.plugins.os_ci.model.Openstack.StackStatus;
import org.jenkinsci.plugins.os_ci.model.maven.MavenPom;
import org.jenkinsci.plugins.os_ci.model.maven.MavenRPMPom;
import org.jenkinsci.plugins.os_ci.repohandlers.NexusClient;
import org.jenkinsci.plugins.os_ci.repohandlers.OpenStackClient;
import org.jenkinsci.plugins.os_ci.utils.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * Copyright 2015 Cisco Systems, Inc.
 * <p/>
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.
 */
public class Product {

    static final long CREATE_TIMEOUT = 40 * 60 * 1000;
    static final long DELETE_TIMEOUT = 30 * 60 * 1000;
    static final long SLEEP_TIME = 60 * 1000;

    private final ArtifactParameters artifact;
    private final AbstractBuild build;
    private final BuildListener listener;

    public Product(ArtifactParameters artifact, AbstractBuild build, BuildListener listener) {
        this.artifact = artifact;
        this.build = build;
        this.listener = listener;
    }

    public ArtifactParameters getArtifact() {
        return artifact;
    }

    public boolean deploy(NexusClient nexusClient, OpenStackClient openStackClient,
            YumRepoParameters yumRepoParameters, DeployParmeters deployParmeters) throws Exception {
        final String targetFolder = Joiner.on(File.separator).join(build.getWorkspace().getRemote(), "archive");

        LogUtils.logSection(listener, "Deploy Product " + artifact.getArtifactId());

        List<String> fileTypes = new ArrayList<String>();
        fileTypes.add("pom");
        fileTypes.add("tar.gz");
        fileTypes.add("rpm");
        fileTypes.add("rh6");
        nexusClient.downloadProductArtifacts(getArtifact(),
                Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId()), fileTypes);
        //****************** get pom file dependencies ******************
        MavenPom mavenPom = new MavenPom(
                new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "pom.xml")));
        List<ArtifactParameters> subProducts = mavenPom.getPomProductDependencies();

        for (ArtifactParameters m : subProducts) {
            Product p = new Product(m, build, listener);
            boolean return_ = p.deploy(nexusClient, openStackClient, yumRepoParameters, deployParmeters);
            if (!return_)
                throw new ProductDeployPluginException(
                        "Deploy dependent product " + m.getArtifactId() + " failed.");
        }

        String buildId = Joiner.on("-").join(new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SS").format(build.getTime()),
                deployParmeters.getDeployCounter());

        if (!new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(),
                "external_dependencies.tar.gz")).exists()) {
            // if there isn't an external_dependencies.tar.gz file
            // only a pom file => we're deploying a profile
            LogUtils.log(listener, "Finish Deploy: " + artifact.getArtifactId());
            return true;
        }

        CompressUtils.untarFile(new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(),
                "external_dependencies.tar.gz")));
        LogUtils.log(listener, "Untar File: " + Joiner.on(File.separator).join(targetFolder,
                artifact.getArtifactId(), "external_dependencies.tar.gz"));

        //****************** move deployment-scripts ******************
        // Push scripts to YUM repo machine
        copyFolderToRepoMachine(build, listener, yumRepoParameters,
                Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "archive", "deploy-scripts"),
                Joiner.on("/").join("/var", "www", "html", "build", buildId));
        LogUtils.log(listener, "Copy deployment-scripts folder to Yum Repo machine.");

        // move external rpms from archive/product/archive/rpms  to /archive/repo folder

        if (new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "archive", "repo"))
                .exists()) {
            moveExternalRpmsToRepoDirectory(
                    Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "archive", "repo"),
                    Joiner.on(File.separator).join(targetFolder, "repo"));
            LogUtils.log(listener, "Copied external RPMS to repo directory.");
        }

        File deploymentScriptsRPM = new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(),
                artifact.getArtifactId() + "-" + artifact.getVersion() + ".rpm"));
        if (deploymentScriptsRPM.exists()) {
            //            Rename RPM file according to rpm metadata
            if (!System.getProperty("os.name").toLowerCase().startsWith("windows")) {
                ExecUtils.executeLocalCommand(
                        "/usr/local/bin/download_rpm.sh " + deploymentScriptsRPM.getPath().replaceAll(" ", "\\ "),
                        deploymentScriptsRPM.getParentFile().getPath().replaceAll(" ", "\\ "));
                deploymentScriptsRPM.delete();
                deploymentScriptsRPM = new File(Joiner.on(File.separator).join(targetFolder,
                        artifact.getArtifactId(), "nds_" + artifact.getArtifactId() + "_deployment-scripts" + "-"
                                + artifact.getVersion() + "_1.noarch.rpm"));
            }

            LogUtils.log(listener, deploymentScriptsRPM.getParentFile().list().toString());
            FileUtils.moveFileToDirectory(deploymentScriptsRPM,
                    new File(Joiner.on(File.separator).join(targetFolder, "repo")), true);
            LogUtils.log(listener, "Copied deployment-scripts to repo directory");
        }
        MavenPom mp = new MavenPom(
                new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "pom.xml")));
        List<ArtifactParameters> rpms = mp.getPomModuleDependencies();

        // download rpms to archive/repo
        LogUtils.logSection(listener, "Download dependent RPMS.");
        for (ArtifactParameters m : rpms) {
            new NexusClient(m, build, listener).downloadRPM(Joiner.on(File.separator).join(targetFolder, "repo"));
        }

        // create yum repo
        createAndMoveYumRepo(build, listener, yumRepoParameters,
                Joiner.on(File.separator).join(targetFolder, "repo"),
                String.valueOf(deployParmeters.getDeployCounter()));
        LogUtils.log(listener, "YUM repository have been created.");

        // deploy stack
        String stackName = artifact.getArtifactId().toLowerCase().replace("-product", "");

        openStackClient.createStack(stackName, deployParmeters.getOverridingParameters(),
                deployParmeters.getGlobalOutputs(), Joiner.on(File.separator).join(targetFolder,
                        artifact.getArtifactId(), "archive", "heat", stackName));

        long startTime = System.currentTimeMillis();
        boolean createComplete = false;

        while (!createComplete && System.currentTimeMillis() - startTime < CREATE_TIMEOUT) {
            StackStatus stackStatus = openStackClient.getStackStatus(stackName);
            LogUtils.log(listener, "Waiting for stack creation for " + stackName + ". Status is: " + stackStatus);
            if (stackStatus == StackStatus.CREATE_COMPLETE) {
                createComplete = true;
                // update outputs map
                Map<String, String> stackOutputs = openStackClient.getStackOutputs(stackName);
                deployParmeters.setGlobalOutputsWithNewOutputs(stackOutputs);
            } else if (stackStatus == StackStatus.FAILED || stackStatus == StackStatus.CREATE_FAILED
                    || stackStatus == StackStatus.UNDEFINED)
                throw new ProductDeployPluginException("Failed to Launch Stack " + stackName);
            else
                Thread.sleep(SLEEP_TIME);

        }
        // if stack is not complete after 40 minutes -  throw a timeout exception
        if (!createComplete)
            throw new TimeoutException("Create Stack- timeout exception");

        // clean files
        try {
            FileUtils.cleanDirectory(new File(Joiner.on(File.separator).join(targetFolder, "repo")));
        } catch (IOException e) {
            /*Swallow*/ }

        deployParmeters.increaseDeployCounter();
        LogUtils.log(listener, "Increased deployment counter.");

        return true;

    }

    public boolean cleanOpenstackBeforeDeployment(NexusClient nexusClient, OpenstackParameters openstackParameters,
            DeployParmeters deployParmeters) throws Exception {
        final String targetFolder = Joiner.on(File.separator).join(build.getWorkspace().getRemote(), "archive");

        OpenStackClient openStackClient = new OpenStackClient(listener, openstackParameters.getOpenstackUser(),
                openstackParameters.getOpenstackPassword(), openstackParameters.getOpenstackTenant(),
                "/v2.0/tokens", openstackParameters.getOpenstackIP(), 5000);

        //        String[] fileTypes = {"pom"};
        List<String> fileTypes = new ArrayList<String>();
        fileTypes.add("pom");
        nexusClient.downloadProductArtifacts(getArtifact(),
                Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId()), fileTypes);

        // parse pom and get its product dependencies
        MavenPom mp = new MavenPom(
                new File(Joiner.on(File.separator).join(targetFolder, artifact.getArtifactId(), "pom.xml")));
        List<ArtifactParameters> dependentProducts = mp.getPomProductDependencies();

        List<ArtifactParameters> subsystems = new ArrayList<ArtifactParameters>();
        subsystems.addAll(dependentProducts);
        subsystems.add(artifact);

        LogUtils.logSection(listener, "Clean Openstack previous deployments:");
        // delete all stacks
        if (subsystems != null) {
            for (ArtifactParameters s : subsystems) {
                String productName = s.getArtifactId().toLowerCase().replace("-product", "");

                StackDetails stackDetails = openStackClient.getStackDetails(productName);
                if (stackDetails.getStackStatus() != StackStatus.UNDEFINED) {
                    LogUtils.log(listener, "Deleting stack " + productName);
                    openStackClient.deleteStack(stackDetails);
                    LogUtils.log(listener, "Releasing IPs");
                    openStackClient.releaseStackFloatingIPs(productName);
                }
            }
        }
        deployParmeters.setGlobalOutputs(new HashMap<String, String>());

        // verify all deletions completed - run every minute for 30 minutes.
        if (subsystems != null) {
            for (ArtifactParameters s : subsystems) {
                String productName = s.getArtifactId().toLowerCase().replace("-product", "");

                long startTime = System.currentTimeMillis();
                boolean deleteComplete = false;

                while (!deleteComplete && (System.currentTimeMillis() - startTime < DELETE_TIMEOUT)) {
                    StackStatus stackStatus = openStackClient.getStackStatus(productName);
                    LogUtils.log(listener, "Waiting for deletion of " + productName + ". Status:" + stackStatus);
                    if (stackStatus == StackStatus.DELETE_COMPLETE || stackStatus == StackStatus.UNDEFINED) {
                        deleteComplete = true;
                    } else
                        Thread.sleep(SLEEP_TIME);
                }
                if (!deleteComplete)
                    throw new TimeoutException("Delete Stack -timeout exception");
            }
        }

        // Prepare parameters map which override the stack 'env'
        prepareStackOverrides(openStackClient, openstackParameters, deployParmeters);
        LogUtils.log(listener, "Get User parameters");

        deployParmeters.resetDeployCounter();
        return true;

    }

    private void setSymlinkOnYumRepo(YumRepoParameters yumRepoParameters, String sourcePath, String targetPath)
            throws IOException {
        FtpUtils.createRemoteSymLink(sourcePath, targetPath, yumRepoParameters.getYumRepoIP(),
                yumRepoParameters.getYumRepoPrivateKey());
    }

    private void createAndMoveYumRepo(AbstractBuild build, BuildListener listener,
            YumRepoParameters yumRepoParameters, String folder, String deployCounter)
            throws IOException, InterruptedException {

        String deploymentScriptsRPM = "nds_" + artifact.getArtifactId() + "_deployment-scripts-"
                + artifact.getVersion() + "_1.noarch.rpm";

        //String basepath = Joiner.on("/").join("/var", "www", "html", "build", "latest");
        String buildId = Joiner.on("-").join(new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SS").format(build.getTime()),
                deployCounter);
        String packagespath = Joiner.on("/").join("/var", "www", "html", "ci-repo", artifact.getArtifactId(),
                "Packages", deploymentScriptsRPM);
        String basepath = Joiner.on("/").join("/var", "www", "html", "build", buildId);

        copyFolderToRepoMachine(build, listener, yumRepoParameters, folder,
                Joiner.on("/").join("/var", "www", "html", "build", buildId));

        // Update symlink on yum repo to point to latest build
        setSymlinkOnYumRepo(yumRepoParameters, basepath,
                Joiner.on("/").join("/var", "www", "html", "build", "latest"));

        String cmds[] = { "rm -rf " + packagespath, "createrepo -o " + basepath + "/repo " + basepath + "/repo",
                "pakrat --name " + artifact.getArtifactId() + " --repoversion " + buildId + " --baseurl http://"
                        + yumRepoParameters.getYumRepoIP() + "/build/" + buildId
                        + "/repo/ --outdir /var/www/html/ci-repo",
                "rm -fr " + basepath + "/repo/*.rpm" };
        ExecUtils.executeRemoteCommand(listener, cmds, yumRepoParameters.getYumRepoIP(),
                yumRepoParameters.getYumRepoPrivateKey());
    }

    private void copyFolderToRepoMachine(AbstractBuild build, BuildListener listener,
            YumRepoParameters yumRepoParameters, String sourceFolder, String targetFolder) {
        FileOutputStream fos = null;
        try {
            String rsapath = Joiner.on(File.separator).join(build.getWorkspace().getRemote(), "id_rsa");
            fos = new FileOutputStream(new File(rsapath));
            fos.write(yumRepoParameters.getYumRepoPrivateKey().getBytes());

            // Copy scripts and yum folders to yum repo machine
            FtpUtils.copyLocalFolderToRemote(sourceFolder, targetFolder, yumRepoParameters.getYumRepoIP(), rsapath);
        } catch (IOException e) {
            throw new OsCiPluginException(e.getMessage());
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    LogUtils.log(listener, "Got an error!");
                }
            }
        }
    }

    private void moveExternalRpmsToRepoDirectory(String rpmsSrcFolder, String repoTargetFolder) {

        File repoFolder = new File(repoTargetFolder);

        for (File f : new File(rpmsSrcFolder).listFiles())
            try {
                FileUtils.moveFileToDirectory(f, repoFolder, true);
            } catch (IOException e) {
            }
    }

    private void prepareStackOverrides(OpenStackClient openStackClient, OpenstackParameters openstackParameters,
            DeployParmeters deployParmeters) {
        Map<String, String> overrides = deployParmeters.getOverridingParameters();

        overrides.put("urn:com:cisco:vci:service:version", artifact.getVersion());

        // Openstack Parameters
        if (StringUtils.isNotEmpty(openstackParameters.getKeyPair())) {
            overrides.put("key_name", openstackParameters.getKeyPair());
            overrides.put("urn:com:cisco:vci:heat:stack:keypairid", openstackParameters.getKeyPair());
        }
        if (StringUtils.isNotEmpty(openstackParameters.getPrivateNetworkID())) {
            overrides.put("private_network_id", openstackParameters.getPrivateNetworkID());
            overrides.put("urn:com:cisco:vci:heat:stack:networkid", openstackParameters.getPrivateNetworkID());
        }
        if (StringUtils.isNotEmpty(openstackParameters.getPrivateSubnetID())) {
            overrides.put("private_subnet_id", openstackParameters.getPrivateSubnetID());
            overrides.put("urn:com:cisco:vci:heat:stack:subnetid", openstackParameters.getPrivateSubnetID());
        }

        if (MapUtils.isNotEmpty(openstackParameters.getAdditionalParams())) {
            for (Map.Entry<String, String> entry : openstackParameters.getAdditionalParams().entrySet())
                overrides.put(entry.getKey(), entry.getValue());

            for (Map.Entry<String, String> entry : openstackParameters.getAdditionalParams().entrySet())
                overrides.put("urn:com:cisco:vci:service:parameter:" + entry.getKey(), entry.getValue());

            //    overrides.put("hiera_params", JsonParser.convertMapToJsonString(openstackParameters.getAdditionalParams()));
        }

        // Policy Parameters
        if (openstackParameters.getPolicyParameters() != null) {
            if (openstackParameters.getPolicyParameters().getNodeConfigurationsParameters() != null) {
                // Node Configuration
                for (NodeConfiguration nodeConfiguration : openstackParameters.getPolicyParameters()
                        .getNodeConfigurationsParameters()) {
                    overrides.put(nodeConfiguration.getName() + ".imagename", nodeConfiguration.getImageName());
                    overrides.put(nodeConfiguration.getName() + ".imageid", nodeConfiguration.getImageId());
                    overrides.put(nodeConfiguration.getName() + ".flavorname", nodeConfiguration.getFlavorName());
                    overrides.put(nodeConfiguration.getName() + ".flavorid", nodeConfiguration.getFlavorId());
                    overrides.put(nodeConfiguration.getName() + ".quantity:min",
                            nodeConfiguration.getQuantityMin());
                    overrides.put(nodeConfiguration.getName() + ".quantity:max",
                            nodeConfiguration.getQuantityMax());

                    overrides.put("image", nodeConfiguration.getImageName());
                    overrides.put("flavor", nodeConfiguration.getFlavorName());
                    overrides.put("min_size", nodeConfiguration.getQuantityMin());
                    overrides.put("max_size", nodeConfiguration.getQuantityMax());
                }
            }
            // Domains
            if (openstackParameters.getPolicyParameters().getDomains() != null) {

                String public_network_name = openStackClient.geListOfPublicNetworks().get(0).getName();
                LogUtils.logSection(listener, "DNS Registration:");

                for (Domain domain : openstackParameters.getPolicyParameters().getDomains()) {
                    FloatingIP fip = openStackClient.createFloatingIP(public_network_name);
                    // register to external DNS
                    registerToExternalDNS(domain.getFqdn(), fip.getFloatingIpAddress(),
                            openstackParameters.getNameservers());

                    overrides.put(domain.getName() + ".fqdn", domain.getFqdn());
                    overrides.put(domain.getName() + ".floatingipid", fip.getFloatingIpId());

                    overrides.put("fqdn", domain.getFqdn());
                    overrides.put("floating_ip_id", fip.getFloatingIpId());
                }
            }

            //AZs
            if (openstackParameters.getPolicyParameters().getAzs() != null) {
                for (AZ az : openstackParameters.getPolicyParameters().getAzs()) {
                    overrides.put(az.getName() + ".azname", az.getazname());

                    overrides.put("availability_zone", az.getazname());
                }
            }
        }
        deployParmeters.setOverridingParameters(overrides);
    }

    public boolean downloadGitRepos(String tempTargetFolder, String targetFolder, String scriptsFolder,
            String scriptsGitUrl, String heatGitUrl, String puppetBaseGitUrl) {
        try {

            LogUtils.logSection(listener, "Downloading git repos");
            // Get Scripts from GIT repo
            if (!scriptsGitUrl.isEmpty()) {
                new GitClient(tempTargetFolder, scriptsGitUrl, "master", "deploy-scripts", listener);
                LogUtils.log(listener, "Downloaded repo " + scriptsGitUrl);
            }
            if (!heatGitUrl.isEmpty()) {
                // Get HEAT templates from GIT repo
                new GitClient(tempTargetFolder, heatGitUrl, "master", "heat", listener);
                LogUtils.log(listener, "Downloaded repo " + heatGitUrl);
            }
            // HEAT repository include templates for all product.
            // Select only the ones we need.
            saveProductResourcesOnly(tempTargetFolder, targetFolder);

            if (!puppetBaseGitUrl.isEmpty()) {
                new GitClient(scriptsFolder, puppetBaseGitUrl, "master", "puppets", listener);
                LogUtils.log(listener, "Downloaded repo " + puppetBaseGitUrl);
                //                createTar("puppet-base.tar.gz", Joiner.on(File.separator).join(scriptsFolder, "puppet-base"));
                //TODO copy
            }

            LogUtils.log(listener, "Saved necessary files only");

        } catch (IOException e) {
            LogUtils.log(listener, "Got an error fetching git repository: " + e.getMessage());
            return false;
        }
        return true;
    }

    private void saveProductResourcesOnly(String srcDir, String tarDir) throws IOException {
        String plainId = artifact.getArtifactId().substring(0, artifact.getArtifactId().lastIndexOf('-'));
        FileUtils.forceMkdir(new File(Joiner.on(File.separator).join(tarDir, "heat")));
        FileUtils.forceMkdir(new File(Joiner.on(File.separator).join(tarDir, "deploy-scripts")));

        // save GLOBAL scripts
        File fgScripts = new File(Joiner.on(File.separator).join(srcDir, "deploy-scripts", "GLOBAL"));
        if (fgScripts.isDirectory()) {
            FileUtils.moveDirectory(fgScripts,
                    new File(Joiner.on(File.separator).join(tarDir, "deploy-scripts", "GLOBAL")));
        }

        // save product resources
        File fHeat = new File(Joiner.on(File.separator).join(srcDir, "heat", plainId.toLowerCase()));
        if (fHeat.isDirectory()) {
            FileUtils.moveDirectory(fHeat,
                    new File(Joiner.on(File.separator).join(tarDir, "heat", plainId.toLowerCase())));
        } else {
            throw new OsCiPluginException("HEAT template missing in repo for product" + plainId.toLowerCase());
        }

        File fScripts = new File(Joiner.on(File.separator).join(srcDir, "deploy-scripts", plainId.toUpperCase()));
        if (fScripts.isDirectory()) {
            FileUtils.moveDirectory(fScripts,
                    new File(Joiner.on(File.separator).join(tarDir, "deploy-scripts", plainId.toUpperCase())));
        }

        // delete temp_archive directory - failed to delete pack file
        //FileUtils.forceDelete(new File(srcDir));
    }

    public String createPom(String targetFolder, ArrayList<ArtifactParameters> productDependencies,
            ArrayList<ArtifactParameters> artifactDependencies) {
        String pomPath = null;
        try {
            LogUtils.logSection(listener, "Creating pom.xml");

            FilePath pomDir = new FilePath(new File(targetFolder)).getParent();
            pomPath = Joiner.on(File.separator).join(pomDir, "pom.xml");
            File f = new File(pomPath);
            new MavenPom.MavenPomBuilder().artifact(artifact)
                    .dependencies(productDependencies, artifactDependencies).build().save(f);
            LogUtils.log(listener, "pom.xml: " + pomPath);
        } catch (FileNotFoundException e) {
            LogUtils.log(listener, "could not save pom.xml " + e.getMessage());
        } catch (IOException e) {
            LogUtils.log(listener, "could not save pom.xml " + e.getMessage());
        }
        return pomPath;

    }

    public String createRPMPom(String targetFolder) {
        String pomPath = null;
        try {
            LogUtils.logSection(listener, "Creating pom.xml");

            FilePath pomDir = new FilePath(new File(targetFolder));
            pomPath = Joiner.on(File.separator).join(pomDir, "pom.xml");
            File f = new File(pomPath);
            new MavenRPMPom.MavenPomBuilder().artifact(artifact).build(targetFolder).save(f);
            LogUtils.log(listener, "pom.xml: " + pomPath);
        } catch (FileNotFoundException e) {
            LogUtils.log(listener, "could not save pom.xml " + e.getMessage());
        } catch (IOException e) {
            LogUtils.log(listener, "could not save pom.xml " + e.getMessage());
        }
        return pomPath;

    }

    public String createExternalDependenciesTar(String targetFolder) {
        return createTar("external_dependencies.tar.gz", targetFolder);
    }

    public String createTar(String filename, String targetFolder) {
        String tarPath;
        try {
            LogUtils.logSection(listener, "Compressing artifacts");
            FilePath tarDir = new FilePath(new File(targetFolder)).getParent();
            tarPath = Joiner.on(File.separator).join(tarDir, filename);
            CompressUtils.tarGzDirectory(targetFolder, tarPath);
            LogUtils.log(listener, "Created archive: " + tarPath);
        } catch (IOException e) {
            LogUtils.log(listener, "Got an error compressing directory: " + e.getMessage());
            return null;
        }
        return tarPath;
    }

    public void registerToExternalDNS(String fqdn, String ipaddress, String nameservers) {
        try {

            LogUtils.log(listener, "DNS registration: " + fqdn + " to " + ipaddress);
            if (!new File("/usr/local/bin/do_nsupdate").exists()) {
                LogUtils.log(listener,
                        "Cannot Register records to DNS. Expected script /usr/local/bin/do_nsupdate is missing");
            } else if (!System.getProperty("os.name").toLowerCase().startsWith("windows")
                    && !nameservers.isEmpty()) {
                // re-register ip ot fqdn
                if (fqdn.contains("_"))
                    throw new InterruptedException("FQDN string cannot contain '_'");
                ExecUtils.executeLocalCommand(
                        "/usr/local/bin/do_nsupdate -D -N " + fqdn + " -R A -S " + nameservers, "/usr/local/bin/");
                ExecUtils.executeLocalCommand(
                        "/usr/local/bin/do_nsupdate -I " + ipaddress + " -A -N " + fqdn + " -R A -S " + nameservers,
                        "/usr/local/bin/");
            } else if (nameservers.isEmpty())
                LogUtils.log(listener,
                        "could not register IP Address to an Empty DNS - please enter a valid nameserver IP or hostname ");
            else
                LogUtils.log(listener, "Cannot Register records to DNS under Windows OS");

        } catch (InterruptedException e) {
            LogUtils.log(listener, "could not register IP Address to external DNS " + e.getMessage());

        }
    }

}