package com.mirantis.mk

/**
 * Setup Docker to run some tests. Returns true/false based on
 were tests successful or not.
 * @param config - LinkedHashMap with configuration params:
 *   dockerHostname - (required) Hostname to use for Docker container.
 *   distribRevision - (optional) Revision of packages to use (default proposed).
 *   runCommands - (optional) Dict with closure structure of body required tests. For example:
 *     [ '001_Test': { sh("./run-some-test") }, '002_Test': { sh("./run-another-test") } ]
 *     Before execution runCommands will be sorted by key names. Alpabetical order is preferred.
 *   runFinally - (optional) Dict with closure structure of body required commands, which should be
 *     executed in any case of test results. Same format as for runCommands
 *   updateRepo - (optional) Whether to run common repo update step.
 *   dockerContainerName - (optional) Docker container name.
 *   dockerImageName - (optional) Docker image name
 *   dockerMaxCpus - (optional) Number of CPUS to use in Docker.
 *   dockerExtraOpts - (optional) Array of Docker extra opts for container
 *   envOpts - (optional) Array of variables that should be passed as ENV vars to Docker container.
 * Return true | false
 */

def setupDockerAndTest(LinkedHashMap config) {
    def common = new com.mirantis.mk.Common()
    def TestMarkerResult = false
    // setup options
    def defaultContainerName = 'test-' + UUID.randomUUID().toString()
    def dockerHostname = config.get('dockerHostname', defaultContainerName)
    def distribRevision = config.get('distribRevision', 'proposed')
    def runCommands = config.get('runCommands', [:])
    def runFinally = config.get('runFinally', [:])
    def baseRepoPreConfig = config.get('baseRepoPreConfig', true)
    def dockerContainerName = config.get('dockerContainerName', defaultContainerName)
    //  def dockerImageName = config.get('image', "mirantis/salt:saltstack-ubuntu-xenial-salt-2017.7")
    // FIXME /PROD-25244
    def dockerImageName = config.get('image', "docker-prod-local.artifactory.mirantis.com/mirantis/salt:saltstack-ubuntu-xenial-salt-2017.7")
    def dockerMaxCpus = config.get('dockerMaxCpus', 4)
    def dockerExtraOpts = config.get('dockerExtraOpts', [])
    def envOpts = config.get('envOpts', [])
    envOpts.add("DISTRIB_REVISION=${distribRevision}")
    def dockerBaseOpts = [
        '-u root:root',
        "--hostname=${dockerHostname}",
        '--ulimit nofile=4096:8192',
        "--name=${dockerContainerName}",
        "--cpus=${dockerMaxCpus}"
    ]
    def dockerOptsFinal = (dockerBaseOpts + dockerExtraOpts).join(' ')
    def extraReposConfig = null
    if (baseRepoPreConfig) {
        // extra repo on mirror.mirantis.net, which is not supported before 2018.11.0 release
        def extraRepoSource = "deb [arch=amd64] http://mirror.mirantis.com/${distribRevision}/extra/xenial xenial main"
        def releaseVersionQ4 = '2018.11.0'
        def oldRelease = false
        try {
            def releaseNaming = 'yyyy.MM.dd'
            def repoDateUsed = new Date().parse(releaseNaming, distribRevision)
            def extraAvailableFrom = new Date().parse(releaseNaming, releaseVersionQ4)
            if (repoDateUsed < extraAvailableFrom) {
                extraRepoSource = "deb http://apt.mcp.mirantis.net/xenial ${distribRevision} extra"
                oldRelease = true
            }
        } catch (Exception e) {
            common.warningMsg(e)
            if (!(distribRevision in ['nightly', 'proposed', 'testing'])) {
                extraRepoSource = "deb [arch=amd64] http://apt.mcp.mirantis.net/xenial ${distribRevision} extra"
                oldRelease = true
            }
        }

        def defaultExtraReposYaml = """
---
aprConfD: |-
  APT::Get::AllowUnauthenticated 'true';
  APT::Get::Install-Suggests 'false';
  APT::Get::Install-Recommends 'false';
repo:
  mcp_saltstack:
    source: "deb [arch=amd64] http://mirror.mirantis.com/${distribRevision}/saltstack-2017.7/xenial xenial main"
    pin:
      - package: "libsodium18"
        pin: "release o=SaltStack"
        priority: 50
      - package: "*"
        pin: "release o=SaltStack"
        priority: "1100"
  mcp_extra:
    source: "${extraRepoSource}"
  mcp_saltformulas:
    source:   "deb [arch=amd64]  http://mirror.mirantis.com/${distribRevision}/salt-formulas/xenial xenial main"
    repo_key: "http://mirror.mirantis.com/${distribRevision}/salt-formulas/xenial/archive-salt-formulas.key"
  ubuntu:
    source: "deb [arch=amd64] http://mirror.mirantis.com/${distribRevision}/ubuntu xenial main restricted universe"
  ubuntu-upd:
    source: "deb [arch=amd64] http://mirror.mirantis.com/${distribRevision}/ubuntu xenial-updates main restricted universe"
  ubuntu-sec:
    source: "deb [arch=amd64] http://mirror.mirantis.com/${distribRevision}/ubuntu xenial-security main restricted universe"
"""
        // override for now
        def extraRepoMergeStrategy = config.get('extraRepoMergeStrategy', 'override')
        def extraRepos = config.get('extraRepos', [:])
        def updateSaltFormulas = config.get('updateSaltFormulas', true).toBoolean()
        def defaultRepos = readYaml text: defaultExtraReposYaml
        // Don't check for magic, if set explicitly
        if (updateSaltFormulas) {
            def updateSaltFormulasRev = config.get('updateSaltFormulasRev', distribRevision)
            if (!oldRelease && distribRevision != releaseVersionQ4) {
                defaultRepos['repo']['mcp_saltformulas_update'] = [
                    'source'  : "deb [arch=amd64]  http://mirror.mirantis.com/update/${updateSaltFormulasRev}/salt-formulas/xenial xenial main",
                    'repo_key': "http://mirror.mirantis.com/update/${updateSaltFormulasRev}/salt-formulas/xenial/archive-salt-formulas.key"
                ]
            }
        }
        if (extraRepoMergeStrategy == 'merge') {
            extraReposConfig = common.mergeMaps(defaultRepos, extraRepos)
        } else {
            extraReposConfig = extraRepos ? extraRepos : defaultRepos
        }
    }
    def img = docker.image(dockerImageName)

    def pull_enabled = config.get('dockerPull', true)

    if ( pull_enabled ) {
        img.pull()
    }

    try {
        img.inside(dockerOptsFinal) {
            withEnv(envOpts) {
                try {
                    sh('printenv |sort -u')
                    // Currently, we don't have any other point to install
                    // runtime dependencies for tests.
                    if (baseRepoPreConfig) {
                        // Warning! POssible point of 'allow-downgrades' issue
                        // Probably, need to add such flag into apt.prefs
                        sh("""#!/bin/bash -xe
                            echo "Installing extra-deb dependencies inside docker:"
                            echo > /etc/apt/sources.list
                            rm -vf /etc/apt/sources.list.d/* || true
                            rm -vf /etc/apt/preferences.d/* || true
                        """)
                        common.debianExtraRepos(extraReposConfig)
                        sh('''#!/bin/bash -xe
                            apt-get update
                            apt-get install -y python-netaddr
                        ''')

                    }
                    runCommands.sort().each { command, body ->
                        common.warningMsg("Running command: ${command}")
                        // doCall is the closure implementation in groovy, allow to pass arguments to closure
                        body.call()
                    }
                    // If we didn't dropped for now - test has been passed.
                    TestMarkerResult = true
                }
                finally {
                    runFinally.sort().each { command, body ->
                        common.warningMsg("Running ${command} command.")
                        // doCall is the closure implementation in groovy, allow to pass arguments to closure
                        body.call()
                    }
                }
            }
        }
    }
    catch (Exception er) {
        common.warningMsg("IgnoreMe:Something wrong with img.Message:\n" + er.toString())
    }

    try {
        timeout(time: 30, unit: 'SECONDS') {
          if (sh(script: "docker inspect ${dockerContainerName}", returnStatus: true) == 0) {
              common.warningMsg("Verify that container is not running. Ignore further docker-daemon errors")
              sh(script: "set -x; test \$(docker inspect -f '{{.State.Running}}' ${dockerContainerName} 2>/dev/null) = 'true' && docker kill ${dockerContainerName}", returnStdout: true)
              sh(script: "set -x; docker rm --force ${dockerContainerName} || true", returnStdout: true)
          }
        }
    }
    catch (Exception er) {
        common.warningMsg("IgnoreMe:Timeout to delete test docker container with force! Message:\n" + er.toString())
    }

    if (TestMarkerResult) {
        common.infoMsg("Test finished: SUCCESS")
    } else {
        common.warningMsg("Test finished: FAILURE")
    }
    return TestMarkerResult
}

