in build_docs.pl [872:964]
sub init_env {
#===================================
if (exists $ENV{SSH_AUTH_SOCK}
&& $ENV{SSH_AUTH_SOCK} eq '/tmp/forwarded_ssh_auth') {
print "Waiting for ssh auth to be forwarded to " . hostname . "\n";
while (<>) {
# Read from stdin waiting for the signal that we're ready. We
# use stdin here because it prevents us from leaving the docker
# container running if something goes wrong with the forwarding
# process. The mechanism of action is that when something goes
# wrong build_docs will die, closing stdin. That will cause us
# to drop out of this loop and cause the process to terminate.
last if ($_ eq "ready\n");
}
die '/tmp/forwarded_ssh_auth is missing' unless (-e '/tmp/forwarded_ssh_auth');
print "Found ssh auth\n";
}
if ( $Opts->{preview} ) {
# `--preview` is run in k8s it doesn't *want* a tty
# so it should avoid doing housekeeping below.
return;
}
# If we're in docker we're relying on closing stdin to cause an orderly
# shutdown because it is really the only way for us to know for sure
# that the python build_docs process thats on the host is dead.
# Since perl's threads are "not recommended" we fork early in the run
# process and have the parent synchronously wait read from stdin. A few
# things can happen here and each has a comment below:
if ( my $child_pid = fork ) {
$SIG{CHLD} = sub {
# The child process exits so we should exit with whatever
# exit code it gave us. This can also come about because the
# child process is killed.
use POSIX ":sys_wait_h";
my $child_status = 'missing';
while ((my $child = waitpid(-1, WNOHANG)) > 0) {
my $status = $? >> 8;
if ( $child == $child_pid ) {
$child_status = $status;
} else {
# Some other subprocess died on us. The calling code
# will handle it.
}
}
exit $child_status unless ( $child_status eq 'missing');
};
$SIG{INT} = sub {
# We're interrupted. This'll happen if we somehow end up in
# the foreground. It isn't likely, but if it does happen we
# should interrupt the child just in case it wasn't already
# interrupted and then exit with whatever code the child exits
# with.
kill 'INT', $child_pid;
wait;
exit $? >> 8;
};
$SIG{TERM} = sub {
# We're terminated. We should pass on the love to the
# child process and return its exit code.
kill 'TERM', $child_pid;
wait;
exit $? >> 8;
};
while (<>) {}
# STDIN is closed. This'll happen if the python build_docs process
# on the host dies for some reason. When the host process dies we
# should do our best to die too so the docker container exits and
# is removed. We do that by interrupting the child and exiting with
# whatever exit code it exits with.
kill 'TERM', $child_pid;
wait;
exit $? >> 8;
}
# If we're running in docker then we won't have a useful username
# so we hack one into place with nss wrapper.
open(my $override, '>', '/tmp/passwd')
or dir("Couldn't write override user file");
# We use the `id` command here because it fetches the id. The native
# perl way to do this (getpwuid($<)) doesn't work because it needs a
# complete user. And we *aren't* one.
my $uid = `id -u`;
my $gid = `id -g`;
chomp($uid);
chomp($gid);
print $override "docker:x:$uid:$gid:docker:/tmp:/bin/bash\n";
close $override;
$ENV{LD_PRELOAD} = '/usr/lib/libnss_wrapper.so';
$ENV{NSS_WRAPPER_PASSWD} = '/tmp/passwd';
$ENV{NSS_WRAPPER_GROUP} = '/etc/group';
}