cloud66-oss/habitus

Habitus is not working on Alpine Linux

dduportal opened this issue · 7 comments

Hello,

thank you for your work on this tool!

I am trying to install habitus inside an Alpine Linux container, and it looks like it is not working:

  • Dockerfile used:
FROM alpine:3.7

ARG DEFAULT_USER=habitus

# Those variables are expected to be set by the habitus install script
ENV TERM=xterm \
  SUDO_USER=${DEFAULT_USER}

# Ncurses is required to have the tput command
RUN addgroup ${DEFAULT_USER} \
  && adduser -D -G ${DEFAULT_USER} ${DEFAULT_USER} \
  && apk add --no-cache bash curl ncurses

RUN curl -sSL https://raw.githubusercontent.com/cloud66/habitus/master/habitus_install.sh | bash

USER ${DEFAULT_USER}

ENTRYPOINT ["habitus"]
CMD ["--version"]
  • It builds without issue, but cannot execute the binary. It looks like a linked library issue (musl ?):
MacBook-Pro-de-Dadou:docker dadou$ docker run --rm -t habitus
standard_init_linux.go:195: exec user process caused "no such file or directory"
MacBook-Pro-de-Dadou:docker dadou$ docker run --rm -t --entrypoint which habitus habitus
/usr/local/bin/habitus
MacBook-Pro-de-Dadou:docker dadou$ docker run --rm -t --entrypoint ldd habitus /home/habitus/.habitus/habitus
	/lib64/ld-linux-x86-64.so.2 (0x7f3fe4c33000)
	libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f3fe4c33000)
	libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f3fe4c33000)
khash commented

It seems you're running Habitus inside of docker which is not going to work.

Hi @khash,

I totally understand the use case here: It is a first evaluation for me.
I have CI cases using Docker in Docker (nested containers), or with Docker on Docker (the /var/run/docker.sock socket bind mounted from the host).

The idea is to provide an image with habitus already installed, to have minimalistic CI build agents.

I'm doing the same kind of things as habitus with custom Makefiles today, and would like to use habitus because it would streamlined my process a lot :)

khash commented

Have you tried the same setup with Ubuntu image to see if the issue related to DIND or Alpine being such minimal distro?

Hi @khash , the following Dockerfile seems to work (Debian based: same as Ubuntu):

FROM debian:jessie

ARG DEFAULT_USER=habitus

# Those variables are expected to be set by the habitus install script
ENV TERM=xterm \
  SUDO_USER=${DEFAULT_USER}

# Ncurses is required to have the tput command
RUN addgroup ${DEFAULT_USER} \
  && adduser --disabled-password --gecos "" --ingroup ${DEFAULT_USER} ${DEFAULT_USER} \
  && apt-get update \
  && apt-get install -y --no-install-recommends bash curl ca-certificates \
  && apt-get clean

RUN curl -sSL https://raw.githubusercontent.com/cloud66/habitus/master/habitus_install.sh | bash

USER ${DEFAULT_USER}

ENTRYPOINT ["habitus"]
CMD ["--version"]

=> It is related to Alpine Linux (no Docker nor DIND involved here).

Given the ldd command output, I'm going to search similar go applications cases under Alpine Linux: the goal is to understand if it is the generated binary linking which is an issue, if it related specifically to musl, or if something a package is missing on my Alpine Linux Dockerfile.

=> I wanted to install habitus on my CI agents, but they are all based on Alpine Linux Base OS, even the bare metals. Debian based container would be a solution, but I'm sure there is not so much top be done to have working on Alpine :)

Quick update:

  • On Alpine, if I install the package libc6-compat which is just a "wrapper" creating symlink from the expected glibC binary, to the musl-c ones:
bash-4.4# ls -l /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx    1 root     root            26 Feb 21 11:44 /lib64/ld-linux-x86-64.so.2 -> /lib/libc.musl-x86_64.so.1

=> It does not guarantee to be fully working, but it looks like ok for the CLI calls:

bash-4.4# habitus 
2018/02/21 11:44:52 ▶ Using '/build.yml' as build file 
2018/02/21 11:44:52 ▶ Failed: open /build.yml: no such file or directory 
bash-4.4# habitus  --version
Habitus - v1.0.1 (c) 2017 Cloud 66 Inc.
  • I wonder if adding the -static flag to the lddflags would make the binary work? I'm not really aware of the impacts of this in Go?

Smoke test with my "DonD" example:

  • Dockerfile:
FROM docker:18.02

RUN apk add --no-cache bash curl libc6-compat \
  && curl -sSL https://github.com/cloud66/habitus/releases/download/1.0.1/habitus_linux_amd64 \
    -o /usr/local/bin/habitus \
  && chmod a+x /usr/local/bin/habitus

ENTRYPOINT ["/usr/local/bin/habitus"]
CMD ["--version"]
  • Build: docker build -t habitus:dond -f Dockerfile.dond ./

  • Execution, from a directory containing my build.yml:

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  -v "$(pwd):/app" -w /app \
  habitus:dond build

It works quite well!

@khash do you want me to contribute:

  • A Documentation/Quickstart example?
  • A default docker image for habitus?
  • Something else?

Feel free to close the issue here (and open other to assign me if YES to the previous question).

khash commented

Thank you @dduportal for the comment and the example. I'd love to have you contribute some documentation around this as well as a default Habitus dockerfile. We can build the image based on that and maintain it.

It would also be great to mention in the documentation your use case for using Habitus in Docker. I believe many will love your idea of a lightweight CI.