Merge pull request #48 from graemechristie/KvmShellImplementation

Kvm shell implementation
This commit is contained in:
David Fowler 2014-06-05 00:25:15 +02:00
commit 9851adabc0
3 changed files with 445 additions and 7 deletions

View File

@ -13,25 +13,35 @@ The samples provided are designed to show some of the features of the new framew
These are the current minimum requirements, they do not necesarilly represent our RTM minimum.
### Windows
* Windows 7 or greater, though Core CLR will only work on Windows 8 today. If using Core CLR you will need to be on Windows 8 or above. At RTM the whole stack will support Windows 7+ and Windows Server 2008 R2+.
* .NET 4.5.1 for hosting in IIS
* Powershell 4. KVM is a Powershell script that makes use of types that older verisons of Powershell cannot load
# Getting Started
### OSX/Linux
* Mono >= 3.4.1 - Currently this means compiling Mono from source from https://github.com/mono/mono
* On Linux, you may need to run `mozroots --import --sync` after installing mono
* bash or zsh and curl
#Getting Started
The first thing we need to do is setup the tools required to build and run an application. We will start out by getting the [K Version Manager (KVM)](https://github.com/aspnet/Home/wiki/version-manager)
* Clone the repository
* On the command line execute ```kvmsetup.cmd```
* On the command line execute
* ```kvmsetup.cmd``` on Windows or
* ```sh kvmsetup.sh && source ~/.kre/kvm/kvm.sh``` on OSX/Linux
* This command will setup your environment, getting it ready to install a version of the runtime. It adds kvm to your path and puts it in your user profile.
* Execute ```kvm install 0.1-alpha-build-0446```. This command will download the named version of the KRE and put it on your user profile ready to use. You can get the latest version by running ```kvm upgrade``` but 0446 was the last version explicitly tested. see the [KVM page](https://github.com/aspnet/Home/wiki/version-manager) for more information on KVM.
* Navigate to samples\ConsoleApp
* Run ```kpm restore```. This downloads the System.Console package so the app can do Console.WriteLine
* Run ```K run```
* Run ```k run```
* You should see a message saying "Hello World"
* Type ```SET KRE_TRACE=1```
* Run ```K run```
* Type
* ```SET KRE_TRACE=1``` on Windows or
* ```export KRE_TRACE=1``` on OSX/Linux
* Run ```k run```
* You should now see compiler output as well as the "Hello World" message
```
@ -86,6 +96,7 @@ If you can do all of the above then everything should be working. You can try ou
# Switching to Core CLR
By default when running the applications you are running against Desktop CLR (4.5), you can change that using the KVM command.
1. Run ```kvm install 0.1-alpha-build-0446 -svrc50``` This command gets the latest Core CLR version of the k runtime and sets it as your default. The -svrc50 switch tells it to use Core CLR, you can use -svr50 to target desktop again.
@ -95,7 +106,9 @@ By default when running the applications you are running against Desktop CLR (4.
**NOTE: There are going to be parts of the stack that work on Desktop but do not work on Core CLR. This set should get smaller and smaller as time goes on, but it is entirely likely as you use Core CLR you will hit errors that can't be worked around as the Core CLR surface area just does not exist yet.**
# Core CLR Packages
**NOTE: There is no Core CLR currently on OSX/Linux. There is only a single platform (mono45) and a single architecture (x86).**
#Core CLR Packages
Currently the BCL is split into some fairly fine grained packages, which was one of the goals of this effort. However, the packages that exist today do not necessarily represent the list of packages that we will end up with. We are still experimenting with what makes sense to be a package and what the experience should be.

337
kvm.sh Normal file
View File

@ -0,0 +1,337 @@
# kvm.sh
# Source this file from your .bash-profile or script to use
_kvm_has() {
type "$1" > /dev/null 2>&1
return $?
}
if _kvm_has "unsetopt"; then
unsetopt nomatch 2>/dev/null
fi
if [ -z "$KRE_USER_HOME" ]; then
eval KRE_USER_HOME=~/.kre
fi
KRE_USER_PACKAGES="$KRE_USER_HOME/packages"
KRE_MONO45=
KRE_X86=
KRE_X64=
KRE_NUGET_API_URL="https://www.myget.org/F/aspnetvnext/api/v2"
_kvm_find_latest() {
local platform="mono45"
local architecture="x86"
if ! _kvm_has "curl"; then
echo 'KVM Needs curl to proceed.' >&2;
return 1
fi
local url="$KRE_NUGET_API_URL/GetUpdates()?packageIds=%27KRE-$platform-$architecture%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false"
local cmd=
local xml="$(curl $url 2>/dev/null)"
version="$(echo $xml | sed 's/.*<[a-zA-Z]:Version>\([^<]*\).*/\1/')"
[[ $xml == $version ]] && return 1
echo $version
}
_kvm_strip_path() {
echo "$1" | sed -e "s#$KRE_USER_PACKAGES/[^/]*$2[^:]*:##g" -e "s#:$KRE_USER_PACKAGES/[^/]*$2[^:]*##g" -e "s#$KRE_USER_PACKAGES/[^/]*$2[^:]*##g"
}
_kvm_prepend_path() {
if [ -z "$1" ]; then
echo "$2"
else
echo "$2:$1"
fi
}
_kvm_download() {
local kreFullName="$1"
local kreFolder="$2"
local pkgName=$(echo "$kreFullName" | sed "s/\([^.]*\).*/\1/")
local pkgVersion=$(echo "$kreFullName" | sed "s/[^.]*.\(.*\)/\1/")
local url="$KRE_NUGET_API_URL/package/$pkgName/$pkgVersion"
local kreFile="$kreFolder/$kreFullName.nupkg"
if [ -e "$kreFolder" ]; then
echo "$kreFullName already installed."
return 0
fi
echo "Downloading $kreFullName from $KRE_NUGET_API_URL"
if ! _kvm_has "curl"; then
echo "KVM Needs curl to proceed." >&2;
return 1
fi
mkdir -p "$kreFolder" > /dev/null 2>&1
local httpResult=$(curl -L -D - -u aspnetreadonly:4d8a2d9c-7b80-4162-9978-47e918c9658c "$url" -o "$kreFile" 2>/dev/null | grep "^HTTP/1.1" | head -n 1 | sed "s/HTTP.1.1 \([0-9]*\).*/\1/")
[[ $httpResult == "404" ]] && echo "$kreFullName was not found in repository $KRE_NUGET_API_URL" && return 1
[[ $httpResult != "302" ]] && echo "Http Error $httpResult fetching $kreFullName from $KRE_NUGET_API_URL" && return 1
_kvm_unpack $kreFile $kreFolder
}
_kvm_unpack() {
local kreFile="$1"
local kreFolder="$2"
echo "Installing to $kreFolder"
if ! _kvm_has "unzip"; then
echo "KVM Needs unzip to proceed." >&2;
return 1
fi
unzip $kreFile -d $kreFolder > /dev/null 2>&1
[ -e "$kreFolder/[Content_Types].xml" ] && rm "$kreFolder/[Content_Types].xml"
[ -e "$kreFolder/_rels/" ] && rm -rf "$kreFolder/_rels/"
[ -e "$kreFolder/package/" ] && rm -rf "$kreFolder/_package/"
#Set shell commands as executable
find "$kreFolder/bin/" -type f \
-exec sh -c "head -c 11 {} | grep '/bin/bash' > /dev/null" \; -print | xargs chmod 775
}
# This is not currently required. Placeholder for the case when we have multiple platforms (ie if we bundle mono)
_kvm_requested_platform() {
local default=$1
[[ -z $KRE_MONO45 ]] && echo "mono45" && return
echo $default
}
# This is not currently required. Placeholder for the case where we have multiple architectures (ie if we bundle mono)
_kvm_requested_architecture() {
local default=$1
[[ -n $KRE_X86 && -n $KRE_X64 ]] && echo "This command cannot accept both -x86 and -x64" && return 1
[[ -z $KRE_X86 ]] && echo "x86" && return
[[ -z $KRE_X64 ]] && echo "x64" && return
echo $default
}
_kvm_requested_version_or_alias() {
local versionOrAlias="$1"
if [ -e "$KRE_USER_HOME/alias/$versionOrAlias.alias" ]; then
local kreFullName=$(cat "$KRE_USER_HOME/alias/$versionOrAlias.alias")
local pkgName=$(echo $kreFullName | sed "s/\([^.]*\).*/\1/")
local pkgVersion=$(echo $kreFullName | sed "s/[^.]*.\(.*\)/\1/")
local pkgPlatform=$(_kvm_requested_platform $(echo "$pkgName" | sed "s/KRE-\([^-]*\).*/\1/"))
local pkgArchitecture=$(_kvm_requested_architecture $(echo "$pkgName" | sed "s/.*-.*-\([^-]*\).*/\1/"))
else
local pkgVersion=$versionOrAlias
local pkgPlatform=$(_kvm_requested_platform "mono45")
local pkgArchitecture=$(_kvm_requested_architecture "x86")
fi
echo "KRE-$pkgPlatform-$pkgArchitecture.$pkgVersion"
}
# This will be more relevant if we support global installs
_kvm_locate_kre_bin_from_full_name() {
local kreFullName=$1
[ -e "$KRE_USER_PACKAGES/$kreFullName/bin" ] && echo "$KRE_USER_PACKAGES/$kreFullName/bin" && return
}
kvm()
{
if [ $# -lt 1 ]; then
kvm help
return
fi
case $1 in
"help" )
echo ""
echo "K Runtime Environment Version Manager - Build {{BUILD_NUMBER}}"
echo ""
echo "USAGE: kvm <command> [options]"
echo ""
echo "kvm upgrade"
echo "install latest KRE from feed"
echo "set 'default' alias to installed version"
echo "add KRE bin to user PATH environment variable persistently"
echo ""
echo "kvm install <semver>|<alias>|<nupkg>"
echo "install requested KRE from feed"
echo "add KRE bin to path of current command line"
echo ""
echo "kvm use <semver>|<alias>|none [-p -persistent]"
echo "<semver>|<alias> add KRE bin to path of current command line "
echo "none remove KRE bin from path of current command line"
echo "-p -persistent set selected version as default"
echo ""
echo "kvm list"
echo "list KRE versions installed "
echo ""
echo "kvm alias"
echo "list KRE aliases which have been defined"
echo ""
echo "kvm alias <alias>"
echo "display value of named alias"
echo ""
echo "kvm alias <alias> <semver>"
echo "set alias to specific version"
echo ""
echo ""
;;
"upgrade" )
[ $# -ne 1 ] && kvm help && return
echo "Determining latest version"
local version=$(_kvm_find_latest mono45 x86)
echo $version
kvm install $version
kvm alias default $version
;;
"install" )
[ $# -ne 2 ] && kvm help && return
local versionOrAlias="$2"
if [ "$versionOrAlias" == *.nupkg ]; then
local kreFullName=$(echo $versionOrAlias | sed "s/\(.*\)\.nupkg/\1/")
local kreFolder="$KRE_USER_PACKAGES/$kreFullName"
local kreFile="$kreFolder/$kreFullName.nupkg"
if [ -e "$kreFolder" ]; then
echo "Target folder '$kreFolder' already exists"
else
mkdir "$kreFolder" > /dev/null 2>&1
cp -a "$versionOrAlias" "$kreFile"
_kvm_unpack "$kreFile" "$kreFolder"
fi
echo "Adding $kreBin to current PATH"
PATH=$(_kvm_strip_path "$PATH" "/bin")
PATH=(_kvm_prepend_path "$PATH" "$kreBin")
else
local kreFullName="$(_kvm_requested_version_or_alias $versionOrAlias)"
local kreFolder="$KRE_USER_PACKAGES/$kreFullName"
_kvm_download "$kreFullName" "$kreFolder"
kvm use "$versionOrAlias"
fi
;;
"use" )
[ $# -gt 3 ] && kvm help && return
[ $# -lt 2 ] && kvm help && return
shift
local persistant=
while [ $# -ne 0 ]
do
if [[ $1 == "-p" || $1 == "-persistant" ]]; then
local persistant="true"
else
local versionOrAlias=$1
fi
shift
done
if [[ $versionOrAlias == "none" ]]; then
echo "Removing KRE from process PATH"
# Strip other version from PATH
PATH=`_kvm_strip_path "$PATH" "/bin"`
if [[ -n $persistent && -e "$KRE_USER_HOME/alias/default.alias" ]]; then
echo "Setting default KRE to none"
rm "$KRE_USER_HOME/alias/default.alias"
fi
return 0
fi
local kreFullName=$(_kvm_requested_version_or_alias "$versionOrAlias")
local kreBin=$(_kvm_locate_kre_bin_from_full_name "$kreFullName")
if [[ -z $kreBin ]]; then
echo "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?"
return 1
fi
echo "Adding" $kreBin "to process PATH"
PATH=`_kvm_strip_path "$PATH" "/bin"`
PATH=`_kvm_prepend_path "$PATH" "$kreBin"`
if [[ -n $persistent ]]; then
echo "Setting $kreBin as default KRE"
kvm alias default "$versionOrAlias"
fi
;;
"alias" )
[[ $# -gt 3 ]] && kvm help && return
if [[ $# == 1 ]]; then
for f in $(find "$KRE_USER_HOME/alias" -name *.alias); do printf "%-20s %s\n" "$(basename $f | sed 's/.alias//')" "$(cat $f)"; done
echo ""
return
fi
local name="$2"
if [[ $# == 2 ]]; then
[[ ! -e "$KRE_USER_HOME/alias/$name.alias" ]] && echo "There is no alias called '$name'" && return
cat "$KRE_USER_HOME/alias/$name.alias"
echo ""
return
fi
local semver="$3"
local kreFullName="KRE-$(_kvm_requested_platform mono45)-$(_kvm_requested_architecture x86).$semver"
[[ ! -d "$KRE_USER_PACKAGES/$kreFullName" ]] && echo "$semver is not an installed KRE version." && return 1
echo "Setting alias '$name' to '$kreFullName'"
[[ ! -e "$KRE_USER_HOME/alias/" ]] && mkdir "$KRE_USER_HOME/alias/" > /dev/null
echo "$kreFullName" > "$KRE_USER_HOME/alias/$name.alias"
;;
"list" )
[[ $# -gt 2 ]] && kvm help && return
[[ ! -d $KRE_USER_PACKAGES ]] && echo "KRE is not installed." && return 1
local searchGlob="KRE-*"
if [ $# == 2 ]; then
local versionOrAlias=$2
local searchGlob=$(_kvm_requested_version_or_alias "$versionOrAlias")
echo $searchGlob
fi
for f in $(find $KRE_USER_PACKAGES/* -name $searchGlob -type d -prune -exec basename {} \;); do
#TODO: Format, extract package, version arch etc
echo -n $f
if [[ $PATH == *"$KRE_USER_PACKAGES/$f/bin"* ]]; then
echo " *"
else
echo ""
fi
[[ $# == 2 ]] && echo "" && return 0
done
echo ""
[[ $# == 2 ]] && return 1 # kvm list xxx - xxx was not found
;;
*)
echo "Unknown command $1"
return 1
esac
}
kvm list default >/dev/null && kvm use default >/dev/null || true

88
kvmsetup.sh Normal file
View File

@ -0,0 +1,88 @@
#!/bin/bash
_kvmsetup_has() {
type "$1" > /dev/null 2>&1
return $?
}
_kvmsetup_update_profile() {
local profile="$1"
local sourceString="$2"
if ! grep -qc 'kvm.sh' $profile; then
echo "Appending source string to $profile"
echo "" >> "$profile"
echo $sourceString >> "$profile"
else
echo "=> Source string already in $profile"
fi
}
if [ -z "$KRE_USER_HOME" ]; then
eval KRE_USER_HOME=~/.kre
fi
if ! _kvmsetup_has "curl"; then
echo "kvmsetup requires curl to be installed"
return 1
fi
if [ -z "$KVM_SOURCE" ]; then
KVM_SOURCE="https://raw.githubusercontent.com/graemechristie/Home/KvmShellImplementation/kvm.sh"
fi
# Downloading to $KVM_DIR
mkdir -p "$KRE_USER_HOME/kvm"
if [ -s "$KRE_USER_HOME/kvm/kvm.sh" ]; then
echo "kvm is already installed in $KRE_USER_HOME/kvm, trying to update"
else
echo "Downloading kvm as script to '$KRE_USER_HOME/kvm'"
fi
curl -s "$KVM_SOURCE" -o "$KRE_USER_HOME/kvm/kvm.sh" || {
echo >&2 "Failed to download '$KVM_SOURCE'.."
return 1
}
echo
# Detect profile file if not specified as environment variable (eg: PROFILE=~/.myprofile).
if [ -z "$PROFILE" ]; then
if [ -f "$HOME/.bash_profile" ]; then
PROFILE="$HOME/.bash_profile"
elif [ -f "$HOME/.bashrc" ]; then
PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.profile" ]; then
PROFILE="$HOME/.profile"
fi
fi
if [ -z "$ZPROFILE" ]; then
if [ -f "$HOME/.zshrc" ]; then
ZPROFILE="$HOME/.zshrc"
fi
fi
SOURCE_STR="[ -s \"$KRE_USER_HOME/kvm/kvm.sh\" ] && . \"$KRE_USER_HOME/kvm/kvm.sh\" # Load kvm"
if [ -z "$PROFILE" -a -z "$ZPROFILE" ] || [ ! -f "$PROFILE" -a ! -f "$ZPROFILE" ] ; then
if [ -z "$PROFILE" ]; then
echo "Profile not found. Tried ~/.bash_profile ~/.zshrc and ~/.profile."
echo "Create one of them and run this script again"
elif [ ! -f "$PROFILE" ]; then
echo "Profile $PROFILE not found"
echo "Create it (touch $PROFILE) and run this script again"
else
echo "Profile $ZPROFILE not found"
echo "Create it (touch $ZPROFILE) and run this script again"
fi
echo " OR"
echo "Append the following line to the correct file yourself:"
echo
echo " $SOURCE_STR"
echo
else
[ -n "$PROFILE" ] && _kvmsetup_update_profile "$PROFILE" "$SOURCE_STR"
[ -n "$ZPROFILE" ] && _kvmsetup_update_profile "$ZPROFILE" "$SOURCE_STR"
fi
echo "Type 'source $KRE_USER_HOME/kvm/kvm.sh' to start using kvm"