Disable Docker Support?

Hi,

I'm trying to make beats/filebeat and maybe the other beats' packages available on AIX.
I've managed to make it locally by porting elastic/go-txfile (I'll submit it soon) and by modifying vendor packages manually (which of courses we don't want).

The reason behind is that libbeat is trying to build docker packages which aren't and can't be supported by AIX. As far as I know beats programs should be able to run without Docker (tell me if I'm wrong).
In a previous conversation Attempting to compile filebeat in AIX, @pierhugues spoke about a way to pickup features we want. But the PR has been closed and I didn't find a way to automatically disable docker during build without changing the source code.
Removing the few problematic imports seems possible (it is for libbeat, but filebeat one is auto-generated so that's a little more complicated to do it).

Therefore, I have a few question:

  • is it possible to disable docker support when building in the current source code without any changes ?
  • if no, what do you rather have:
    • new files with "+build OSES" to only import docker's packages when it's supported ?
    • new files with "+build tag_docker" to allow build with or without docker at build time (it should be possible but harder) .
    • any other options ?

My aim is to allow any AIX user to be able to compile filebeat from the source as is.

Sincerely,
Clément

I'm leaning towards build tags, but platform specific like CGO, linux, windows and so on.

Custom build tags can be annoying to use, as one needs to remember those. If we need to introduce custom build tags, we should force users to set them in order to remove a compilation unit. E.g. without_<X> or no_<X>. Still I'd prefer to not have custom tags.

What exactly is the error you get?

When building libbeat, I'm getting:

   $ make
    go build -i -ldflags "-X github.com/elastic/beats/libbeat/version.buildTime=2019-04-24T19:51:29Z -X github.com/elastic/beats/libbeat/version.commit=8c35af49e12c4e658d6a09680933e8422933a499"
    # github.com/elastic/beats/vendor/github.com/docker/docker/pkg/system
    ../vendor/github.com/docker/docker/pkg/system/lstat_unix.go:18:9: undefined: fromStatT
    ../vendor/github.com/docker/docker/pkg/system/stat_unix.go:59:9: undefined: fromStatT

This is normal as docker/docker/pkg/system doesn't know AIX.
Note that this pacakge is only used by libbeat/common/docker which is needed for libbeat/autodiscover/providers/docker and libbeat/processors/add_docker_metadata.
If these two last packages are removed from libbeat/cmd/instance/imports.go, libbeat can be built (with a few update of vendors packages though).

Hm... I think we should fix the docker client library. Docker clients can talk to local or remote docker hosts. At least the later should still be possible, even with AIX.

The add_docker_metadata processor is supposed to be used with the local machine only, so we can safely disable this one in libbeat. The autodiscovery provider could still be interesting for heartbeat/metricbeat instances collecting data from remote hosts, but this is very much an edge case.

Both, provider and processor are mostly isolated. They are (should not) be reused by other packages. When importing those packages the init function ensures that the plugins register with the global plugin registry. We can remove those by adding +build !aix to each go file of the respective packages. Only checking for AIX lessens the impact for other OSes Beats eventually compiles for.
The package must still exist. Maybe add a doc.go file without any code, if the build fails due to having a package without any go files.

It's pretty awesome that you try to get Beats running on AIX. What other build issues did you run into?

Yes, I'll have to check which Docker packages are needed when taking to remote hosts. Maybe in a first instance, every part linked with Docker can be disabled. I'd rather have a partial libbeat as soon as possible than a fully available libbeat after 3 months of works for Docker.

Adding +build !aix on the problematic packages seems a really bad idea for me. Won't it be better to import this packages only when needed/available ? This way it can be just one file with +build !aix instead of a whole package. It will allow more granularity for OSes as some might have docker but not Kubernetes or whatever. Developers will understand pretty easily how to disable their problematic features.
I surely don't want to impact others OSes but it seems to me that it will be easier for future new OSes to port beats packages. Moreover, you can change these problematic packages without having to think "it still must be disable for AIX".

The core of libbeat seems ok, I haven't run the whole tests though. The main problem are with dependencies like beats/go-txfile (which is ported locally, but I want to test it under libbeat/filebeat before submitted it) and mattn/go-isatty (which is now fully supported in master).

Yes, but imports are automatically generated via scripts in a few places, whereas others are updated manually. These files should not be updated manually, as it's too easy to forget to do the right 'import' at the right place.

You can only guard files with build tags only. A go file already contains linking information via imports. Alternatively you will you can create include_all.go, include_docker.go, include_kubernetes.go and so on. But default should be to have these features to be compiled in. I'm fine with +build !no_docker and the include approach as well, which again makes it more difficult to update the scripts.

Metricbeat/Filebeat includes for modules are automatically generated via scripts. Here we'd need to find another way?

Won't it be better to import this packages only when needed/available ?

This is a little tricky here. Which OSes is docker available for? The docker client is/should be available to all OSes to some extent. In the end it's just an HTTP client (via TCP or Unix sockets). It's also available on BSD and macOS, as one can run docker via VMs locally. Yet neither is a natural target of the docker daemon. Problem here seems to be that the syscall (and docker) package is not always compatible between OSes or architectures (Filebeat uses lstat itself). I did run into a similar issues on Linux ARM in the past. A symbol was not available in the syscall package, but I was lucky to find it in x/sys/unix. Unfortunately one often finds these issues when porting to a new platform.
Ultimately the syscall package needs to be fixed and updated, not Beats or the docker client.

Alternatively you will you can create include_all.go , include_docker.go , include_kubernetes.go and so on.

That's what I was thinking of with a +build !aix. Is it not possible to update the script or it seems to complicated (more than just porting the needed docker packages ? )

Ultimately the syscall package needs to be fixed and updated, not Beats or the docker client.

I'm the one who's porting the Go toolchain on AIX and that's one of the reason I want to port beats packages to see if any syscalls are missing (as long as many people requesting it).

I'll check docker packages if it's not too complicated to make it work for remote client (or at least having the build available) it might not be a problem after all. I'll keep you update.

Porting the client part of Docker might take a few weeks as AIX isn't yet known in most of its dependencies. We're discussing internally in order to know if we want to do such thing.
I'll keep you update.

Thanks. I'm definitely curious to learn how things go.

I'm afraid there is no nice way on how to do the includes. But I'd love to have Beats compile/work on AIX. Luckily the places docker/kubernetes is included from is actually not auto-generated. So we could indeed add an include_docker.go, include_kubernetes.go file with build tags. I'm fine if we have an intermediate solution in one or the other way, so to make it compile and open an issue to clean up how we do imports (create profiles) later (Or wait for docker to be fixed). Personally I don't have strong feelings towards !aix or no_docker per se.

Out of curiosity, what else is failing on the docker part? The compilation error you've shown suggests that lstat fails (which should be available on AIX). I wonder if Beats or the docker package pulls in too many dependencies.

Beats uses x/sys as alternative for the syscall package in a few places. Are you also updating this one to AIX?

Also curious about the AIX fix to go-txfile. Does the go-txfile testsuite run through for you? If so we should be ok. Feel free to open an PR and we set it to in progress until you are confident.
Most of the go-txfile test suite is run via Travis right now. No idea how we could automatically run the test suite for AIX, though. If we have support I'd want to make sure we don't break it by accident.

So we could indeed add an include_docker.go, include_kubernetes.go file with build tags.

Ok, I'll check if it does work on AIX

what else is failing on the docker part?

The main problem is not what is failing (for libbeat only docker/client and docker/pkg/system must be ported), but having the fix accepted by the Docker community. They have removed all the Solaris files because docker was fully available on it. And I do fear they won't accept any changes if we aren't sure docker (even just the client part) is working correctly.
In order to be sure everything is working, I need to port the docker cli which has a lot more dependencies.

Beats uses x/sys as alternative for the syscall package in a few places. Are you also updating this one to AIX?

It's already done normally. Maybe some syscalls are missing, but the main ones are available.

Does the go-txfile testsuite run through for you?

I've a current version based on cmd/go/internal/lockedfile/internal/filelock package in the standard library. However, I've ported gofrs/flock since (as flock isn't available on AIX) and I'm planning to use it like Windows. If you want to see the "flock" implementation: Add AIX support with fcntl by Helflym · Pull Request #40 · gofrs/flock · GitHub.

I've a current version based on cmd/go/internal/lockedfile/internal/filelock package in the standard library. However, I've ported gofrs/flock since (as flock isn't available on AIX) and I'm planning to use it like Windows

+1
Maybe it would be better to use flock in go-txfile always (independent of OS).

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.