diff --git a/Dockerfile b/Dockerfile index 2f6387c5b..bb3bb9304 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG PLATFORM=amd64 -FROM ${PLATFORM}/alpine:3.10 AS build +FROM ${PLATFORM}/alpine:3.10 WORKDIR /build @@ -26,12 +26,4 @@ COPY *.c *.h autogen.sh Makefile.am configure.ac ./ RUN ./autogen.sh && ./configure --enable-static RUN make -j $(nproc) RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate -RUN ./tmate -V - -FROM alpine:3.9 - -RUN apk --no-cache add bash -RUN mkdir /build -ENV PATH=/build:$PATH -COPY --from=build /build/tmate.symbols /build -COPY --from=build /build/tmate /build +RUN ./tmate -V \ No newline at end of file diff --git a/DockerfileCompile b/DockerfileCompile new file mode 100644 index 000000000..a25a5f527 --- /dev/null +++ b/DockerfileCompile @@ -0,0 +1,25 @@ +ARG PLATFORM=amd64 +FROM harness/tmate-ssh-server:tmate-client-build AS build + +WORKDIR /build + + +RUN set -ex; \ + mkdir -p /src/libssh/build; \ + cd /src; \ + wget -O libssh.tar.xz https://www.libssh.org/files/0.9/libssh-0.9.0.tar.xz; \ + tar -xf libssh.tar.xz -C /src/libssh --strip-components=1; \ + cd /src/libssh/build; \ + cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + -DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF \ + -DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF ..; \ + make -j $(nproc); \ + make install + +COPY compat ./compat +COPY *.c *.h autogen.sh Makefile.am configure.ac ./ + +RUN ./autogen.sh && ./configure --enable-static +RUN make -j $(nproc) +RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate +RUN ./tmate -V diff --git a/build_static_release.sh b/build_static_release.sh index 9cb354356..186f6ff1e 100755 --- a/build_static_release.sh +++ b/build_static_release.sh @@ -8,11 +8,6 @@ PLATFORM=$2 SRC_VERSION=`cat configure.ac | grep AC_INIT | sed -E 's/^AC_INIT\(tmate, (.+)\)$/\1/'` -if [ $SRC_VERSION != $VERSION ]; then - echo "Version mismatch: $SRC_VERSION != $VERSION" - exit 1 -fi - RELEASE_NAME=tmate-$VERSION-static-linux-$PLATFORM echo "Building $RELEASE_NAME" diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 000000000..de7a5eb03 --- /dev/null +++ b/chart/.helmignore @@ -0,0 +1,8 @@ +# Patterns to ignore when building packages. +*.swp +*.bak +*.tmp +*.orig +*~ +.git/ +.gitignore diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 000000000..f872da368 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: harness-vm-runner-tmate +description: Harness VM Runner Tmate Binary +type: application +version: 1.0.0 +appVersion: "1.0.0" +dependencies: [] diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 000000000..d71ca3293 --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1,5 @@ +This chart contains the Harness VM Runner Tmate binary. +The binary is available in the Docker image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + +This chart is not meant to be deployed as a Kubernetes application. +It exists only to satisfy the build pipeline requirements. diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 000000000..eed7c24b8 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,5 @@ +image: + registry: "" + repository: "harness-vm-runner-tmate" + tag: "latest" + pullPolicy: IfNotPresent diff --git a/config/manifest.yaml b/config/manifest.yaml new file mode 100644 index 000000000..de85a1d85 --- /dev/null +++ b/config/manifest.yaml @@ -0,0 +1,3 @@ +DOCKER_FILE_PATH: /harness/tmate/docker/Dockerfile-tmate +CONTEXT_PATH: /harness/tmate +HELM_CHART_SOURCE_DIRECTORY: /harness/tmate/chart diff --git a/docker/Dockerfile-tmate b/docker/Dockerfile-tmate new file mode 100644 index 000000000..333d295ec --- /dev/null +++ b/docker/Dockerfile-tmate @@ -0,0 +1,93 @@ +# ---------------------------------------------------------# +# Build Tmate Binary # +# ---------------------------------------------------------# +FROM debian:bookworm-slim AS builder + +WORKDIR /build + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget ca-certificates xz-utils \ + cmake make gcc g++ \ + pkg-config \ + zlib1g-dev libssl-dev \ + automake autoconf libtool \ + libevent-dev libncurses-dev libmsgpack-dev \ + git \ + && rm -rf /var/lib/apt/lists/* + +# Build libssh from source without GSSAPI to avoid static linking issues +RUN set -ex; \ + mkdir -p /src/libssh/build; \ + cd /src; \ + wget -O libssh.tar.xz https://www.libssh.org/files/0.10/libssh-0.10.6.tar.xz; \ + tar -xf libssh.tar.xz -C /src/libssh --strip-components=1; \ + cd /src/libssh/build; \ + cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + -DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF \ + -DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF ..; \ + make -j $(nproc); \ + make install + +# Copy source code +COPY compat ./compat +COPY *.c *.h autogen.sh Makefile.am configure.ac ./ + +# Create empty forkpty-linux.c stub (forkpty is provided by glibc on Linux) +RUN echo '/* forkpty is provided by glibc on Linux - no compat needed */' > compat/forkpty-linux.c + +# Build arguments for metadata +ARG BUILD_VERSION +ARG BUILD_TIME +ARG COMMIT_SHA +ARG BRANCH_NAME +ARG TARGETOS=linux +ARG TARGETARCH + +# Build tmate (without --enable-static to avoid compat library issues) +RUN ./autogen.sh && ./configure +RUN make -j $(nproc) +RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate + +# Verify build +RUN ./tmate -V + +# ---------------------------------------------------------# +# Create final image # +# ---------------------------------------------------------# +FROM debian:bookworm-slim + +WORKDIR /binaries + +# Install runtime dependencies for dynamically linked tmate binary +RUN apt-get update && apt-get install -y --no-install-recommends \ + libevent-2.1-7 \ + libncurses6 \ + libmsgpackc2 \ + libssh-4 \ + && rm -rf /var/lib/apt/lists/* + +# Copy the binary +COPY --from=builder /build/tmate /binaries/tmate + +# Build metadata labels +ARG BUILD_VERSION +ARG BUILD_TIME +ARG COMMIT_SHA +ARG BRANCH_NAME +ARG TARGETARCH +ARG TARGETOS + +LABEL org.opencontainers.image.title="Tmate" +LABEL org.opencontainers.image.description="Tmate terminal sharing binary for Harness CI" +LABEL org.opencontainers.image.vendor="Harness Inc." +LABEL org.opencontainers.image.created="${BUILD_TIME}" +LABEL org.opencontainers.image.revision="${COMMIT_SHA}" +LABEL org.opencontainers.image.source="https://github.com/harness/tmate" +LABEL org.opencontainers.image.version="${BUILD_VERSION}" +LABEL BUILD_VERSION="${BUILD_VERSION}" +LABEL BUILD_TIME="${BUILD_TIME}" +LABEL BRANCH_NAME="${BRANCH_NAME}" +LABEL COMMIT_SHA="${COMMIT_SHA}" +LABEL ARCHITECTURE="${TARGETARCH}" +LABEL OS="${TARGETOS}" diff --git a/options-table.c b/options-table.c index e3362ba88..435a99811 100644 --- a/options-table.c +++ b/options-table.c @@ -902,6 +902,12 @@ const struct options_table_entry options_table[] = { .default_str = "" }, + { .name = "tmate-user", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_SERVER, + .default_str = "" + }, + { .name = "tmate-server-host", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, diff --git a/tmate-session.c b/tmate-session.c index 5ba0896cb..b976ba487 100644 --- a/tmate-session.c +++ b/tmate-session.c @@ -193,7 +193,6 @@ void tmate_session_start(void) */ if (tmate_foreground) { tmate_set_val("foreground", "true"); - tmate_info("To connect to the session locally, run: tmate -S %s attach", socket_path); } else { cfg_add_cause("%s", "Tip: if you wish to use tmate only for remote access, run: tmate -F"); cfg_add_cause("%s", "To see the following messages again, run in a tmate session: tmate show-messages"); diff --git a/tmate-ssh-client.c b/tmate-ssh-client.c index bed79e953..75f1cfd3b 100644 --- a/tmate-ssh-client.c +++ b/tmate-ssh-client.c @@ -250,6 +250,8 @@ static void init_conn_fd(struct tmate_ssh_client *client) event_add(client->ev_ssh, NULL); } +static const size_t MAX_ACCOUNT_LEN = 30; + static void on_ssh_client_event(struct tmate_ssh_client *client) { ssh_session session = client->session; @@ -272,7 +274,16 @@ static void on_ssh_client_event(struct tmate_ssh_client *client) ssh_options_set(session, SSH_OPTIONS_HOST, client->server_ip); ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); ssh_options_set(session, SSH_OPTIONS_PORT, &port); - ssh_options_set(session, SSH_OPTIONS_USER, "tmate"); + char* tmate_user = options_get_string(global_options, + "tmate-user"); + size_t tmate_user_len = strlen(tmate_user); + + if (tmate_user_len > MAX_ACCOUNT_LEN) + { + tmate_fatal("Invalid tmate-user"); + } + + ssh_options_set(session, SSH_OPTIONS_USER, tmate_user); ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes"); char *identity;