oswitch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/README.mkd +295 -0
  4. data/bin/oswitch +45 -0
  5. data/lib/oswitch.rb +293 -0
  6. data/oswitch.gemspec +27 -0
  7. metadata +68 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f17f0c2bd70cf5a969f60d6a000ebacaba1940dc
4
+ data.tar.gz: 4fc93cdb2580315e7a49032c2ff32797566144a1
5
+ SHA512:
6
+ metadata.gz: 08362f1f00b5d02531c2df28c59ccb9107f13e9ffcce5efef32cf2378e922f83c8db512dd098af6c081237b6db7920bf64c1d258c0f916762de5bd5a3eb0e883
7
+ data.tar.gz: 73b363b026815f51c84b110dd59a857a168fc9c8e9aaee6b22b14cb96341b4d83c7eba06b02a92d9fd18ef2cbb4d4f2fd91307cf1ba52f27aa4b6909da0f8e3e
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.mkd ADDED
@@ -0,0 +1,295 @@
1
+ # OSwitch
2
+
3
+ One-line access to other operating systems.
4
+
5
+ * [Usage](#example-usage)
6
+ * [Installation](#installation)
7
+ * [FAQ](#faq)
8
+ * [Roadmap](#roadmap)
9
+ * [Contributors & Funding](#contributors-&-funding)
10
+
11
+ ## Background
12
+
13
+ Genomic analyses require using many bioinformatics tools starting from assessing
14
+ the quality of sequenced data and assembly, to annotation, comparison and
15
+ analysis. The data types are young, thus the tools are too and many
16
+ genomicists lack computational training. Thus tools are frequently
17
+ updated yet often challenging to install. Furthermore, software updates often
18
+ involve changes in algorithms or input/output formats, making analyses
19
+ difficult to reproduce. To make matters worse, genomicists often lack
20
+ the skills necessary to setup complex bioinformatics software, and
21
+ systems administrators can be overwhelmed by large numbers of software
22
+ installation requests & the challenges of managing multiple versions.
23
+
24
+ ## Aim & Features
25
+
26
+ We are developing `oswitch` to enable **seamless switching
27
+ 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
30
+ [BioLinux](http://environmentalomics.org/bio-linux/) on our MacBooks
31
+ and our university HPC system.
32
+
33
+ For this we take advantage of the [docker](http://docker.io/)
34
+ technology. Docker works by creating "to the specification" image from
35
+ a Dockerfile, which is then run in an isolated
36
+ "container". Dockerfiles or the resulting images can persist forever,
37
+ are easily [shared or published](https://hub.docker.com/), and make
38
+ it possible for anybody to recreate the exact same setup at
39
+ any point of time in the future. This is similar to using virtual
40
+ machine images - but much more
41
+ [flexible and light-weight](http://stackoverflow.com/questions/16047306/how-is-docker-io-different-from-a-normal-virtual-machine).
42
+
43
+ `oswitch` is thus a wrapper facilitating access to docker images (without the
44
+ need for ssh-ing). Importantly, when switching operating systems inside a
45
+ shell, most things remain unchanged:
46
+
47
+ * Current working directory is maintained
48
+ * User name, uid and gid are maintained
49
+ * Login shell (bash/zsh/fish) is maintained
50
+ * Home directory is maintained (thus all .dotfiles and config files
51
+ are maintained).
52
+ * read/write permissions are maintained
53
+ * Paths are maintained whenever possible. Thus volumes (external drives,
54
+ NAS) mounted on the host are available in the container at the same
55
+ path.
56
+
57
+ ## Example Usage
58
+
59
+ There are two broad usage scenarios: interactive use & non-interactive
60
+ use.
61
+
62
+ ##### Use a package interactively in a normal command-line
63
+
64
+ Minimalist example:
65
+
66
+ ```shell
67
+ Yannick@n56-169 ~/g/oswitch> uname -a
68
+ 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 ~/g/oswitch> oswitch yeban/biolinux:8
70
+ ### You are now running: biolinux_8, in container: biolinux_8-27182. ###
71
+ Yannick@biolinux_8-27182 ~/g/oswitch> uname -a
72
+ 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
+ ```
74
+
75
+ Biologically relevant example:
76
+
77
+ ```shell
78
+ # Trying to run blast.
79
+ pixel:~/test/ $ ls
80
+ mygene.fasta
81
+ pixel:~/test/ $ cat mygene.fa
82
+ >myfavoritegene isthisone
83
+ MNTLWLSLWDYPGKLPLNFMVFDTKDDLQAAYWRDPYSIPLAVIFEDPQPISQRLIYEIR
84
+ TNPSYTLPPPPTKLYSAPISCRKNKTGHWMDDILSIKTGESCPVNNYLHSGFLALQMITD
85
+ ITKIKLENSDVTIPDIKLIMFPKEPYTADWMLAFRVVIPLYMVLALSQFITYLLILIVGE
86
+ KENKIKEGMKMMGLNDSVF
87
+ pixel:~/test/ $ blastp -query mygene.fa -remote -db nr -outfmt 7 > mygene_blastp_nr.tab
88
+ zsh: command not found: blastp
89
+ # Indeed... blastp is not installed on my MacBook.
90
+
91
+ # Switch to BioLinux and run blastp.
92
+ pixel:~/test/ $ oswitch biolinux
93
+ ###### You are now running: biolinux in container biolinux-7187. ######
94
+ biolinux-7187:~/test/ $ blastp -query mygene.fa -remote -db nr -outfmt 7 > mygene_blastp_nr.tab
95
+ # BioLinux includes blastp, thus the command ran smoothly.
96
+
97
+ # View the result.
98
+ biolinux-7187:~/test/ $ head mygene_blastp_nr.tab
99
+ # BLASTP 2.2.28+
100
+ # Query: myfavoritegene isthisone
101
+ # RID: BJAHAHU9015
102
+ # Database: nr
103
+ # Fields: query id, subject id, % identity, alignment length, mismatches, gap opens, q. start, q. end, s. start, s. end, evalue, bit score
104
+ # 501 hits found
105
+ myfavoritegene gi|322796550|gb|EFZ19024.1| 100.00 199 0 0 1 199 1 199 2e-142 407
106
+ myfavoritegene gi|307183032|gb|EFN69988.1| 86.07 201 25 2 1 199 80 279 6e-115 361
107
+ myfavoritegene gi|572260155|ref|XP_006608402.1| 80.60 201 36 2 1 199 95 294 4e-108 350
108
+ myfavoritegene gi|328778864|ref|XP_397465.4| 80.60 201 36 2 1 199 95 294 5e-108 350
109
+
110
+
111
+ # [... potentially run other analyses that require biolinux things...]
112
+
113
+ # Return to normal operating system
114
+ biolinux-7187:~/test/ $ exit
115
+ pixel:~/test/ $ ls
116
+ mygene.fasta mygene_blastp_nr.txt
117
+ ```
118
+
119
+ ##### Use a package non-interactively
120
+
121
+ Alternatively, single commands can be run directly in a container
122
+ (e.g. BioLinux) without entering it interactively. This can
123
+ be useful to test new tools, or to run a single piece of
124
+ not-locally-installed software as part of a single command. The
125
+ container terminates automatically once the command has been
126
+ executed, output is printed to the terminal and can be redirected, and
127
+ the exit status of the command run within container is returned.
128
+
129
+ ```shell
130
+ # 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
132
+ ```
133
+
134
+ ##### Listing available operating system containers
135
+
136
+ OSwitch can pull any image from docker hub. You can see the images you pulled
137
+ from docker hub using oswitch as:
138
+
139
+ ```shell
140
+ pixel:~ $ oswitch -l
141
+ yeban/biolinux:8
142
+ ubuntu:14.04
143
+ ```
144
+
145
+ ##### Availability
146
+
147
+ OSwitch has been tested on:
148
+
149
+ * Mac OS X Yosemite
150
+ * Ubuntu 14.04.1
151
+ * CentOS 7
152
+
153
+ ##### Caveats
154
+
155
+ * Works only for Debian, Ubuntu, CentOS based docker images.
156
+ * Host directories/volumes with paths conflicting with container paths are
157
+ skipped.
158
+ * SELinux must be disabled on CentOS for mounting volumes to work.
159
+
160
+ ## Installation
161
+
162
+ OSwitch first requires a working docker install.
163
+
164
+ #### Install and setup docker
165
+
166
+ ##### Mac OS X
167
+
168
+ Installing docker - https://docs.docker.com/installation/mac/
169
+
170
+ ##### Ubuntu
171
+
172
+ Installing docker - https://docs.docker.com/installation/ubuntulinux/
173
+
174
+ Add yourself to docker group so you can run docker client without sudo:
175
+
176
+ ```shell
177
+ $ sudo usermod -aG docker `whoami`
178
+
179
+ # then logout and login again for the above command to take effect
180
+ ```
181
+
182
+ ##### CentOS
183
+
184
+ Installing docker - https://docs.docker.com/installation/centos/
185
+
186
+ Add yourself to docker group so you can run docker client without sudo:
187
+
188
+ ```shell
189
+ $ sudo usermod -aG docker `whoami`
190
+
191
+ # then logout and login again for the above command to take effect
192
+ ```
193
+
194
+ Disable SELinux as it gets in the way of mounting volumes within the container:
195
+
196
+ ```shell
197
+ $ sed -i .bak 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
198
+
199
+ # then reboot your system
200
+ ```
201
+
202
+ The above command backs up the original file to `/etc/selinux/config.bak`. If
203
+ you are concerned about disabling SELinux, do note that we are trying to work
204
+ out a better solution.
205
+
206
+ #### Test that docker is correctly installed
207
+
208
+ The following should give an encouraging message:
209
+
210
+ $ docker run hello-world
211
+
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
+ ## FAQ
223
+
224
+ ##### Q. Directories mounted within container on Mac host are empty.
225
+ The problem is, on Mac `boot2docker` is the _real_ host, not OS X. `oswitch`
226
+ can mount only what's available to it from `boot2docker`. For example,
227
+ `/Applications`.
228
+
229
+ Run `boot2docker ssh ls /Applications` and you will find it empty as well.
230
+
231
+ The workaround is to correctly mount the directories you want in `boot2docker`
232
+ first.
233
+
234
+ ```
235
+ boot2docker down
236
+ VBoxManage sharedfolder remove boot2docker-vm --name Applications
237
+ VBoxManage sharedfolder add boot2docker-vm --name Applications --hostpath /Applications
238
+ boot2docker up
239
+ boot2docker ssh "sudo mkdir -p /Applications && sudo mount -t vboxsf -o uid=1000,gid=50 Applications /Applications"
240
+ ```
241
+
242
+ ##### Q. cwd is empty in the container
243
+ This means the said directory was not mounted by oswitch, or was incorrectly
244
+ mounted. On Linux host, directories that can conflict with paths within
245
+ container are not mounted. On Mac, `boot2docker` can get in the way.
246
+
247
+ Please [report](https://github.com/yeban/oswitch/issues/new) this on our [issue
248
+ tracker](https://github.com/yeban/oswitch/issues). To help us debug, please
249
+ include:
250
+
251
+ 1. the directory in question
252
+ 2. the operating system you are running
253
+
254
+ ##### Q. oswitch does not work with my docker image
255
+ Please [report](https://github.com/yeban/oswitch/issues/new) this on our [issue
256
+ tracker](https://github.com/yeban/oswitch/issues) with oswitch's output. If the
257
+ image you are using is not available via docker hub or another public
258
+ repository, please include the Dockerfile as well.
259
+
260
+ ## Roadmap
261
+
262
+ 1. ~~make it possible to use docker containers without inheriting our
263
+ current baseimage~~
264
+ 2. ~~gem distribution for easier installation~~
265
+ 3. brew recipe for Mac
266
+ 4. test on QMUL's compute cluster
267
+ 5. create an SELinux policy to run oswitch on CentOS without having to disable
268
+ SELinux entirely
269
+ 6. rpm and deb packages
270
+ 7. make available images for common bioinformatics software
271
+ 8. deploy at [RAL/JASMIN](http://www.jasmin.ac.uk)
272
+
273
+ ## Contribute
274
+
275
+ $ git clone https://github.com/yeban/oswitch
276
+ $ cd oswitch
277
+ $ gem install bundler && bundle
278
+ $ bundle exec bin/oswitch biolinux
279
+
280
+ ## Contributors & Funding
281
+
282
+ * Anurag Priyam - [a.priyam@qmul.ac.uk](mailto:a.priyam@qmul.ac.uk) | [@yeban](//twitter.com/yeban)
283
+ * [Bruno Vieira](https://github.com/bmpvieira) ([@bmpvieira](//twitter.com/bmpvieira))
284
+ * [Saurabh Kumar](https://github.com/sa1)
285
+ * 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__)
288
+
289
+ ---
290
+
291
+ <p align="center">
292
+ Development funded as part of NERC EOS Cloud at
293
+ <a href="http://wurmlab.github.io/">Wurm Lab</a>,
294
+ <a href="http://sbcs.mul.ac.uk/">Queen Mary University of London</a>.
295
+ </p>
data/bin/oswitch ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'oswitch'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+ collect = lambda do |key|
8
+ lambda do |value|
9
+ options[key] = value
10
+ end
11
+ end
12
+
13
+ optspec = OptionParser.new do |opts|
14
+ opts.banner = "Usage: oswitch [options] <package> [cmd]"
15
+
16
+ opts.on '-l', '--list',
17
+ 'List packages.',
18
+ &collect[:list]
19
+
20
+ opts.on '-h', '--help',
21
+ 'Print help.',
22
+ &collect[:help]
23
+ end
24
+
25
+ begin
26
+ optspec.order!
27
+ rescue OptionParser::InvalidOption,
28
+ OptionParser::MissingArgument => e
29
+ puts e
30
+ exit
31
+ end
32
+
33
+ if options[:help] || (options.empty? && ARGV.empty?)
34
+ puts optspec
35
+ exit
36
+ end
37
+
38
+ if options[:list]
39
+ puts OSwitch.packages
40
+ exit
41
+ end
42
+
43
+ package = ARGV[0]
44
+ command = ARGV[1..-1]
45
+ OSwitch.to(package, command)
data/lib/oswitch.rb ADDED
@@ -0,0 +1,293 @@
1
+ require 'timeout'
2
+ require 'colorize'
3
+ require 'fileutils'
4
+ require 'shellwords'
5
+
6
+ # OSwitch leverages docker to provide access to complex Bioinformatics software
7
+ # (even Biolinux!) in just one command.
8
+ #
9
+ # Images are built on the user's system on demand and executed in a container.
10
+ # Containers are removed after execution.
11
+ #
12
+ # Volumes from host OS are mounted in the container just the same, including
13
+ # home directory. USER, HOME, SHELL, and PWD are preserved.
14
+ 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
138
+
139
+ DOTDIR = File.expand_path('~/.oswitch')
140
+
141
+ class << self
142
+ # Invoke as `OSwitch.to` instead of `OSwitch.new`.
143
+ alias_method :to, :new
144
+ private :new
145
+
146
+ def packages
147
+ Dir["#{DOTDIR}/*"].
148
+ select {|entry| File.directory? entry}.
149
+ map {|pkg|
150
+ pkg.gsub("#{DOTDIR}/", '')
151
+ }
152
+ end
153
+ end
154
+
155
+ def initialize(package, command = [])
156
+ @package = package.strip
157
+ @command = command.join(' ')
158
+ @imgname = "oswitch_#{@package}"
159
+ @cntname = "#{@package.gsub(%r{/|:}, '_')}-#{Process.pid}"
160
+ exec
161
+ end
162
+
163
+ attr_reader :package, :command, :imgname, :cntname
164
+
165
+ def exec
166
+ ping and build and switch
167
+ rescue ENODKR, ENOPKG => e
168
+ puts e
169
+ exit
170
+ end
171
+
172
+ private
173
+
174
+ def switch
175
+ cmdline = "docker run --name #{cntname} --hostname #{cntname} -it --rm" \
176
+ " -w #{cwd} #{mountargs} #{imgname} "
177
+ if command.empty?
178
+ # Display motd and run interactive shell.
179
+ cmdline << "#{shell} -c \"echo #{motd}; #{shell} -i\""
180
+ else
181
+ cmdline << "#{shell} -c \"#{command}\""
182
+ end
183
+ Kernel.exec cmdline
184
+ end
185
+
186
+ def build
187
+ return true if Image.exists? imgname
188
+ write_context && system("docker build -t #{imgname} #{context_dir}")
189
+ end
190
+
191
+ # Ping docker daemon. Raise error if no response within 10s.
192
+ def ping
193
+ pong = timeout 5, ENODKR do
194
+ system 'docker info > /dev/null 2>&1'
195
+ end
196
+ pong or raise ENODKR
197
+ end
198
+
199
+ ## Code to generate context dir that will be built into a docker image. ##
200
+
201
+ # Write data to context dir.
202
+ def write_context
203
+ create_context_dir
204
+ write_dockerfile
205
+ end
206
+
207
+ # Create context dir.
208
+ def create_context_dir
209
+ FileUtils.mkdir_p context_dir
210
+ FileUtils.cp_r(template_files, context_dir)
211
+ end
212
+
213
+ # Write Dockerfile.
214
+ def write_dockerfile
215
+ dockerfile = File.join(context_dir, 'Dockerfile')
216
+ File.write(dockerfile, dockerfile_data)
217
+ end
218
+
219
+ # Generate String that get written to Dockerfile.
220
+ def dockerfile_data
221
+ data = ["FROM #{package}"]
222
+ data << 'COPY _switch /'
223
+ data << 'COPY wheel /etc/sudoers.d/'
224
+ data << "RUN /_switch #{userargs} 2>&1 | tee /tmp/oswitch.log"
225
+ data << 'ENV LC_ALL en_US.UTF-8'
226
+ data << "USER #{username}"
227
+ data << "ENTRYPOINT [\"#{shell}\", \"-c\"]"
228
+ data.join("\n")
229
+ end
230
+
231
+ # Location of context dir.
232
+ def context_dir
233
+ File.join(DOTDIR, package)
234
+ end
235
+
236
+ # Location of template dir.
237
+ def template_dir
238
+ File.expand_path('../context/', File.dirname(__FILE__))
239
+ end
240
+
241
+ # Template files.
242
+ def template_files
243
+ Dir[File.join(template_dir, '*')]
244
+ end
245
+
246
+
247
+ ## Data required to switchify a container. ##
248
+ def username
249
+ ENV['USER']
250
+ end
251
+
252
+ def home
253
+ ENV['HOME']
254
+ end
255
+
256
+ def shell
257
+ File.basename ENV['SHELL']
258
+ end
259
+
260
+ def cwd
261
+ Dir.pwd
262
+ end
263
+
264
+ def motd
265
+ str =<<MOTD
266
+ ################################################################################
267
+ You are now running: #{package}, in container: #{cntname}.
268
+
269
+ Container is distinct from the shell your launched this container from. Changes
270
+ you make here will be lost unless it's made to one of the directories below:
271
+
272
+ - #{mountpoints.join("\n - ")}
273
+
274
+ It's possible you may not be able to write to one or more directories above,
275
+ but it should be possible to read data from all. Home directory is often the
276
+ safest to write to.
277
+
278
+ Press Ctrl-D or type 'exit' to go back.
279
+ ################################################################################
280
+ MOTD
281
+ str.blue.shellescape
282
+ end
283
+
284
+ def mountargs
285
+ mountpoints.map do |mountpoint|
286
+ "-v '#{mountpoint}':'#{mountpoint}'"
287
+ end.join(' ')
288
+ end
289
+
290
+ def userargs
291
+ [uid, gid, username, home, shell].join(' ')
292
+ end
293
+ end
data/oswitch.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |s|
2
+ # meta
3
+ s.name = 'oswitch'
4
+ s.version = '0.1.0'
5
+ s.authors = ['Anurag Priyam']
6
+ s.email = ['anurag08priyam@gmail.com']
7
+ s.homepage = 'https://github.com/yeban/oswitch'
8
+ s.license = 'MIT'
9
+
10
+ s.summary = "Use docker image as the host operating system's user and \
11
+ access host operating system's filesystem."
12
+ s.description = <<DESC
13
+ Use any docker image as the host operating system's user (same user name, same
14
+ uid, same gid, and even the same shell!) and access to host operating system's
15
+ filesystem.
16
+ DESC
17
+
18
+ # dependencies
19
+ s.add_dependency('colorize', '~> 0.7.5')
20
+
21
+ # gem
22
+ s.files = Dir['lib/**/*'] + Dir['Dockerfiles/**/*']
23
+ s.files = s.files + ['Gemfile', 'oswitch.gemspec']
24
+ s.files = s.files + ['README.mkd']
25
+ s.require_paths = ['lib']
26
+ s.executables = ['oswitch']
27
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oswitch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anurag Priyam
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.5
27
+ description: |
28
+ Use any docker image as the host operating system's user (same user name, same
29
+ uid, same gid, and even the same shell!) and access to host operating system's
30
+ filesystem.
31
+ email:
32
+ - anurag08priyam@gmail.com
33
+ executables:
34
+ - oswitch
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - Gemfile
39
+ - README.mkd
40
+ - bin/oswitch
41
+ - lib/oswitch.rb
42
+ - oswitch.gemspec
43
+ homepage: https://github.com/yeban/oswitch
44
+ licenses:
45
+ - MIT
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.4.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Use docker image as the host operating system's user and access host operating
67
+ system's filesystem.
68
+ test_files: []