Skip to content

Make AppRun script dependency free #395

Description

@lalten

Currently rules_appimage uses an AppRun script created here:

apprun_lines.append('OWD="${OWD=$PWD}"') # remove when https://github.com/AppImage/type2-runtime/issues/23 is fixed
apprun_lines.append('BUILD_WORKING_DIRECTORY="${BUILD_WORKING_DIRECTORY=$OWD}"')
apprun_lines.append("export BUILD_WORKING_DIRECTORY")
# Some environment variables set by Bazel at runtime that interfere with runfiles resolution need to be unset.
# This can be important when running an AppImage under Bazel (e.g. for integration tests)
# https://github.com/bazelbuild/bazel/blob/8.4.2/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java#L193
apprun_lines.append("unset JAVA_RUNFILES")
apprun_lines.append("unset RUNFILES_MANIFEST_FILE")
apprun_lines.append("unset RUNFILES_MANIFEST_ONLY")
apprun_lines.append("unset TEST_SRCDIR")
# Explicitly set RUNFILES_DIR to the runfiles dir of the binary instead of the appimage rule itself
apprun_lines.append('thisdir="${0%/*}"') # Same as "$(dirname "$0")"
apprun_lines.append('workdir="$thisdir/%s"' % get_workdir(ctx))
apprun_lines.append('RUNFILES_DIR="${workdir%/*}"') # Get parent directory of workdir
apprun_lines.append("export RUNFILES_DIR")
# Run under runfiles
apprun_lines.append('cd "$workdir"')
# Launch the actual binary
apprun_lines.append('exec "./%s" "$@"' % get_entrypoint(ctx))
return "\n".join(apprun_lines) + "\n"

While there has been work to strip away some dependencies like "Don't call /usr/bin/dirname in AppRun" (#296) this still has some dependencies, most notably the shell interpreter /bin/sh itself.
This has prompted some workarounds like

# distroless "debug" images contain their shell at /busybox/sh, but the AppRun script uses a "/bin/sh" shebang
pkg_mklink(
name = "link_sh",
link_name = "/bin/sh",
target = "/busybox/sh",
)
pkg_tar(
name = "link_sh.tar",
srcs = [":link_sh"],
)

If we didn't depend on a shell but had a compiled and statically linked AppRun instead, this would be a non-issue, and AppImages would work (with APPIMAGE_EXTRACT_AND_RUN=1) inside mostly-empty containers like https://github.com/GoogleContainerTools/distroless/tree/main/cc or even https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions