oswitch 0.2.3 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.mkd +117 -57
- data/lib/oswitch/exceptions.rb +18 -0
- data/lib/oswitch/image.rb +33 -0
- data/lib/oswitch/os/darwin.rb +30 -0
- data/lib/oswitch/os/linux.rb +45 -0
- data/lib/oswitch/os.rb +40 -0
- data/lib/oswitch/pkg.rb +3 -0
- data/lib/oswitch.rb +17 -151
- data/oswitch.gemspec +2 -2
- data/{context → share/oswitch/context}/_switch +0 -0
- data/{context → share/oswitch/context}/wheel +0 -0
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75af23e839e1c6933df699ecb6e14f5512ce863c
|
4
|
+
data.tar.gz: 902745b152459f284ff363b6897efba8e2c341ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ee1019f702540123b5bcf4305059eb432d00946564f820770d2aeec4dbfc0d220cff2b927f16ab47eddeb9bbdcaf8c69a18c4fea659abaa230ff297dae153d2
|
7
|
+
data.tar.gz: 6c08c54c9bc36fcaf58d2aab8814da44b6ef50b7b6dc41cee1dc6a21a0d22bf42dceb37c9af6540106bcc3c65fc06a28e5c605a275b4710cae7d7c510eacf12b
|
data/README.mkd
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
One-line access to other operating systems.
|
4
4
|
|
5
|
+
Mini-example:
|
6
|
+
|
7
|
+
```bash
|
8
|
+
mymacbook:~/2015-02-01-myproject> abyss-pe
|
9
|
+
zsh: command not found: abyss-pe
|
10
|
+
mymacbook:~/2015-02-01-myproject> oswitch -l
|
11
|
+
yeban/biolinux:8
|
12
|
+
ubuntu:14.04
|
13
|
+
ontouchstart/texlive-full
|
14
|
+
ipython/ipython
|
15
|
+
hlapp/rpopgen
|
16
|
+
mymacbook:~/2015-02-01-myproject> oswitch biolinux
|
17
|
+
###### You are now running: biolinux in container biolinux-7187. ######
|
18
|
+
biolinux-7187:~/2015-02-01-myproject> abyss-pe k=25 reads.fastq.gz
|
19
|
+
[... just works on your files where they are...]
|
20
|
+
biolinux-7187:~/2015-02-01-myproject> exit
|
21
|
+
mymacbook:~/2015-02-01-myproject>
|
22
|
+
[... output is where you expect it to be ...]
|
23
|
+
```
|
24
|
+
|
25
|
+
Detailed information:
|
26
|
+
* [Features](#features)
|
5
27
|
* [Usage](#example-usage)
|
6
28
|
* [Installation](#installation)
|
7
29
|
* [FAQ](#faq)
|
@@ -10,39 +32,40 @@ One-line access to other operating systems.
|
|
10
32
|
|
11
33
|
## Background
|
12
34
|
|
13
|
-
Genomic analyses require
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
systems administrators can be overwhelmed by large numbers of software
|
22
|
-
installation requests & the challenges of managing multiple versions.
|
35
|
+
Genomic analyses require jumping back and forth between many bioinformatics tools.
|
36
|
+
The data types are young, thus so are the tools. This leads to frequent
|
37
|
+
updates of tools that are often challenging to install. Furthermore, it is
|
38
|
+
challenging to keep different versions of software for different projects, yet
|
39
|
+
changing versions can make analyses difficult to reproduce. To make matters worse,
|
40
|
+
genomicists often lack the skills necessary to setup complex bioinformatics software,
|
41
|
+
and systems administrators can be overwhelmed by large numbers of software
|
42
|
+
installation requests.
|
23
43
|
|
24
|
-
## Aim
|
44
|
+
## Aim
|
25
45
|
|
26
46
|
We are developing `oswitch` to enable **seamless switching
|
27
47
|
from one operating system to another** - providing access to diverse
|
28
|
-
ranges of tools. This project grew from our own need to rapidly access
|
29
|
-
software distributed as part of
|
48
|
+
ranges of tools. This project grew from our own need to rapidly access
|
49
|
+
diverse pieces of specific versions of software including those distributed as part of
|
30
50
|
[BioLinux](http://environmentalomics.org/bio-linux/) on our MacBooks
|
31
|
-
and our university HPC system.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
machine images - but much more
|
51
|
+
and our university HPC system. This was previously too difficult, but is
|
52
|
+
important for [reproducible research](http://www.software.ac.uk) and agility.
|
53
|
+
@bmpvieira made it clear early on that the [docker](http://docker.io/) could
|
54
|
+
help make something happen. We first shared the resulting concept during a
|
55
|
+
[Balti & Bioinformatics](http://nickloman.github.io/balti/2014/05/01/balti-and-bioinformatics-27th-may-2014/)
|
56
|
+
presentation in the form of this (now out of date!) slide:
|
57
|
+
|
58
|
+
[![Slide from Balti](http://i.imgur.com/exfDi6a.png)](http://www.slideshare.net/yannickwurm/2014-0527-opinion-computing-for-genomics-sucks)
|
59
|
+
|
60
|
+
Docker images feel similar to using virtual machine images - but are much more
|
41
61
|
[flexible and light-weight](http://stackoverflow.com/questions/16047306/how-is-docker-io-different-from-a-normal-virtual-machine).
|
62
|
+
They are thus easily [shared or published](https://hub.docker.com/). We are extremely lucky to
|
63
|
+
be able to build upon this amazing technology.
|
64
|
+
|
65
|
+
## Features
|
42
66
|
|
43
|
-
|
44
|
-
|
45
|
-
shell, most things remain unchanged:
|
67
|
+
**`oswitch` is a wrapper facilitating access to docker images**. Importantly, when switching
|
68
|
+
operating systems inside a shell, most things remain unchanged:
|
46
69
|
|
47
70
|
* Current working directory is maintained
|
48
71
|
* User name, uid and gid are maintained
|
@@ -51,7 +74,7 @@ shell, most things remain unchanged:
|
|
51
74
|
are maintained).
|
52
75
|
* read/write permissions are maintained
|
53
76
|
* Paths are maintained whenever possible. Thus volumes (external drives,
|
54
|
-
NAS) mounted on the host are available in the container at the same
|
77
|
+
NAS, USB) mounted on the host are available in the container at the same
|
55
78
|
path.
|
56
79
|
|
57
80
|
## Example Usage
|
@@ -64,11 +87,11 @@ use.
|
|
64
87
|
Minimalist example:
|
65
88
|
|
66
89
|
```shell
|
67
|
-
Yannick@n56-169 ~/
|
90
|
+
Yannick@n56-169 ~/myproject> uname -a
|
68
91
|
Darwin n56-169.sbcs.qmul.ac.uk 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
|
69
|
-
Yannick@n56-169 ~/
|
92
|
+
Yannick@n56-169 ~/myproject> oswitch yeban/biolinux
|
70
93
|
### You are now running: biolinux_8, in container: biolinux_8-27182. ###
|
71
|
-
Yannick@biolinux_8-27182 ~/
|
94
|
+
Yannick@biolinux_8-27182 ~/myproject> uname -a
|
72
95
|
Linux biolinux_8-27182 3.16.4-tinycore64 #1 SMP Thu Oct 23 16:14:24 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
|
73
96
|
```
|
74
97
|
|
@@ -86,10 +109,10 @@ ITKIKLENSDVTIPDIKLIMFPKEPYTADWMLAFRVVIPLYMVLALSQFITYLLILIVGE
|
|
86
109
|
KENKIKEGMKMMGLNDSVF
|
87
110
|
pixel:~/test/ $ blastp -query mygene.fa -remote -db nr -outfmt 7 > mygene_blastp_nr.tab
|
88
111
|
zsh: command not found: blastp
|
89
|
-
# Indeed... blastp is
|
112
|
+
# Indeed... blastp is missing from my MacBook.
|
90
113
|
|
91
114
|
# Switch to BioLinux and run blastp.
|
92
|
-
pixel:~/test/ $ oswitch biolinux
|
115
|
+
pixel:~/test/ $ oswitch yeban/biolinux
|
93
116
|
###### You are now running: biolinux in container biolinux-7187. ######
|
94
117
|
biolinux-7187:~/test/ $ blastp -query mygene.fa -remote -db nr -outfmt 7 > mygene_blastp_nr.tab
|
95
118
|
# BioLinux includes blastp, thus the command ran smoothly.
|
@@ -114,6 +137,7 @@ myfavoritegene gi|328778864|ref|XP_397465.4| 80.60 201 36 2 1 199 95 294 5e-108
|
|
114
137
|
biolinux-7187:~/test/ $ exit
|
115
138
|
pixel:~/test/ $ ls
|
116
139
|
mygene.fasta mygene_blastp_nr.txt
|
140
|
+
# our newly generated file is where we'd expect it to be.
|
117
141
|
```
|
118
142
|
|
119
143
|
##### Use a package non-interactively
|
@@ -128,7 +152,7 @@ the exit status of the command run within container is returned.
|
|
128
152
|
|
129
153
|
```shell
|
130
154
|
# Run command directly in BioLinux and view results if success.
|
131
|
-
pixel:~/test/ $ oswitch biolinux blastp -remote -query mygene.fa -db nr > mygene_blastp_nr.txt
|
155
|
+
pixel:~/test/ $ oswitch yeban/biolinux blastp -remote -query mygene.fa -db nr > mygene_blastp_nr.txt
|
132
156
|
```
|
133
157
|
|
134
158
|
##### Listing available operating system containers
|
@@ -140,11 +164,14 @@ from docker hub using oswitch as:
|
|
140
164
|
pixel:~ $ oswitch -l
|
141
165
|
yeban/biolinux:8
|
142
166
|
ubuntu:14.04
|
167
|
+
ontouchstart/texlive-full
|
168
|
+
ipython/ipython
|
169
|
+
hlapp/rpopgen
|
143
170
|
```
|
144
171
|
|
145
172
|
##### Availability
|
146
173
|
|
147
|
-
|
174
|
+
We have tested OSwitch on:
|
148
175
|
|
149
176
|
* Mac OS X Yosemite
|
150
177
|
* Ubuntu 14.04.1
|
@@ -152,20 +179,57 @@ OSwitch has been tested on:
|
|
152
179
|
|
153
180
|
##### Caveats
|
154
181
|
|
155
|
-
*
|
182
|
+
* Some features work only for Debian, Ubuntu, CentOS based docker images.
|
156
183
|
* Host directories/volumes with paths conflicting with container paths are
|
157
184
|
skipped.
|
158
185
|
* SELinux must be disabled on CentOS for mounting volumes to work.
|
186
|
+
* [Volume mounting on Mac OS hosts is imperfect](#q-directories-mounted-within-container-on-mac-host-are-empty).
|
159
187
|
|
160
188
|
## Installation
|
161
189
|
|
162
|
-
OSwitch first requires a working docker install.
|
190
|
+
OSwitch first requires a [working docker install](#Install and setup docker).
|
191
|
+
|
192
|
+
#### Install oswitch
|
193
|
+
|
194
|
+
##### Mac
|
195
|
+
|
196
|
+
Using [homebrew](http://brew.sh/).
|
197
|
+
|
198
|
+
$ brew install https://raw.githubusercontent.com/yeban/oswitch/master/homebrew/oswitch.rb
|
199
|
+
|
200
|
+
Depending on whether Homebrew is installed systemwide or only for your user,
|
201
|
+
this will install `oswitch` systemwide or only for your user.
|
202
|
+
|
203
|
+
##### Linux
|
204
|
+
|
205
|
+
###### Debian / Ubuntu
|
206
|
+
|
207
|
+
A `deb` package of `oswitch` is available in BioLinux repository for Trusty,
|
208
|
+
Vivid and Jessie.
|
209
|
+
|
210
|
+
$ sudo add-apt-repository ppa:nebc/biolinux
|
211
|
+
$ sudo apt-get update
|
212
|
+
$ sudo apt-get install oswitch
|
213
|
+
|
214
|
+
###### Others
|
215
|
+
|
216
|
+
Requirements: Ruby 2.0 or higher.
|
217
|
+
|
218
|
+
$ gem install oswitch
|
163
219
|
|
164
|
-
|
220
|
+
Depending on whether Ruby is installed systemwide (via your package-manager) or
|
221
|
+
only for your user, this will install `oswitch` systemwide or only for your
|
222
|
+
user.
|
223
|
+
|
224
|
+
#### Test oswitch
|
225
|
+
|
226
|
+
$ oswitch ubuntu:14.04
|
227
|
+
|
228
|
+
## Install and setup docker
|
165
229
|
|
166
230
|
##### Mac OS X
|
167
231
|
|
168
|
-
Installing docker - https://docs.docker.com/installation/mac/
|
232
|
+
Installing docker is much easier than before - https://docs.docker.com/installation/mac/
|
169
233
|
|
170
234
|
##### Ubuntu
|
171
235
|
|
@@ -209,16 +273,6 @@ The following should give an encouraging message:
|
|
209
273
|
|
210
274
|
$ docker run hello-world
|
211
275
|
|
212
|
-
#### Install oswitch
|
213
|
-
|
214
|
-
Requirements: Ruby 2.0 or higher.
|
215
|
-
|
216
|
-
$ gem install oswitch
|
217
|
-
|
218
|
-
#### Testing oswitch
|
219
|
-
|
220
|
-
$ oswitch ubuntu:14.04
|
221
|
-
|
222
276
|
## FAQ
|
223
277
|
|
224
278
|
##### Q. Directories mounted within container on Mac host are empty.
|
@@ -257,18 +311,24 @@ tracker](https://github.com/yeban/oswitch/issues) with oswitch's output. If the
|
|
257
311
|
image you are using is not available via docker hub or another public
|
258
312
|
repository, please include the Dockerfile as well.
|
259
313
|
|
314
|
+
##### Q. How does all this work?
|
315
|
+
We create a new image on the fly that inherits from the given image. While creating
|
316
|
+
the new image we execute a shell script that installs packages required for
|
317
|
+
oswitch to work and creates a user in the image (almost) identical to that on the host.
|
318
|
+
|
260
319
|
## Roadmap
|
261
320
|
|
262
321
|
1. ~~make it possible to use docker containers without inheriting our
|
263
322
|
current baseimage~~
|
264
323
|
2. ~~gem distribution for easier installation~~
|
265
|
-
3.
|
266
|
-
4.
|
267
|
-
5.
|
324
|
+
3. ~~brew recipe for Mac~~
|
325
|
+
4. ~~deb package~~
|
326
|
+
5. test on QMUL's compute cluster
|
327
|
+
6. make available images for common bioinformatics software
|
328
|
+
7. deploy at [RAL/JASMIN](http://www.jasmin.ac.uk)
|
329
|
+
8. create an SELinux policy to run oswitch on CentOS without having to disable
|
268
330
|
SELinux entirely
|
269
|
-
|
270
|
-
7. make available images for common bioinformatics software
|
271
|
-
8. deploy at [RAL/JASMIN](http://www.jasmin.ac.uk)
|
331
|
+
9. rpm package
|
272
332
|
|
273
333
|
## Contribute
|
274
334
|
|
@@ -283,13 +343,13 @@ SELinux entirely
|
|
283
343
|
* [Bruno Vieira](https://github.com/bmpvieira) ([@bmpvieira](//twitter.com/bmpvieira))
|
284
344
|
* [Saurabh Kumar](https://github.com/sa1)
|
285
345
|
* Richard Nichols - [http://www.sbcs.qmul.ac.uk/staff/richardnichols.html](http://www.sbcs.qmul.ac.uk/staff/richardnichols.html) | [@qmwugbt112](//twitter.com/qmwugbt112)
|
286
|
-
* Yannick Wurm - [http://wurmlab.github.io](http://wurmlab.github.io) |
|
287
|
-
[@yannick__](//twitter.com/yannick__)
|
346
|
+
* Yannick Wurm - [http://wurmlab.github.io](http://wurmlab.github.io) | [@yannick__](//twitter.com/yannick__)
|
288
347
|
|
289
348
|
---
|
290
349
|
|
291
350
|
<p align="center">
|
292
|
-
Development funded as part of
|
351
|
+
Development funded as part of
|
352
|
+
<a href="http://environmentalomics.org/portfolio/big-data-infrastructure/">NERC Environmental Omics (EOS) Cloud</a> at<br/>
|
293
353
|
<a href="http://wurmlab.github.io/">Wurm Lab</a>,
|
294
354
|
<a href="http://sbcs.mul.ac.uk/">Queen Mary University of London</a>.
|
295
355
|
</p>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class OSwitch
|
2
|
+
class ENOPKG < StandardError
|
3
|
+
def initialize(name)
|
4
|
+
@name = name
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
"Recipe to run #@name not available."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ENODKR < StandardError
|
13
|
+
def to_s
|
14
|
+
"***** Docker not installed / correctly setup / running.
|
15
|
+
Are you able to run 'docker info'?"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class OSwitch
|
2
|
+
# Captures a docker image's metadata.
|
3
|
+
Image = Struct.new :repository, :tag, :id, :created, :size
|
4
|
+
|
5
|
+
class Image
|
6
|
+
|
7
|
+
# Model Image's eigenclass as a collection of Image objects.
|
8
|
+
class << self
|
9
|
+
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
def all
|
13
|
+
`docker images`.split("\n").drop(1).
|
14
|
+
map{|l| Image.new(*l.split(/\s{2,}/))}
|
15
|
+
end
|
16
|
+
|
17
|
+
def each(&block)
|
18
|
+
all.each(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(imgname)
|
22
|
+
repository, tag = imgname.split(':')
|
23
|
+
return if not repository or repository.empty?
|
24
|
+
tag = 'latest' if not tag or tag.empty?
|
25
|
+
find {|img| img.repository == repository and img.tag == tag}
|
26
|
+
end
|
27
|
+
|
28
|
+
def exists?(imgname)
|
29
|
+
!!get(imgname)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class OSwitch
|
2
|
+
module OS
|
3
|
+
# OS X specific code.
|
4
|
+
module Darwin
|
5
|
+
BLACKLIST =
|
6
|
+
%r{
|
7
|
+
^/$|
|
8
|
+
^/(bin|cores|dev|etc|home|Incompatible\ Software|
|
9
|
+
installer\.failurerequests|lost\+found|net|
|
10
|
+
Network|opt|private|sbin|System|Users|tmp|
|
11
|
+
usr|var|Volumes$)
|
12
|
+
}x
|
13
|
+
|
14
|
+
def uid
|
15
|
+
`boot2docker ssh id -u`.chomp
|
16
|
+
end
|
17
|
+
|
18
|
+
def gid
|
19
|
+
`boot2docker ssh id -g`.chomp
|
20
|
+
end
|
21
|
+
|
22
|
+
def mountpoints
|
23
|
+
volumes = Dir['/Volumes/*'].map {|v| File.symlink?(v) ? File.readlink(v) : v}
|
24
|
+
volumes = volumes | Dir['/*']
|
25
|
+
volumes.reject! { |mount| mount =~ BLACKLIST }
|
26
|
+
volumes << home
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class OSwitch
|
2
|
+
module OS
|
3
|
+
# Linux specific code.
|
4
|
+
module Linux
|
5
|
+
BLACKLIST =
|
6
|
+
%r{
|
7
|
+
^/$|
|
8
|
+
^/(bin|boot|dev|etc|home|lib|lib64|lost\+found|opt|proc|
|
9
|
+
run(?!/media)|sbin|srv|sys|tmp|usr|var|
|
10
|
+
initrd.img|initrd.img.old|vmlinuz|vmlinuz.old)
|
11
|
+
}x
|
12
|
+
|
13
|
+
def uid
|
14
|
+
Process.uid
|
15
|
+
end
|
16
|
+
|
17
|
+
def gid
|
18
|
+
Process.gid
|
19
|
+
end
|
20
|
+
|
21
|
+
def mountpoints
|
22
|
+
volumes = IO.readlines('/proc/mounts')
|
23
|
+
.map { |line| line.split(/\s+/)[1] }
|
24
|
+
.map { |path| unescape(path) }
|
25
|
+
volumes = volumes | Dir['/*']
|
26
|
+
|
27
|
+
volumes.reject! do |path|
|
28
|
+
(path =~ BLACKLIST) || !File.readable?(path) || !File.directory?(path)
|
29
|
+
end
|
30
|
+
|
31
|
+
volumes << home
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def unescape(mount)
|
37
|
+
mount
|
38
|
+
.gsub(/\\040/, " ")
|
39
|
+
.gsub(/\\012/, "\n")
|
40
|
+
.gsub(/\\134/, "\\")
|
41
|
+
.gsub(/\\011/, "\t")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/oswitch/os.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class OSwitch
|
2
|
+
# Get OS specific info. Like, what directories to mount in the container,
|
3
|
+
# current user, home directory.
|
4
|
+
#
|
5
|
+
# This module first defines methods common to Linux and Darwin, then does
|
6
|
+
# OS detection and loads OS specific code.
|
7
|
+
module OS
|
8
|
+
def username
|
9
|
+
ENV['USER']
|
10
|
+
end
|
11
|
+
|
12
|
+
def home
|
13
|
+
ENV['HOME']
|
14
|
+
end
|
15
|
+
|
16
|
+
def shell
|
17
|
+
File.basename ENV['SHELL']
|
18
|
+
end
|
19
|
+
|
20
|
+
def cwd
|
21
|
+
Dir.pwd
|
22
|
+
end
|
23
|
+
|
24
|
+
# Detect Linux or Darwin and load OS specific code. Following methods are
|
25
|
+
# added:
|
26
|
+
#
|
27
|
+
# uid, gid, mountpoints
|
28
|
+
#
|
29
|
+
# NOTE:
|
30
|
+
# This won't work on JRuby, as it sets RUBY_PLATFORM to 'java'.
|
31
|
+
case RUBY_PLATFORM
|
32
|
+
when /linux/
|
33
|
+
require_relative 'os/linux'
|
34
|
+
include Linux
|
35
|
+
when /darwin/
|
36
|
+
require_relative 'os/darwin'
|
37
|
+
include Darwin
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/oswitch/pkg.rb
ADDED
data/lib/oswitch.rb
CHANGED
@@ -3,6 +3,11 @@ require 'colorize'
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'shellwords'
|
5
5
|
|
6
|
+
require 'oswitch/exceptions'
|
7
|
+
require 'oswitch/image'
|
8
|
+
require 'oswitch/pkg'
|
9
|
+
require 'oswitch/os'
|
10
|
+
|
6
11
|
# OSwitch leverages docker to provide access to complex Bioinformatics software
|
7
12
|
# (even Biolinux!) in just one command.
|
8
13
|
#
|
@@ -12,129 +17,7 @@ require 'shellwords'
|
|
12
17
|
# Volumes from host OS are mounted in the container just the same, including
|
13
18
|
# home directory. USER, HOME, SHELL, and PWD are preserved.
|
14
19
|
class OSwitch
|
15
|
-
|
16
|
-
class ENOPKG < StandardError
|
17
|
-
|
18
|
-
def initialize(name)
|
19
|
-
@name = name
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
"Recipe to run #@name not available."
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class ENODKR < StandardError
|
28
|
-
|
29
|
-
def to_s
|
30
|
-
"***** Docker not installed / correctly setup / running.
|
31
|
-
Are you able to run 'docker info'?"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
include Timeout
|
36
|
-
|
37
|
-
# Captures a docker image's metadata.
|
38
|
-
Image = Struct.new :repository, :tag, :id, :created, :size
|
39
|
-
|
40
|
-
class Image
|
41
|
-
|
42
|
-
# Model Image's eigenclass as a collection of Image objects.
|
43
|
-
class << self
|
44
|
-
|
45
|
-
include Enumerable
|
46
|
-
|
47
|
-
def all
|
48
|
-
`docker images`.split("\n").drop(1).
|
49
|
-
map{|l| Image.new(*l.split(/\s{2,}/))}
|
50
|
-
end
|
51
|
-
|
52
|
-
def each(&block)
|
53
|
-
all.each(&block)
|
54
|
-
end
|
55
|
-
|
56
|
-
def get(imgname)
|
57
|
-
repository, tag = imgname.split(':')
|
58
|
-
return if not repository or repository.empty?
|
59
|
-
tag = 'latest' if not tag or tag.empty?
|
60
|
-
find {|img| img.repository == repository and img.tag == tag}
|
61
|
-
end
|
62
|
-
|
63
|
-
def exists?(imgname)
|
64
|
-
!!get(imgname)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Linux specific code.
|
70
|
-
module Linux
|
71
|
-
|
72
|
-
def uid
|
73
|
-
Process.uid
|
74
|
-
end
|
75
|
-
|
76
|
-
def gid
|
77
|
-
Process.gid
|
78
|
-
end
|
79
|
-
|
80
|
-
# Parse /proc/mounts for mountpoints.
|
81
|
-
def mountpoints
|
82
|
-
mtab = IO.readlines '/proc/mounts'
|
83
|
-
mountpoints = mtab.map{ |line| line.split(/\s+/)[1]}
|
84
|
-
mountpoints.map!{ |mount| unescape(mount) }
|
85
|
-
# Ignore common system mountpoints.
|
86
|
-
mountpoints.reject!{ |mount| mount =~ /^\/$/ }
|
87
|
-
mountpoints.reject!{ |mount| mount =~ /^\/(proc|sys|usr|boot|tmp|dev|var|bin|etc|lib).*/ }
|
88
|
-
# Mount /run/media/* but ignore other /run/ mountpoints.
|
89
|
-
mountpoints.reject!{ |mount| mount =~ /^\/run.*/ unless mount =~ /^\/run\/(media.*)/ }
|
90
|
-
|
91
|
-
# Add home dir.
|
92
|
-
mountpoints << home
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def unescape(mount)
|
98
|
-
mount.gsub(/\\040/, " ").gsub(/\\012/, "\n").gsub(/\\134/, "\\").gsub(/\\011/, "\t")
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Mac OS X specific code.
|
103
|
-
module Darwin
|
104
|
-
|
105
|
-
BLACKLIST =
|
106
|
-
%r{
|
107
|
-
^/$|
|
108
|
-
^/(bin|cores|dev|etc|home|Incompatible\ Software|
|
109
|
-
installer\.failurerequests|lost\+found|net|
|
110
|
-
Network|opt|private|sbin|System|Users|tmp|
|
111
|
-
usr|var|Volumes$)
|
112
|
-
}x
|
113
|
-
|
114
|
-
def uid
|
115
|
-
`boot2docker ssh id -u`.chomp
|
116
|
-
end
|
117
|
-
|
118
|
-
def gid
|
119
|
-
`boot2docker ssh id -g`.chomp
|
120
|
-
end
|
121
|
-
|
122
|
-
def mountpoints
|
123
|
-
volumes = Dir['/Volumes/*'].map {|v| File.symlink?(v) ? File.readlink(v) : v}
|
124
|
-
volumes = volumes | Dir['/*']
|
125
|
-
volumes.reject! { |mount| mount =~ BLACKLIST }
|
126
|
-
volumes << home
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# NOTE:
|
131
|
-
# This won't work on JRuby, as it sets RUBY_PLATFORM to 'java'.
|
132
|
-
case RUBY_PLATFORM
|
133
|
-
when /linux/
|
134
|
-
include Linux
|
135
|
-
when /darwin/
|
136
|
-
include Darwin
|
137
|
-
end
|
20
|
+
include OS, Timeout
|
138
21
|
|
139
22
|
DOTDIR = File.expand_path('~/.oswitch')
|
140
23
|
|
@@ -189,7 +72,8 @@ class OSwitch
|
|
189
72
|
|
190
73
|
def build
|
191
74
|
return true if Image.exists? imgname
|
192
|
-
|
75
|
+
create_context_dir &&
|
76
|
+
system("docker build -t #{imgname} #{context_dir}") || !remove_context_dir
|
193
77
|
end
|
194
78
|
|
195
79
|
# Ping docker daemon. Raise error if no response within 10s.
|
@@ -202,16 +86,16 @@ class OSwitch
|
|
202
86
|
|
203
87
|
## Code to generate context dir that will be built into a docker image. ##
|
204
88
|
|
205
|
-
# Write data to context dir.
|
206
|
-
def write_context
|
207
|
-
create_context_dir
|
208
|
-
write_dockerfile
|
209
|
-
end
|
210
|
-
|
211
89
|
# Create context dir.
|
212
90
|
def create_context_dir
|
213
91
|
FileUtils.mkdir_p context_dir
|
214
92
|
FileUtils.cp_r(template_files, context_dir)
|
93
|
+
write_dockerfile
|
94
|
+
end
|
95
|
+
|
96
|
+
# Remove context dir.
|
97
|
+
def remove_context_dir
|
98
|
+
FileUtils.rm_r(context_dir)
|
215
99
|
end
|
216
100
|
|
217
101
|
# Write Dockerfile.
|
@@ -225,7 +109,7 @@ class OSwitch
|
|
225
109
|
data = ["FROM #{package}"]
|
226
110
|
data << 'COPY _switch /'
|
227
111
|
data << 'COPY wheel /etc/sudoers.d/'
|
228
|
-
data << "RUN /_switch #{userargs} 2>&1
|
112
|
+
data << "RUN /_switch #{userargs} 2>&1"
|
229
113
|
data << 'ENV LC_ALL en_US.UTF-8'
|
230
114
|
data << "USER #{username}"
|
231
115
|
data << "ENTRYPOINT [\"#{shell}\", \"-c\"]"
|
@@ -239,7 +123,7 @@ class OSwitch
|
|
239
123
|
|
240
124
|
# Location of template dir.
|
241
125
|
def template_dir
|
242
|
-
File.
|
126
|
+
File.join(PREFIX, 'share', 'oswitch', 'context')
|
243
127
|
end
|
244
128
|
|
245
129
|
# Template files.
|
@@ -247,24 +131,6 @@ class OSwitch
|
|
247
131
|
Dir[File.join(template_dir, '*')]
|
248
132
|
end
|
249
133
|
|
250
|
-
|
251
|
-
## Data required to switchify a container. ##
|
252
|
-
def username
|
253
|
-
ENV['USER']
|
254
|
-
end
|
255
|
-
|
256
|
-
def home
|
257
|
-
ENV['HOME']
|
258
|
-
end
|
259
|
-
|
260
|
-
def shell
|
261
|
-
File.basename ENV['SHELL']
|
262
|
-
end
|
263
|
-
|
264
|
-
def cwd
|
265
|
-
Dir.pwd
|
266
|
-
end
|
267
|
-
|
268
134
|
def motd
|
269
135
|
str =<<MOTD
|
270
136
|
################################################################################
|
@@ -282,7 +148,7 @@ safest to write to.
|
|
282
148
|
Press Ctrl-D or type 'exit' to go back.
|
283
149
|
################################################################################
|
284
150
|
MOTD
|
285
|
-
str.
|
151
|
+
str.shellescape
|
286
152
|
end
|
287
153
|
|
288
154
|
def mountargs
|
data/oswitch.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
# meta
|
3
3
|
s.name = 'oswitch'
|
4
|
-
s.version = '0.2.
|
4
|
+
s.version = '0.2.6'
|
5
5
|
s.authors = ['Anurag Priyam', 'Bruno Vieira', 'Yannick Wurm']
|
6
6
|
s.email = ['anurag08priyam@gmail.com']
|
7
7
|
s.homepage = 'https://github.com/yeban/oswitch'
|
@@ -20,7 +20,7 @@ DESC
|
|
20
20
|
s.required_ruby_version = '>= 2.0'
|
21
21
|
|
22
22
|
# gem
|
23
|
-
s.files = Dir['lib/**/*'] + Dir['
|
23
|
+
s.files = Dir['lib/**/*'] + Dir['share/**/*']
|
24
24
|
s.files = s.files + ['Gemfile', 'oswitch.gemspec']
|
25
25
|
s.files = s.files + ['README.mkd']
|
26
26
|
s.require_paths = ['lib']
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oswitch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anurag Priyam
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: colorize
|
@@ -40,10 +40,16 @@ files:
|
|
40
40
|
- Gemfile
|
41
41
|
- README.mkd
|
42
42
|
- bin/oswitch
|
43
|
-
- context/_switch
|
44
|
-
- context/wheel
|
45
43
|
- lib/oswitch.rb
|
44
|
+
- lib/oswitch/exceptions.rb
|
45
|
+
- lib/oswitch/image.rb
|
46
|
+
- lib/oswitch/os.rb
|
47
|
+
- lib/oswitch/os/darwin.rb
|
48
|
+
- lib/oswitch/os/linux.rb
|
49
|
+
- lib/oswitch/pkg.rb
|
46
50
|
- oswitch.gemspec
|
51
|
+
- share/oswitch/context/_switch
|
52
|
+
- share/oswitch/context/wheel
|
47
53
|
homepage: https://github.com/yeban/oswitch
|
48
54
|
licenses:
|
49
55
|
- MIT
|
@@ -70,3 +76,4 @@ specification_version: 4
|
|
70
76
|
summary: Use docker image as the host operating system's user and access host operating
|
71
77
|
system's filesystem.
|
72
78
|
test_files: []
|
79
|
+
has_rdoc:
|