runshare 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +21 -0
- data/README.md +103 -0
- data/Rakefile +14 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/runshare/extconf.rb +33 -0
- data/ext/runshare/include/all-io.h +115 -0
- data/ext/runshare/include/c.h +479 -0
- data/ext/runshare/include/caputils.h +34 -0
- data/ext/runshare/include/namespace.h +56 -0
- data/ext/runshare/include/pathnames.h +218 -0
- data/ext/runshare/include/pwdutils.h +14 -0
- data/ext/runshare/include/signames.h +8 -0
- data/ext/runshare/include/strutils.h +393 -0
- data/ext/runshare/runshare.c +261 -0
- data/ext/runshare/unshare.c +498 -0
- data/ext/runshare/unshare.h +82 -0
- data/lib/runshare/version.rb +3 -0
- data/lib/runshare.rb +7 -0
- data/runshare.gemspec +44 -0
- metadata +231 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cb0cad2d91fecadd6f8e1b1068f37cf8c4a44623
|
4
|
+
data.tar.gz: 67fdb4217e143f4e0fe1673807bd34fa42836885
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9f93b3354a8a51d911895fd367092a8773bfed1c98efa515e09ab250034fe498fd03cb75add6b461b975a55db0031a273fbeacc8462f9f866a67bd5fbfacdbf1
|
7
|
+
data.tar.gz: cf463e5f29ed3f93cdf8b6c3df53077c70a2cc4db846a534c3374ab8a4e911a9fdbe289eaf4ca709a7291216141c0dbf4a510fdd13d0efa9835e4835cdf26bba
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/_yardoc/
|
4
|
+
/coverage/
|
5
|
+
/doc/
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/tmp/
|
9
|
+
/.idea/
|
10
|
+
.tool-versions
|
11
|
+
CMakeLists.txt
|
12
|
+
/cmake-build-debug/
|
13
|
+
|
14
|
+
*.bundle
|
15
|
+
*.so
|
16
|
+
*.o
|
17
|
+
*.a
|
18
|
+
mkmf.log
|
19
|
+
|
20
|
+
# rspec failure tracking
|
21
|
+
.rspec_status
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
runshare (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.4.4)
|
10
|
+
rake (10.5.0)
|
11
|
+
rake-compiler (1.1.1)
|
12
|
+
rake
|
13
|
+
rspec (3.10.0)
|
14
|
+
rspec-core (~> 3.10.0)
|
15
|
+
rspec-expectations (~> 3.10.0)
|
16
|
+
rspec-mocks (~> 3.10.0)
|
17
|
+
rspec-core (3.10.1)
|
18
|
+
rspec-support (~> 3.10.0)
|
19
|
+
rspec-expectations (3.10.1)
|
20
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
+
rspec-support (~> 3.10.0)
|
22
|
+
rspec-mocks (3.10.2)
|
23
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
+
rspec-support (~> 3.10.0)
|
25
|
+
rspec-support (3.10.2)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
bundler (~> 1.17)
|
32
|
+
runshare!
|
33
|
+
rake (~> 10.0)
|
34
|
+
rake-compiler
|
35
|
+
rspec (~> 3.0)
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
1.17.3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Ivan Prisyazhnyy
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# ruby unshare (runshare)
|
2
|
+
|
3
|
+
This tool allows to unshare Linux namespaces.
|
4
|
+
The implementation is similar to the unshare(1) tool.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'runshare'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install runshare
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
> require "runshare"
|
25
|
+
> RUnshare::unshare
|
26
|
+
|
27
|
+
For example:
|
28
|
+
|
29
|
+
cat > test.rb
|
30
|
+
|
31
|
+
require "runshare"
|
32
|
+
|
33
|
+
pid = RUnshare::unshare(
|
34
|
+
:clone_newpid => true,
|
35
|
+
:clone_newns => true,
|
36
|
+
:clone_newcgroup => true,
|
37
|
+
:clone_newipc => true,
|
38
|
+
:clone_newuts => true,
|
39
|
+
:clone_newnet => true,
|
40
|
+
:clone_newtime => true,
|
41
|
+
:fork => true,
|
42
|
+
:mount_proc => "/proc",
|
43
|
+
# docker export $(docker create hello-world) | tar -xf - -C rootfs
|
44
|
+
:root => "/tmp/rootfs"
|
45
|
+
)
|
46
|
+
|
47
|
+
if pid == 0
|
48
|
+
# child
|
49
|
+
puts "--- #{Process.pid}"
|
50
|
+
if system("/hello") != true
|
51
|
+
raise "bad"
|
52
|
+
end
|
53
|
+
puts "--- done"
|
54
|
+
else
|
55
|
+
# parent
|
56
|
+
puts "-- unshare=#{pid}, pid=#{Process.pid}"
|
57
|
+
puts "-- exit=#{Process.waitpid(pid)}"
|
58
|
+
end
|
59
|
+
|
60
|
+
^D
|
61
|
+
|
62
|
+
sudo ruby -I ./lib ./test.rb
|
63
|
+
|
64
|
+
## Quick start
|
65
|
+
|
66
|
+
$ rake compile && echo 'require "runshare"; RUnshare::unshare(:clone_newuts => true)' | irb
|
67
|
+
install -c tmp/x86_64-linux/runshare/2.4.10/runshare.so lib/runshare/runshare.so
|
68
|
+
cp tmp/x86_64-linux/runshare/2.4.10/runshare.so tmp/x86_64-linux/stage/lib/runshare/runshare.so
|
69
|
+
Switch to inspect mode.
|
70
|
+
require "runshare"; RUnshare::unshare
|
71
|
+
|
72
|
+
## Ruby <2.5
|
73
|
+
|
74
|
+
If your app is single threaded and you are observing:
|
75
|
+
|
76
|
+
eval:1: warning: pthread_create failed for timer: Invalid argument, scheduling broken
|
77
|
+
|
78
|
+
Just ignore it with some degree of bravity. You also
|
79
|
+
can silence it by setting:
|
80
|
+
|
81
|
+
$VERBOSE = nil
|
82
|
+
|
83
|
+
## Development
|
84
|
+
|
85
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
86
|
+
Then, run `rake spec` to run the tests.
|
87
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
88
|
+
|
89
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
90
|
+
To release a new version, update the version number in `version.rb`,
|
91
|
+
and then run `bundle exec rake release`, which will create a git tag
|
92
|
+
for the version, push git commits and tags, and push the `.gem` file
|
93
|
+
to [rubygems.org](https://rubygems.org).
|
94
|
+
|
95
|
+
## Contributing
|
96
|
+
|
97
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sitano/runshare.
|
98
|
+
This project is intended to be a safe, welcoming space for collaboration,
|
99
|
+
and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
100
|
+
|
101
|
+
## License
|
102
|
+
|
103
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
require "rake/extensiontask"
|
7
|
+
|
8
|
+
task :build => :compile
|
9
|
+
|
10
|
+
Rake::ExtensionTask.new("runshare") do |ext|
|
11
|
+
ext.lib_dir = "lib/runshare"
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => [:clobber, :compile, :spec]
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "runshare"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
append_cflags('-D_GNU_SOURCE')
|
4
|
+
append_cflags('-DPACKAGE_STRING="\"runshare\""')
|
5
|
+
append_cflags('-Wno-discarded-qualifiers')
|
6
|
+
|
7
|
+
if have_func("nanosleep", "time.h")
|
8
|
+
$defs.push("-DHAVE_NANOSLEEP")
|
9
|
+
elsif have_func("usleep", "time.h")
|
10
|
+
$defs.push("-DHAVE_USLEEP")
|
11
|
+
end
|
12
|
+
|
13
|
+
if have_func("fsync", "unistd.h")
|
14
|
+
$defs.push("-DHAVE_FSYNC")
|
15
|
+
end
|
16
|
+
|
17
|
+
if have_func("vasprintf", "stdio.h")
|
18
|
+
$defs.push("-DHAVE_VASPRINTF")
|
19
|
+
end
|
20
|
+
|
21
|
+
if have_func("unshare", "sys/syscall.h")
|
22
|
+
$defs.push("-DHAVE_UNSHARE")
|
23
|
+
end
|
24
|
+
if have_func("setns", "sys/syscall.h")
|
25
|
+
$defs.push("-DHAVE_SETNS")
|
26
|
+
end
|
27
|
+
if have_func("err", "err.h")
|
28
|
+
$defs.push("-DHAVE_ERR_H")
|
29
|
+
end
|
30
|
+
|
31
|
+
$srcs = ["runshare.c", "unshare.c"]
|
32
|
+
|
33
|
+
create_makefile("runshare/runshare")
|
@@ -0,0 +1,115 @@
|
|
1
|
+
/*
|
2
|
+
* No copyright is claimed. This code is in the public domain; do with
|
3
|
+
* it what you wish.
|
4
|
+
*
|
5
|
+
* Written by Karel Zak <kzak@redhat.com>
|
6
|
+
* Petr Uzel <petr.uzel@suse.cz>
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef UTIL_LINUX_ALL_IO_H
|
10
|
+
#define UTIL_LINUX_ALL_IO_H
|
11
|
+
|
12
|
+
#include <string.h>
|
13
|
+
#include <unistd.h>
|
14
|
+
#include <errno.h>
|
15
|
+
#include <sys/types.h>
|
16
|
+
#ifdef HAVE_SYS_SENDFILE_H
|
17
|
+
# include <sys/sendfile.h>
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#include "c.h"
|
21
|
+
|
22
|
+
static inline int write_all(int fd, const void *buf, size_t count)
|
23
|
+
{
|
24
|
+
while (count) {
|
25
|
+
ssize_t tmp;
|
26
|
+
|
27
|
+
errno = 0;
|
28
|
+
tmp = write(fd, buf, count);
|
29
|
+
if (tmp > 0) {
|
30
|
+
count -= tmp;
|
31
|
+
if (count)
|
32
|
+
buf = (const void *) ((const char *) buf + tmp);
|
33
|
+
} else if (errno != EINTR && errno != EAGAIN)
|
34
|
+
return -1;
|
35
|
+
if (errno == EAGAIN) /* Try later, *sigh* */
|
36
|
+
xusleep(250000);
|
37
|
+
}
|
38
|
+
return 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
static inline int fwrite_all(const void *ptr, size_t size,
|
42
|
+
size_t nmemb, FILE *stream)
|
43
|
+
{
|
44
|
+
while (nmemb) {
|
45
|
+
size_t tmp;
|
46
|
+
|
47
|
+
errno = 0;
|
48
|
+
tmp = fwrite(ptr, size, nmemb, stream);
|
49
|
+
if (tmp > 0) {
|
50
|
+
nmemb -= tmp;
|
51
|
+
if (nmemb)
|
52
|
+
ptr = (const void *) ((const char *) ptr + (tmp * size));
|
53
|
+
} else if (errno != EINTR && errno != EAGAIN)
|
54
|
+
return -1;
|
55
|
+
if (errno == EAGAIN) /* Try later, *sigh* */
|
56
|
+
xusleep(250000);
|
57
|
+
}
|
58
|
+
return 0;
|
59
|
+
}
|
60
|
+
|
61
|
+
static inline ssize_t read_all(int fd, char *buf, size_t count)
|
62
|
+
{
|
63
|
+
ssize_t ret;
|
64
|
+
ssize_t c = 0;
|
65
|
+
int tries = 0;
|
66
|
+
|
67
|
+
memset(buf, 0, count);
|
68
|
+
while (count > 0) {
|
69
|
+
ret = read(fd, buf, count);
|
70
|
+
if (ret < 0) {
|
71
|
+
if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) {
|
72
|
+
xusleep(250000);
|
73
|
+
continue;
|
74
|
+
}
|
75
|
+
return c ? c : -1;
|
76
|
+
}
|
77
|
+
if (ret == 0)
|
78
|
+
return c;
|
79
|
+
tries = 0;
|
80
|
+
count -= ret;
|
81
|
+
buf += ret;
|
82
|
+
c += ret;
|
83
|
+
}
|
84
|
+
return c;
|
85
|
+
}
|
86
|
+
|
87
|
+
static inline ssize_t sendfile_all(int out, int in, off_t *off, size_t count)
|
88
|
+
{
|
89
|
+
#if defined(HAVE_SENDFILE) && defined(__linux__)
|
90
|
+
ssize_t ret;
|
91
|
+
ssize_t c = 0;
|
92
|
+
int tries = 0;
|
93
|
+
while (count) {
|
94
|
+
ret = sendfile(out, in, off, count);
|
95
|
+
if (ret < 0) {
|
96
|
+
if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) {
|
97
|
+
xusleep(250000);
|
98
|
+
continue;
|
99
|
+
}
|
100
|
+
return c ? c : -1;
|
101
|
+
}
|
102
|
+
if (ret == 0)
|
103
|
+
return c;
|
104
|
+
tries = 0;
|
105
|
+
count -= ret;
|
106
|
+
c += ret;
|
107
|
+
}
|
108
|
+
return c;
|
109
|
+
#else
|
110
|
+
errno = ENOSYS;
|
111
|
+
return -1;
|
112
|
+
#endif
|
113
|
+
}
|
114
|
+
|
115
|
+
#endif /* UTIL_LINUX_ALL_IO_H */
|