/**
 * Wrapper around setupDockerAndTest, to run checks against new Reclass version
 * that current model is compatible with new Reclass.
 *
 * @param config - LinkedHashMap with configuration params:
 *   dockerHostname - (required) Hostname to use for Docker container.
 *   distribRevision - (optional) Revision of packages to use (default proposed).
 *   extraRepo - (optional) Extra repo to use to install new Reclass version. Has
 *     high priority on distribRevision
 *   targetNodes - (required) List nodes to check pillar data.
 */
def compareReclassVersions(config) {
    def common = new com.mirantis.mk.Common()
    def salt = new com.mirantis.mk.Salt()
    common.infoMsg("Going to test new reclass for CFG node")
    def distribRevision = config.get('distribRevision', 'proposed')
    def venv = config.get('venv')
    def extraRepo = config.get('extraRepo', '')
    def extraRepoKey = config.get('extraRepoKey', '')
    def targetNodes = config.get('targetNodes')
    sh "rm -rf ${env.WORKSPACE}/old ${env.WORKSPACE}/new"
    sh "mkdir -p ${env.WORKSPACE}/old ${env.WORKSPACE}/new"
    def configRun = [
        'distribRevision': distribRevision,
        'dockerExtraOpts': [
            "-v /srv/salt/reclass:/srv/salt/reclass:ro",
            "-v /etc/salt:/etc/salt:ro",
            "-v /usr/share/salt-formulas/:/usr/share/salt-formulas/:ro"
        ],
        'envOpts'        : [
            "WORKSPACE=${env.WORKSPACE}",
            "NODES_LIST=${targetNodes.join(' ')}"
        ],
        'runCommands'    : [
            '001_Update_Reclass_package'    : {
                sh('apt-get update && apt-get install -y reclass')
            },
            '002_Test_Reclass_Compatibility': {
                sh('''
                reclass-salt -b /srv/salt/reclass -t > ${WORKSPACE}/new/inventory || exit 1
                for node in $NODES_LIST; do
                    reclass-salt -b /srv/salt/reclass -p $node > ${WORKSPACE}/new/$node || exit 1
                done
              ''')
            }
        ]
    ]
    if (extraRepo) {
        // FIXME
        configRun['runCommands']['0001_Additional_Extra_Repo_Passed'] = {
            sh("""
                echo "${extraRepo}" > /etc/apt/sources.list.d/mcp_extra.list
                [ "${extraRepoKey}" ] && wget -O - ${extraRepoKey} | apt-key add -
            """)
        }
    }
    if (setupDockerAndTest(configRun)) {
        common.infoMsg("New reclass version is compatible with current model: SUCCESS")
        def inventoryOld = salt.cmdRun(venv, "I@salt:master", "reclass-salt -b /srv/salt/reclass -t", true, null, true).get("return")[0].values()[0]
        // [0..-31] to exclude 'echo Salt command execution success' from output
        writeFile(file: "${env.WORKSPACE}/old/inventory", text: inventoryOld[0..-31])
        for (String node in targetNodes) {
            def nodeOut = salt.cmdRun(venv, "I@salt:master", "reclass-salt -b /srv/salt/reclass -p ${node}", true, null, true).get("return")[0].values()[0]
            writeFile(file: "${env.WORKSPACE}/old/${node}", text: nodeOut[0..-31])
        }
        def reclassDiff = common.comparePillars(env.WORKSPACE, env.BUILD_URL, '')
        currentBuild.description = reclassDiff
        if (reclassDiff != '<b>No job changes</b>') {
            throw new RuntimeException("Pillars with new reclass version has been changed: FAILED")
        } else {
            common.infoMsg("Pillars not changed with new reclass version: SUCCESS")
        }
    } else {
        throw new RuntimeException("New reclass version is not compatible with current model: FAILED")
    }
}

