Skip to content

Commit 9851ada

Browse files
committed
Merge pull request dotnet#48 from graemechristie/KvmShellImplementation
Kvm shell implementation
2 parents d2a4f7b + 3bec520 commit 9851ada

File tree

3 files changed

+445
-7
lines changed

3 files changed

+445
-7
lines changed

README.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,35 @@ The samples provided are designed to show some of the features of the new framew
1313

1414
These are the current minimum requirements, they do not necesarilly represent our RTM minimum.
1515

16+
### Windows
1617
* 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+.
1718
* .NET 4.5.1 for hosting in IIS
1819
* Powershell 4. KVM is a Powershell script that makes use of types that older verisons of Powershell cannot load
1920

20-
21-
# Getting Started
21+
22+
### OSX/Linux
23+
* Mono >= 3.4.1 - Currently this means compiling Mono from source from https://github.com/mono/mono
24+
* On Linux, you may need to run `mozroots --import --sync` after installing mono
25+
* bash or zsh and curl
26+
27+
#Getting Started
2228

2329
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)
2430

2531
* Clone the repository
26-
* On the command line execute ```kvmsetup.cmd```
32+
* On the command line execute
33+
* ```kvmsetup.cmd``` on Windows or
34+
* ```sh kvmsetup.sh && source ~/.kre/kvm/kvm.sh``` on OSX/Linux
2735
* 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.
2836
* 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.
2937
* Navigate to samples\ConsoleApp
3038
* Run ```kpm restore```. This downloads the System.Console package so the app can do Console.WriteLine
31-
* Run ```K run```
39+
* Run ```k run```
3240
* You should see a message saying "Hello World"
33-
* Type ```SET KRE_TRACE=1```
34-
* Run ```K run```
41+
* Type
42+
* ```SET KRE_TRACE=1``` on Windows or
43+
* ```export KRE_TRACE=1``` on OSX/Linux
44+
* Run ```k run```
3545
* You should now see compiler output as well as the "Hello World" message
3646

