Container-Buildah

 view release on metacpan or  search on metacpan

lib/Container/Buildah/Stage.pm  view on Meta::CPAN

		$self->status("build tarball ($tarball_result): $tarball_out");
	}

	#
	# run container for this stage
	# commit it if configured (usually that's only for the final stage)
	# otherwise a stage is discarded except for its product tarball
	#

	# if the container exists, remove it
	$self->rmcontainer;

	# get the base image
	my $cb = Container::Buildah->instance();
	$cb->from({name => $self->container_name}, $self->get_from);

	# get copy of @ARGV saved by main() for use here re-launching in namespace
	my $argv_ref = Container::Buildah->get_config("argv");
	if (ref $argv_ref ne "ARRAY") {
		confess "wrong type for argv - expected ARRAY ref, got ".(ref $argv_ref);
	}

	# run the builder script in the container
	$cb->unshare({container => $self->container_name,
		envname => $mnt_env_name},
		progpath(),
		"--internal=".$self->get_name,
		@$argv_ref,
		);

	# commit the container if configured
	my $commit = $self->get_commit;
	my @tags;
	if (defined $commit) {
		if (not ref $commit) {
			@tags = ($commit);
		} elsif (ref $commit eq "ARRAY") {
			@tags = @$commit;
		} else {
			confess "reference to ".(ref $commit)." not supported in commit - use scalar or array";
		}
	}
	my $image_name = shift @tags;
	$self->commit($image_name);
	if (@tags) {
		$cb->tag({image => $image_name}, @tags);
	}
	return;
}

# import tarball(s) from other container stages if configured
# private instance method
sub consume
{
	my $self = shift;

	# create groups and users before import
	my $user = $self->get_user;
	if (defined $self->get_user) {
		my $user_name = $user;
		my ($uid, $group_name, $gid);
		if ($user =~ /:/x) {
			($user_name, $group_name) = split /:/x, $user;
			if ($user_name =~ /=/x) {
				($user_name, $uid) = split /=/x, $user_name;
			}
			if ($group_name =~ /=/x) {
				($group_name, $gid) = split /=/x, $group_name;
			}
		}
		# TODO: find distro-independent approach instead of assuming Linux Fileystem Standard /usr/sbin paths
		if (defined $group_name) {
			$self->run(["/usr/sbin/groupadd", ((defined $gid) ? ("--gid=$gid") : ()), $group_name]);
		}
		my $user_home = $self->get_user_home;
		$self->run(
			["/usr/sbin/useradd", ((defined $uid) ? ("--uid=$uid") : ()),
				((defined $group_name) ? ("--gid=$group_name") : ()),
				((defined $user_home) ? ("--home-dir=$user_home") : ()), $user_name],
		);
	}

	# import tarballs from each stage we depend upon
	my $consumes = $self->get_consumes;
	if (defined $consumes) {
		if (ref $consumes eq "ARRAY") {
			my @in_stages = @$consumes;
			my $cwd = getcwd();
			foreach my $in_stage (@in_stages) {
				my $tarball_in = $self->tarball($in_stage);
				$self->debug("in ".$self->get_name." stage before untar; pid=$$ cwd=$cwd tarball=$tarball_in");
				(-f $tarball_in) or croak "consume(".join(" ", @in_stages)."): ".$tarball_in." not found";
				$self->add({dest => "/"}, $tarball_in);
			}
		} else {
			croak "consume stage->consumes was set but not an array ref";
		}
	}
	return;
}

# drop leading slash from a path
# private class function
sub dropslash
{
	my $str = shift;
	if (substr($str,0,1) eq '/') {
		substr($str,0,1,'');
	}
	return $str;
}

# export tarball for availability to other container stages if configured
# private instance method
sub produce
{
	my $self = shift;

	# export directories to tarball for product of this stage
	my $produces = $self->get_produces;
	if (defined $produces) {
		if (ref $produces eq "ARRAY") {
			my $tarball_out = $self->tarball;
			my $cb = Container::Buildah->instance();
			my @product_dirs;
			foreach my $product (@$produces) {
				push @product_dirs, dropslash($product);
			}

			# move any existing tarball to backup
			if ( -f $tarball_out ) {
				rename $tarball_out, $tarball_out.".bak";
			}

			# create the tarball
			my $cwd = getcwd();
			$self->debug("in ".$self->get_name." stage before tar; pid=$$ cwd=$cwd product_dirs="
				.join(" ", @product_dirs));



( run in 1.954 second using v1.01-cache-2.11-cpan-5735350b133 )