From c0b4aa284e49eae6e820b333986422c14f6829ed Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Tue, 1 Nov 2016 15:06:53 -0700 Subject: [PATCH 01/12] Moving Rover (cli-bootstrapping tool) from private repository, into public --- tools/cli-bootstrap/.dockerignore | 1 + tools/cli-bootstrap/.gitattributes | 3 + tools/cli-bootstrap/.gitignore | 4 + tools/cli-bootstrap/README.md | 36 ++ tools/cli-bootstrap/cli.bootstrap.py | 562 ++++++++++++++++++ tools/cli-bootstrap/dockerfiles/bake.sh | 8 + .../dockerfiles/centos71/Dockerfile | 8 + .../dockerfiles/debian8/Dockerfile | 8 + .../dockerfiles/fedora23/Dockerfile | 8 + .../dockerfiles/opensuse13.2/Dockerfile | 8 + .../dockerfiles/opensuse42.1/Dockerfile | 8 + .../dockerfiles/ubuntu1404/Dockerfile | 8 + .../dockerfiles/ubuntu1604/Dockerfile | 8 + .../dockerfiles/ubuntu1610/Dockerfile | 8 + .../repo-dependencies-installer.py | 39 ++ tools/cli-bootstrap/repo-dependencies.json | 38 ++ 16 files changed, 755 insertions(+) create mode 100644 tools/cli-bootstrap/.dockerignore create mode 100644 tools/cli-bootstrap/.gitattributes create mode 100644 tools/cli-bootstrap/.gitignore create mode 100644 tools/cli-bootstrap/README.md create mode 100644 tools/cli-bootstrap/cli.bootstrap.py create mode 100644 tools/cli-bootstrap/dockerfiles/bake.sh create mode 100644 tools/cli-bootstrap/dockerfiles/centos71/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/debian8/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile create mode 100644 tools/cli-bootstrap/repo-dependencies-installer.py create mode 100644 tools/cli-bootstrap/repo-dependencies.json diff --git a/tools/cli-bootstrap/.dockerignore b/tools/cli-bootstrap/.dockerignore new file mode 100644 index 00000000..e1e32c2b --- /dev/null +++ b/tools/cli-bootstrap/.dockerignore @@ -0,0 +1 @@ +.git/* \ No newline at end of file diff --git a/tools/cli-bootstrap/.gitattributes b/tools/cli-bootstrap/.gitattributes new file mode 100644 index 00000000..92c9828f --- /dev/null +++ b/tools/cli-bootstrap/.gitattributes @@ -0,0 +1,3 @@ +*.py -crlf +*.sh -crlf +*.json -crlf diff --git a/tools/cli-bootstrap/.gitignore b/tools/cli-bootstrap/.gitignore new file mode 100644 index 00000000..1a3581cb --- /dev/null +++ b/tools/cli-bootstrap/.gitignore @@ -0,0 +1,4 @@ +.rover +*~ +*-dotnet +.vscode \ No newline at end of file diff --git a/tools/cli-bootstrap/README.md b/tools/cli-bootstrap/README.md new file mode 100644 index 00000000..6639dde9 --- /dev/null +++ b/tools/cli-bootstrap/README.md @@ -0,0 +1,36 @@ +# Rover +The dotnet CLI bootstrapping tool + +## What +Bootstrapping a tool like the dotnet CLI can be a dizzying effort. From a high-level we simply want to replace the native components of a pre-existing CLI with new ones that +have been built on the targetted platform. Unfortunately, from the bottom-up, this means that we need to clone a handful of dotnet repositories, execute particular +command lines with particular arguments and then copy them in to a pre-existing dotnet file. Rover aims to simplify that. + +The goal is to place Rover on to the distro of choice, execute it, and then have it do the required steps for you - and then things 'just work'! + +However, things don't always 'just work.' When this is the case Rover hopes to reduce the amount of effort necessary to fix build or script breaks by placing 'repro' shell scripts when there is a failure so that a developer can go in and 'apply pressure' where appropriate. + +## How + +There are default settings for each of the rover arguments. If all is going to plan, you should never need to specify any additional parameters. However +many situations arise where it becomes a necessity or a nice-to-have. Namely, when things go wrong, you want to be able to get in there and fix +up the build, make changes, etc. This is 'development mode' or DevMode for short. In DevMode, NO git commands are executed. This is to prevent +the script from stomping out any changes you have made in the working directory. + +DevMode is triggered if the working directory is pre-existing. Consequently, when things fail in the script, we do not 'clean up' the working directory. We write a repro script +of the command that failed and then we bail out immediately. + +Rover has the following command line options: + +- -clone [-c] - This defines the set of repositories that we want to clone. This WILL NOT function in DevMode. By default the full clone set is specified as {coreclr, corefx, core-setup, libuv}. + +- -build [-b] - This defines the set of repositories we want to build. By default the full build set is specified as {coreclr, corefx, core-setup, libuv} + +- -nopatch + +- -payload - a path to a local tarball that we will extract and then subsequently patch. If this is not specified, we pull the latest tarball from the dotnet repository. + +## Work Flow +Place Rover in a directory. Run it. + +In the event of a failure, we prevent clean-up. If the failure is not a rover script error, there is likely a rover_failure-repro.sh in the directory where the command failed (you are notified on diff --git a/tools/cli-bootstrap/cli.bootstrap.py b/tools/cli-bootstrap/cli.bootstrap.py new file mode 100644 index 00000000..7a3756d3 --- /dev/null +++ b/tools/cli-bootstrap/cli.bootstrap.py @@ -0,0 +1,562 @@ +#!/usr/bin/env python + +import os +import json +import platform +import argparse +import sys +import traceback + +# for readability +from subprocess import call +from subprocess import check_output +from subprocess import check_call +from subprocess import CalledProcessError + +from os import path +from os import makedirs + +from string import find +from urllib import urlretrieve + + +# ROVER BASE # +class RoverMods: + HEADER = '\033[95m' + BLUE = '\033[94m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + RED = '\033[91m' + WHITE = '\033[97m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + ENDC = '\033[0m' + + @staticmethod + def Header(line): + return RoverMods.HEADER + line + RoverMods.ENDC + + @staticmethod + def Blue(line): + return RoverMods.BLUE + line + RoverMods.ENDC + + @staticmethod + def Green(line): + return RoverMods.GREEN + line + RoverMods.ENDC + + @staticmethod + def Yellow(line): + return RoverMods.YELLOW + line + RoverMods.ENDC + + @staticmethod + def White(line): + return RoverMods.WHITE + line + RoverMods.ENDC + + @staticmethod + def Red(line): + return RoverMods.RED + line + RoverMods.ENDC + + @staticmethod + def Bold(line): + return RoverMods.BOLD + line + RoverMods.ENDC + + @staticmethod + def Underline(line): + return RoverMods.UNDERLINE + line + RoverMods.ENDC + +def RoverPrint(line): + print(RoverMods.Bold(RoverMods.Header('** ' + RoverMods.Underline('ROVER'))) + ' ' + (str(line))) + +def UnexpectedRoverException(exc_info): + RoverPrint(RoverMods.Red('CAUGHT AN UNEXPECTED EXCEPTION: \"' + RoverMods.White('%s'%(str(exc_info[1]))) + '\" of type: %s'%(str(exc_info[0])))) + RoverPrint(RoverMods.White('%s'%(str(traceback.print_tb(exc_info[2]))))) + + +# probably a pretty shaky interpretation of the semantic versioning 2.0.0 standard (http://semver.org/) +# I really focused on clauses 9, 10 and 11 +class SemanticVersion: + # this is python overloading the '>' operator + def __gt__(self, other): + # Major, minor, and patch versions are always compared numerically. + # Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. + for index, val in enumerate(self.VersionTuple[0]): + if self.VersionTuple[0][index] > other.VersionTuple[0][index]: + return True + + # When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. + # Example: 1.0.0-alpha < 1.0.0 + if(len(self.VersionTuple) < len(other.VersionTuple)): + return True + + # Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined + # by comparing each dot separated identifier from left to right until a difference is found as follows: + # identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared + # lexically in ASCII sort order. + + # Numeric identifiers always have lower precedence than non-numeric identifiers. + # A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. + # Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. + + # Maybe a tad hacky - but I treat the remainder of the version (the non numerical piece) as being lex-sorted. + # assuming, of course, that we have two to compare. + if(len(self.VersionTuple) >= 2 and len(self.VersionTuple) >= 2): + if(self.VersionTuple[1] > other.VersionTuple[1]): + return True + + return False + + def GetVersionTuple(self, versionStr): + # a version string potentially looks like this: + # 0.0.0-alpha-00000 + # the first part is canonical: 0.0.0 - it is ordered by the 'ol intuitive manner + # the second part is 'build metadata' - it is ordered lexically + middleIndex = versionStr.find('-') + # if we do not have a middle + if middleIndex == -1: + array = versionStr.split('.') + versionTuple = ([array]) + else: + # otherwise, we'll slice in two + versionTuple = (versionStr[0:middleIndex].split('.'), versionStr[middleIndex:len(versionStr)]) + + return versionTuple + + def __str__(self): + return self.VersionString + + def __init__(self, versionStr): + self.VersionTuple = self.GetVersionTuple(versionStr) + self.VersionString = versionStr + +# END ROVER BASE # + +class RoverSettings: + # Setting dev mode to True means that we keep a folder around. + # By Design DevMode is triggered if there is a pre-existing working directory + # By Design, when in DevMode we do not run any git commands. + _DevMode=False + + # This function needs to be here, because otherwise we wouldnt be able to change DevMode. + def FetchOSVariables(): + try: + os_release_path = '/etc/os-release' + + # according to the man page, we should fall back here if the canonical os-release is missing. + if not path.exists(os_release_path): + os_release_path = '/usr/lib/os-release' + + os_vars = {} + with open(os_release_path) as f: + for line in f.readlines(): + line = line.strip() + + if not line: # skip blank lines + continue + + data = line.split('=') + os_vars[str(data[0]).strip('\n\"')] = str(data[1]).strip('\n\"') + + return os_vars + except IOError: + RoverPrint(RoverMods.Red('requires \'/etc/os-release/\' to exist. For more information, try ' + RoverMods.White('man os-release'))) + except: + RoverSettings._DevMode = True # to prevent cleanup (to support investigation) + RoverPrint(RoverMods.Red('CAUGHT AN UNEXPECTED EXCEPTION: \"' + RoverMods.White("%s") + '\" of type: %s'%(str(sys.exc_info()[1]), str(sys.exc_info()[0])))) + RoverPrint(RoverMods.Red(RoverMods.White('%s')%(str(sys.exc_info()[3])))) + + _OsVars = FetchOSVariables() + _Rid = '%s.%s-x64'%(_OsVars['ID'], _OsVars['VERSION_ID']) + _Moniker = '%s-dotnet'%(_Rid) + + _WorkingDirectory = '%s'%(_Moniker) + _srcDirectory = path.join(_WorkingDirectory, "src") + _objDirectory = path.join(_WorkingDirectory, "obj") + _binDirectory = path.join(_WorkingDirectory, "bin") + + _ScriptDirectory = str(path.dirname(path.abspath(__file__))) + _LaunchedFromDirectory = os.getcwd() + + PayloadPath = str('') + PatchTargetPath = _binDirectory + CloneSet = [] + BuildSet = [] + Patch = True + + CoreCLRBinDirectory = '' + CoreFXBinDirectory = '' + CoreSetupBinDirectory = '' + LibUVBinDirectory = '' + + PatchTarget_Shared = '' + PatchTarget_SDK = '' + PatchTarget_Host = '' + + DotNetCommitHash = 'rover-boot-strap' + + @staticmethod + def MaxPrecedence(versionStrA, versionStrB): + versionA = SemanticVersion(versionStrA) + versionB = SemanticVersion(versionStrB) + + if(versionA > versionB): + return versionA + + return versionB + + + @staticmethod + def SelectGreatestPrecendenceDirectory(containerDirectory): + maxVersion = '0.0.0-alpha-00000' + + for root, dirs, files in os.walk(containerDirectory): + for dirName in dirs: + maxVersion = RoverSettings.MaxPrecedence(dirName, maxVersion) + + break # just 'walk' the top level. + + return str(maxVersion) + + @staticmethod + def SetPatchTargetPath(pathToFolder): + if path.exists(pathToFolder): + RoverSettings.PatchTargetPath = pathToFolder + # require there to be a Microsoft.NETCore.App in the shared + # we will locate the highest version; + shared_containerFolder = path.join(pathToFolder, path.join('shared', 'Microsoft.NETCore.App')) + RoverSettings.PatchTarget_Shared = path.join(shared_containerFolder, RoverSettings.SelectGreatestPrecendenceDirectory(shared_containerFolder)) + + # will locate the highest version and patch that + sdk_containerFolder = path.join(pathToFolder, path.join('sdk')) + RoverSettings.PatchTarget_SDK = path.join(sdk_containerFolder, RoverSettings.SelectGreatestPrecendenceDirectory(sdk_containerFolder)) + + # require the host to be 'fxr', then we take the highest version. + host_containerFolder = path.join(pathToFolder, path.join('host', 'fxr')) + RoverSettings.PatchTarget_Host = path.join(host_containerFolder, RoverSettings.SelectGreatestPrecendenceDirectory(host_containerFolder)) + + +if path.exists(RoverSettings._WorkingDirectory): + RoverPrint(RoverMods.Header(RoverMods.Red('FORCED SETTINGS CHANGE: DEV MODE \'ON\' '))) + RoverPrint(RoverMods.Yellow(('will skip all git commands.'))) + RoverPrint(RoverMods.Yellow(('requires the deletion of the directory \'%s\' to reset the dev-mode trigger.'%(RoverSettings._WorkingDirectory)))) + + RoverSettings._DevMode=True + +# A 'Rover Shell Call' is a shell call that we want to be reproduceable in the event of a failure. +# namely, something that a developer can go in and 'drill in' on without running the entirety of the +# build again. +def RoverShellCall(cmd, cwd = None): + if not cwd: + cwd = os.getcwd() + + try: + check_call(cmd, shell=True, cwd=cwd) + + except CalledProcessError as repro_data: + RoverSettings._DevMode = True + + repro_filename = 'rover_failure-repro.sh' + repro_destination = path.join(cwd, repro_filename) + + # when the call fails, print a repro to the working directory. + with open(repro_destination, 'w') as repro_file: + repro_file.writelines(['#!/usr/bin/env bash\n', repro_data.cmd + '\n']) + + if os.getuid() == 0: + call('chmod +x %s'%(repro_filename), shell=True, cwd=cwd) + + RoverPrint(RoverMods.Red('has detected a failure. A repro shell script has been placed at ') + RoverMods.Yellow(repro_destination)) + RoverPrint(RoverMods.White('To reproduce the failure:\n\tcd %s\n\t./%s'%(cwd, repro_filename))) + RoverPrint(RoverMods.Red('is forcefully closing. Note that re-running Rover will execute it with DevMode enabled (no git commands will be run)')) + + os._exit(1) # if we fail a check_call then we want to bail out asap so the dev can investigate. + + + + +## +## ROVER FUNCTION DEFINITIONS +## + +# detination_folder is expected to be relative to the _ScriptDirectory. +# payload path is expected to be a dotn``et-cli tarball. +def SpawnPatchTarget(destination_folder, payload_path): + try: + if payload_path and not path.isabs(payload_path): + payload_path = path.join(RoverSettings._LaunchedFromDirectory, payload_path) + + if not path.isabs(destination_folder): + destination_folder = path.join(RoverSettings._LaunchedFromDirectory, destination_folder) + + if not path.exists(str(payload_path)): + fallback_url = 'https://dotnetcli.blob.core.windows.net/dotnet/Sdk/rel-1.0.0/dotnet-dev-debian-x64.latest.tar.gz' + RoverPrint('could not locate a payload at path: \'%s\' so I am going to download the latest dotnet CLI from %s'%(payload_path, fallback_url)) + + payload_filename = 'dotnet-dev-debian-x64.latest.tar.gz' + + RoverPrint(RoverMods.Blue('is downloading latest .NET CLI for bootstrapping (%s)'%(payload_filename))) + + payload_path = path.join(RoverSettings._objDirectory, 'dotnet-dev-debian-x64.latest.tar.gz') + + urlretrieve(fallback_url, payload_path) + + # lets force the path to be made absolute - assuming that the payload path is relative to the directory we launched the script from. + # otherwise if we have an abs path already - fantastic. + + RoverShellCall('tar xf %s -C %s'%(payload_path, destination_folder)) + except: + RoverSettings._DevMode = True + UnexpectedRoverException(sys.exc_info()) + + RoverSettings.SetPatchTargetPath(path.join(RoverSettings._ScriptDirectory, destination_folder)) + +def CloneRepositories(cwd, + coreclr_commit_hash, + corefx_commit_hash, + dotnet_commit_hash): + try: + if not RoverSettings._DevMode: + RoverPrint(RoverMods.Blue('is initializing the .NET GitHub repositories.')) + + if 'coreclr' in RoverSettings.CloneSet: + if not path.exists(path.join(cwd, 'coreclr')): + RoverShellCall('git clone http://www.github.com/dotnet/coreclr', cwd=cwd) + RoverShellCall('git checkout %s'%(coreclr_commit_hash), cwd=path.join(cwd, 'coreclr')) + + if 'corefx' in RoverSettings.CloneSet: + if not path.exists(path.join(cwd, 'corefx')): + RoverShellCall('git clone http://www.github.com/dotnet/corefx', cwd=cwd) + RoverShellCall('git checkout %s'%(corefx_commit_hash), cwd=path.join(cwd, 'corefx')) + + if 'core-setup' in RoverSettings.CloneSet: + if not path.exists(path.join(cwd, 'core-setup')): + RoverShellCall('git clone http://www.github.com/dotnet/core-setup', cwd=cwd) + RoverShellCall('git checkout %s'%(dotnet_commit_hash), cwd=path.join(cwd, 'core-setup')) + + if 'libuv' in RoverSettings.CloneSet: + if not path.exists(path.join(cwd, 'libuv')): + RoverShellCall('git clone http://www.github.com/libuv/libuv', cwd=cwd) + # we are fixed to using libuv 1.9.0 - this is the commit hash for that (https://github.com/libuv/libuv/commit/229b3a4cc150aebd6561e6bd43076eafa7a03756) + RoverShellCall('git checkout %s'%('229b3a4cc150aebd6561e6bd43076eafa7a03756'), cwd=path.join(cwd, 'libuv')) + + else: + RoverPrint(RoverMods.Yellow(('DEVMODE IS ON. Skipping all git calls : I.e. you must manually control git your self.'))) + + except: + RoverSettings._DevMode = True + UnexpectedRoverException(sys.exc_info()) + + + +def BuildNativeComponents( coreclr_git_directory, + corefx_git_directory, + core_setup_git_directory, + libuv_git_directory): + try: + RoverPrint(RoverMods.Blue('is building the .NET GitHub repositories.')) + + # Build CoreCLR + # skipping non-essential for bootstrapping. + if 'coreclr' in RoverSettings.BuildSet: + RoverShellCall('./build.sh x64 release skiptests skipnuget', cwd=coreclr_git_directory) + + # Build CoreFX Native Pieces + if 'corefx' in RoverSettings.BuildSet: + # at different points in the history of CoreFX there have been differing build behaviors, these conditionals + # cover that. However, if we find these differences, we will need to adapt.s + if path.exists(path.join(corefx_git_directory, 'src', 'Native', 'build-native.sh')): + RoverShellCall('./build-native.sh x64 release Linux --numProc 1', cwd="%s/src/Native"%(corefx_git_directory)) + else: + RoverShellCall('./build.sh native x64 release', cwd=corefx_git_directory) + + # Build corehost from core-setup + # TODO: declare proper runtime id + # TODO: hostver? + # TODO: fxrver? + # TODO: policyver? + if 'core-setup' in RoverSettings.BuildSet: + RoverShellCall('./build.sh --arch x64 --rid %s --hostver 0.0.0 --fxrver 0.0.0 --policyver 0.0.0 --commithash %s'%(RoverSettings._Rid, RoverSettings.DotNetCommitHash), cwd="%s/src/corehost"%(core_setup_git_directory)) + + # Build libUV + if 'libuv' in RoverSettings.BuildSet: + RoverShellCall('./autogen.sh', cwd=libuv_git_directory) + RoverShellCall('./configure', cwd=libuv_git_directory) + RoverShellCall('make', cwd=libuv_git_directory) + + except: + RoverSettings._DevMode = True + UnexpectedRoverException(sys.exc_info()) + + +def PatchTarget(patchTarget_folder, + coreclr_bin_directory, + corefx_native_bin_directory, + core_setup_cli_bin_directory, + libuv_bin_directory): + try: + if RoverSettings.Patch: + RoverPrint(RoverMods.Blue('is patching %s'%(RoverMods.Yellow(patchTarget_folder)))) + + # replace native dotnet in the base directory + # from core_setup + RoverShellCall('cp dotnet %s'%(path.join(patchTarget_folder)), cwd='%s/exe/'%(core_setup_cli_bin_directory)) + + # replace native files in 'shared' folder. + # from coreclr + RoverShellCall('cp *so %s'%(RoverSettings.PatchTarget_Shared), cwd=coreclr_bin_directory) + RoverShellCall('cp corerun %s'%(RoverSettings.PatchTarget_Shared), cwd=coreclr_bin_directory) + RoverShellCall('cp crossgen %s'%(RoverSettings.PatchTarget_Shared), cwd=coreclr_bin_directory) + + # from core_setup + RoverShellCall('cp dotnet %s'%(RoverSettings.PatchTarget_Shared), cwd='%s/exe/'%(core_setup_cli_bin_directory)) + RoverShellCall('cp libhostpolicy.so %s'%(RoverSettings.PatchTarget_Shared), cwd='%s/dll/'%(core_setup_cli_bin_directory)) + RoverShellCall('cp libhostfxr.so %s'%(RoverSettings.PatchTarget_Shared), cwd='%s/fxr/'%(core_setup_cli_bin_directory)) + + # from corefxcd + RoverShellCall('cp System.* %s'%(RoverSettings.PatchTarget_Shared), cwd=corefx_native_bin_directory) + + # from libuv + RoverShellCall('cp libuv.so %s'%(RoverSettings.PatchTarget_Shared), cwd=libuv_bin_directory) + + # replace native files in 'sdk' folder. + # from core_setup + RoverShellCall('cp libhostpolicy.so %s'%(RoverSettings.PatchTarget_SDK), cwd='%s/dll/'%(core_setup_cli_bin_directory)) + RoverShellCall('cp libhostfxr.so %s'%(RoverSettings.PatchTarget_SDK), cwd='%s/fxr/'%(core_setup_cli_bin_directory)) + + # replace native files in 'host' folder. + # from core_setup + RoverShellCall('cp libhostfxr.so %s'%(RoverSettings.PatchTarget_Host), cwd='%s/fxr/'%(core_setup_cli_bin_directory)) + + RoverPrint(RoverMods.Blue('has finished patching %s'%(RoverMods.Yellow(patchTarget_folder)))) + except: + RoverSettings._DevMode = True + UnexpectedRoverException(sys.exc_info()) + +## +## END ROVER FUNCTION DEFINITIONS +## + +if __name__ == "__main__": + ## + ## COMMAND-LINE BEHAVIOR + ## + + parser = argparse.ArgumentParser(description = 'Rover is the dotnet bootstrapping tool.') + parser.add_argument('-clone', metavar='c', nargs='*', default=['coreclr', 'corefx', 'core-setup', 'libuv'], help='Clones specified repositories in to the working directory. Select from the following repositories: {' + + '%s, %s, %s, %s'%(RoverMods.Red('coreclr'), RoverMods.Blue('corefx'), RoverMods.Green('core-setup'), RoverMods.Yellow('libuv') +'}')) + parser.add_argument('-build', metavar='b', nargs='*', default = ['coreclr', 'corefx', 'core-setup', 'libuv'],help='\'Builds\' all native components if no arguments are specified. Otherwise, specify one or more (space separated) arguments from the following : {' + + '%s, %s, %s, %s'%(RoverMods.Red('coreclr'), RoverMods.Blue('corefx'), RoverMods.Green('core-setup'), RoverMods.Yellow('libuv') +'}')) + parser.add_argument('-nopatch', action='store_true', default=False, help='prevents the copying of specific native binaries from the pre-built repositories in to the destination directory.') + parser.add_argument('-payload', nargs=1, help='Specify a path to a tarball (something that we can tar xf) that contains a version of the dotnet CLI.') + + args = parser.parse_args() + + if args.payload: + RoverPrint('using payload ' + RoverMods.White(str(args.payload))) + + RoverPrint('Cloning Set: ' + RoverMods.White(str(args.clone))) + RoverPrint('Building Set: ' + RoverMods.White(str(args.build))) + RoverPrint('Is Patching? ' + RoverMods.White(str(not args.nopatch))) + + RoverSettings.CloneSet = args.clone + RoverSettings.BuildSet = args.build + + # I am guessing that users are more inclined to want patching to happen whenever it can, and so I ask + # for specificity in the instances that they do not want patching. + RoverSettings.Patch = not args.nopatch + + if args.payload: + RoverSettings.PayloadPath = args.payload[0] + ## + ## END COMMAND-LINE BEHAVIOR + ## + + ## + ## BEGIN DECLARATIONS + ## + + coreclr_working_git_directory = path.join(RoverSettings._srcDirectory, 'coreclr') + corefx_working_git_directory = path.join(RoverSettings._srcDirectory, 'corefx') + core_setup_working_git_directory = path.join(RoverSettings._srcDirectory, 'core-setup') + libuv_working_git_directory = path.join(RoverSettings._srcDirectory, 'libuv') + + default_coreclr_bin_directory = '%s/bin/Product/Linux.x64.Release/'%(coreclr_working_git_directory) + default_corefx_native_bin_directory = '%s/bin/Linux.x64.Release/Native'%(corefx_working_git_directory) + default_core_setup_cli_bin_directory= '%s/src/corehost/cli'%(core_setup_working_git_directory) + default_libuv_bin_directory = '%s/.libs'%(libuv_working_git_directory) + + RoverSettings.CoreCLRBinDirectory = default_coreclr_bin_directory + RoverSettings.CoreFXBinDirectory = default_corefx_native_bin_directory + RoverSettings.CoreSetupBinDirectory = default_core_setup_cli_bin_directory + RoverSettings.LibUVBinDirectory = default_libuv_bin_directory + + platform_info = platform.uname() + this_distro_name = str(platform.linux_distribution()[0]).lower() + + ## + ## END DECLARATIONS + ## + + ## + ## BEGIN PROCEDURE + ## + + try: + os.putenv('ID', RoverSettings._OsVars['ID']) + os.putenv('VERSION_ID', RoverSettings._OsVars['VERSION_ID']) + + RoverPrint(RoverMods.Blue('RID: %s'%(RoverMods.Green(RoverSettings._Rid)))) + + # if we're root, then we will install dependencies + # should we ask first? It's going to be running apt-get in 'yes' mode. + if os.getuid() == 0: + RoverPrint(RoverMods.Yellow('(because sudo) is installing required dependencies to build the native components of the .NET GitHub Repositories.')) + + # are people cool with this? + RoverShellCall('chmod +x %s/repo-dependencies-installer.py'%(RoverSettings._ScriptDirectory), cwd=RoverSettings._ScriptDirectory) + RoverShellCall('python %s/repo-dependencies-installer.py'%(RoverSettings._ScriptDirectory), cwd=RoverSettings._ScriptDirectory) + + # Spawn our working directory + if not path.exists(RoverSettings._WorkingDirectory): + makedirs(RoverSettings._WorkingDirectory) + makedirs(RoverSettings._srcDirectory) + makedirs(RoverSettings._objDirectory) + makedirs(RoverSettings._binDirectory) + + + SpawnPatchTarget(RoverSettings._binDirectory, RoverSettings.PayloadPath) + + # Fetch the commit hashes from the native files. + coreclr_output = check_output('strings libcoreclr.so | grep @\(#\)', shell = True, cwd=RoverSettings.PatchTarget_Shared) + corefx_output = check_output('strings System.Native.so | grep @\(#\)', shell = True, cwd=RoverSettings.PatchTarget_Shared) + + dotnet_commit_hash = check_output('strings dotnet | grep "[a-f0-9]\{40\}"', shell = True, cwd=RoverSettings.PatchTarget_Shared) + coreclr_commit_hash = coreclr_output[find(coreclr_output, 'Commit Hash: ') + len('Commit Hash: '):len(coreclr_output)] + corefx_commit_hash = corefx_output[find(corefx_output, 'Commit Hash: ') + len('Commit Hash: '):len(corefx_output)] + + RoverSettings.DotNetCommitHash = dotnet_commit_hash + + CloneRepositories(RoverSettings._srcDirectory, + coreclr_commit_hash, + corefx_commit_hash, + dotnet_commit_hash) + + BuildNativeComponents(coreclr_working_git_directory, + corefx_working_git_directory, + core_setup_working_git_directory, + libuv_working_git_directory) + + PatchTarget(RoverSettings.PatchTargetPath, + RoverSettings.CoreCLRBinDirectory, + RoverSettings.CoreFXBinDirectory, + RoverSettings.CoreSetupBinDirectory, + RoverSettings.LibUVBinDirectory) + + RoverPrint(RoverMods.Green('spawned a \'dotnet\' in %s'%(RoverMods.Yellow('./' + path.relpath(RoverSettings.PatchTargetPath) + '/'))) + RoverMods.Green('(enjoy!)')) + except: + RoverSettings._DevMode = True + UnexpectedRoverException(sys.exc_info()) + + + ## + ## END PROCEDURE + ## diff --git a/tools/cli-bootstrap/dockerfiles/bake.sh b/tools/cli-bootstrap/dockerfiles/bake.sh new file mode 100644 index 00000000..2be36e31 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/bake.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +for dir in */ ; do + echo "$dir" + pushd $dir + name=${dir%"/"} + docker build -t "rover:$name" . + popd +done \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile b/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile new file mode 100644 index 00000000..841c95e0 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile @@ -0,0 +1,8 @@ +FROM centos:7.1.1503 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile b/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile new file mode 100644 index 00000000..80ab2cee --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile @@ -0,0 +1,8 @@ +FROM debian:8.0 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile b/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile new file mode 100644 index 00000000..759b47cf --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile @@ -0,0 +1,8 @@ +FROM fedora:23 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile b/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile new file mode 100644 index 00000000..b9196dc6 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile @@ -0,0 +1,8 @@ +FROM opensuse:13.2 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile b/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile new file mode 100644 index 00000000..85459571 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile @@ -0,0 +1,8 @@ +FROM opensuse:42.1 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile new file mode 100644 index 00000000..cd87cc53 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:14.04 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile new file mode 100644 index 00000000..49e8425d --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:16.04 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile new file mode 100644 index 00000000..cc2d5d6d --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:16.10 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install git +RUN apt-get -qqy install python +VOLUME /env/rover +WORKDIR /env/rover +ENTRYPOINT python rover.py diff --git a/tools/cli-bootstrap/repo-dependencies-installer.py b/tools/cli-bootstrap/repo-dependencies-installer.py new file mode 100644 index 00000000..ac8aef59 --- /dev/null +++ b/tools/cli-bootstrap/repo-dependencies-installer.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +import json + +from subprocess import call +from subprocess import check_output +from os import path + +# Debian .deb apt, apt-cache, apt-get, dpkg +# Ubuntu .deb apt, apt-cache, apt-get, dpkg +# CentOS .rpm yum +# Fedora .rpm dnf +# FreeBSD Ports,.txz make, pkg + +def Detect(pm_name): + aptget_check_output = check_output('whereis %s'%(pm_name), shell=True) + + if(len(str(aptget_check_output).strip()) > len('%s:'%(pm_name))): + return True + + return False + +if __name__ == "__main__": + scriptDirectory = path.dirname(path.abspath(__file__)) + dependencies = json.load(open(path.join(scriptDirectory, 'repo-dependencies.json'), mode='r')) + + if Detect('apt-get'): + print('detected apt-get.') + for dep in dependencies['apt-get']: + call('apt-get -qqy install %s'%(str(dep)), shell=True) + elif Detect('yum'): + print('detected yum.') + + for dep in dependencies['yum']: + call('yum -qy install %s'%(str(dep)), shell=True) + else: + print('failed to find a compatible package manager.') + + print('TODO: Print list of dependencies, or attempt to fetch them from the web?') diff --git a/tools/cli-bootstrap/repo-dependencies.json b/tools/cli-bootstrap/repo-dependencies.json new file mode 100644 index 00000000..96bd7fe8 --- /dev/null +++ b/tools/cli-bootstrap/repo-dependencies.json @@ -0,0 +1,38 @@ +{ + "apt-get": + [ + "g++", + "cmake", + "llvm-3.5", + "clang-3.5", + "lldb-3.5", + "lldb-3.5-dev", + "libunwind8", + "libunwind8-dev", + "gettext", + "libicu-dev", + "liblttng-ust-dev", + "libcurl4-openssl-dev", + "libssl-dev", + "uuid-dev", + "libkrb5-dev", + "automake", + "libtool-bin" + ], + "yum": + [ + + ], + "dnf": + [ + + ], + "pkg": + [ + + ], + "ports": + [ + + ] +} \ No newline at end of file From 23c1fca5f465ab062309152333fcfe7591df9926 Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Wed, 2 Nov 2016 15:35:04 -0700 Subject: [PATCH 02/12] we'd like line endings to be normalized --- .gitattributes | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..a1e1e97a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain \ No newline at end of file From db9ade7e0068686de4880d0ea194bff033ecb528 Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Wed, 2 Nov 2016 15:37:27 -0700 Subject: [PATCH 03/12] we do not want to install dependencies for the end-user --- tools/cli-bootstrap/cli.bootstrap.py | 9 ----- .../repo-dependencies-installer.py | 39 ------------------- tools/cli-bootstrap/repo-dependencies.json | 38 ------------------ 3 files changed, 86 deletions(-) delete mode 100644 tools/cli-bootstrap/repo-dependencies-installer.py delete mode 100644 tools/cli-bootstrap/repo-dependencies.json diff --git a/tools/cli-bootstrap/cli.bootstrap.py b/tools/cli-bootstrap/cli.bootstrap.py index 7a3756d3..f55b8c4d 100644 --- a/tools/cli-bootstrap/cli.bootstrap.py +++ b/tools/cli-bootstrap/cli.bootstrap.py @@ -506,15 +506,6 @@ if __name__ == "__main__": RoverPrint(RoverMods.Blue('RID: %s'%(RoverMods.Green(RoverSettings._Rid)))) - # if we're root, then we will install dependencies - # should we ask first? It's going to be running apt-get in 'yes' mode. - if os.getuid() == 0: - RoverPrint(RoverMods.Yellow('(because sudo) is installing required dependencies to build the native components of the .NET GitHub Repositories.')) - - # are people cool with this? - RoverShellCall('chmod +x %s/repo-dependencies-installer.py'%(RoverSettings._ScriptDirectory), cwd=RoverSettings._ScriptDirectory) - RoverShellCall('python %s/repo-dependencies-installer.py'%(RoverSettings._ScriptDirectory), cwd=RoverSettings._ScriptDirectory) - # Spawn our working directory if not path.exists(RoverSettings._WorkingDirectory): makedirs(RoverSettings._WorkingDirectory) diff --git a/tools/cli-bootstrap/repo-dependencies-installer.py b/tools/cli-bootstrap/repo-dependencies-installer.py deleted file mode 100644 index ac8aef59..00000000 --- a/tools/cli-bootstrap/repo-dependencies-installer.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python - -import json - -from subprocess import call -from subprocess import check_output -from os import path - -# Debian .deb apt, apt-cache, apt-get, dpkg -# Ubuntu .deb apt, apt-cache, apt-get, dpkg -# CentOS .rpm yum -# Fedora .rpm dnf -# FreeBSD Ports,.txz make, pkg - -def Detect(pm_name): - aptget_check_output = check_output('whereis %s'%(pm_name), shell=True) - - if(len(str(aptget_check_output).strip()) > len('%s:'%(pm_name))): - return True - - return False - -if __name__ == "__main__": - scriptDirectory = path.dirname(path.abspath(__file__)) - dependencies = json.load(open(path.join(scriptDirectory, 'repo-dependencies.json'), mode='r')) - - if Detect('apt-get'): - print('detected apt-get.') - for dep in dependencies['apt-get']: - call('apt-get -qqy install %s'%(str(dep)), shell=True) - elif Detect('yum'): - print('detected yum.') - - for dep in dependencies['yum']: - call('yum -qy install %s'%(str(dep)), shell=True) - else: - print('failed to find a compatible package manager.') - - print('TODO: Print list of dependencies, or attempt to fetch them from the web?') diff --git a/tools/cli-bootstrap/repo-dependencies.json b/tools/cli-bootstrap/repo-dependencies.json deleted file mode 100644 index 96bd7fe8..00000000 --- a/tools/cli-bootstrap/repo-dependencies.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "apt-get": - [ - "g++", - "cmake", - "llvm-3.5", - "clang-3.5", - "lldb-3.5", - "lldb-3.5-dev", - "libunwind8", - "libunwind8-dev", - "gettext", - "libicu-dev", - "liblttng-ust-dev", - "libcurl4-openssl-dev", - "libssl-dev", - "uuid-dev", - "libkrb5-dev", - "automake", - "libtool-bin" - ], - "yum": - [ - - ], - "dnf": - [ - - ], - "pkg": - [ - - ], - "ports": - [ - - ] -} \ No newline at end of file From 63d7044bbafac6b6ef9c74febec895cada189c9f Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Thu, 3 Nov 2016 17:10:32 -0700 Subject: [PATCH 04/12] updated documentation --- tools/cli-bootstrap/README.md | 95 ++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/tools/cli-bootstrap/README.md b/tools/cli-bootstrap/README.md index 6639dde9..cea6e072 100644 --- a/tools/cli-bootstrap/README.md +++ b/tools/cli-bootstrap/README.md @@ -1,36 +1,85 @@ -# Rover -The dotnet CLI bootstrapping tool +CLI.BOOTSTRAP(1) +### NAME +.NET CLI Bootstrapping Tool - A tool to help you bootstrap the .NET Command Line Tool on unsupported platforms. -## What -Bootstrapping a tool like the dotnet CLI can be a dizzying effort. From a high-level we simply want to replace the native components of a pre-existing CLI with new ones that -have been built on the targetted platform. Unfortunately, from the bottom-up, this means that we need to clone a handful of dotnet repositories, execute particular -command lines with particular arguments and then copy them in to a pre-existing dotnet file. Rover aims to simplify that. +### SYNOPSIS +python cli.bootstrap.py [-b __build_set__] [-nopatch] [-payload __tarball_path__] -The goal is to place Rover on to the distro of choice, execute it, and then have it do the required steps for you - and then things 'just work'! +### DESCRIPTION +cli.bootstrap.py is the .NET CLI bootstrapping script that intends to help developers move to new platforms and "bring up" the required pieces. -However, things don't always 'just work.' When this is the case Rover hopes to reduce the amount of effort necessary to fix build or script breaks by placing 'repro' shell scripts when there is a failure so that a developer can go in and 'apply pressure' where appropriate. - -## How - -There are default settings for each of the rover arguments. If all is going to plan, you should never need to specify any additional parameters. However +There are default settings that intend to hit the 'most cases' scenario. If all is going to plan, you should never need to specify any additional parameters. However many situations arise where it becomes a necessity or a nice-to-have. Namely, when things go wrong, you want to be able to get in there and fix up the build, make changes, etc. This is 'development mode' or DevMode for short. In DevMode, NO git commands are executed. This is to prevent -the script from stomping out any changes you have made in the working directory. +the script from stomping out any changes you have made in the working directory. Additionally, when things do go wrong (inevitably they will), this tool places a shell/batch script +within the working directory that contains the command line that failed. This is to enable the scenario where you want to 'drill into' a problem. -DevMode is triggered if the working directory is pre-existing. Consequently, when things fail in the script, we do not 'clean up' the working directory. We write a repro script -of the command that failed and then we bail out immediately. +### EXAMPLES +The first time you run this tool HAS to be like this: +``` +./cli.bootstrap.py +``` +This will spawn a directory next to the bootstrap script, named after its runtime identifier (the runtime identifier is currently picked from the /os/release and we concatenate the +VERSION and VERSION_ID values). So on an AMD64 Ubuntu 16.04 machine, the RID is ubuntu.16.04-x64-dotnet -Rover has the following command line options: -- -clone [-c] - This defines the set of repositories that we want to clone. This WILL NOT function in DevMode. By default the full clone set is specified as {coreclr, corefx, core-setup, libuv}. +Any additional runs can be controlled via these command lines, and consequently, any additional runs are going to be in DevMode. -- -build [-b] - This defines the set of repositories we want to build. By default the full build set is specified as {coreclr, corefx, core-setup, libuv} +``` +./cli.bootstrap.py -b corefx libuv +``` +This will build only the corefx binaries and coreclr binaries, then patch the files. -- -nopatch +If you want to prevent patching (for example, just to re-run a build): -- -payload - a path to a local tarball that we will extract and then subsequently patch. If this is not specified, we pull the latest tarball from the dotnet repository. +``` +./cli.bootstrap.py -b corefx coreclr -nopatch +``` -## Work Flow -Place Rover in a directory. Run it. +Additionally, if you have a tarball of the files that you'd like to produce, consider: -In the event of a failure, we prevent clean-up. If the failure is not a rover script error, there is likely a rover_failure-repro.sh in the directory where the command failed (you are notified on +``` +./cli.bootstrap.py -b corefx coreclr -nopatch -payload ~/downloads/dotnet-dev-build.tar.gz +``` + +### DEFAULTS + +By default, running ./cli.bootstrap.py with no additional parameters is equivalent to this command line: +``` +./cli.bootstrap.py -b corefx coreclr libuv core-setup -payload __dotnet_cli_repository_url__ +``` + +### OPTIONS +*-b __build_set__* + +    __build_set__ is the space-delimited set of repositories to place. At the moment it is one of these {coreclr, corefx, core-setup, libuv}. + +*-nopatch* + +    As part of the bootstrapping process, we "patch" (overwrite/replace native binaries) a pre-built version of the CLI. + +*-payload __tar_filepath__* + +    By default cli.bootstrap will pull in a pre-built tar file from the CLI repository and patch this. If you want to provide your own binaries to patch + (from dev builds or something), then specify a path (relative or absolute). + +### OVERVIEW +After you run the cli.bootstrap, you'll see a directory named after the Runtime Identifier (RID) next to the script, the directory tree looks like this (for example), + +``` + +├── bin +│   ├── dotnet +│   ├── host +│   ├── LICENSE.txt +│   ├── sdk +│   ├── shared +│   └── ThirdPartyNotices.txt +├── obj +│   └── dotnet-dev-debian-x64.latest.tar.gz +└── src + ├── coreclr + ├── corefx + ├── core-setup + └── libuv +``` \ No newline at end of file From b2893c1fdcbb772ebbd36b227c9b0421466767ba Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Thu, 3 Nov 2016 17:28:19 -0700 Subject: [PATCH 05/12] These are not necessary --- tools/cli-bootstrap/.dockerignore | 1 - tools/cli-bootstrap/.gitattributes | 3 --- tools/cli-bootstrap/.gitignore | 4 ---- 3 files changed, 8 deletions(-) delete mode 100644 tools/cli-bootstrap/.dockerignore delete mode 100644 tools/cli-bootstrap/.gitattributes delete mode 100644 tools/cli-bootstrap/.gitignore diff --git a/tools/cli-bootstrap/.dockerignore b/tools/cli-bootstrap/.dockerignore deleted file mode 100644 index e1e32c2b..00000000 --- a/tools/cli-bootstrap/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.git/* \ No newline at end of file diff --git a/tools/cli-bootstrap/.gitattributes b/tools/cli-bootstrap/.gitattributes deleted file mode 100644 index 92c9828f..00000000 --- a/tools/cli-bootstrap/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -*.py -crlf -*.sh -crlf -*.json -crlf diff --git a/tools/cli-bootstrap/.gitignore b/tools/cli-bootstrap/.gitignore deleted file mode 100644 index 1a3581cb..00000000 --- a/tools/cli-bootstrap/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.rover -*~ -*-dotnet -.vscode \ No newline at end of file From a6f7eac41b777768e69c873777d991225678f442 Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Thu, 3 Nov 2016 17:33:48 -0700 Subject: [PATCH 06/12] only use colors if we are in a real terminal --- tools/cli-bootstrap/cli.bootstrap.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/cli-bootstrap/cli.bootstrap.py b/tools/cli-bootstrap/cli.bootstrap.py index f55b8c4d..68fb3a49 100644 --- a/tools/cli-bootstrap/cli.bootstrap.py +++ b/tools/cli-bootstrap/cli.bootstrap.py @@ -22,6 +22,8 @@ from urllib import urlretrieve # ROVER BASE # class RoverMods: + PIPE_TO_STDOUT = not sys.stdout.isatty() + HEADER = '\033[95m' BLUE = '\033[94m' GREEN = '\033[92m' @@ -34,34 +36,58 @@ class RoverMods: @staticmethod def Header(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.HEADER + line + RoverMods.ENDC @staticmethod def Blue(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.BLUE + line + RoverMods.ENDC @staticmethod def Green(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.GREEN + line + RoverMods.ENDC @staticmethod def Yellow(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.YELLOW + line + RoverMods.ENDC @staticmethod def White(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.WHITE + line + RoverMods.ENDC @staticmethod def Red(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.RED + line + RoverMods.ENDC @staticmethod def Bold(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.BOLD + line + RoverMods.ENDC @staticmethod def Underline(line): + if(RoverMods.PIPE_TO_STDOUT): + return line + return RoverMods.UNDERLINE + line + RoverMods.ENDC def RoverPrint(line): From d5ae4db0d9fad0876a0c4e8c1380250ac8b4222f Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Tue, 8 Nov 2016 10:53:41 -0800 Subject: [PATCH 07/12] Laying down docker interfaces --- .../dockerfiles/bake-containers.sh | 35 +++++ tools/cli-bootstrap/dockerfiles/bake.sh | 8 - .../dockerfiles/centos71/Dockerfile | 29 +++- .../dockerfiles/debian8/Dockerfile | 8 - .../dockerfiles/docker-cleanup.sh | 5 + .../dockerfiles/fedora23/Dockerfile | 8 - .../dockerfiles/opensuse13.2/Dockerfile | 8 - .../dockerfiles/opensuse42.1/Dockerfile | 8 - .../dockerfiles/test-container.sh | 30 ++++ .../dockerfiles/ubuntu1404/Dockerfile | 8 - .../dockerfiles/ubuntu1604/Dockerfile | 8 - .../dockerfiles/ubuntu1610/Dockerfile | 8 - tools/cli-bootstrap/testing/e2e/Program.cs | 75 ++++++++++ tools/cli-bootstrap/testing/e2e/quotes.txt | 59 ++++++++ .../README.md | 32 ++-- tools/dotnet-bootstrap/base/README.md | 6 + tools/dotnet-bootstrap/base/lab/.gitignore | 9 ++ tools/dotnet-bootstrap/base/lab/README.md | 31 ++++ tools/dotnet-bootstrap/base/lab/cases.py | 137 ++++++++++++++++++ .../base/lab/cases/e2e/Program.cs | 74 ++++++++++ .../base/lab/cases/e2e/quotes.txt | 59 ++++++++ tools/dotnet-bootstrap/base/lab/containers.py | 82 +++++++++++ .../lab/containers/centos71/.dockerignore | 5 + .../base/lab/containers/centos71/Dockerfile | 26 ++++ .../base/lab/containers/debian8/.dockerignore | 5 + .../base/lab/containers/debian8/Dockerfile | 73 ++++++++++ .../lab/containers/fedora23/.dockerignore | 5 + .../base/lab/containers/fedora23/Dockerfile | 47 ++++++ .../lab/containers/opensuse13.2/.dockerignore | 5 + .../lab/containers/opensuse13.2/Dockerfile | 52 +++++++ .../lab/containers/opensuse42.1/.dockerignore | 5 + .../lab/containers/opensuse42.1/Dockerfile | 56 +++++++ .../lab/containers/ubuntu1404/.dockerignore | 5 + .../base/lab/containers/ubuntu1404/Dockerfile | 11 ++ .../lab/containers/ubuntu1604/.dockerignore | 5 + .../base/lab/containers/ubuntu1604/Dockerfile | 11 ++ .../lab/containers/ubuntu1610/.dockerignore | 5 + .../base/lab/containers/ubuntu1610/Dockerfile | 11 ++ .../base/lab/dockercleanup.py | 9 ++ tools/dotnet-bootstrap/base/lab/globals.py | 8 + tools/dotnet-bootstrap/base/lab/shellcall.py | 48 ++++++ tools/dotnet-bootstrap/base/lab/shellcall.pyc | Bin 0 -> 1150 bytes .../dotnet.bootstrap.py} | 89 ++++++------ .../ubuntu.14.04-x64-dotnet/src/core-setup | 1 + .../ubuntu.14.04-x64-dotnet/src/coreclr | 1 + .../ubuntu.14.04-x64-dotnet/src/corefx | 1 + .../ubuntu.14.04-x64-dotnet/src/libuv | 1 + 47 files changed, 1083 insertions(+), 129 deletions(-) create mode 100644 tools/cli-bootstrap/dockerfiles/bake-containers.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/bake.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/debian8/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/docker-cleanup.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile delete mode 100644 tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile delete mode 100644 tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile create mode 100644 tools/cli-bootstrap/dockerfiles/test-container.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile delete mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile delete mode 100644 tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile create mode 100644 tools/cli-bootstrap/testing/e2e/Program.cs create mode 100644 tools/cli-bootstrap/testing/e2e/quotes.txt rename tools/{cli-bootstrap => dotnet-bootstrap}/README.md (57%) create mode 100644 tools/dotnet-bootstrap/base/README.md create mode 100644 tools/dotnet-bootstrap/base/lab/.gitignore create mode 100644 tools/dotnet-bootstrap/base/lab/README.md create mode 100755 tools/dotnet-bootstrap/base/lab/cases.py create mode 100644 tools/dotnet-bootstrap/base/lab/cases/e2e/Program.cs create mode 100644 tools/dotnet-bootstrap/base/lab/cases/e2e/quotes.txt create mode 100755 tools/dotnet-bootstrap/base/lab/containers.py create mode 100644 tools/dotnet-bootstrap/base/lab/containers/centos71/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/centos71/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/debian8/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/debian8/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/fedora23/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/fedora23/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/Dockerfile create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/.dockerignore create mode 100644 tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/Dockerfile create mode 100755 tools/dotnet-bootstrap/base/lab/dockercleanup.py create mode 100755 tools/dotnet-bootstrap/base/lab/globals.py create mode 100755 tools/dotnet-bootstrap/base/lab/shellcall.py create mode 100644 tools/dotnet-bootstrap/base/lab/shellcall.pyc rename tools/{cli-bootstrap/cli.bootstrap.py => dotnet-bootstrap/dotnet.bootstrap.py} (89%) mode change 100644 => 100755 create mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup create mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr create mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx create mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv diff --git a/tools/cli-bootstrap/dockerfiles/bake-containers.sh b/tools/cli-bootstrap/dockerfiles/bake-containers.sh new file mode 100644 index 00000000..14116a12 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/bake-containers.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# This shell script 'bakes' the docker containers that we depend on. Essentially, it sets up the docker containers in a certain manner where we +# are enabled to run a test case within them. + +# specify a single directory name to bake just a single container + + +function BakePlatform +{ + SELECTED_CONTAINER=$1 + + echo "baking 'cli-bootstrap:${SELECTED_CONTAINER}'" + pushd ${SELECTED_CONTAINER} + docker build -t "cli-bootstrap:${SELECTED_CONTAINER}" . + popd +} + +# if you don't specify a parameter, we will build all of the platforms in the directory +if [ -z ${1} ] + then + for dir in */ ; do + name=${SELECTED_CONTAINER%"/"} + BakePlatform $name + done +else + # otherwise, specifying a single directory will cause just that directory to be baked (so long as the directory exists) + if [ -d "$1" ] + then + BakePlatform $1 + else + echo "The directory $1 could not be found." + fi +fi + + diff --git a/tools/cli-bootstrap/dockerfiles/bake.sh b/tools/cli-bootstrap/dockerfiles/bake.sh deleted file mode 100644 index 2be36e31..00000000 --- a/tools/cli-bootstrap/dockerfiles/bake.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -for dir in */ ; do - echo "$dir" - pushd $dir - name=${dir%"/"} - docker build -t "rover:$name" . - popd -done \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile b/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile index 841c95e0..46101ce2 100644 --- a/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile +++ b/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile @@ -1,8 +1,25 @@ FROM centos:7.1.1503 MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file +RUN yum -q -y install deltarpm +RUN yum -q -y install epel-release +RUN yum -q -y update +RUN yum -q -y install unzip libunwind8 libunwind8-dev gettext libcurl-devel openssl-devel zlib libicu-devel liblttng-ust lttng-ust-devel libunwind-devel libuuid-devel automake autoconf libtool +RUN yum install -y http://mirror.symnds.com/distributions/gf/el/7/plus/x86_64/cmake-3.3.2-1.gf.el7.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/clang-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/clang-libs-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/lldb-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/lldb-devel-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/llvm-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/llvm-libs-3.6.2-1.el7.centos.x86_64.rpm \ + which \ + make + +RUN yum -q -y install tar git + +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 +RUN update-alternatives --set c++ /usr/bin/clang++ + +RUN yum -q -y install sudo + +VOLUME /env/cli-bootstrap +WORKDIR /env/cli-bootstrap diff --git a/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile b/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile deleted file mode 100644 index 80ab2cee..00000000 --- a/tools/cli-bootstrap/dockerfiles/debian8/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM debian:8.0 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh b/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh new file mode 100644 index 00000000..c05da7c8 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Delete all containers +docker rm $(docker ps -a -q) +# Delete all images +docker rmi $(docker images -q) \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile b/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile deleted file mode 100644 index 759b47cf..00000000 --- a/tools/cli-bootstrap/dockerfiles/fedora23/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM fedora:23 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile b/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile deleted file mode 100644 index b9196dc6..00000000 --- a/tools/cli-bootstrap/dockerfiles/opensuse13.2/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM opensuse:13.2 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile b/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile deleted file mode 100644 index 85459571..00000000 --- a/tools/cli-bootstrap/dockerfiles/opensuse42.1/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM opensuse:42.1 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/test-container.sh b/tools/cli-bootstrap/dockerfiles/test-container.sh new file mode 100644 index 00000000..33e69dc8 --- /dev/null +++ b/tools/cli-bootstrap/dockerfiles/test-container.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# This shell script 'bakes' the docker containers that we depend on. Essentially, it sets up the docker containers in a certain manner where we +# are enabled to run a test case within them. + +# to add a new platform to test on, simply create a directory (named anything that isn't already present) with a dockerfile in it. + +function RunPlatform +{ + SELECTED_CONTAINER=$1 + + echo "running 'cli-bootstrap:${SELECTED_CONTAINER}'" + pushd ../dockerfiles/$dir + + # copy the bootstrap in to place. + + # copy ../../cli.bootstrap.py . + + # this will mount our current directory as the working directory in the docker containers + docker run -v $PWD:/env/cli-bootstrap cli-bootstrap:$name python cli.bootstrap.py -to . # this will generate the src, obj, and bin directory here. + + # copy test cases to this platform + # cp ../testing/* testing + popd +} + +for dir in ../dockerfiles/*/ ; do + echo "$dir" + name=${dir%"/"} + RunPlatform $name +done \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile deleted file mode 100644 index cd87cc53..00000000 --- a/tools/cli-bootstrap/dockerfiles/ubuntu1404/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM ubuntu:14.04 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile deleted file mode 100644 index 49e8425d..00000000 --- a/tools/cli-bootstrap/dockerfiles/ubuntu1604/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM ubuntu:16.04 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py diff --git a/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile b/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile deleted file mode 100644 index cc2d5d6d..00000000 --- a/tools/cli-bootstrap/dockerfiles/ubuntu1610/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM ubuntu:16.10 -MAINTAINER Bryan P. Arant -RUN apt-get -qqy update -RUN apt-get -qqy install git -RUN apt-get -qqy install python -VOLUME /env/rover -WORKDIR /env/rover -ENTRYPOINT python rover.py diff --git a/tools/cli-bootstrap/testing/e2e/Program.cs b/tools/cli-bootstrap/testing/e2e/Program.cs new file mode 100644 index 00000000..2a685f27 --- /dev/null +++ b/tools/cli-bootstrap/testing/e2e/Program.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; + +public static class Program +{ + public static int Main(string[] args) + { + // Draw a dotnet bot. + Bot(QuoteOfTheDay()); + + return 42; // test pass code + } + + public static string QuoteOfTheDay() + { + var quotes = File.ReadAllLines("quotes.txt"); + + return quotes[new Random().Next(0, quotes.Length - 1)]; + } + + + + public static void Bot(string message) + { + var _tempForeground = Console.ForegroundColor; + + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(message); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(@" + __________________ + \ + \"); + Console.ForegroundColor = ConsoleColor.Magenta; + Console.WriteLine(@" + .... + ....' + .... + .......... + .............'..'.. + ................'..'..... + .......'..........'..'..'.... + ........'..........'..'..'..... + .'....'..'..........'..'.......'. + .'..................'... ...... + . ......'......... ..... + . ...... + .. . .. ...... + .... . ....... + ...... ....... ............ + ................ ...................... + ........................'................ + ......................'..'...... ....... + .........................'..'..... ....... + ........ ..'.............'..'.... .......... + ..'..'... ...............'....... .......... + ...'...... ...... .......... ...... ....... + ........... ....... ........ ...... + ....... '...'.'. '.'.'.' .... + ....... .....'.. ..'..... + .. .......... ..'........ + ............ .............. + ............. '.............. + ...........'.. .'.'............ + ............... .'.'............. + .............'.. ..'..'........... + ............... .'.............. + ......... .............. + ....."); + + } + + Console.ForegroundColor = _tempForeground; +} \ No newline at end of file diff --git a/tools/cli-bootstrap/testing/e2e/quotes.txt b/tools/cli-bootstrap/testing/e2e/quotes.txt new file mode 100644 index 00000000..1fc1274f --- /dev/null +++ b/tools/cli-bootstrap/testing/e2e/quotes.txt @@ -0,0 +1,59 @@ +We have a strange illusion that mere time cancels sin. But mere time does nothing either to the fact or to the guilt of a sin. +There can be no deep disappointment where there is not deep love. +My therapist told me the way to achieve true inner peace is to finish what I start. So far today, I have finished 2 bags of M&M`s and a chocolate cake. I feel better already. +Half a truth is often a great lie. +The survival of liberty in our land increasingly depends on the success of liberty in other lands. +The Constitution is not an instrument for the government to restrain the people, it is an instrument for the people to restrain the government -- lest it come to dominate our lives and interests. +From the prodigious hilltops of New Hampshire, let freedom ring. From the mighty mountains of New York, let freedom ring. From the heightening Alleghenies of Pennsylvania, let freedom ring. But not only that: Let freedom ring from every hill and molehill of Mississippi. +Without music, life would be a mistake. +Prosperity is the measure or touchstone of virtue, for it is less difficult to bear misfortune than to remain uncorrupted by pleasure. +The more you read about politics, you got to admit that each party is worse than the other. +Just the omission of Jane Austen`s books alone would make a fairly good library out of a library that hadn`t a book in it. +An unexciting truth may be eclipsed by a thrilling lie. +Beware how you take away hope from another human being. +Marriage is a duel to the death which no man of honour should decline. +If liberty and equality, as is thought by some, are chiefly to be found in democracy, they will be best attained when all persons alike share in government to the utmost. +Ignore death up to the last moment; then, when it can`t be ignored any longer, have yourself squirted full of morphia and shuffle off in a coma. Thoroughly sensible, humane and scientific, eh? +A good novel tells us the truth about its hero; but a bad novel tells us the truth about its author. +I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin, but by the content of their character. +Take from the church the miraculous, the supernatural, the incomprehensible, the unreasonable, the impossible, the unknowable, the absurd, and nothing but a vacuum remains. +Power over a man`s subsistence is power over his will. +The puritanism of Christianity has played havoc with the moderation that an enlightened and tolerant critical spirit would have produced. I`ve noticed that in whatever country, county, town, or other region there is a regulation enjoining temperance, the population seems to be entirely composed of teetotallers and drunkards. There`s a Bible on that shelf there. But I keep it next to Voltaire - poison and antidote. +Never pick a fight with people who buy ink by the barrel. +There can be no liberty unless there is economic liberty. +Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment. +If there were no God, there would be no Atheists. +It is impossible to travel faster than the speed of light, and certainly not desirable, as one`s hat keeps blowing off. +God is really only another artist. He invented the giraffe, the elephant and the cat. He has no real style, He just goes on trying other things. +Saturate yourself with your subject and the camera will all but take you by the hand. +Familiarity breeds contempt - and children. +Heaven have mercy on us all--Presbyterians and Pagans alike--for we are all dreadfully cracked about the head and desperately in need of mending. +The difference between Los Angeles and yogurt is that yogurt comes with less fruit. +I`m afraid that if you look at a thing long enough, it loses all of its meaning. +The difference between sex and death is that with death you can do it alone and no one is going to make fun of you. +Money buys you everything except the chance to do it again. +Never worry about the size of your Christmas tree. In the eyes of children, they are all thirty feet tall. +I think, at a child`s birth, if a mother could ask a fairy godmother to endow it with the most useful gift, that gift should be curiosity. +An unexamined life is not worth living. +It`s a phonetic language. Anything can make sense. How do you think Dr. Seuss wrote any of that sh*t? +Make everything as simple as possible, but not simpler. +There are lots of people who mistake their imagination for their memory. +We are what we repeatedly do. Excellence, therefore, is not an act, but a habit. +Wise men argue causes, and fools decide them. +A pint of sweat, saves a gallon of blood. +It ain`t the parts of the Bible that I can`t understand that bother me, it is the parts that I do understand. +A `geek` by definition is someone who eats live animals....I`ve never eaten live animals. +No virtuous act is quite as virtuous from the standpoint of our friend or foe, as from our own. Therefore, we are saved by the final form of love which is forgiveness. +The ladder of success is best climbed by stepping on the rungs of opportunity. +My best friend is the man who in wishing me well wishes it for my sake. +The best way to win an argument is to begin by being right. +Christmas is the gentlest, loveliest festival of the revolving year. And yet, for all that, when it speaks, its voice has strong authority. +Whenever science makes a discovery, the devil grabs it while the angels are debating the best way to use it. +Don`t you wish you had a job like mine? All you have to do is think up a certain number of words! Plus, you can repeat words! And they don`t even have to be true! +When angry, count ten before you speak; if very angry, a hundred. +People have a way of becoming what you encourage them to be, not what you nag them to be. +A man never tells you anything until you contradict him. +There are very few monsters who warrant the fear we have of them. +Perspective is worth 80 IQ Points - Alan Kay +The best way to predict the future is to invent it. - Alan Kay +The Internet was done so well that most people think of it as a natural resource like the Pacific Ocean, rather than something that was man-made. When was the last time a technology with a scale like that was so error-free? The Web, in comparison, is a joke. The Web was done by amateurs. - Alan Kay \ No newline at end of file diff --git a/tools/cli-bootstrap/README.md b/tools/dotnet-bootstrap/README.md similarity index 57% rename from tools/cli-bootstrap/README.md rename to tools/dotnet-bootstrap/README.md index cea6e072..fdc94a1d 100644 --- a/tools/cli-bootstrap/README.md +++ b/tools/dotnet-bootstrap/README.md @@ -1,52 +1,52 @@ -CLI.BOOTSTRAP(1) +DOTNET.BOOTSTRAP(1) ### NAME .NET CLI Bootstrapping Tool - A tool to help you bootstrap the .NET Command Line Tool on unsupported platforms. ### SYNOPSIS -python cli.bootstrap.py [-b __build_set__] [-nopatch] [-payload __tarball_path__] +python dotnet.bootstrap.py [-b __build_set__] [-nopatch] [-payload __tarball_path__] ### DESCRIPTION -cli.bootstrap.py is the .NET CLI bootstrapping script that intends to help developers move to new platforms and "bring up" the required pieces. +dotnet.bootstrap.py is the .NET CLI bootstrapping script (written for Python 2.7) that intends to help developers move to new platforms and "bring up" the required pieces. There are default settings that intend to hit the 'most cases' scenario. If all is going to plan, you should never need to specify any additional parameters. However many situations arise where it becomes a necessity or a nice-to-have. Namely, when things go wrong, you want to be able to get in there and fix -up the build, make changes, etc. This is 'development mode' or DevMode for short. In DevMode, NO git commands are executed. This is to prevent -the script from stomping out any changes you have made in the working directory. Additionally, when things do go wrong (inevitably they will), this tool places a shell/batch script -within the working directory that contains the command line that failed. This is to enable the scenario where you want to 'drill into' a problem. +up the build, make changes, etc. This is 'development mode' or DevMode for short. In DevMode, NO git commands are executed (ONE EXCEPTION: if the expected repo directories (coreclr, corefx, core-setup, libuv) do not exist, +we will clone them in). This is to prevent the script from stomping out any changes you have made in the working directory. Additionally, when things do go wrong (inevitably they will), this tool places a shell/batch +script within the working directory that contains the command line that failed. This is to enable the scenario where you want to 'drill into' a problem. ### EXAMPLES -The first time you run this tool HAS to be like this: +Intended use, + ``` -./cli.bootstrap.py +./dotnet.bootstrap.py ``` This will spawn a directory next to the bootstrap script, named after its runtime identifier (the runtime identifier is currently picked from the /os/release and we concatenate the VERSION and VERSION_ID values). So on an AMD64 Ubuntu 16.04 machine, the RID is ubuntu.16.04-x64-dotnet - Any additional runs can be controlled via these command lines, and consequently, any additional runs are going to be in DevMode. ``` -./cli.bootstrap.py -b corefx libuv +./dotnet.bootstrap.py -b corefx libuv ``` This will build only the corefx binaries and coreclr binaries, then patch the files. If you want to prevent patching (for example, just to re-run a build): ``` -./cli.bootstrap.py -b corefx coreclr -nopatch +./dotnet.bootstrap.py -b corefx coreclr -nopatch ``` Additionally, if you have a tarball of the files that you'd like to produce, consider: ``` -./cli.bootstrap.py -b corefx coreclr -nopatch -payload ~/downloads/dotnet-dev-build.tar.gz +./dotnet.bootstrap.py -b corefx coreclr -nopatch -payload ~/downloads/dotnet-dev-build.tar.gz ``` ### DEFAULTS -By default, running ./cli.bootstrap.py with no additional parameters is equivalent to this command line: +By default, running ./dotnet.bootstrap.py with no additional parameters is equivalent to this command line: ``` -./cli.bootstrap.py -b corefx coreclr libuv core-setup -payload __dotnet_cli_repository_url__ +./dotnet.bootstrap.py -b corefx coreclr libuv core-setup -payload __dotnet_cli_repository_url__ ``` ### OPTIONS @@ -60,11 +60,11 @@ By default, running ./cli.bootstrap.py with no additional parameters is equivale *-payload __tar_filepath__* -    By default cli.bootstrap will pull in a pre-built tar file from the CLI repository and patch this. If you want to provide your own binaries to patch +    By default dotnet.bootstrap will pull in a pre-built tar file from the CLI repository and patch this. If you want to provide your own binaries to patch (from dev builds or something), then specify a path (relative or absolute). ### OVERVIEW -After you run the cli.bootstrap, you'll see a directory named after the Runtime Identifier (RID) next to the script, the directory tree looks like this (for example), +After you run the dotnet.bootstrap, you'll see a directory named after the Runtime Identifier (RID) next to the script, the directory tree looks like this (for example), ``` diff --git a/tools/dotnet-bootstrap/base/README.md b/tools/dotnet-bootstrap/base/README.md new file mode 100644 index 00000000..8a208a9b --- /dev/null +++ b/tools/dotnet-bootstrap/base/README.md @@ -0,0 +1,6 @@ +# BASE + +## Lab +Go to the lab for testing information. + + diff --git a/tools/dotnet-bootstrap/base/lab/.gitignore b/tools/dotnet-bootstrap/base/lab/.gitignore new file mode 100644 index 00000000..16d3fd20 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/.gitignore @@ -0,0 +1,9 @@ +**/bin/* +**/src/* +**/obj/* +**/testing/* +dotnet.bootstrap.py +*~ +*-dotnet +shellcall_failure-repro.sh +*.deb \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/README.md b/tools/dotnet-bootstrap/base/lab/README.md new file mode 100644 index 00000000..fd38b4cc --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/README.md @@ -0,0 +1,31 @@ +# LAB + +## Test Cases +Intended interface for access is the class `Cases` in `cases.py`. + +Listing all test cases, +``` +./cases.py list +``` + +Running all test cases in all containers, +``` +./cases.py run +``` + +Running specific testcase in all containers, +``` +./cases.py run e2e +``` + +Running specific testcase in specific container, +``` +./cases.py run e2e -in debian8 +``` + +## Environments +Docker containers are used as the 'unit of environment.' + +``` +./containers.py list +``` \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/cases.py b/tools/dotnet-bootstrap/base/lab/cases.py new file mode 100755 index 00000000..f2d42975 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/cases.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +import os +import sys + +from shellcall import ShellCall +from shellcall import ContinueOnError +from sys import argv +from os import getcwd +from os.path import join +from os.path import exists + +from globals import g_override + +# interface + data binding for managing the testcases. +class Cases: + # TODO: use script directory instead of cwd, and require the containers directory to be local to the script + _supported_containers = join(getcwd(), 'containers/') # our 'list' of current supported platforms are the directories in this directory + _testcases = join(getcwd(), 'cases/') + _continueOnError = True + _lenient = True + + + # if current_working_directory = None, then we use the working dir dictated by the dockerfile + # if none is specified in the dockerfile, then docker uses '/' + def _docker_compose(self, identifier, local_volume, current_working_directory = None): + wdir_parameter = None + + if current_working_directory: + wdir_parameter = '-w "%s"'%(current_working_directory) + + return 'docker run %s -v %s:/env/dotnet-bootstrap dotnet-bootstrap:%s'%(wdir_parameter, local_volume, identifier) + + # Runs a select case + def RunIn(self, container_name, casename): + local_mount_location = join(self._supported_containers, container_name) + testing_destination = join(local_mount_location, "testing/") + + ShellCall("echo \"running 'dotnet-bootstrap:%s - testcase: %s'\""%(container_name, casename), lenient = self._lenient) + + # copy the bootstrap and test source in to the container working directory (next to the Dockerfile) + ShellCall('cp ../../dotnet.bootstrap.py %s'%(join(self._supported_containers, container_name)), lenient = self._lenient) + ShellCall('mkdir -p %s'%(join(testing_destination, casename)), lenient=self._lenient) + ShellCall('cp -R %s %s'%(join(self._testcases, casename), join(testing_destination, casename)), lenient = self._lenient) + + docker_run_cmd = 'docker run -v %s:/env/dotnet-bootstrap dotnet-bootstrap:%s'%(local_mount_location, str(container_name)) + # ^ : This runs docker using the current container directory (with the Dockerfile) as the current working directory. + # so that anything placed in that directory becomes accessible. + # eventually we will copy the tests in to this directory as well (see below) + + # run the bootstrap + ShellCall('%s python /env/dotnet-bootstrap/dotnet.bootstrap.py -to /env/dotnet-bootstrap/'%(docker_run_cmd), lenient = self._lenient) # this will generate the src, obj, and bin directory here. + + # create whatever project file is the latest and greatest (was project.json, and is now named after the directory.csproj) + ShellCall('%s /env/dotnet-bootstrap/bin/dotnet new -t Console'%(self._docker_compose(container_name, local_mount_location, join("/env/dotnet-bootstrap/testing/", casename))), lenient= self._lenient) + #ShellCall('ls', cwd=join(testing_destination, casename, casename + '.csproj')) + + # confirm that it exists. + if exists(join(testing_destination, casename, casename + '.csproj')): + ShellCall('mkdir -p %s'%join(testing_destination, casename, "result")) + ShellCall('touch %s'%(join(testing_destination, casename, "result", "pass"))) # spawn a result; a failure is when this doesn't exist. If this exists, this is a passing testcase. + + ShellCall('cp -R %s/* %s'%(join(self._testcases, casename), join(testing_destination, casename)), lenient= self._lenient) + # ShellCall('%s /env/dotnet-bootstrap/bin/dotnet restore .'%(self._docker_compose(container_name, local_mount_location, join("/env/dotnet-bootstrap/testing/", casename))), lenient=self._lenient) + # ShellCall('%s /env/dotnet-bootstrap/bin/dotnet run'%(self._docker_compose(container_name, local_mount_location, join("/env/dotnet-bootstrap/testing/", casename))), lenient=self._lenient) + + self.Report() + + def _runOverride(self): + for container in g_override["containers"]: + for case in g_override["cases"]: + try: + self.RunIn(container, case) + except ContinueOnError: # we threw this up with the intention of being OK with moving on. + continue + + def _status(self, container, case): + print("CONTAINER - CASE - STATUS") + target = "%s - %s"%(container, case) + testing_destination = join(self._supported_containers, container, "testing/") + if exists(join(testing_destination, case, "result", "pass")): + print("%s - pass"%(target)) + else: + print("%s - fail"%(target)) + + + def Report(self): + for container in g_override["containers"]: + for case in g_override["cases"]: + self._status(container, case) + + # runs the full matrix of tests + def RunAll(self): + if g_override: + self._runOverride() + return + + for root, containers, files in os.walk(self._supported_containers): + for container in containers: # we keep it explicitly the case that there are no other directories in the cases or containers directories. + for root, cases, files in os.walk(self._testcases): + for case in cases: + try: + self.RunIn(container, case) # runs the full matrix of environments and cases + except ContinueOnError: + continue + break # just walk the top level + break # just walk the top level. + + def List(self): + ShellCall('ls -1 %s'%(self._testcases), lenient = self._lenient) + + + def __init__(self): + if not exists(self._supported_containers): + print('no such directory: %s\n'%(self._supported_containers)) + sys.exit() + + if not exists(self._testcases): + print('no such directory: %s\n'%(self._testcases)) + sys.exit() + +def PrintUsage(): + print("TODO: Usage") + +if __name__ == '__main__': + testcases = Cases() + + if len(argv) <= 1: + PrintUsage() + exit() + + dictionary = { + "run": testcases.RunAll, + "list": testcases.List, + "report": testcases.Report + } + + dictionary[argv[1]]() diff --git a/tools/dotnet-bootstrap/base/lab/cases/e2e/Program.cs b/tools/dotnet-bootstrap/base/lab/cases/e2e/Program.cs new file mode 100644 index 00000000..37cf47ff --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/cases/e2e/Program.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; + +public static class Program +{ + public static int Main(string[] args) + { + // Draw a dotnet bot. + Bot(QuoteOfTheDay()); + + return 42; // test pass code + } + + public static string QuoteOfTheDay() + { + var quotes = File.ReadAllLines("quotes.txt"); + + return quotes[new Random().Next(0, quotes.Length - 1)]; + } + + public static void Bot(string message) + { + var _tempForeground = Console.ForegroundColor; + + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(message); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(@" + __________________ + \\ + \\"); + Console.ForegroundColor = ConsoleColor.Magenta; + Console.WriteLine(@" + .... + ....' + .... + .......... + .............'..'.. + ................'..'..... + .......'..........'..'..'.... + ........'..........'..'..'..... + .'....'..'..........'..'.......'. + .'..................'... ...... + . ......'......... ..... + . ...... + .. . .. ...... + .... . ....... + ...... ....... ............ + ................ ...................... + ........................'................ + ......................'..'...... ....... + .........................'..'..... ....... + ........ ..'.............'..'.... .......... + ..'..'... ...............'....... .......... + ...'...... ...... .......... ...... ....... + ........... ....... ........ ...... + ....... '...'.'. '.'.'.' .... + ....... .....'.. ..'..... + .. .......... ..'........ + ............ .............. + ............. '.............. + ...........'.. .'.'............ + ............... .'.'............. + .............'.. ..'..'........... + ............... .'.............. + ......... .............. + ....."); + + + + Console.ForegroundColor = _tempForeground; + } +} \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/cases/e2e/quotes.txt b/tools/dotnet-bootstrap/base/lab/cases/e2e/quotes.txt new file mode 100644 index 00000000..1fc1274f --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/cases/e2e/quotes.txt @@ -0,0 +1,59 @@ +We have a strange illusion that mere time cancels sin. But mere time does nothing either to the fact or to the guilt of a sin. +There can be no deep disappointment where there is not deep love. +My therapist told me the way to achieve true inner peace is to finish what I start. So far today, I have finished 2 bags of M&M`s and a chocolate cake. I feel better already. +Half a truth is often a great lie. +The survival of liberty in our land increasingly depends on the success of liberty in other lands. +The Constitution is not an instrument for the government to restrain the people, it is an instrument for the people to restrain the government -- lest it come to dominate our lives and interests. +From the prodigious hilltops of New Hampshire, let freedom ring. From the mighty mountains of New York, let freedom ring. From the heightening Alleghenies of Pennsylvania, let freedom ring. But not only that: Let freedom ring from every hill and molehill of Mississippi. +Without music, life would be a mistake. +Prosperity is the measure or touchstone of virtue, for it is less difficult to bear misfortune than to remain uncorrupted by pleasure. +The more you read about politics, you got to admit that each party is worse than the other. +Just the omission of Jane Austen`s books alone would make a fairly good library out of a library that hadn`t a book in it. +An unexciting truth may be eclipsed by a thrilling lie. +Beware how you take away hope from another human being. +Marriage is a duel to the death which no man of honour should decline. +If liberty and equality, as is thought by some, are chiefly to be found in democracy, they will be best attained when all persons alike share in government to the utmost. +Ignore death up to the last moment; then, when it can`t be ignored any longer, have yourself squirted full of morphia and shuffle off in a coma. Thoroughly sensible, humane and scientific, eh? +A good novel tells us the truth about its hero; but a bad novel tells us the truth about its author. +I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin, but by the content of their character. +Take from the church the miraculous, the supernatural, the incomprehensible, the unreasonable, the impossible, the unknowable, the absurd, and nothing but a vacuum remains. +Power over a man`s subsistence is power over his will. +The puritanism of Christianity has played havoc with the moderation that an enlightened and tolerant critical spirit would have produced. I`ve noticed that in whatever country, county, town, or other region there is a regulation enjoining temperance, the population seems to be entirely composed of teetotallers and drunkards. There`s a Bible on that shelf there. But I keep it next to Voltaire - poison and antidote. +Never pick a fight with people who buy ink by the barrel. +There can be no liberty unless there is economic liberty. +Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment. +If there were no God, there would be no Atheists. +It is impossible to travel faster than the speed of light, and certainly not desirable, as one`s hat keeps blowing off. +God is really only another artist. He invented the giraffe, the elephant and the cat. He has no real style, He just goes on trying other things. +Saturate yourself with your subject and the camera will all but take you by the hand. +Familiarity breeds contempt - and children. +Heaven have mercy on us all--Presbyterians and Pagans alike--for we are all dreadfully cracked about the head and desperately in need of mending. +The difference between Los Angeles and yogurt is that yogurt comes with less fruit. +I`m afraid that if you look at a thing long enough, it loses all of its meaning. +The difference between sex and death is that with death you can do it alone and no one is going to make fun of you. +Money buys you everything except the chance to do it again. +Never worry about the size of your Christmas tree. In the eyes of children, they are all thirty feet tall. +I think, at a child`s birth, if a mother could ask a fairy godmother to endow it with the most useful gift, that gift should be curiosity. +An unexamined life is not worth living. +It`s a phonetic language. Anything can make sense. How do you think Dr. Seuss wrote any of that sh*t? +Make everything as simple as possible, but not simpler. +There are lots of people who mistake their imagination for their memory. +We are what we repeatedly do. Excellence, therefore, is not an act, but a habit. +Wise men argue causes, and fools decide them. +A pint of sweat, saves a gallon of blood. +It ain`t the parts of the Bible that I can`t understand that bother me, it is the parts that I do understand. +A `geek` by definition is someone who eats live animals....I`ve never eaten live animals. +No virtuous act is quite as virtuous from the standpoint of our friend or foe, as from our own. Therefore, we are saved by the final form of love which is forgiveness. +The ladder of success is best climbed by stepping on the rungs of opportunity. +My best friend is the man who in wishing me well wishes it for my sake. +The best way to win an argument is to begin by being right. +Christmas is the gentlest, loveliest festival of the revolving year. And yet, for all that, when it speaks, its voice has strong authority. +Whenever science makes a discovery, the devil grabs it while the angels are debating the best way to use it. +Don`t you wish you had a job like mine? All you have to do is think up a certain number of words! Plus, you can repeat words! And they don`t even have to be true! +When angry, count ten before you speak; if very angry, a hundred. +People have a way of becoming what you encourage them to be, not what you nag them to be. +A man never tells you anything until you contradict him. +There are very few monsters who warrant the fear we have of them. +Perspective is worth 80 IQ Points - Alan Kay +The best way to predict the future is to invent it. - Alan Kay +The Internet was done so well that most people think of it as a natural resource like the Pacific Ocean, rather than something that was man-made. When was the last time a technology with a scale like that was so error-free? The Web, in comparison, is a joke. The Web was done by amateurs. - Alan Kay \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers.py b/tools/dotnet-bootstrap/base/lab/containers.py new file mode 100755 index 00000000..2afff3b1 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +# This shell script 'bakes' the docker containers that we depend on. Essentially, it sets up the docker containers in a certain manner where we +# are enabled to run a test case within them. + +# specify a single directory name to bake just a single container + +from shellcall import ShellCall +from shellcall import ContinueOnError +import sys +import os + +from sys import argv +from os.path import join +from os import getcwd + +from globals import g_override + +# interface + data binding for managing the containers. +class Containers: + _supported_platforms = join(getcwd(), 'containers') + '/' # our 'list' of current supported platforms are the directories in this directory + + def Bake(self, selected_platform): + ShellCall("echo baking 'dotnet-bootstrap:%s'"%(selected_platform), lenient=True) + ShellCall("docker build -t \"dotnet-bootstrap:%s\" ."%(selected_platform), join(self._supported_platforms, selected_platform), lenient=True) + + def CleanContainerFolder(self, container, folderName): + ShellCall("rm -R -f %s"%(join(self._supported_platforms, container, folderName)), lenient=True) + + def CleanAll(self): + for root, platforms, files in os.walk(self._supported_platforms): + for platform in platforms: + self.CleanContainerFolder(platform, "src") + self.CleanContainerFolder(platform, "obj") + self.CleanContainerFolder(platform, "bin") + self.CleanContainerFolder(platform, "testing") + + break + + def _bakeOverride(self): + for container in g_override["containers"]: + try: + self.Bake(container) + except ContinueOnError: + continue + + + def BakeAll(self): + if g_override: + self._bakeOverride() + return + + for root, platforms, files in os.walk(self._supported_platforms): + for platform in platforms: # we keep it explicitly the case that there are no other directories in the cases or containers directories. + try: + self.Bake(platform) + except ContinueOnError: + continue + break + + def List(self): + ShellCall('ls -1 %s'%(self._supported_platforms)) + + +def PrintUsage(): + print("TODO: Usage") + +if __name__ == '__main__': + containers = Containers() + + dictionary = { + "bake": containers.BakeAll, + "list": containers.List, + "clean": containers.CleanAll + } + + if len(argv) <= 1: + PrintUsage() + exit() + + dictionary[argv[1]]() + diff --git a/tools/dotnet-bootstrap/base/lab/containers/centos71/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/centos71/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/centos71/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/centos71/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/centos71/Dockerfile new file mode 100644 index 00000000..e53c26fa --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/centos71/Dockerfile @@ -0,0 +1,26 @@ +FROM centos:7.1.1503 +MAINTAINER Bryan P. Arant +RUN yum -q -y install deltarpm +RUN yum -q -y install epel-release +RUN yum -q -y update +RUN yum -q -y install unzip libunwind8 libunwind8-dev gettext libcurl-devel openssl-devel zlib libicu-devel liblttng-ust lttng-ust-devel libunwind-devel libuuid-devel automake autoconf libtool +RUN yum -q -y install binutils +RUN yum install -y http://mirror.symnds.com/distributions/gf/el/7/plus/x86_64/cmake-3.3.2-1.gf.el7.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/clang-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/clang-libs-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/lldb-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/lldb-devel-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/llvm-3.6.2-1.el7.centos.x86_64.rpm \ + https://matell.blob.core.windows.net/rpms/llvm-libs-3.6.2-1.el7.centos.x86_64.rpm \ + which \ + make + +RUN yum -q -y install tar git + +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 +RUN update-alternatives --set c++ /usr/bin/clang++ + +RUN yum -q -y install sudo + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap diff --git a/tools/dotnet-bootstrap/base/lab/containers/debian8/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/debian8/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/debian8/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/debian8/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/debian8/Dockerfile new file mode 100644 index 00000000..677618f0 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/debian8/Dockerfile @@ -0,0 +1,73 @@ +# +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +# Dockerfile that creates a container suitable to build dotnet-cli +FROM debian:8.0 + +# Misc Dependencies for build +RUN apt-get update && \ + apt-get -qqy install \ + llvm-3.5 \ + lldb-3.5 \ + lldb-3.5-dev \ + curl \ + uuid-dev \ + unzip \ + gettext \ + sudo && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# This could become a "microsoft/coreclr" image, since it just installs the dependencies for CoreCLR (and stdlib) +RUN apt-get update &&\ + apt-get -qqy install \ + libunwind8 \ + libunwind8-dev \ + libkrb5-3 \ + libicu52 \ + libicu-dev \ + liblttng-ust0 \ + liblttng-ust-dev \ + libssl1.0.0 \ + zlib1g \ + libssl-dev \ + zlib1g-dev \ + libuuid1 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install Build Prereqs +RUN apt-get update && \ + apt-get -qqy install \ + autogen \ + binutils \ + debhelper \ + build-essential \ + devscripts \ + git \ + automake \ + cmake \ + libkrb5-dev \ + libtool \ + libcurl4-openssl-dev \ + clang-3.5 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Use clang as c++ compiler +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 +RUN update-alternatives --set c++ /usr/bin/clang++-3.5 + +# Set working directory +WORKDIR /opt/code + +# Work around https://github.com/dotnet/cli/issues/1582 until Docker releases a +# fix (https://github.com/docker/docker/issues/20818). This workaround allows +# the container to be run with the default seccomp Docker settings by avoiding +# the restart_syscall made by LTTng which causes a failed assertion. +ENV LTTNG_UST_REGISTER_TIMEOUT 0 + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/fedora23/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/fedora23/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/fedora23/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/fedora23/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/fedora23/Dockerfile new file mode 100644 index 00000000..1ee44a50 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/fedora23/Dockerfile @@ -0,0 +1,47 @@ +# +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +# Dockerfile that creates a container suitable to build dotnet-cli +FROM fedora:23 + +# Install the base toolchain we need to build anything (clang, cmake, make and the like) +# this does not include libraries that we need to compile different projects, we'd like +# them in a different layer. +RUN dnf install -y cmake \ + clang \ + lldb-devel \ + make \ + which && \ + dnf clean all + +# Install tools used by the VSO build automation. +RUN dnf install -y git \ + zip \ + tar \ + nodejs \ + findutils \ + npm && \ + dnf clean all && \ + npm install -g azure-cli && \ + npm cache clean + +# Dependencies of CoreCLR and CoreFX. +RUN dnf install -y libicu-devel \ + libuuid-devel \ + libtool \ + libcurl-devel \ + openssl-devel \ + libunwind-devel \ + lttng-ust-devel && \ + dnf clean all + +# Upgrade NSS, used for SSL, to avoid NuGet restore timeouts. +RUN dnf upgrade -y nss +RUN dnf clean all + + +# Set working directory +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap diff --git a/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/Dockerfile new file mode 100644 index 00000000..e2bccc5f --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/opensuse13.2/Dockerfile @@ -0,0 +1,52 @@ +# +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +FROM opensuse:13.2 + +# Install the base toolchain we need to build anything (clang, cmake, make and the like) +# this does not include libraries that we need to compile different projects, we'd like +# them in a different layer. +RUN zypper -n update + +RUN zypper -n install binutils \ + python \ + cmake \ + which \ + gcc \ + libtool \ + python-xml \ + libicu-devel \ + lldb \ + lldb-devel \ + libunwind-devel \ + libuuid-devel \ + llvm-clang \ + tar \ + ncurses-utils \ + curl \ + git \ + sudo && \ + ln -s /usr/bin/clang++ /usr/bin/clang++-3.5 && \ + zypper clean -a + +# Dependencies of CoreCLR and CoreFX. We need to add an additional repository to get lttng. +RUN zypper addrepo -G http://download.opensuse.org/repositories/devel:/tools:/lttng/openSUSE_13.2/devel:tools:lttng.repo && \ + zypper refresh && \ + zypper -n remove krb5-mini && \ + zypper -n install libunwind \ + libicu \ + krb5-devel \ + lttng-ust-devel \ + libuuid1 \ + libopenssl-devel \ + libopenssl1_0_0 \ + libcurl-devel && \ + zypper clean -a + +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 +RUN update-alternatives --set c++ /usr/bin/clang++ + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/Dockerfile new file mode 100644 index 00000000..08e64d8b --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/opensuse42.1/Dockerfile @@ -0,0 +1,56 @@ +# +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +FROM opensuse:42.1 + +# Install the base toolchain we need to build anything (clang, cmake, make and the like) +# this does not include libraries that we need to compile different projects, we'd like +# them in a different layer. +RUN zypper -n update + +RUN zypper -n install binutils \ + python \ + cmake \ + which \ + gcc \ + libtool \ + python-xml \ + libicu-devel \ + lldb \ + lldb-devel \ + libunwind-devel \ + libuuid-devel \ + llvm-clang \ + tar \ + ncurses-utils \ + curl \ + git \ + sudo && \ + ln -s /usr/bin/clang++ /usr/bin/clang++-3.5 && \ + zypper clean -a + +# Dependencies of CoreCLR and CoreFX. We need to add an additional repository to get lttng. +RUN zypper addrepo -G http://download.opensuse.org/repositories/devel:/tools:/lttng/openSUSE_13.2/devel:tools:lttng.repo +RUN whereis zypper +RUN zypper refresh +RUN whereis zypper +RUN whereis zypper +RUN zypper -n -q install libunwind +RUN whereis zypper +# we have to force zypper to resolve this dependency because it, +# itself, depends on krb5-mini which needs to be uninstalled (possibly +# uninstalling zypper) +RUN zypper -n -q install --force-resolution krb5-devel +RUN zypper -n -q install lttng-ust-devel +RUN zypper -n -q install libuuid1 +RUN zypper -n -q install libopenssl-devel +RUN zypper -n -q install libopenssl1_0_0 +RUN zypper -n -q install libcurl-devel + +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 +RUN update-alternatives --set c++ /usr/bin/clang++ + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/Dockerfile new file mode 100644 index 00000000..acb94466 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1404/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:14.04 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install libkrb5-dev build-essential libtool git binutils python automake cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev uuid-dev + +# Use clang as c++ compiler +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 +RUN update-alternatives --set c++ /usr/bin/clang++-3.5 + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/Dockerfile new file mode 100644 index 00000000..2cdf723d --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1604/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:16.04 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install libkrb5-dev build-essential libtool git binutils python automake cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev uuid-dev + +# Use clang as c++ compiler +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 +RUN update-alternatives --set c++ /usr/bin/clang++-3.5 + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/.dockerignore b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/.dockerignore new file mode 100644 index 00000000..6d1fc225 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/.dockerignore @@ -0,0 +1,5 @@ +src/* +bin/* +obj/* +testing/* +dotnet.bootstrap.py \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/Dockerfile b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/Dockerfile new file mode 100644 index 00000000..3d037797 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/containers/ubuntu1610/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:16.10 +MAINTAINER Bryan P. Arant +RUN apt-get -qqy update +RUN apt-get -qqy install libkrb5-dev build-essential libtool git binutils python automake cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev uuid-dev + +# Use clang as c++ compiler +RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 +RUN update-alternatives --set c++ /usr/bin/clang++-3.5 + +VOLUME /env/dotnet-bootstrap +WORKDIR /env/dotnet-bootstrap diff --git a/tools/dotnet-bootstrap/base/lab/dockercleanup.py b/tools/dotnet-bootstrap/base/lab/dockercleanup.py new file mode 100755 index 00000000..8eeea300 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/dockercleanup.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + + +from shellcall import ShellCall + +# Delete all containers +ShellCall("docker rm $(docker ps -a -q)") +# Delete all images +ShellCall("docker rmi $(docker images -q)") \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/globals.py b/tools/dotnet-bootstrap/base/lab/globals.py new file mode 100755 index 00000000..717ab257 --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/globals.py @@ -0,0 +1,8 @@ +g_override = { + "containers": [ + "ubuntu1404" + ], + "cases" : [ + "e2e" + ] +} \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/shellcall.py b/tools/dotnet-bootstrap/base/lab/shellcall.py new file mode 100755 index 00000000..e561db8c --- /dev/null +++ b/tools/dotnet-bootstrap/base/lab/shellcall.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# A 'Shell Call' is a shell call (duh) that we want to be reproduceable in the event of a failure. +# namely, something that a developer can go in and 'drill in' on without running the entirety of the +# build again. + +import os +from subprocess import call +from subprocess import check_call +from subprocess import CalledProcessError +from os import path + +class ContinueOnError(Exception): + def __init__(self, working_directory, reprofile): + self.working_directory = working_directory + self.reprofile = reprofile + + def __str__(self): + return '%s - %s'%(working_directory, reprofile) + +def ShellCall(cmd, cwd = None, lenient=False): + if not cwd: + cwd = os.getcwd() + + try: + check_call(cmd, shell=True, cwd=cwd) + + except CalledProcessError as repro_data: + repro_filename = 'shellcall_failure-repro.sh' + repro_destination = path.join(cwd, repro_filename) + + # when the call fails, print a repro to the working directory. + with open(repro_destination, 'w') as repro_file: + repro_file.writelines(['#!/usr/bin/env bash\n', repro_data.cmd + '\n']) + + # if we're rooted + if os.getuid() == 0: + call('chmod +x %s'%(repro_filename), shell=True, cwd=cwd) + + # prints "Rover has detected a failure" + print("a reproduction script was placed at : %s"%(repro_destination)) + print("To reproduce the failure:\n\tcd %s\n\t./%s"%(cwd, repro_filename)) + + # meh, lets just try to keep building everything. + if lenient: + raise ContinueOnError(cwd, repro_filename) # if we're feeling lenient, then we will raise up this opportunity to continue. + + os._exit(1) # if we fail a check_call then we want to bail out asap so the dev can investigate. \ No newline at end of file diff --git a/tools/dotnet-bootstrap/base/lab/shellcall.pyc b/tools/dotnet-bootstrap/base/lab/shellcall.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cbbc77369a762c2c25520512f2d1e98e3e805eb GIT binary patch literal 1150 zcmb_bO>Yx15FLBBX|io8R8XV}q^+u=sHok0g%A>|;D9RFBDKmT+N|BK(~Z5d9nwn4 zsoeQ3T=_X%kht;#V8&_7$C*t$nHf)>-@NfgKUR{R?^`D&Tt6ItU*K|Y&xj;VGOLodddfmnc#40 z>Uy4A!`w@ZqEu4BP|o07C{>05b*};Bo^z zhiT}-Ma|F& z4?g7-63jA)rGTs%oFMp7cNu#f&P{oOG8#fsevwvEsdTiycm5nufuJWY# z#N9``wV92b%?3(mQh!JXg{u-r+lfL0ZV63Ujf_a2UZmU3buli|03^nxS4O9E>#T#0}P1iBL+K1kL*LLiunLa}qMA zGXh5FuP+K;_&b=Jho`ERx)@1+?=~gy5Ty%};gA1OA?XCcxC8XEk@i`c<+3p@6UJ+a zp|LXa#?&{N-GMRQd0R9Y&Ov5%G04JLiSS-?={tyYM02K>f*89;Xn?iYDv#I(Uqx>% zT4O1$$598f-9_BbNz1^`jR$xG=uHZu{-fog(K4q?@tger?x2n6&+s;lYx$h0IZ7 Date: Sun, 20 Nov 2016 23:43:11 +0000 Subject: [PATCH 08/12] cleaning up old stuff --- .../dockerfiles/bake-containers.sh | 35 --------- .../dockerfiles/centos71/Dockerfile | 25 ------- .../dockerfiles/docker-cleanup.sh | 5 -- .../dockerfiles/test-container.sh | 30 -------- tools/cli-bootstrap/testing/e2e/Program.cs | 75 ------------------- tools/cli-bootstrap/testing/e2e/quotes.txt | 59 --------------- 6 files changed, 229 deletions(-) delete mode 100644 tools/cli-bootstrap/dockerfiles/bake-containers.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/centos71/Dockerfile delete mode 100644 tools/cli-bootstrap/dockerfiles/docker-cleanup.sh delete mode 100644 tools/cli-bootstrap/dockerfiles/test-container.sh delete mode 100644 tools/cli-bootstrap/testing/e2e/Program.cs delete mode 100644 tools/cli-bootstrap/testing/e2e/quotes.txt diff --git a/tools/cli-bootstrap/dockerfiles/bake-containers.sh b/tools/cli-bootstrap/dockerfiles/bake-containers.sh deleted file mode 100644 index 14116a12..00000000 --- a/tools/cli-bootstrap/dockerfiles/bake-containers.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# This shell script 'bakes' the docker containers that we depend on. Essentially, it sets up the docker containers in a certain manner where we -# are enabled to run a test case within them. - -# specify a single directory name to bake just a single container - - -function BakePlatform -{ - SELECTED_CONTAINER=$1 - - echo "baking 'cli-bootstrap:${SELECTED_CONTAINER}'" - pushd ${SELECTED_CONTAINER} - docker build -t "cli-bootstrap:${SELECTED_CONTAINER}" . - popd -} - -# if you don't specify a parameter, we will build all of the platforms in the directory -if [ -z ${1} ] - then - for dir in */ ; do - name=${SELECTED_CONTAINER%"/"} - BakePlatform $name - done -else - # otherwise, specifying a single directory will cause just that directory to be baked (so long as the directory exists) - if [ -d "$1" ] - then - BakePlatform $1 - else - echo "The directory $1 could not be found." - fi -fi - - diff --git a/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile b/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile deleted file mode 100644 index 46101ce2..00000000 --- a/tools/cli-bootstrap/dockerfiles/centos71/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM centos:7.1.1503 -MAINTAINER Bryan P. Arant -RUN yum -q -y install deltarpm -RUN yum -q -y install epel-release -RUN yum -q -y update -RUN yum -q -y install unzip libunwind8 libunwind8-dev gettext libcurl-devel openssl-devel zlib libicu-devel liblttng-ust lttng-ust-devel libunwind-devel libuuid-devel automake autoconf libtool -RUN yum install -y http://mirror.symnds.com/distributions/gf/el/7/plus/x86_64/cmake-3.3.2-1.gf.el7.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/clang-3.6.2-1.el7.centos.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/clang-libs-3.6.2-1.el7.centos.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/lldb-3.6.2-1.el7.centos.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/lldb-devel-3.6.2-1.el7.centos.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/llvm-3.6.2-1.el7.centos.x86_64.rpm \ - https://matell.blob.core.windows.net/rpms/llvm-libs-3.6.2-1.el7.centos.x86_64.rpm \ - which \ - make - -RUN yum -q -y install tar git - -RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 -RUN update-alternatives --set c++ /usr/bin/clang++ - -RUN yum -q -y install sudo - -VOLUME /env/cli-bootstrap -WORKDIR /env/cli-bootstrap diff --git a/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh b/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh deleted file mode 100644 index c05da7c8..00000000 --- a/tools/cli-bootstrap/dockerfiles/docker-cleanup.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# Delete all containers -docker rm $(docker ps -a -q) -# Delete all images -docker rmi $(docker images -q) \ No newline at end of file diff --git a/tools/cli-bootstrap/dockerfiles/test-container.sh b/tools/cli-bootstrap/dockerfiles/test-container.sh deleted file mode 100644 index 33e69dc8..00000000 --- a/tools/cli-bootstrap/dockerfiles/test-container.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -# This shell script 'bakes' the docker containers that we depend on. Essentially, it sets up the docker containers in a certain manner where we -# are enabled to run a test case within them. - -# to add a new platform to test on, simply create a directory (named anything that isn't already present) with a dockerfile in it. - -function RunPlatform -{ - SELECTED_CONTAINER=$1 - - echo "running 'cli-bootstrap:${SELECTED_CONTAINER}'" - pushd ../dockerfiles/$dir - - # copy the bootstrap in to place. - - # copy ../../cli.bootstrap.py . - - # this will mount our current directory as the working directory in the docker containers - docker run -v $PWD:/env/cli-bootstrap cli-bootstrap:$name python cli.bootstrap.py -to . # this will generate the src, obj, and bin directory here. - - # copy test cases to this platform - # cp ../testing/* testing - popd -} - -for dir in ../dockerfiles/*/ ; do - echo "$dir" - name=${dir%"/"} - RunPlatform $name -done \ No newline at end of file diff --git a/tools/cli-bootstrap/testing/e2e/Program.cs b/tools/cli-bootstrap/testing/e2e/Program.cs deleted file mode 100644 index 2a685f27..00000000 --- a/tools/cli-bootstrap/testing/e2e/Program.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; - -public static class Program -{ - public static int Main(string[] args) - { - // Draw a dotnet bot. - Bot(QuoteOfTheDay()); - - return 42; // test pass code - } - - public static string QuoteOfTheDay() - { - var quotes = File.ReadAllLines("quotes.txt"); - - return quotes[new Random().Next(0, quotes.Length - 1)]; - } - - - - public static void Bot(string message) - { - var _tempForeground = Console.ForegroundColor; - - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(@" - __________________ - \ - \"); - Console.ForegroundColor = ConsoleColor.Magenta; - Console.WriteLine(@" - .... - ....' - .... - .......... - .............'..'.. - ................'..'..... - .......'..........'..'..'.... - ........'..........'..'..'..... - .'....'..'..........'..'.......'. - .'..................'... ...... - . ......'......... ..... - . ...... - .. . .. ...... - .... . ....... - ...... ....... ............ - ................ ...................... - ........................'................ - ......................'..'...... ....... - .........................'..'..... ....... - ........ ..'.............'..'.... .......... - ..'..'... ...............'....... .......... - ...'...... ...... .......... ...... ....... - ........... ....... ........ ...... - ....... '...'.'. '.'.'.' .... - ....... .....'.. ..'..... - .. .......... ..'........ - ............ .............. - ............. '.............. - ...........'.. .'.'............ - ............... .'.'............. - .............'.. ..'..'........... - ............... .'.............. - ......... .............. - ....."); - - } - - Console.ForegroundColor = _tempForeground; -} \ No newline at end of file diff --git a/tools/cli-bootstrap/testing/e2e/quotes.txt b/tools/cli-bootstrap/testing/e2e/quotes.txt deleted file mode 100644 index 1fc1274f..00000000 --- a/tools/cli-bootstrap/testing/e2e/quotes.txt +++ /dev/null @@ -1,59 +0,0 @@ -We have a strange illusion that mere time cancels sin. But mere time does nothing either to the fact or to the guilt of a sin. -There can be no deep disappointment where there is not deep love. -My therapist told me the way to achieve true inner peace is to finish what I start. So far today, I have finished 2 bags of M&M`s and a chocolate cake. I feel better already. -Half a truth is often a great lie. -The survival of liberty in our land increasingly depends on the success of liberty in other lands. -The Constitution is not an instrument for the government to restrain the people, it is an instrument for the people to restrain the government -- lest it come to dominate our lives and interests. -From the prodigious hilltops of New Hampshire, let freedom ring. From the mighty mountains of New York, let freedom ring. From the heightening Alleghenies of Pennsylvania, let freedom ring. But not only that: Let freedom ring from every hill and molehill of Mississippi. -Without music, life would be a mistake. -Prosperity is the measure or touchstone of virtue, for it is less difficult to bear misfortune than to remain uncorrupted by pleasure. -The more you read about politics, you got to admit that each party is worse than the other. -Just the omission of Jane Austen`s books alone would make a fairly good library out of a library that hadn`t a book in it. -An unexciting truth may be eclipsed by a thrilling lie. -Beware how you take away hope from another human being. -Marriage is a duel to the death which no man of honour should decline. -If liberty and equality, as is thought by some, are chiefly to be found in democracy, they will be best attained when all persons alike share in government to the utmost. -Ignore death up to the last moment; then, when it can`t be ignored any longer, have yourself squirted full of morphia and shuffle off in a coma. Thoroughly sensible, humane and scientific, eh? -A good novel tells us the truth about its hero; but a bad novel tells us the truth about its author. -I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin, but by the content of their character. -Take from the church the miraculous, the supernatural, the incomprehensible, the unreasonable, the impossible, the unknowable, the absurd, and nothing but a vacuum remains. -Power over a man`s subsistence is power over his will. -The puritanism of Christianity has played havoc with the moderation that an enlightened and tolerant critical spirit would have produced. I`ve noticed that in whatever country, county, town, or other region there is a regulation enjoining temperance, the population seems to be entirely composed of teetotallers and drunkards. There`s a Bible on that shelf there. But I keep it next to Voltaire - poison and antidote. -Never pick a fight with people who buy ink by the barrel. -There can be no liberty unless there is economic liberty. -Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment. -If there were no God, there would be no Atheists. -It is impossible to travel faster than the speed of light, and certainly not desirable, as one`s hat keeps blowing off. -God is really only another artist. He invented the giraffe, the elephant and the cat. He has no real style, He just goes on trying other things. -Saturate yourself with your subject and the camera will all but take you by the hand. -Familiarity breeds contempt - and children. -Heaven have mercy on us all--Presbyterians and Pagans alike--for we are all dreadfully cracked about the head and desperately in need of mending. -The difference between Los Angeles and yogurt is that yogurt comes with less fruit. -I`m afraid that if you look at a thing long enough, it loses all of its meaning. -The difference between sex and death is that with death you can do it alone and no one is going to make fun of you. -Money buys you everything except the chance to do it again. -Never worry about the size of your Christmas tree. In the eyes of children, they are all thirty feet tall. -I think, at a child`s birth, if a mother could ask a fairy godmother to endow it with the most useful gift, that gift should be curiosity. -An unexamined life is not worth living. -It`s a phonetic language. Anything can make sense. How do you think Dr. Seuss wrote any of that sh*t? -Make everything as simple as possible, but not simpler. -There are lots of people who mistake their imagination for their memory. -We are what we repeatedly do. Excellence, therefore, is not an act, but a habit. -Wise men argue causes, and fools decide them. -A pint of sweat, saves a gallon of blood. -It ain`t the parts of the Bible that I can`t understand that bother me, it is the parts that I do understand. -A `geek` by definition is someone who eats live animals....I`ve never eaten live animals. -No virtuous act is quite as virtuous from the standpoint of our friend or foe, as from our own. Therefore, we are saved by the final form of love which is forgiveness. -The ladder of success is best climbed by stepping on the rungs of opportunity. -My best friend is the man who in wishing me well wishes it for my sake. -The best way to win an argument is to begin by being right. -Christmas is the gentlest, loveliest festival of the revolving year. And yet, for all that, when it speaks, its voice has strong authority. -Whenever science makes a discovery, the devil grabs it while the angels are debating the best way to use it. -Don`t you wish you had a job like mine? All you have to do is think up a certain number of words! Plus, you can repeat words! And they don`t even have to be true! -When angry, count ten before you speak; if very angry, a hundred. -People have a way of becoming what you encourage them to be, not what you nag them to be. -A man never tells you anything until you contradict him. -There are very few monsters who warrant the fear we have of them. -Perspective is worth 80 IQ Points - Alan Kay -The best way to predict the future is to invent it. - Alan Kay -The Internet was done so well that most people think of it as a natural resource like the Pacific Ocean, rather than something that was man-made. When was the last time a technology with a scale like that was so error-free? The Web, in comparison, is a joke. The Web was done by amateurs. - Alan Kay \ No newline at end of file From c95654b72e193d70fe8184167a86f2cc989650ff Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Nov 2016 23:47:01 +0000 Subject: [PATCH 09/12] testing ci --- .gitignore | 1 + netci.groovy | 8 ++++---- tools/dotnet-bootstrap/base/lab/shellcall.pyc | Bin 1150 -> 0 bytes 3 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 tools/dotnet-bootstrap/base/lab/shellcall.pyc diff --git a/.gitignore b/.gitignore index d38d4c72..ba9ed9d4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ bin/ obj/ project.lock.json .DS_Store +*.pyc \ No newline at end of file diff --git a/netci.groovy b/netci.groovy index 426cb02e..c830db4c 100644 --- a/netci.groovy +++ b/netci.groovy @@ -16,9 +16,6 @@ def branch = GithubBranchName // is a boolean indicating whether the job will be a PR job. If true, the // suffix _prtest will be appended. def newJobName = Utilities.getFullJobName(project, configuration, isPR) - - // Define build string - def buildString = """echo Configuration: ${configuration} isPR: ${isPR}""" // Create a new job with the specified name. The brace opens a new closure // and calls made within that closure apply to the newly created job. @@ -28,7 +25,10 @@ def branch = GithubBranchName // Indicates that a batch script should be run with the build string (see above) // Also available is: // shell (for unix scripting) - shell(buildString) + shell("ls") + + shell("python tools/dotnet-bootstrap/base/lab/containers.py bake") + shell("python tools/dotnet-bootstrap/base/lab/cases.py run") } } diff --git a/tools/dotnet-bootstrap/base/lab/shellcall.pyc b/tools/dotnet-bootstrap/base/lab/shellcall.pyc deleted file mode 100644 index 2cbbc77369a762c2c25520512f2d1e98e3e805eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb_bO>Yx15FLBBX|io8R8XV}q^+u=sHok0g%A>|;D9RFBDKmT+N|BK(~Z5d9nwn4 zsoeQ3T=_X%kht;#V8&_7$C*t$nHf)>-@NfgKUR{R?^`D&Tt6ItU*K|Y&xj;VGOLodddfmnc#40 z>Uy4A!`w@ZqEu4BP|o07C{>05b*};Bo^z zhiT}-Ma|F& z4?g7-63jA)rGTs%oFMp7cNu#f&P{oOG8#fsevwvEsdTiycm5nufuJWY# z#N9``wV92b%?3(mQh!JXg{u-r+lfL0ZV63Ujf_a2UZmU3buli|03^nxS4O9E>#T#0}P1iBL+K1kL*LLiunLa}qMA zGXh5FuP+K;_&b=Jho`ERx)@1+?=~gy5Ty%};gA1OA?XCcxC8XEk@i`c<+3p@6UJ+a zp|LXa#?&{N-GMRQd0R9Y&Ov5%G04JLiSS-?={tyYM02K>f*89;Xn?iYDv#I(Uqx>% zT4O1$$598f-9_BbNz1^`jR$xG=uHZu{-fog(K4q?@tger?x2n6&+s;lYx$h0IZ7 Date: Mon, 21 Nov 2016 00:34:47 +0000 Subject: [PATCH 10/12] adjusting working directory --- tools/dotnet-bootstrap/base/lab/cases.py | 12 ++++++------ tools/dotnet-bootstrap/base/lab/containers.py | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/dotnet-bootstrap/base/lab/cases.py b/tools/dotnet-bootstrap/base/lab/cases.py index f2d42975..3e6f74bc 100755 --- a/tools/dotnet-bootstrap/base/lab/cases.py +++ b/tools/dotnet-bootstrap/base/lab/cases.py @@ -6,16 +6,16 @@ from shellcall import ShellCall from shellcall import ContinueOnError from sys import argv from os import getcwd -from os.path import join -from os.path import exists + +from os.path import join, exists, dirname, realpath from globals import g_override # interface + data binding for managing the testcases. class Cases: - # TODO: use script directory instead of cwd, and require the containers directory to be local to the script - _supported_containers = join(getcwd(), 'containers/') # our 'list' of current supported platforms are the directories in this directory - _testcases = join(getcwd(), 'cases/') + _labPath = dirname(realpath(__file__)) + _supported_containers = join(_labPath, 'containers/') # our 'list' of current supported platforms are the directories in this directory + _testcases = join(_labPath, 'cases/') _continueOnError = True _lenient = True @@ -38,7 +38,7 @@ class Cases: ShellCall("echo \"running 'dotnet-bootstrap:%s - testcase: %s'\""%(container_name, casename), lenient = self._lenient) # copy the bootstrap and test source in to the container working directory (next to the Dockerfile) - ShellCall('cp ../../dotnet.bootstrap.py %s'%(join(self._supported_containers, container_name)), lenient = self._lenient) + ShellCall('cp %s %s'%(join(self._labPath, '../../dotnet.bootstrap.py'), join(self._supported_containers, container_name)), lenient = self._lenient) ShellCall('mkdir -p %s'%(join(testing_destination, casename)), lenient=self._lenient) ShellCall('cp -R %s %s'%(join(self._testcases, casename), join(testing_destination, casename)), lenient = self._lenient) diff --git a/tools/dotnet-bootstrap/base/lab/containers.py b/tools/dotnet-bootstrap/base/lab/containers.py index 2afff3b1..7b52a276 100755 --- a/tools/dotnet-bootstrap/base/lab/containers.py +++ b/tools/dotnet-bootstrap/base/lab/containers.py @@ -12,13 +12,15 @@ import os from sys import argv from os.path import join +from os.path import dirname +from os.path import realpath from os import getcwd from globals import g_override # interface + data binding for managing the containers. class Containers: - _supported_platforms = join(getcwd(), 'containers') + '/' # our 'list' of current supported platforms are the directories in this directory + _supported_platforms = join(dirname(realpath(__file__)), 'containers') + '/' # our 'list' of current supported platforms are the directories in this directory def Bake(self, selected_platform): ShellCall("echo baking 'dotnet-bootstrap:%s'"%(selected_platform), lenient=True) From ee1715e8ca7419c48aa2e71a3f90ac513ac075a1 Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Mon, 28 Nov 2016 14:11:02 -0800 Subject: [PATCH 11/12] accidental checkin of bootstrap --- tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup | 1 - tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr | 1 - tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx | 1 - tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv | 1 - 4 files changed, 4 deletions(-) delete mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup delete mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr delete mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx delete mode 160000 tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv diff --git a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup b/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup deleted file mode 160000 index cee57bf6..00000000 --- a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/core-setup +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cee57bf6c981237d80aa1631cfe83cb9ba329f12 diff --git a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr b/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr deleted file mode 160000 index 51131a5a..00000000 --- a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/coreclr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 51131a5a2af24783044c43a60f1052fc35196076 diff --git a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx b/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx deleted file mode 160000 index 9688ddbb..00000000 --- a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/corefx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9688ddbb62c04189cac4c4a06e31e93377dccd41 diff --git a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv b/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv deleted file mode 160000 index 229b3a4c..00000000 --- a/tools/dotnet-bootstrap/ubuntu.14.04-x64-dotnet/src/libuv +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 229b3a4cc150aebd6561e6bd43076eafa7a03756 From 01b5f4a4ba6a2d42abb820ef566a21543ee3dc3f Mon Sep 17 00:00:00 2001 From: Bryan Arant Date: Mon, 28 Nov 2016 14:26:51 -0800 Subject: [PATCH 12/12] do not keep retrieving the patch target --- tools/dotnet-bootstrap/dotnet.bootstrap.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/dotnet-bootstrap/dotnet.bootstrap.py b/tools/dotnet-bootstrap/dotnet.bootstrap.py index 65029f06..92749bc0 100755 --- a/tools/dotnet-bootstrap/dotnet.bootstrap.py +++ b/tools/dotnet-bootstrap/dotnet.bootstrap.py @@ -321,14 +321,13 @@ def SpawnPatchTarget(destination_folder, payload_path): destination_folder = path.join(RoverSettings._LaunchedFromDirectory, destination_folder) if not path.exists(str(payload_path)): - fallback_url = 'https://dotnetcli.blob.core.windows.net/dotnet/Sdk/rel-1.0.0/dotnet-dev-debian-x64.latest.tar.gz' - RoverPrint('could not locate a payload at path: \'%s\' so I am going to download the latest dotnet CLI from %s'%(payload_path, fallback_url)) + fallback_url = 'https://dotnetcli.blob.core.windows.net/dotnet/Sdk/rel-1.0.0/dotnet-dev-debian-x64.latest.tar.gz' - payload_filename = 'dotnet-dev-debian-x64.latest.tar.gz' - - RoverPrint(RoverMods.Blue('is downloading latest .NET CLI for bootstrapping (%s)'%(payload_filename))) - - payload_path = path.join(RoverSettings._objDirectory, 'dotnet-dev-debian-x64.latest.tar.gz') + payload_filename = 'dotnet.latest.tar.gz' + payload_path = path.join(RoverSettings._objDirectory, payload_filename) + + if not path.exists(payload_path): + RoverPrint(RoverMods.Blue('is downloading latest .NET CLI for bootstrapping (%s)'%(payload_filename))) urlretrieve(fallback_url, payload_path)