3747
```
@@ -86,6 +96,7 @@ If you can do all of the above then everything should be working. You can try ou
8696

8797
# Switching to Core CLR
8898

99+
89100
By default when running the applications you are running against Desktop CLR (4.5), you can change that using the KVM command.
90101

91102
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.
95106

96107
**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.**
97108

98-
# Core CLR Packages
109+
**NOTE: There is no Core CLR currently on OSX/Linux. There is only a single platform (mono45) and a single architecture (x86).**
110+
111+
#Core CLR Packages
99112

100113
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.
101114

kvm.sh

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
# kvm.sh
2+
# Source this file from your .bash-profile or script to use
3+
_kvm_has() {
4+
type "$1" > /dev/null 2>&1
5+
return $?
6+
}
7+
8+
if _kvm_has "unsetopt"; then
9+
unsetopt nomatch 2>/dev/null
10+
fi
11+
12+
if [ -z "$KRE_USER_HOME" ]; then
13+
eval KRE_USER_HOME=~/.kre
14+
fi
15+
16+
KRE_USER_PACKAGES="$KRE_USER_HOME/packages"
17+
KRE_MONO45=
18+
KRE_X86=
19+
KRE_X64=
20+
KRE_NUGET_API_URL="https://www.myget.org/F/aspnetvnext/api/v2"
21+
22+
_kvm_find_latest() {
23+
local platform="mono45"
24+
local architecture="x86"
25+
26+
if ! _kvm_has "curl"; then
27+
echo 'KVM Needs curl to proceed.' >&2;
28+
return 1
29+
fi
30+
31+
local url="$KRE_NUGET_API_URL/GetUpdates()?packageIds=%27KRE-$platform-$architecture%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false"
32+
local cmd=
33+
local xml="$(curl $url 2>/dev/null)"
34+
version="$(echo $xml | sed 's/.*<[a-zA-Z]:Version>\([^<]*\).*/\1/')"
35+
[[ $xml == $version ]] && return 1
36+
echo $version
37+
}
38+
39+
_kvm_strip_path() {
40+
echo "$1" | sed -e "s#$KRE_USER_PACKAGES/[^/]*$2[^:]*:##g" -e "s#:$KRE_USER_PACKAGES/[^/]*$2[^:]*##g" -e "s#$KRE_USER_PACKAGES/[^/]*$2[^:]*##g"
41+
}
42+
43+
_kvm_prepend_path() {
44+
if [ -z "$1" ]; then
45+
echo "$2"
46+
else
47+
echo "$2:$1"
48+
fi
49+
}
50+
51+
_kvm_download() {
52+
local kreFullName="$1"
53+
local kreFolder="$2"
54+
55+
local pkgName=$(echo "$kreFullName" | sed "s/\([^.]*\).*/\1/")
56+
local pkgVersion=$(echo "$kreFullName" | sed "s/[^.]*.\(.*\)/\1/")
57+
local url="$KRE_NUGET_API_URL/package/$pkgName/$pkgVersion"
58+
local kreFile="$kreFolder/$kreFullName.nupkg"
59+
60+
if [ -e "$kreFolder" ]; then
61+
echo "$kreFullName already installed."
62+
return 0
63+
fi
64+
65+
echo "Downloading $kreFullName from $KRE_NUGET_API_URL"
66+
67+
if ! _kvm_has "curl"; then
68+
echo "KVM Needs curl to proceed." >&2;
69+
return 1
70+
fi
71+
72+
mkdir -p "$kreFolder" > /dev/null 2>&1
73+
74+
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/")
75+
76+
[[ $httpResult == "404" ]] && echo "$kreFullName was not found in repository $KRE_NUGET_API_URL" && return 1
77+
[[ $httpResult != "302" ]] && echo "Http Error $httpResult fetching $kreFullName from $KRE_NUGET_API_URL" && return 1
78+
79+
_kvm_unpack $kreFile $kreFolder
80+
}
81+
82+
_kvm_unpack() {
83+
local kreFile="$1"
84+
local kreFolder="$2"
85+
86+
echo "Installing to $kreFolder"
87+
88+
if ! _kvm_has "unzip"; then
89+
echo "KVM Needs unzip to proceed." >&2;
90+
return 1
91+
fi
92+
93+
unzip $kreFile -d $kreFolder > /dev/null 2>&1
94+
95+
[ -e "$kreFolder/[Content_Types].xml" ] && rm "$kreFolder/[Content_Types].xml"
96+
97+
[ -e "$kreFolder/_rels/" ] && rm -rf "$kreFolder/_rels/"
98+
99+
[ -e "$kreFolder/package/" ] && rm -rf "$kreFolder/_package/"
100+
101+
#Set shell commands as executable
102+
find "$kreFolder/bin/" -type f \
103+
-exec sh -c "head -c 11 {} | grep '/bin/bash' > /dev/null" \; -print | xargs chmod 775
104+
}
105+
106+
# This is not currently required. Placeholder for the case when we have multiple platforms (ie if we bundle mono)
107+
_kvm_requested_platform() {
108+
local default=$1
109+
[[ -z $KRE_MONO45 ]] && echo "mono45" && return
110+
echo $default
111+
}
112+
113+
# This is not currently required. Placeholder for the case where we have multiple architectures (ie if we bundle mono)
114+
_kvm_requested_architecture() {
115+
local default=$1
116+
117+
[[ -n $KRE_X86 && -n $KRE_X64 ]] && echo "This command cannot accept both -x86 and -x64" && return 1
118+
[[ -z $KRE_X86 ]] && echo "x86" && return
119+
[[ -z $KRE_X64 ]] && echo "x64" && return
120+
echo $default
121+
}
122+
123+
_kvm_requested_version_or_alias() {
124+
local versionOrAlias="$1"
125+
126+
if [ -e "$KRE_USER_HOME/alias/$versionOrAlias.alias" ]; then
127+
local kreFullName=$(cat "$KRE_USER_HOME/alias/$versionOrAlias.alias")
128+
local pkgName=$(echo $kreFullName | sed "s/\([^.]*\).*/\1/")
129+
local pkgVersion=$(echo $kreFullName | sed "s/[^.]*.\(.*\)/\1/")
130+
local pkgPlatform=$(_kvm_requested_platform $(echo "$pkgName" | sed "s/KRE-\([^-]*\).*/\1/"))
131+
local pkgArchitecture=$(_kvm_requested_architecture $(echo "$pkgName" | sed "s/.*-.*-\([^-]*\).*/\1/"))
132+
else
133+
local pkgVersion=$versionOrAlias
134+
local pkgPlatform=$(_kvm_requested_platform "mono45")
135+
local pkgArchitecture=$(_kvm_requested_architecture "x86")
136+
fi
137+
echo "KRE-$pkgPlatform-$pkgArchitecture.$pkgVersion"
138+
}
139+
140+
# This will be more relevant if we support global installs
141+
_kvm_locate_kre_bin_from_full_name() {
142+
local kreFullName=$1
143+
[ -e "$KRE_USER_PACKAGES/$kreFullName/bin" ] && echo "$KRE_USER_PACKAGES/$kreFullName/bin" && return
144+
}
145+
146+
kvm()
147+
{
148+
if [ $# -lt 1 ]; then
149+
kvm help
150+
return
151+
fi
152+
153+
case $1 in
154+
"help" )
155+
echo ""
156+
echo "K Runtime Environment Version Manager - Build {{BUILD_NUMBER}}"
157+
echo ""
158+
echo "USAGE: kvm <command> [options]"
159+
echo ""
160+
echo "kvm upgrade"
161+
echo "install latest KRE from feed"
162+
echo "set 'default' alias to installed version"
163+
echo "add KRE bin to user PATH environment variable persistently"
164+
echo ""
165+
echo "kvm install <semver>|<alias>|<nupkg>"
166+
echo "install requested KRE from feed"
167+
echo "add KRE bin to path of current command line"
168+
echo ""
169+
echo "kvm use <semver>|<alias>|none [-p -persistent]"
170+
echo "<semver>|<alias> add KRE bin to path of current command line "
171+
echo "none remove KRE bin from path of current command line"
172+
echo "-p -persistent set selected version as default"
173+
echo ""
174+
echo "kvm list"
175+
echo "list KRE versions installed "
176+
echo ""
177+
echo "kvm alias"
178+
echo "list KRE aliases which have been defined"
179+
echo ""
180+
echo "kvm alias <alias>"
181+
echo "display value of named alias"
182+
echo ""
183+
echo "kvm alias <alias> <semver>"
184+
echo "set alias to specific version"
185+
echo ""
186+
echo ""
187+
;;
188+
189+
"upgrade" )
190+
[ $# -ne 1 ] && kvm help && return
191+
echo "Determining latest version"
192+
local version=$(_kvm_find_latest mono45 x86)
193+
echo $version
194+
kvm install $version
195+
kvm alias default $version
196+
;;
197+
198+
"install" )
199+
[ $# -ne 2 ] && kvm help && return
200+
201+
local versionOrAlias="$2"
202+
203+
if [ "$versionOrAlias" == *.nupkg ]; then
204+
local kreFullName=$(echo $versionOrAlias | sed "s/\(.*\)\.nupkg/\1/")
205+
local kreFolder="$KRE_USER_PACKAGES/$kreFullName"
206+
local kreFile="$kreFolder/$kreFullName.nupkg"
207+
208+
if [ -e "$kreFolder" ]; then
209+
echo "Target folder '$kreFolder' already exists"
210+
else
211+
mkdir "$kreFolder" > /dev/null 2>&1
212+
cp -a "$versionOrAlias" "$kreFile"
213+
_kvm_unpack "$kreFile" "$kreFolder"
214+
fi
215+
216+
echo "Adding $kreBin to current PATH"
217+
PATH=$(_kvm_strip_path "$PATH" "/bin")
218+
PATH=(_kvm_prepend_path "$PATH" "$kreBin")
219+
else
220+
local kreFullName="$(_kvm_requested_version_or_alias $versionOrAlias)"
221+
local kreFolder="$KRE_USER_PACKAGES/$kreFullName"
222+
_kvm_download "$kreFullName" "$kreFolder"
223+
kvm use "$versionOrAlias"
224+
fi
225+
;;
226+
227+
"use" )
228+
[ $# -gt 3 ] && kvm help && return
229+
[ $# -lt 2 ] && kvm help && return
230+
231+
shift
232+
local persistant=
233+
234+
while [ $# -ne 0 ]
235+
do
236+
if [[ $1 == "-p" || $1 == "-persistant" ]]; then
237+
local persistant="true"
238+
else
239+
local versionOrAlias=$1
240+
fi
241+
shift
242+
done
243+
244+
if [[ $versionOrAlias == "none" ]]; then
245+
echo "Removing KRE from process PATH"
246+
# Strip other version from PATH
247+
PATH=`_kvm_strip_path "$PATH" "/bin"`
248+
249+
if [[ -n $persistent && -e "$KRE_USER_HOME/alias/default.alias" ]]; then
250+
echo "Setting default KRE to none"
251+
rm "$KRE_USER_HOME/alias/default.alias"
252+
fi
253+
return 0
254+
fi
255+
256+
local kreFullName=$(_kvm_requested_version_or_alias "$versionOrAlias")
257+
local kreBin=$(_kvm_locate_kre_bin_from_full_name "$kreFullName")
258+
259+
if [[ -z $kreBin ]]; then
260+
echo "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?"
261+
return 1
262+
fi
263+
264+
echo "Adding" $kreBin "to process PATH"
265+
266+
PATH=`_kvm_strip_path "$PATH" "/bin"`
267+
PATH=`_kvm_prepend_path "$PATH" "$kreBin"`
268+
269+
if [[ -n $persistent ]]; then
270+
echo "Setting $kreBin as default KRE"
271+
kvm alias default "$versionOrAlias"
272+
fi
273+
;;
274+
275+
"alias" )
276+
[[ $# -gt 3 ]] && kvm help && return
277+
278+
if [[ $# == 1 ]]; then
279+
for f in $(find "$KRE_USER_HOME/alias" -name *.alias); do printf "%-20s %s\n" "$(basename $f | sed 's/.alias//')" "$(cat $f)"; done
280+
echo ""
281+
return
282+
fi
283+
284+
local name="$2"
285+
286+
if [[ $# == 2 ]]; then
287+
[[ ! -e "$KRE_USER_HOME/alias/$name.alias" ]] && echo "There is no alias called '$name'" && return
288+
cat "$KRE_USER_HOME/alias/$name.alias"
289+
echo ""
290+
return
291+
fi
292+
293+
local semver="$3"
294+
local kreFullName="KRE-$(_kvm_requested_platform mono45)-$(_kvm_requested_architecture x86).$semver"
295+
296+
[[ ! -d "$KRE_USER_PACKAGES/$kreFullName" ]] && echo "$semver is not an installed KRE version." && return 1
297+
298+
echo "Setting alias '$name' to '$kreFullName'"
299+
[[ ! -e "$KRE_USER_HOME/alias/" ]] && mkdir "$KRE_USER_HOME/alias/" > /dev/null
300+
301+
echo "$kreFullName" > "$KRE_USER_HOME/alias/$name.alias"
302+
;;
303+
304+
"list" )
305+
[[ $# -gt 2 ]] && kvm help && return
306+
307+
[[ ! -d $KRE_USER_PACKAGES ]] && echo "KRE is not installed." && return 1
308+
309+
local searchGlob="KRE-*"
310+
if [ $# == 2 ]; then
311+
local versionOrAlias=$2
312+
local searchGlob=$(_kvm_requested_version_or_alias "$versionOrAlias")
313+
echo $searchGlob
314+
fi
315+
316+
for f in $(find $KRE_USER_PACKAGES/* -name $searchGlob -type d -prune -exec basename {} \;); do
317+
#TODO: Format, extract package, version arch etc
318+
echo -n $f
319+
if [[ $PATH == *"$KRE_USER_PACKAGES/$f/bin"* ]]; then
320+
echo " *"
321+
else
322+
echo ""
323+
fi
324+
[[ $# == 2 ]] && echo "" && return 0
325+
done
326+
327+
echo ""
328+
[[ $# == 2 ]] && return 1 # kvm list xxx - xxx was not found
329+
;;
330+
331+
*)
332+
echo "Unknown command $1"
333+
return 1
334+
esac
335+
}
336+
337+
kvm list default >/dev/null && kvm use default >/dev/null || true

0 commit comments

Comments
 (0)