Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI (Buildkite): Add the package_linux64 and doctest builders #41541

Merged
merged 1 commit into from
Jul 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .buildkite/misc/doctest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones
# since we need nestable sandboxing. The rootfs images being used here are built from
# the `.buildkite/rootfs_images/llvm-passes.jl` file.
agents:
queue: "julia"
# Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing
sandbox.jl: "true"
os: "linux"

steps:
- label: "doctest"
key: doctest
plugins:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
uid: 1000
gid: 1000
workspaces:
# Include `/cache/repos` so that our `git` version introspection works.
- "/cache/repos:/cache/repos"
commands: |
echo "--- Build Julia from source"
make -j 6
echo "--- Print Julia version info"
./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()'
echo "--- Build Julia docs"
make docs
echo "--- Run Julia doctests"
JULIA_NUM_THREADS=1 make -C doc doctest=true
timeout_in_minutes: 120
notify:
- github_commit_status:
context: "doctest"
4 changes: 2 additions & 2 deletions .buildkite/embedding.yml → .buildkite/misc/embedding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ steps:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz
rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8"
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
uid: 1000
gid: 1000
workspaces:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ steps:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz
rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8"
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/llvm_passes.x86_64.tar.gz
rootfs_treehash: "9dd715500b117a16fcfa419ea0bca0c0ca902cee"
workspaces:
# Include `/cache/repos` so that our `git` version introspection works.
- "/cache/repos:/cache/repos"
Expand All @@ -36,8 +36,8 @@ steps:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz
rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8"
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
uid: 1000
gid: 1000
workspaces:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ steps:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz
rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8"
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
workspaces:
- "/cache/repos:/cache/repos"
commands: |
Expand Down
19 changes: 12 additions & 7 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@
#
# Yes, this is creating another layer of indirection; the flow now looks like:
#
# [webui] -> pipeline.yml -> llvm_passes.yml
# [webui] -> pipeline.yml -> misc/whitespace.yml
#
# when we could theoretically just have the `webui` launch `llvm_passes.yml`,
# when we could theoretically just have the `webui` launch `misc/whitespace.yml`,
# however this raises the bar for contributors to add new (unsigned) steps to
# our CI configuration, so I'd rather live with an extra layer of indirection
# and only need to touch the webui configuration when we need to alter
# something about the privileged steps.
steps:
- label: ":buildkite: Launch unsigned pipelines"
commands: |
# We launch whitespace first, because we want that pipeline to finish as quickly as possible.
# The remaining unsigned pipelines are launched in alphabetical order.
buildkite-agent pipeline upload .buildkite/whitespace.yml
buildkite-agent pipeline upload .buildkite/embedding.yml
buildkite-agent pipeline upload .buildkite/llvm_passes.yml
# First, we launch whitespace, because we want that pipeline to finish as quickly as possible.
buildkite-agent pipeline upload .buildkite/misc/whitespace.yml
# Next, we launch the miscellaneous pipelines in alphabetical order.
buildkite-agent pipeline upload .buildkite/misc/doctest.yml
buildkite-agent pipeline upload .buildkite/misc/embedding.yml
buildkite-agent pipeline upload .buildkite/misc/llvmpasses.yml
# Finally, we launch the platform pipelines in alphabetical order.
buildkite-agent pipeline upload .buildkite/platforms/linux64.yml
agents:
queue: julia
80 changes: 80 additions & 0 deletions .buildkite/platforms/linux64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones
# since we need nestable sandboxing. The rootfs images being used here are built from
# the `.buildkite/rootfs_images/llvm-passes.jl` file.
agents:
queue: "julia"
# Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing
sandbox.jl: "true"
os: "linux"

steps:
- label: "package_linux64"
key: package_linux64
plugins:
- JuliaCI/julia#v1:
version: 1.6
- staticfloat/sandbox#v1:
rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
uid: 1000
gid: 1000
workspaces:
# Include `/cache/repos` so that our `git` version introspection works.
- "/cache/repos:/cache/repos"
commands: |
echo "--- Build Julia from source"
make -j 6
make release
make install
echo "--- Print Julia version info"
./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()'
echo "--- Compress build artifacts"
mv julia-* julia-artifact
rm -rf julia-linux64.tar.gz
tar czf julia-linux64.tar.gz julia-artifact/
echo "--- Upload build artifacts"
buildkite-agent artifact upload julia-linux64.tar.gz
timeout_in_minutes: 60
notify:
- github_commit_status:
context: "package_linux64"

# - label: "tester_linux64"
# key: tester_linux64
# depends_on: package_linux64
# plugins:
# - JuliaCI/julia#v1:
# version: 1.6
# - staticfloat/sandbox#v1:
# # TODO: use a separate `tester_linux` image, instead of using the `package_linux` image.
# rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz
# rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756"
# uid: 1000
# gid: 1000
# workspaces:
# # Include `/cache/repos` so that our `git` version introspection works.
# - "/cache/repos:/cache/repos"
# env:
# JULIA_SHELL: "/bin/bash"
# commands: |
# echo "--- Download build artifacts"
# rm -rf julia-linux64.tar.gz
# buildkite-agent artifact download julia-linux64.tar.gz .
#
# echo "--- Extract build artifacts"
# rm -rf julia-artifact/
# tar xzf julia-linux64.tar.gz julia-artifact/
#
# echo "--- Print Julia version info"
# julia-artifact/bin/julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()'
#
# echo "--- Run the Julia test suite"
# unset JULIA_DEPOT_PATH
# julia-artifact/bin/julia .buildkite/rr_capture.jl julia-artifact/bin/julia -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)'
# timeout_in_minutes: 120
# notify:
# - github_commit_status:
# context: "tester_linux64"
134 changes: 134 additions & 0 deletions .buildkite/rr_capture.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using Dates
using Pkg
using Tar

