Merge pull request #48 from graemechristie/KvmShellImplementation
Kvm shell implementation
This commit is contained in:
commit
9851adabc0
27
README.md
27
README.md
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
Loading…
Reference in New Issue