/**
 * Wrapper over setupDockerAndTest, to test CC model.
 *
 * @param config - dict with params:
 *   dockerHostname - (required) salt master's name
 *   clusterName - (optional) model cluster name
 *   extraFormulas - (optional) extraFormulas to install. DEPRECATED
 *   formulasSource - (optional) formulas source (git or pkg, default pkg)
 *   reclassVersion - (optional) Version of used reclass (branch, tag, ...) (optional, default master)
 *   reclassEnv - (require) directory of model
 *   ignoreClassNotfound - (optional) Ignore missing classes for reclass model (default false)
 *   aptRepoUrl - (optional) package repository with salt formulas
 *   aptRepoGPG - (optional) GPG key for apt repository with formulas
 *   testContext - (optional) Description of test
 Return: true\exception
 */

def testNode(LinkedHashMap config) {
    def common = new com.mirantis.mk.Common()
    def dockerHostname = config.get('dockerHostname')
    def domain = config.get('domain')
    def reclassEnv = config.get('reclassEnv')
    def clusterName = config.get('clusterName', "")
    def formulasSource = config.get('formulasSource', 'pkg')
    def extraFormulas = config.get('extraFormulas', 'linux')
    def ignoreClassNotfound = config.get('ignoreClassNotfound', false)
    def aptRepoUrl = config.get('aptRepoUrl', "")
    def aptRepoGPG = config.get('aptRepoGPG', "")
    def testContext = config.get('testContext', 'test')
    def nodegenerator = config.get('nodegenerator', false)
    config['envOpts'] = [
        "RECLASS_ENV=${reclassEnv}", "SALT_STOPSTART_WAIT=5",
        "HOSTNAME=${dockerHostname}", "CLUSTER_NAME=${clusterName}",
        "DOMAIN=${domain}", "FORMULAS_SOURCE=${formulasSource}",
        "EXTRA_FORMULAS=${extraFormulas}", "EXTRA_FORMULAS_PKG_ALL=true",
        "RECLASS_IGNORE_CLASS_NOTFOUND=${ignoreClassNotfound}", "DEBUG=1",
        "APT_REPOSITORY=${aptRepoUrl}", "APT_REPOSITORY_GPG=${aptRepoGPG}"
    ]

    config['runCommands'] = [
        '001_Clone_salt_formulas_scripts': {
            sh(script: 'git clone http://gerrit.mcp.mirantis.com/salt-formulas/salt-formulas-scripts /srv/salt/scripts', returnStdout: true)
        },

        '002_Prepare_something'          : {
            sh('''#!/bin/bash -x
              rsync -ah ${RECLASS_ENV}/* /srv/salt/reclass && echo '127.0.1.2  salt' >> /etc/hosts
              echo "127.0.0.1 ${HOSTNAME}.${DOMAIN}" >> /etc/hosts
              if [ -f '/srv/salt/reclass/salt_master_pillar.asc' ] ; then
                mkdir -p /etc/salt/gpgkeys
                chmod 700 /etc/salt/gpgkeys
                GNUPGHOME=/etc/salt/gpgkeys gpg --import /srv/salt/reclass/salt_master_pillar.asc
              fi
              cd /srv/salt && find . -type f \\( -name '*.yml' -or -name '*.sh' \\) -exec sed -i 's/apt-mk.mirantis.com/apt.mcp.mirantis.net/g' {} \\;
              cd /srv/salt && find . -type f \\( -name '*.yml' -or -name '*.sh' \\) -exec sed -i 's/apt.mirantis.com/apt.mcp.mirantis.net/g' {} \\;
            ''')
        },

        '003_Install_Reclass_package'    : {
            sh('apt-get install -y reclass')
        },

        '004_Run_tests'                  : {
            def testTimeout = 40 * 60
            timeout(time: testTimeout, unit: 'SECONDS') {
                sh('''#!/bin/bash
                source /srv/salt/scripts/bootstrap.sh
                cd /srv/salt/scripts
                source_local_envs
                configure_salt_master
                configure_salt_minion
                install_salt_formula_pkg
                source /srv/salt/scripts/bootstrap.sh
                cd /srv/salt/scripts
                saltservice_restart''')

                sh('''#!/bin/bash
                source /srv/salt/scripts/bootstrap.sh
                cd /srv/salt/scripts
                source_local_envs
                saltmaster_init''')

                sh('''#!/bin/bash
                source /srv/salt/scripts/bootstrap.sh
                cd /srv/salt/scripts
                verify_salt_minions''')
            }
        }
    ]
    config['runFinally'] = [
        '001_Archive_artefacts': {
            sh(script: "cd /tmp; tar -czf ${env.WORKSPACE}/nodesinfo.tar.gz *reclass*", returnStatus: true)
            archiveArtifacts artifacts: "nodesinfo.tar.gz"
        }
    ]
    // this tool should be tested in master branch only
    // and not for all jobs, as pilot will be used cc-reclass-chunk
    if (nodegenerator) {
        config['runCommands']['005_Test_new_nodegenerator'] = {
            try {
                sh('''#!/bin/bash
                new_generated_dir=/srv/salt/_new_generated
                mkdir -p ${new_generated_dir}
                nodegenerator -b /srv/salt/reclass/classes/ -o ${new_generated_dir} ${CLUSTER_NAME}
                diff -r /srv/salt/reclass/nodes/_generated ${new_generated_dir} > /tmp/nodegenerator.diff
                tar -czf /tmp/_generated.tar.gz /srv/salt/reclass/nodes/_generated/
                tar -czf /tmp/_new_generated.tar.gz ${new_generated_dir}/
                tar -czf /tmp/_model.tar.gz /srv/salt/reclass/classes/cluster/*
                ''')
            } catch (Exception e) {
                print "Test new nodegenerator tool is failed: ${e}"
            }
        }
        config['runFinally']['002_Archive_nodegenerator_artefact'] = {
            sh(script: "cd /tmp; [ -f nodegenerator.diff ] && tar -czf ${env.WORKSPACE}/nodegenerator.tar.gz nodegenerator.diff _generated.tar.gz _new_generated.tar.gz _model.tar.gz", returnStatus: true)
            if (fileExists('nodegenerator.tar.gz')) {
                archiveArtifacts artifacts: "nodegenerator.tar.gz"
            }
        }
    }
    testResult = setupDockerAndTest(config)
    if (testResult) {
        common.infoMsg("Node test for context: ${testContext} model: ${reclassEnv} finished: SUCCESS")
    } else {
        throw new RuntimeException("Node test for context: ${testContext} model: ${reclassEnv} finished: FAILURE")
    }
    return testResult
}