if Base.VERSION < v"1.6"
throw(ErrorException("The `rr_capture.jl` script requires Julia 1.6 or greater"))
end

if length(ARGS) < 1
throw(ErrorException("Usage: rr_capture.jl [command...]"))
end

const TIMEOUT = 2 * 60 * 60 # timeout in seconds

# We only use `rr` on the `tester_linux64` builder
const use_rr_if_builder_is = "tester_linux64"

const run_id = get(ENV, "BUILDKITE_JOB_ID", "unknown")
const shortcommit = get(ENV, "BUILDKITE_COMMIT", "unknown")
const builder = get(ENV, "BUILDKITE_STEP_KEY", use_rr_if_builder_is)
const use_rr = builder == use_rr_if_builder_is

@info "" run_id shortcommit builder use_rr
@info "" ARGS

# if !use_rr # TODO: uncomment this line
if true # TODO: delete this line
@info "We will not run the tests under rr"
p = run(`$ARGS`)
exit(p.exitcode)
end

@info "We will run the tests under rr"

const num_cores = min(Sys.CPU_THREADS, 8, parse(Int, get(ENV, "JULIA_TEST_NUM_CORES", "8")) + 1)
@info "" num_cores

proc = nothing

new_env = copy(ENV)
mktempdir() do dir
Pkg.activate(dir)
Pkg.add("rr_jll")
Pkg.add("Zstd_jll")

rr_jll = Base.require(Base.PkgId(Base.UUID((0xe86bdf43_55f7_5ea2_9fd0_e7daa2c0f2b4)), "rr_jll"))
zstd_jll = Base.require(Base.PkgId(Base.UUID((0x3161d3a3_bdf6_5164_811a_617609db77b4)), "Zstd_jll"))
rr(func) = Base.invokelatest(rr_jll.rr, func; adjust_LIBPATH=false)
rr() do rr_path
capture_script_path = joinpath(dir, "capture_output.sh")
loader = Sys.WORD_SIZE == 64 ? "/lib64/ld-linux-x86-64.so.2" : "/lib/ld-linux.so.2"
open(capture_script_path, "w") do io
write(io, """
#!/bin/bash
$(rr_path) record --nested=detach "\$@" > >(tee -a $(dir)/stdout.log) 2> >(tee -a $(dir)/stderr.log >&2)
""")
end
chmod(capture_script_path, 0o755)

new_env = copy(ENV)
new_env["_RR_TRACE_DIR"] = joinpath(dir, "rr_traces")
new_env["RR_LOG"]="all:debug"
new_env["RR_LOG_BUFFER"]="100000"
new_env["JULIA_RR"] = capture_script_path
t_start = time()
global proc = run(setenv(`$(rr_path) record --num-cores=$(num_cores) $ARGS`, new_env), (stdin, stdout, stderr); wait=false)

# Start asynchronous timer that will kill `rr`
@async begin
sleep(TIMEOUT)

# If we've exceeded the timeout and `rr` is still running, kill it.
if isopen(proc)
println(stderr, "\n\nProcess timed out. Signalling `rr` for force-cleanup!")
kill(proc, Base.SIGTERM)

# Give `rr` a chance to cleanup
sleep(60)

if isopen(proc)
println(stderr, "\n\n`rr` failed to cleanup within one minute, killing and exiting immediately!")
kill(proc, Base.SIGKILL)
exit(1)
end
end
end

# Wait for `rr` to finish, either through naturally finishing its run, or `SIGTERM`.
# If we have to `SIGKILL`
wait(proc)

# On a non-zero exit code, upload the `rr` trace
if !success(proc)
println(stderr, "`rr` returned $(proc.exitcode), packing and uploading traces...")

if !isdir(joinpath(dir, "rr_traces"))
println(stderr, "No `rr_traces` directory! Did `rr` itself fail?")
exit(1)
end

# Clean up non-traces
rm(joinpath(dir, "rr_traces", "latest-trace"))
rm(joinpath(dir, "rr_traces", "cpu_lock"))

# Create a directory for the pack files to go
pack_dir = joinpath(dir, "pack")
mkdir(pack_dir)

# Pack all traces
trace_dirs = [joinpath(dir, "rr_traces", f) for f in readdir(joinpath(dir, "rr_traces"))]
filter!(isdir, trace_dirs)
run(ignorestatus(`$(rr_path) pack --pack-dir=$pack_dir $(trace_dirs)`))

# Tar it up
mkpath("dumps")
datestr = Dates.format(now(), dateformat"yyyy-mm-dd_HH_MM_SS")
dst_path = "dumps/rr-run_$(run_id)-gitsha_$(shortcommit)-$(datestr).tar.zst"
zstd_jll.zstdmt() do zstdp
tarproc = open(`$zstdp -o $dst_path`, "w")
Tar.create(dir, tarproc)
close(tarproc.in)
end
end
end
end

# Pass the exit code back up to Buildkite
if proc.termsignal != 0
ccall(:raise, Cvoid, (Cint,), proc.termsignal)
exit(1) # Just in case the signal did not cause an exit
else
exit(proc.exitcode)
end