Skip to content
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
26 changes: 26 additions & 0 deletions ydb/deploy/breakpad_init/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# syntax=docker/dockerfile:1.4
ARG BASE_IMAGE="cr.yandex/mirror/ubuntu"
ARG BASE_IMAGE_TAG="focal"
ARG BREAKPAD_GIT_TAG="v2022.07.12"
FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} AS breakpad-base
RUN \
apt-get -yqq update && \
apt-get -yqq install --no-install-recommends git build-essential libz-dev python3 curl && \
apt-get clean all && rm -rf /var/lib/apt/lists/*
RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
ENV PATH="/depot_tools:${PATH}"

FROM breakpad-base AS breakpad-build
COPY /breakpad_init.cc /breakpad/breakpad_init.cc
RUN \
cd breakpad && \
fetch breakpad && \
cd src && \
git checkout -- . && git checkout tags/${BREAKPAD_GIT_TAG} && \
./configure && make && \
g++ -std=c++11 -shared -Wall -o ../libbreakpad_init.so -fPIC ../breakpad_init.cc -Isrc/ -Lsrc/client/linux/ -lbreakpad_client -lpthread

FROM scratch AS breakpad-release
COPY --link --from=breakpad-build /breakpad/libbreakpad_init.so /usr/lib/libbreakpad_init.so
COPY --link --from=breakpad-build /breakpad/src/src/tools/linux/md2core/minidump-2-core /usr/bin/minidump-2-core
COPY --link --from=breakpad-build /breakpad/src/src/processor/minidump_stackwalk /usr/bin/minidump_stackwalk
43 changes: 43 additions & 0 deletions ydb/deploy/breakpad_init/breakpad_init.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// breakpad_init.cc: A shared library to initialize breakpad signal handler via LD_PRELOAD.

#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "client/linux/handler/exception_handler.h"

using google_breakpad::MinidumpDescriptor;
using google_breakpad::ExceptionHandler;

// callback function, called after minidump was created
static bool dumpCallback(const MinidumpDescriptor& descriptor, void* context, bool succeeded) {
char *script = getenv("BREAKPAD_MINIDUMPS_SCRIPT");
if (script != NULL) {
pid_t pid=fork();
if (pid == 0) {
char* dumpSucceded = succeeded ? (char *)"true" : (char *)"false";
char* descriptorPath = succeeded ? (char *)descriptor.path() : (char *)"\0";
char* cmd[] = {script, dumpSucceded, descriptorPath, NULL};
execve(cmd[0], &cmd[0], NULL);
} else {
waitpid(pid, 0, 0);
}
}
return succeeded;
}

// create signal handlers on shared library init
__attribute__((constructor))
static void breakpad_init() {

const char * path = ::getenv("BREAKPAD_MINIDUMPS_PATH");

static MinidumpDescriptor descriptor((path) ? path : "/tmp");
static ExceptionHandler handler(
descriptor, // minidump descriptor
NULL, // callback filter
dumpCallback, // callback function
NULL, // callback context
true, // do install handler
-1 // server descriptor
);
}
38 changes: 38 additions & 0 deletions ydb/deploy/breakpad_init/pkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"meta": {
"name": "breakpad_init",
"maintainer": "ydb <info@ydb.tech>",
"description": "Package with breakpad_init",
"version": "v2022.07.12.{revision}"
},
"build": {},
"params": {
"docker_build_network": "host",
"docker_registry": "cr.yandex",
"docker_repository": "crp2lrlsrs36odlvd8dv",
"docker_target": "breakpad-release",
"docker_build_arg": {
"BREAKPAD_GIT_TAG": "v2022.07.12"
}
},
"data": [
{
"source": {
"type": "RELATIVE",
"path": "Dockerfile"
},
"destination": {
"path": "/Dockerfile"
}
},
{
"source": {
"type": "RELATIVE",
"path": "breakpad_init.cc"
},
"destination": {
"path": "/breakpad_init.cc"
}
}
]
}
79 changes: 79 additions & 0 deletions ydb/deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# syntax=docker/dockerfile:1.4
ARG BASE_IMAGE="cr.yandex/mirror/ubuntu"
ARG BASE_IMAGE_TAG="focal"
ARG BREAKPAD_INIT_IMAGE="cr.yandex/crp2lrlsrs36odlvd8dv/breakpad_init"
ARG BREAKPAD_INIT_IMAGE_TAG="v2022.07.12"

###
# Base image with required deb packages
###
FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} AS base
RUN groupadd -r ydb && useradd --no-log-init -r -m -g ydb -G disk ydb && \
apt-get -yqq update && \
apt-get -yqq install --no-install-recommends libcap2-bin ca-certificates && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# release information
COPY --chmod=0644 /AUTHORS /AUTHORS
COPY --chmod=0644 /LICENSE /LICENSE
COPY --chmod=0644 /README.md /README.md
# dynamic libraries
COPY --chmod=0644 /libiconv.so /lib/libiconv.so
COPY --chmod=0644 /liblibidn-dynamic.so /lib/liblibidn-dynamic.so
COPY --chmod=0644 /liblibaio-dynamic.so /lib/liblibaio-dynamic.so

###
# Base image with google brekpad assets
###
FROM ${BREAKPAD_INIT_IMAGE}:${BREAKPAD_INIT_IMAGE_TAG} AS breakpad_init
FROM base AS base-breakpad
RUN \
apt-get -yqq update && \
apt-get -yqq install --no-install-recommends binutils gdb strace linux-tools-generic && \
apt-get clean && rm -rf /var/lib/apt/lists/*
ENV LD_PRELOAD=libbreakpad_init.so
ENV BREAKPAD_MINIDUMPS_PATH=/opt/ydb/volumes/coredumps
ENV BREAKPAD_MINIDUMPS_SCRIPT=/opt/ydb/bin/minidump_script.py
# breakpad binaries
COPY --chmod=4644 --from=breakpad_init /usr/lib/libbreakpad_init.so /usr/lib/libbreakpad_init.so
COPY --chmod=0755 --from=breakpad_init /usr/bin/minidump_stackwalk /usr/bin/minidump_stackwalk
COPY --chmod=0755 --from=breakpad_init /usr/bin/minidump-2-core /usr/bin/minidump-2-core
# minidump callback script
COPY --chmod=0755 --chown=ydb /minidump_script.py /opt/ydb/bin/minidump_script.py

FROM base AS ydbd-setcap
COPY --chmod=0755 --chown=ydb /ydbd /opt/ydb/bin/ydbd
# workaround for decrease image size
RUN /sbin/setcap CAP_SYS_RAWIO=ep /opt/ydb/bin/ydbd

###
# Release image
###
FROM base AS release
# ydb binaries
COPY --chmod=0755 --chown=ydb /ydb /opt/ydb/bin/ydb
COPY --link --from=ydbd-setcap /opt/ydb/bin/ydbd /opt/ydb/bin/ydbd
WORKDIR /opt/ydb/bin
USER ydb

###
# Breakpad Image
###
FROM base-breakpad AS breakpad
# ydb binaries
COPY --chmod=0755 --chown=ydb /ydb /opt/ydb/bin/ydb
COPY --link --from=ydbd-setcap /opt/ydb/bin/ydbd /opt/ydb/bin/ydbd
WORKDIR /opt/ydb/bin
USER ydb

###
# Debug Image
###
FROM breakpad AS debug
USER root
RUN \
apt-get -yqq update && \
apt-get -yqq install --no-install-recommends dnsutils telnet netcat-openbsd iputils-ping curl && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# debug symbols
COPY --chmod=0644 --chown=ydb /ydbd.debug /opt/ydb/bin/ydbd.debug
USER ydb
61 changes: 61 additions & 0 deletions ydb/deploy/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Docker image

## Base image

Base image is official `ubuntu:focal` with installed packages:
- libcap2-bin (for setcap to binaries)
- ca-certificates (for working with CA bundle)

Also base image included `LICENSE`, `AUTHORS` and `README.md` files from root of repository
and dynamic cpp libraries `libiconv`, `liblibidn` and `libaio`.

### Base breakpad image

Extend base image with:
- additional packages to collect and manage minidump format (binutils, gdb, strace, linux-tools-generic)
- dynamic library `libbreakpad_init.so` from breakpad_init image (ydb/deploy/breakpad_init)
- environment variable `LD_PRELOAD` for loading breakpad library on process start
- environment variables `BREAKPAD_MINIDUMPS_PATH` and `BREAKPAD_MINIDUMPS_SCRIPT` to setup breakpad
- binaries `minidump_stackwalk` and `minidump-2-core` to collect stacktrace and convert in coredump format
- python script `minidump_script.py` as dumpCallback handler for breakpad

## Image Types

### Release

Image with minimal requirements to launch ydbd in container

```bash
ya package --docker ydb/deploy/docker/release/pkg.json
```

Used base image and included:
- ydb cli binary
- ydbd server strip'ed binary baked with build type `Release`

### Breakpad

Image with google breakpad assets to collect minidump

```bash
ya package --docker ydb/deploy/docker/breakpad/pkg.json
```

Used base breakpad image and included:

- ydb cli binary
- ydbd server binary baked with build flag `DEBUGINFO_LINES_ONLY`

### Debug

Image with debug symbols and utils for dev purposes

```bash
ya package --docker ydb/deploy/docker/debug/pkg.json
```

Used base breakpad image and included:
- additional packages with debug utils (dnsutils, telnet, netcat-openbsd, iputils-ping, curl)
- ydb cli binary
- ydbd server strip'ed binary baked with build type `Release`
- debug symbols for ydbd binary
43 changes: 43 additions & 0 deletions ydb/deploy/docker/breakpad/minidump_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/python3.8

import json
import subprocess
import argparse
import os

if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Minidump files processing"
)
parser.add_argument("succeeded", action="store")
parser.add_argument("dmp_file", action="store")
args = parser.parse_args()
dmp_file = args.dmp_file
core_file = args.dmp_file[:-3] + "core"
json_file = args.dmp_file[:-3] + "json"
succeeded = args.succeeded

if succeeded == "true":
elf_cmd = ["readelf", "-n", "/opt/ydb/bin/ydbd"]
svnrev_cmd = ["/opt/ydb/bin/ydbd", "--svnrevision"]
mndmp_cmd = ["/usr/bin/minidump-2-core", "-v", dmp_file, "-o", core_file]
gdb_cmd = [
"/usr/bin/gdb",
"/opt/ydb/bin/ydbd",
core_file,
"-iex=set auto-load safe-path /",
"-ex=thread apply all bt",
"--batch",
"-q"
]

elf_resp = subprocess.check_output(elf_cmd).decode("utf-8")
svnrev_resp = subprocess.check_output(svnrev_cmd).decode("utf-8")
subprocess.run(mndmp_cmd)
gdb_resp = subprocess.check_output(gdb_cmd).decode("utf-8")
os.remove(dmp_file)
os.remove(core_file)

ret = json.dumps({"binary": "/opt/ydb/bin/ydbd", "readelf": elf_resp, "svnrevision": svnrev_resp, "stacktrace": gdb_resp})
with open(json_file,"w") as out:
out.write(ret)
Loading
Loading