/**
 * setup and test salt-master
 *
 * @param masterName salt master's name
 * @param clusterName model cluster name
 * @param extraFormulas extraFormulas to install. DEPRECATED
 * @param formulasSource formulas source (git or pkg)
 * @param reclassVersion Version of used reclass (branch, tag, ...) (optional, default master)
 * @param testDir directory of model
 * @param formulasSource Salt formulas source type (optional, default pkg)
 * @param formulasRevision APT revision for formulas (optional default stable)
 * @param ignoreClassNotfound Ignore missing classes for reclass model
 * @param dockerMaxCpus max cpus passed to docker (default 0, disabled)
 * @param legacyTestingMode do you want to enable legacy testing mode (iterating through the nodes directory definitions instead of reading cluster models)
 * @param aptRepoUrl package repository with salt formulas
 * @param aptRepoGPG GPG key for apt repository with formulas
 * Return                     true | false
 */

def setupAndTestNode(masterName, clusterName, extraFormulas = '*', testDir, formulasSource = 'pkg',
                     formulasRevision = 'stable', reclassVersion = "master", dockerMaxCpus = 0,
                     ignoreClassNotfound = false, legacyTestingMode = false, aptRepoUrl = '', aptRepoGPG = '', dockerContainerName = false) {
    def common = new com.mirantis.mk.Common()
    // TODO
    common.errorMsg('You are using deprecated function!Please migrate to "setupDockerAndTest".' +
        'It would be removed after 2018.q4 release!Pushing forced 60s sleep..')
    sh('sleep 60')
    // timeout for test execution (40min)
    def testTimeout = 40 * 60
    def TestMarkerResult = false
    def saltOpts = "--retcode-passthrough --force-color"
    def workspace = common.getWorkspace()
    def img = docker.image("mirantis/salt:saltstack-ubuntu-xenial-salt-2017.7")
    img.pull()

    if (formulasSource == 'pkg') {
        if (extraFormulas) {
            common.warningMsg("You have passed deprecated variable:extraFormulas=${extraFormulas}. " +
                "\n It would be ignored, and all formulas would be installed anyway")
        }
    }
    if (!dockerContainerName) {
        dockerContainerName = 'setupAndTestNode' + UUID.randomUUID().toString()
    }
    def dockerMaxCpusOpt = "--cpus=4"
    if (dockerMaxCpus > 0) {
        dockerMaxCpusOpt = "--cpus=${dockerMaxCpus}"
    }
    try {
        img.inside("-u root:root --hostname=${masterName} --ulimit nofile=4096:8192 ${dockerMaxCpusOpt} --name=${dockerContainerName}") {
            withEnv(["FORMULAS_SOURCE=${formulasSource}", "EXTRA_FORMULAS=${extraFormulas}", "EXTRA_FORMULAS_PKG_ALL=true",
                     "DISTRIB_REVISION=${formulasRevision}",
                     "DEBUG=1", "MASTER_HOSTNAME=${masterName}",
                     "CLUSTER_NAME=${clusterName}", "MINION_ID=${masterName}",
                     "RECLASS_VERSION=${reclassVersion}", "RECLASS_IGNORE_CLASS_NOTFOUND=${ignoreClassNotfound}",
                     "APT_REPOSITORY=${aptRepoUrl}", "SALT_STOPSTART_WAIT=5",
                     "APT_REPOSITORY_GPG=${aptRepoGPG}"]) {
                try {
                    // Currently, we don't have any other point to install
                    // runtime dependencies for tests.
                    sh("""#!/bin/bash -xe
            echo "Installing extra-deb dependencies inside docker:"
            echo "APT::Get::AllowUnauthenticated 'true';"  > /etc/apt/apt.conf.d/99setupAndTestNode
            echo "APT::Get::Install-Suggests 'false';"  >> /etc/apt/apt.conf.d/99setupAndTestNode
            echo "APT::Get::Install-Recommends 'false';"  >> /etc/apt/apt.conf.d/99setupAndTestNode
            rm -vf /etc/apt/sources.list.d/* || true
            echo 'deb [arch=amd64] http://mirror.mirantis.com/$DISTRIB_REVISION/ubuntu xenial main restricted universe' > /etc/apt/sources.list
            echo 'deb [arch=amd64] http://mirror.mirantis.com/$DISTRIB_REVISION/ubuntu xenial-updates main restricted universe' >> /etc/apt/sources.list
            apt-get update
            apt-get install -y python-netaddr
            """)
                    sh(script: "git clone https://github.com/salt-formulas/salt-formulas-scripts /srv/salt/scripts", returnStdout: true)
                    sh("""rsync -ah ${testDir}/* /srv/salt/reclass && echo '127.0.1.2  salt' >> /etc/hosts
            cd /srv/salt && find . -type f \\( -name '*.yml' -or -name '*.sh' \\) -exec sed -i 's/apt-mk.mirantis.com/apt.mcp.mirantis.net/g' {} \\;
            cd /srv/salt && find . -type f \\( -name '*.yml' -or -name '*.sh' \\) -exec sed -i 's/apt.mirantis.com/apt.mcp.mirantis.net/g' {} \\;
            """)
                    // FIXME: should be changed to use reclass from mcp_extra_nigtly?
                    sh("""for s in \$(python -c \"import site; print(' '.join(site.getsitepackages()))\"); do
            sudo -H pip install --install-option=\"--prefix=\" --upgrade --force-reinstall -I \
            -t \"\$s\" git+https://github.com/salt-formulas/reclass.git@${reclassVersion};
            done""")
                    timeout(time: testTimeout, unit: 'SECONDS') {
                        sh('''#!/bin/bash
              source /srv/salt/scripts/bootstrap.sh
              cd /srv/salt/scripts
              source_local_envs
              configure_salt_master
              configure_salt_minion
              install_salt_formula_pkg
              source /srv/salt/scripts/bootstrap.sh
              cd /srv/salt/scripts
              saltservice_restart''')
                        sh('''#!/bin/bash
              source /srv/salt/scripts/bootstrap.sh
              cd /srv/salt/scripts
              source_local_envs
              saltmaster_init''')

                        if (!legacyTestingMode.toBoolean()) {
                            sh('''#!/bin/bash
                source /srv/salt/scripts/bootstrap.sh
                cd /srv/salt/scripts
                verify_salt_minions
                ''')
                        }
                    }
                    // If we didn't dropped for now - test has been passed.
                    TestMarkerResult = true
                }

                finally {
                    // Collect rendered per-node data.Those info could be simply used
                    // for diff processing. Data was generated via reclass.cli --nodeinfo,
                    /// during verify_salt_minions.
                    sh(script: "cd /tmp; tar -czf ${env.WORKSPACE}/nodesinfo.tar.gz *reclass*", returnStatus: true)
                    archiveArtifacts artifacts: "nodesinfo.tar.gz"
                }
            }
        }
    }
    catch (Exception er) {
        common.warningMsg("IgnoreMe:Something wrong with img.Message:\n" + er.toString())
    }

    if (legacyTestingMode.toBoolean()) {
        common.infoMsg("Running legacy mode test for master hostname ${masterName}")
        def nodes = sh(script: "find /srv/salt/reclass/nodes -name '*.yml' | grep -v 'cfg*.yml'", returnStdout: true)
        for (minion in nodes.tokenize()) {
            def basename = sh(script: "set +x;basename ${minion} .yml", returnStdout: true)
            if (!basename.trim().contains(masterName)) {
                testMinion(basename.trim())
            }
        }
    }

    try {
        common.warningMsg("IgnoreMe:Force cleanup slave.Ignore docker-daemon errors")
        timeout(time: 10, unit: 'SECONDS') {
            sh(script: "set -x; docker kill ${dockerContainerName} || true", returnStdout: true)
        }
        timeout(time: 10, unit: 'SECONDS') {
            sh(script: "set -x; docker rm --force ${dockerContainerName} || true", returnStdout: true)
        }
    }
    catch (Exception er) {
        common.warningMsg("IgnoreMe:Timeout to delete test docker container with force!Message:\n" + er.toString())
    }

    if (TestMarkerResult) {
        common.infoMsg("Test finished: SUCCESS")
    } else {
        common.warningMsg("Test finished: FAILURE")
    }
    return TestMarkerResult

}

