def build_with_docker(build_dir_mesos, build_dir_packaging, packages_dir):
    image_name = "mesos-docker-build-{}".format(MesosConfig.operating_system().replace(":","-"))
    if not Utils.is_docker_image(LOG, image_name):
        LOG.info("Docker image not found. Building...")
        Utils.exit_if_docker_image_not_built( LOG,
                                              MesosConfig.docker_templates_dir(),
                                              MesosConfig.operating_system().replace(":", "\\:"),
                                              image_name )

    mesos_build_command = "docker run -ti -v {}:/mesos-deb-packaging -v {}:/mesos-src {} /bin/bash -c 'cd /mesos-deb-packaging && ./build_mesos --build-version {} --src-dir /mesos-src; exit $?'".format(
                                  build_dir_packaging,
                                  build_dir_mesos,
                                  image_name,
                                  MesosConfig.mesos_build_version() )

    Utils.cmd("echo '{}'".format(mesos_build_command.replace("'", "\\'")))
    LOG.info("Building Mesos {} for {}. This will take a while...".format(MesosConfig.mesos_version(), MesosConfig.operating_system()))
    build_start_time = int(time.time())
    build_status = Utils.cmd(mesos_build_command)
    build_end_time = int(time.time())
    if build_status['ExitCode'] == 0:
        Utils.cmd("mkdir -p {0} && rm -Rf {0}/*".format( packages_dir ))
        Utils.cmd("mv {}/*.deb {}/ 2>/dev/null".format( build_dir_packaging, packages_dir ))
        Utils.cmd("mv {}/*.rpm {}/ 2>/dev/null".format( build_dir_packaging, packages_dir ))
        Utils.cmd("mv {}/*.egg {}/ 2>/dev/null".format( build_dir_packaging, packages_dir ))#
        LOG.info( "Mesos {} for {} built successfully. Build took {} seconds. Output available in {}. Cleaning up...".format(
                    MesosConfig.mesos_version(),
                    MesosConfig.operating_system(),
                    str( build_end_time - build_start_time ),
                    packages_dir ))
        Utils.cmd("rm -rf {}".format(build_dir_mesos))
        Utils.cmd("rm -rf {}".format(build_dir_packaging))
    else:
        LOG.error( "Mesos build failed. Leaving build log and temp directories for inspection. mesos={}; packaging={}".format( build_dir_mesos, build_dir_packaging ) )
        exit(107)
def op_build():
    if Utils.ensure_sources(LOG, MarathonConfig.marathon_repository_dir(), MarathonConfig.marathon_git_repository()):
        validate_input()
        image_name = "marathon-docker-build"
        if not Utils.is_docker_image(LOG, image_name):
            LOG.info("Docker image not found. Building...")
            Utils.exit_if_docker_image_not_built( LOG,
                                                  MarathonConfig.docker_templates_dir(),
                                                  "default",
                                                  image_name )

        build_dir    = "{}/{}".format( MarathonConfig.work_dir(),
                               MarathonConfig.marathon_version() )
        packages_dir = "{}/{}".format( MarathonConfig.packages_dir(),
                               MarathonConfig.marathon_version() )

        if os.path.exists(packages_dir):
            if not Utils.confirm("Marathon build for {} already exists. To rebuild, continue.".format(
                    MarathonConfig.marathon_version() )):
                exit(0)

        build_log_file = "{}.{}.log".format(build_dir, str(int(time.time())))
        LOG.info("Recording build process to {}.".format(build_log_file))
        Config.set_cmd_log(build_log_file)

        # cleanup old data:
        Utils.cmd("rm -rf {}".format(packages_dir))
        Utils.cmd("rm -rf {}".format(build_dir))

        # copy sources
        LOG.info("Fetching Marathon {} sources...".format(MarathonConfig.marathon_git_repository()))
        Utils.cmd("cp -R {} {}".format( MarathonConfig.marathon_repository_dir(), build_dir ))

        # ensure branch / tag
        Utils.exit_if_git_release_not_set( LOG, build_dir,
                                           MarathonConfig.marathon_version(),
                                           MarathonConfig.marathon_master_branch(),
                                           MarathonConfig.marathon_git_repository() )

        marathon_sbt_version = None
        raw_sbt_file_content = None
        if os.path.exists("{}/version.sbt".format( build_dir )):
            with open("{}/version.sbt".format( build_dir ), 'r') as sbt_file:
                raw_sbt_file_content = sbt_file.read().replace('\n', '')
                match_obj = re.match(r'.*"(.*)".*', raw_sbt_file_content)
                if match_obj:
                    marathon_sbt_version = match_obj.group(1)
        else:
            LOG.error("No version.sbt file for Marathon {}. Can't continue.".format( MarathonConfig.marathon_version() ))
            exit(110)

        if marathon_sbt_version == None:
            LOG.error("Version could not be reliably established from the version.sbt file. Raw content: {}. Can't continue.".format( raw_sbt_file_content ))
            exit(111)

        LOG.info("Marathon version from SBT: {}".format( marathon_sbt_version ))

        # TODO: Actual build
        build_command = "docker run -ti -v {}:/output -v {}:/marathon-src -v {}:/root/.ivy2 -e \"BUILD_MARATHON_VERSION={}\" -e \"FPM_OUTPUT_VERSION={}\" -e \"ASSEMBLY_WITH_TESTS={}\" {} /bin/bash -c 'cd /marathon-build && ./marathon-build.sh; exit $?'".format(
                                    os.path.dirname(packages_dir),
                                    build_dir,
                                    MarathonConfig.ivy2_dir(),
                                    MarathonConfig.marathon_version(),
                                    marathon_sbt_version,
                                    MarathonConfig.with_tests(),
                                    image_name )
        
        Utils.cmd("echo '{}'".format(build_command.replace("'", "\\'")))
        LOG.info("Building Marathon {}. This will take a while...".format(MarathonConfig.marathon_version()))
        build_start_time = int(time.time())
        build_status = Utils.cmd(build_command)
        build_end_time = int(time.time())
        if build_status['ExitCode'] == 0:
            LOG.info( "Marathon {} built successfully. Build took {} seconds. Output available in {}. Cleaning up...".format(
                      MarathonConfig.marathon_version(),
                      str( build_end_time - build_start_time ),
                      packages_dir ))
            Utils.cmd("rm -rf {}".format(build_dir))
        else:
            LOG.error( "Marathon build failed. Leaving build log and temp directory for inspection. marathon={}".format( build_dir ) )
            exit(107)
