diff --git a/lib/Sys/Linux/Mount.pm b/lib/Sys/Linux/Mount.pm index daf7bc2..242370b 100644 --- a/lib/Sys/Linux/Mount.pm +++ b/lib/Sys/Linux/Mount.pm @@ -12,6 +12,7 @@ my @mount_consts = qw/MS_RDONLY MS_NOSUID MS_NODEV MS_NOEXEC MS_SYNCHRONOUS MS_R our @EXPORT_OK = (@mount_consts, qw/mount/); our %EXPORT_TAGS = ( + 'consts' => \@mount_consts, 'all' => [@mount_consts, qw/mount/], ); diff --git a/lib/Sys/Linux/Namespace.pm b/lib/Sys/Linux/Namespace.pm new file mode 100644 index 0000000..a28529a --- /dev/null +++ b/lib/Sys/Linux/Namespace.pm @@ -0,0 +1,43 @@ +package Sys::Linux::Namespace; + +use strict; +use warnings; + +use Sys::Linux::Mount qw/:all/; +use Sys::Linux::Unshare qw/:all/; + +sub namespace { + my ($options) = @_; + + my $uflags = 0; + my $mflags = 0; + + if ($options->{pid}) { + die "TODO, need to setup a proper 'init' PID 1"; + } + + if ($options->{mount} || $options->{private_mount} || $options->{private_tmp}) { + $uflags |= CLONE_NEWNS; + } + + if ($options->{net}) { + die "TODO, need to setup network interfaces"; + } + + unshare($uflags); + + # If we want a private /tmp, or private mount we need to recursively make every mount private. it CAN be done without that but this is more reliable. + if ($options->{private_mount} || $options->{private_tmp}) { + mount("/", "/", undef, MS_REC|MS_PRIVATE, undef); + } + + if ($options->{private_tmp}) { + if (ref $options->{private_tmp} eq 'HASH') { + mount("/tmp", "/tmp", "tmpfs", MS_PRIVATE, $options->{private_tmp}); + } elsif (ref $options->{private_tmp}) { + die "Bad ref type passed as private_tmp"; + } else { + mount("/tmp", "/tmp", "tmpfs", MS_PRIVATE, undef); + } + } +} diff --git a/lib/Sys/Linux/Unshare.pm b/lib/Sys/Linux/Unshare.pm index 812e6c8..1ebc283 100644 --- a/lib/Sys/Linux/Unshare.pm +++ b/lib/Sys/Linux/Unshare.pm @@ -12,7 +12,8 @@ my @unshare_consts = qw/CSIGNAL CLONE_VM CLONE_FS CLONE_FILES CLONE_SIGHAND CLON our @EXPORT_OK = (@unshare_consts, qw/unshare/); our %EXPORT_TAGS = ( - 'all' => [@unshare_consts, qw/unshare/], + 'consts' => \@unshare_consts, + 'all' => [@unshare_consts, qw/unshare/], ); sub unshare {