/**
 * Test salt-minion
 *
 * @param minion salt minion
 */

def testMinion(minionName) {
    sh(script: "bash -c 'source /srv/salt/scripts/bootstrap.sh; cd /srv/salt/scripts && verify_salt_minion ${minionName}'", returnStdout: true)
}

/**
 * Wrapper over setupAndTestNode, to test exactly one CC model.
 Whole workspace and model - should be pre-rendered and passed via MODELS_TARGZ
 Flow: grab all data, and pass to setupAndTestNode function
 under-modell will be directly mirrored to `model/{cfg.testReclassEnv}/* /srv/salt/reclass/*`
 *
 * @param cfg - dict with params:
 MODELS_TARGZ       http link to arch with (models|contexts|global_reclass)
 modelFile
 DockerCName        directly passed to setupAndTestNode
 EXTRA_FORMULAS     directly passed to setupAndTestNode
 DISTRIB_REVISION   directly passed to setupAndTestNode
 reclassVersion     directly passed to setupAndTestNode

 Return: true\exception
 */

def testCCModel(cfg) {
    def common = new com.mirantis.mk.Common()
    common.errorMsg('You are using deprecated function!Please migrate to "testNode".' +
        'It would be removed after 2018.q4 release!Pushing forced 60s sleep..')
    sh('sleep 60')
    sh(script: 'find . -mindepth 1 -delete || true', returnStatus: true)
    sh(script: "wget --progress=dot:mega --auth-no-challenge -O models.tar.gz ${cfg.MODELS_TARGZ}")
    // unpack data
    sh(script: "tar -xzf models.tar.gz ")
    common.infoMsg("Going to test exactly one context: ${cfg.modelFile}\n, with params: ${cfg}")
    content = readFile(file: cfg.modelFile)
    templateContext = readYaml text: content
    clusterName = templateContext.default_context.cluster_name
    clusterDomain = templateContext.default_context.cluster_domain

    def testResult = false
    testResult = setupAndTestNode(
        "cfg01.${clusterDomain}",
        clusterName,
        '',
        cfg.testReclassEnv, // Sync into image exactly one env
        'pkg',
        cfg.DISTRIB_REVISION,
        cfg.reclassVersion,
        0,
        false,
        false,
        '',
        '',
        cfg.DockerCName)
    if (testResult) {
        common.infoMsg("testCCModel for context: ${cfg.modelFile} model: ${cfg.testReclassEnv} finished: SUCCESS")
    } else {
        throw new RuntimeException("testCCModel for context: ${cfg.modelFile} model: ${cfg.testReclassEnv} finished: FAILURE")
    }
    return testResult
}