def op_build():
    validate_input()
    if Utils.ensure_sources(LOG, ChronosConfig.chronos_repository_dir(), ChronosConfig.chronos_git_repository()):
        image_name = "chronos-docker-build"
        if not Utils.is_docker_image(LOG, image_name):
            LOG.info("Docker image not found. Building...")
            Utils.exit_if_docker_image_not_built( LOG,
                                                  ChronosConfig.docker_templates_dir(),
                                                  "default",
                                                  image_name )

        build_dir    = "{}/{}".format( ChronosConfig.work_dir(),
                               ChronosConfig.chronos_version() )
        packages_dir = "{}/{}".format( ChronosConfig.packages_dir(),
                               ChronosConfig.chronos_version() )

        if os.path.exists(packages_dir):
            if not Utils.confirm("Chronos build for {} already exists. To rebuild, continue.".format(
                    ChronosConfig.chronos_version() )):
                LOG.info("You have cancelled the action.")
                exit(0)

        build_log_file = "{}.{}.log".format(build_dir, str(int(time.time())))
        LOG.info("Recording build process to {}.".format(build_log_file))
        Config.set_cmd_log(build_log_file)

        # cleanup old data:
        Utils.cmd("rm -rf {}".format(packages_dir))
        Utils.cmd("rm -rf {}".format(build_dir))

        # copy sources
        LOG.info("Fetching Chronos {} sources...".format(ChronosConfig.chronos_git_repository()))
        Utils.cmd("cp -R {} {}".format( ChronosConfig.chronos_repository_dir(), build_dir ))

        # ensure branch / tag
        Utils.exit_if_git_release_not_set( LOG, build_dir,
                                           ChronosConfig.chronos_version(),
                                           ChronosConfig.chronos_master_branch(),
                                           ChronosConfig.chronos_git_repository() )

        chronos_mvn_version = None
        if os.path.exists("{}/pom.xml".format( build_dir )):
            chronos_res = Utils.cmd("cat {}/pom.xml | grep '<version>' | head -n1 | sed 's/.*>\\(.*\\)<.*/\\1/' 2>/dev/null".format( build_dir ))
            if chronos_res['ExitCode'] != 0:
                LOG.error("Not able to establish Chronos version from the POM file. Can't continue.")
                exit(112)
            chronos_mvn_version = chronos_res['StdOut'].strip()
        else:
            LOG.error("No pom.xml file for Chronos {}. Can't continue.".format( ChronosConfig.chronos_version() ))
            exit(110)

        if chronos_mvn_version == None:
            LOG.error("Version could not be reliably established from the pom.xml file. Can't continue.")
            exit(111)

        LOG.info("Chronos version from Maven: {}".format( chronos_mvn_version ))

        docker_command = list()
        docker_command.append("docker run -ti ")
        docker_command.append("-v {}:/output ".format( os.path.dirname(packages_dir) ))
        docker_command.append("-v {}:/chronos-src ".format( build_dir ))
        docker_command.append("-v {}:/root/.m2 ".format( ChronosConfig.m2_dir() ))
        docker_command.append("-e \"BUILD_CHRONOS_VERSION={}\" ".format( ChronosConfig.chronos_version() ))
        docker_command.append("-e \"FPM_OUTPUT_VERSION={}\" ".format( chronos_mvn_version ))
        docker_command.append("-e \"ASSEMBLY_WITH_TESTS={}\" ".format( ChronosConfig.with_tests() ))
        docker_command.append("{} ".format( image_name ))
        docker_command.append("/bin/bash -c 'cd /chronos-build && ./chronos-build.sh; exit $?'")
        build_command = "".join( docker_command )
        LOG.info("Docker command: {}".format(build_command))
        LOG.info("Building Chronos {}. This will take a while...".format(ChronosConfig.chronos_version()))
        LOG.info("You can monitor the build with: tail -F {}".format(build_log_file))
        build_start_time = int(time.time())
        build_status = Utils.cmd(build_command)
        build_end_time = int(time.time())
        if build_status['ExitCode'] == 0:
            LOG.info( "Chronos {} built successfully. Build took {} seconds. Output available in {}. Cleaning up...".format(
                      ChronosConfig.chronos_version(),
                      str( build_end_time - build_start_time ),
                      packages_dir ))
            Utils.cmd("rm -rf {}".format(build_dir))
        else:
            LOG.error( "Chronos build failed. Leaving build log and temp directory for inspection. chronos={}".format( build_dir ) )
            exit(107)