// The current architecture.
string arch;
- // The script path that builds a container.
- string container_build_script_path;
+ // The script path that builds a container docker file.
+ string build_docker_file_script_path;
};
docker_path.clear();
}
- container_build_script_path = string(PKGLIBDIR)
- + "/httpd/docker/stap_build_docker_image.py";
+ build_docker_file_script_path = string(PKGLIBDIR)
+ + "/httpd/docker/stap_build_docker_file.py";
datadir = string(PKGDATADIR) + "/httpd/docker";
string stap_image_uuid = "stap." + uuid + "." + datetime;
- // Kick off building the container image. Note we're using the
- // UUID as the container image name. This keeps us from trying to
- // build multiple images with the same name at the same time.
+ // Note we're creating a new temporary directory here. This is so
+ // that if we reuse the container we're about to build, no files
+ // from this run could "leak" over into a new run with the same
+ // container.
+ char tmp_dir_template[] = "/tmp/stap-httpd.XXXXXX";
+ char *tmp_dir_ptr;
+ tmp_dir_ptr = mkdtemp(tmp_dir_template);
+ if (tmp_dir_ptr == NULL) {
+ // Return an error.
+ server_error(_F("mkdtemp failed: %s", strerror(errno)));
+ return -1;
+ }
+
vector<string> cmd_args;
#if defined(PYTHON3_BASENAME)
cmd_args.push_back(PYTHON3_BASENAME);
#else
#error "Couldn't find python version 2 or 3."
#endif
- cmd_args.push_back(container_build_script_path);
+ cmd_args.push_back(build_docker_file_script_path);
cmd_args.push_back("--distro-file");
cmd_args.push_back(data_files[crd->distro_name]);
cmd_args.push_back("--build-file");
cmd_args.push_back(build_data_path);
cmd_args.push_back("--data-dir");
cmd_args.push_back(datadir);
- cmd_args.push_back(stap_image_uuid);
-
+ cmd_args.push_back("--dest-dir");
+ cmd_args.push_back(tmp_dir_ptr);
int rc = execute_and_capture(2, cmd_args, crd->env_vars,
container_stdout_path, container_stderr_path);
server_error(_F("Spawned process returned %d", rc));
if (rc != 0) {
server_error(_F("%s failed.",
- container_build_script_path.c_str()));
+ build_docker_file_script_path.c_str()));
+ return -1;
+ }
+
+ // Kick off building the container image. Note we're using the
+ // UUID as the container image name. This keeps us from trying to
+ // build multiple images with the same name at the same time.
+ string docker_file_path = string(tmp_dir_ptr) + "/base.docker";
+ cmd_args.clear();
+ cmd_args.push_back("docker");
+ cmd_args.push_back("build");
+ cmd_args.push_back("-t");
+ cmd_args.push_back(stap_image_uuid);
+ cmd_args.push_back("-f");
+ cmd_args.push_back(docker_file_path);
+ cmd_args.push_back(tmp_dir_ptr);
+ rc = execute_and_capture(2, cmd_args, crd->env_vars,
+ container_stdout_path, container_stderr_path);
+ server_error(_F("Spawned process returned %d", rc));
+ if (rc != 0) {
+ server_error("docker build failed.");
return -1;
}
+ // We're done with the temporary directory we created above.
+ vector<string> cleanupcmd { "rm", "-rf", tmp_dir_ptr };
+ rc = stap_system(0, cleanupcmd);
+ if (rc != 0)
+ server_error (_("Error in tmpdir cleanup"));
+ if (crd->verbose > 1)
+ server_error(_F("Removed temporary directory \"%s\"", tmp_dir_ptr));
+
// The client can optionally send over a "client.zip" file, which
// was unziped up in build_info::module_build(). If it exists, we
// need to copy those files down into the container image before
# Make sure all the JSON files get installed.
pkgdatadocker_DATA += $(wildcard $(srcdir)/*.json)
-pkglibexecdocker_PYTHON += stap_build_docker_image.py
+pkglibexecdocker_PYTHON += stap_build_docker_file.py
endif
# Make sure all the JSON files get installed.
@HAVE_HTTP_SUPPORT_TRUE@am__append_1 = fedora_install_package.py \
@HAVE_HTTP_SUPPORT_TRUE@ $(wildcard $(srcdir)/*.json)
-@HAVE_HTTP_SUPPORT_TRUE@am__append_2 = stap_build_docker_image.py
+@HAVE_HTTP_SUPPORT_TRUE@am__append_2 = stap_build_docker_file.py
subdir = httpd/docker
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-am__pkglibexecdocker_PYTHON_DIST = stap_build_docker_image.py
+am__pkglibexecdocker_PYTHON_DIST = stap_build_docker_file.py
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
def _usage():
"""Display command-line usage."""
_eprint('Usage: %s [-v] --distro-file DISTRO_JSON_FILE'
- ' --build-file DATA_JSON_FILE --data-dir DATA_DIR DOCKER_TAG'
+ ' --build-file DATA_JSON_FILE --data-dir DATA_DIR'
+ ' --dest-dir DEST_DIR'
% sys.argv[0])
sys.exit(1)
try:
(opts, pargs) = getopt.getopt(sys.argv[1:], 'v',
['distro-file=', 'build-file=',
- 'data-dir='])
+ 'data-dir=', 'dest-dir='])
except getopt.GetoptError as err:
_eprint("Error: %s" % err)
_usage()
ivars['BUILD_FILE'] = value
elif opt == '--data-dir':
ivars['DATA_DIR'] = value
+ elif opt == '--dest-dir':
+ ivars['DEST_DIR'] = value
- if len(pargs) != 1:
- _eprint("No DOCKER_TAG specified.")
+ if len(pargs) != 0:
+ _eprint("Extra argument found.")
_usage()
if 'DISTRO_FILE' not in ivars or 'BUILD_FILE' not in ivars \
- or 'DATA_DIR' not in ivars:
- _eprint("Arguments '--distro-file', '--build-file', and '--data-dir' are required.")
+ or 'DATA_DIR' not in ivars or 'DEST_DIR' not in ivars:
+ _eprint("Arguments '--distro-file', '--build-file',"
+ " '--data-dir', and '--dest-dir' are required.")
_usage()
- ivars['DOCKER_TAG'] = pargs[0]
return (verbose, ivars)
def _load_distro_file(distro_path):
(verbose, ivars) = _handle_command_line()
- # Create a temporary directory for our use.
- tmpdir_path = tempfile.mkdtemp()
-
# Read the distro file.
distro_json = _load_distro_file(ivars['DISTRO_FILE'])
ivars['DVER'] = build_json['distro_version']
# If we've got a distro-specific script needed to install
- # packages, copy it to the temporary directory, since type docker
- # 'COPY' directive only works on paths relative to the temporary
+ # packages, copy it to the destination directory, since the docker
+ # 'COPY' directive only works on paths relative to the destination
# directory.
if 'distro_package_installer' in distro_json:
try:
src_path = os.path.join(ivars['DATA_DIR'],
distro_json['distro_package_installer'])
- shutil.copy(src_path, tmpdir_path)
+ shutil.copy(src_path, ivars['DEST_DIR'])
except (shutil.Error, IOError) as err:
_eprint("Error: copy failed: %s" % err)
sys.exit(1)
dockerfile_data += template.substitute(ivars)
# Write the dockerfile data to a file.
- dockerfile_path = "%s/%s.docker" % (tmpdir_path, ivars['DOCKER_TAG'])
+ dockerfile_path = ("%s/base.docker" % ivars['DEST_DIR'])
tmpfile = open(dockerfile_path, "w")
tmpfile.write(dockerfile_data)
tmpfile.close()
- print("created file in %s\n" % tmpdir_path)
+ print("created file in %s\n" % ivars['DEST_DIR'])
+
+ # At this point we've created the docker file, so we're done.
+ sys.exit(0)
+
- # At this point we've created the docker file. Actually
# build the docker container image. Arguments:
#
# -t TAG: Repository names (and optionally with tags) to be