From c9ab6a45bb5bade0be2a2bce352e2b104c68cc2e Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Thu, 1 Nov 2018 21:52:08 +0100 Subject: [PATCH 01/28] Include docker image building in package release build --- dev-tools/mage/dockerbuilder.go | 112 ++++++++++++++++++ dev-tools/mage/pkgtypes.go | 23 ++++ dev-tools/packaging/packages.yml | 4 +- .../templates/docker/Dockerfile.tmpl | 40 +++++++ .../templates/docker/docker-entrypoint.tmpl | 25 ++++ metricbeat/magefile.go | 2 +- 6 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 dev-tools/mage/dockerbuilder.go create mode 100644 dev-tools/packaging/templates/docker/Dockerfile.tmpl create mode 100644 dev-tools/packaging/templates/docker/docker-entrypoint.tmpl diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go new file mode 100644 index 000000000000..ee77d532e32c --- /dev/null +++ b/dev-tools/mage/dockerbuilder.go @@ -0,0 +1,112 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package mage + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/magefile/mage/sh" + + "github.com/pkg/errors" +) + +type dockerTemplateData struct { + BeatName string + Version string + License string + Env map[string]string + LinuxCapabilities string + User string +} + +type dockerBuilder struct { + PackageSpec +} + +func newDockerBuilder(spec PackageSpec) (*dockerBuilder, error) { + return &dockerBuilder{ + PackageSpec: spec, + }, nil +} + +func (b *dockerBuilder) Build() error { + buildDir := filepath.Join(b.packageDir, "docker-build") + beatDir := filepath.Join(buildDir, "beat") + // TODO: defer removal of buildDir + + elasticBeatsDir, err := ElasticBeatsDir() + if err != nil { + return err + } + templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") + + for _, f := range b.Files { + target := filepath.Join(beatDir, f.Target) + if err := Copy(f.Source, target); err != nil { + return errors.Wrapf(err, "failed to copy from %s to %s", f.Source, target) + } + } + + /* TODO: + data := dockerTemplateData{ + BeatName: b.Name, + Version: b.Version, + License: b.License, + } + */ + data := map[string]interface{}{ + "From": "centos:7", // TODO: Parametrize this + "BeatName": b.Name, + "Version": b.Version, + "License": b.License, + "Env": map[string]string{}, + "LinuxCapabilities": "", + "User": b.Name, + } + + // TODO: Expand templates from packages.yml? + err = filepath.Walk(templatesDir, func(path string, info os.FileInfo, err error) error { + /* TODO: Why there is an error here? + if err != nil { + return err + } + */ + if !info.IsDir() { + target := strings.TrimSuffix( + filepath.Join(buildDir, filepath.Base(path)), + ".tmpl", + ) + err = expandFile(path, target, data) + if err != nil { + return errors.Wrapf(err, "expanding template '%s' to '%s'", path, target) + } + } + return nil + }) + if err != nil { + return err + } + + // TODO: Tag container on build + repository := "docker.elastic.co/beats" // TODO: Parametrize this + tag := fmt.Sprintf("%s/%s:%s", repository, b.Name, b.Version) + return sh.RunCmd("docker", "build", "-t", tag, buildDir)() +} diff --git a/dev-tools/mage/pkgtypes.go b/dev-tools/mage/pkgtypes.go index 736ddebc8db9..b58f632b8004 100644 --- a/dev-tools/mage/pkgtypes.go +++ b/dev-tools/mage/pkgtypes.go @@ -61,6 +61,7 @@ const ( Zip TarGz DMG + Docker ) // OSPackageArgs define a set of package types to build for an operating @@ -165,6 +166,9 @@ var OSArchNames = map[string]map[PackageType]map[string]string{ "ppc64le": "ppc64le", "s390x": "s390x", }, + Docker: map[string]string{ + "amd64": "amd64", + }, }, } @@ -204,6 +208,8 @@ func (typ PackageType) String() string { return "tar.gz" case DMG: return "dmg" + case Docker: + return "docker" default: return "invalid" } @@ -227,6 +233,8 @@ func (typ *PackageType) UnmarshalText(text []byte) error { *typ = Zip case "dmg": *typ = DMG + case "docker": + *typ = Docker default: return errors.Errorf("unknown package type: %v", string(text)) } @@ -256,6 +264,8 @@ func (typ PackageType) Build(spec PackageSpec) error { return PackageTarGz(spec) case DMG: return PackageDMG(spec) + case Docker: + return PackageDocker(spec) default: return errors.Errorf("unknown package type: %v", typ) } @@ -823,3 +833,16 @@ func PackageDMG(spec PackageSpec) error { return b.Build() } + +// PackageDocker packages the Beat into a docker image. +func PackageDocker(spec PackageSpec) error { + if err := HaveDocker(); err != nil { + return errors.Errorf("docker daemon required to build images: %s", err) + } + + b, err := newDockerBuilder(spec) + if err != nil { + return err + } + return b.Build() +} diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index 7d70f31e5220..3bdf5df611b5 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -255,7 +255,7 @@ specs: name: '{{.BeatName}}-oss' - os: linux - types: [tgz] + types: [tgz, docker] spec: <<: *binary_spec <<: *apache_license_for_binaries @@ -369,7 +369,7 @@ specs: <<: *elastic_license_for_macos_pkg - os: linux - types: [tgz] + types: [tgz, docker] spec: <<: *binary_spec <<: *elastic_license_for_binaries diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl new file mode 100644 index 000000000000..8f3c4844eb85 --- /dev/null +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -0,0 +1,40 @@ +{{- $beatHome := printf "%s/%s" "/usr/share" .BeatName }} +{{- $beatBinary := printf "%s/%s" $beatHome .BeatName }} + +FROM {{ .From }} + +LABEL \ + org.label-schema.schema-version="1.0" \ + org.label-schema.vendor="Elastic" \ + org.label-schema.name="{{ .BeatName }}" \ + org.label-schema.version="{{ .Version }}" \ + org.label-schema.url="https://www.elastic.co/products/beats/{{ .BeatName }}" \ + org.label-schema.vcs-url="https://github.com/elastic/beats-docker" \ + license="{{ .License }}" + +ENV ELASTIC_CONTAINER "true" +ENV PATH={{ $beatHome }}:$PATH +{{- range $key, $value := .Env }} +ENV {{ $key }} {{ $value }} +{{- end }} + +COPY beat {{ $beatHome }} +COPY docker-entrypoint /usr/local/bin/docker-entrypoint +RUN chmod a+x /usr/local/bin/docker-entrypoint + +{{- if .LinuxCapabilities }} +RUN setcap {{ .LinuxCapabilities }} {{ $beatBinary }} +{{- end }} + +RUN groupadd --gid 1000 {{ .BeatName }} +{{- if .User }} +RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .User }} +USER {{ .User }} +{{- end }} + +WORKDIR /usr/share/{{ .BeatName }} + +# TODO: Fix permissions in files + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] +CMD ["-e"] diff --git a/dev-tools/packaging/templates/docker/docker-entrypoint.tmpl b/dev-tools/packaging/templates/docker/docker-entrypoint.tmpl new file mode 100644 index 000000000000..f073e21e3188 --- /dev/null +++ b/dev-tools/packaging/templates/docker/docker-entrypoint.tmpl @@ -0,0 +1,25 @@ +#!/bin/bash + +set -euo pipefail + +# Check if the the user has invoked the image with flags. +# eg. "{{ .BeatName }} -c {{ .BeatName }}.yml" +if [[ -z $1 ]] || [[ ${1:0:1} == '-' ]] ; then + exec {{ .BeatName }} "$@" +else + # They may be looking for a Beat subcommand, like "{{ .BeatName }} setup". + subcommands=$({{ .BeatName }} help \ + | awk 'BEGIN {RS=""; FS="\n"} /Available Commands:/' \ + | awk '/^\s+/ {print $1}') + + # If we _did_ get a subcommand, pass it to {{ .BeatName }}. + for subcommand in $subcommands; do + if [[ $1 == $subcommand ]]; then + exec {{ .BeatName }} "$@" + fi + done +fi + +# If neither of those worked, then they have specified the binary they want, so +# just do exactly as they say. +exec "$@" diff --git a/metricbeat/magefile.go b/metricbeat/magefile.go index 535d4ae33add..7a9a914a8c08 100644 --- a/metricbeat/magefile.go +++ b/metricbeat/magefile.go @@ -174,7 +174,7 @@ func customizePackaging() { default: pkgType := args.Types[0] switch pkgType { - case mage.TarGz, mage.Zip: + case mage.TarGz, mage.Zip, mage.Docker: args.Spec.Files[archiveModulesDir] = modulesDir case mage.Deb, mage.RPM, mage.DMG: args.Spec.Files[unixModulesDir] = modulesDir From cb332eac88e61e0cb6b144c52252461073f7699b Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sat, 3 Nov 2018 22:27:24 +0100 Subject: [PATCH 02/28] Reorganize code, save docker as artifact, parametrize vendor --- dev-tools/mage/dockerbuilder.go | 97 ++++++++++++------- .../templates/docker/Dockerfile.tmpl | 2 +- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index ee77d532e32c..8ebcbc81df89 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -28,15 +28,6 @@ import ( "github.com/pkg/errors" ) -type dockerTemplateData struct { - BeatName string - Version string - License string - Env map[string]string - LinuxCapabilities string - User string -} - type dockerBuilder struct { PackageSpec } @@ -48,52 +39,76 @@ func newDockerBuilder(spec PackageSpec) (*dockerBuilder, error) { } func (b *dockerBuilder) Build() error { - buildDir := filepath.Join(b.packageDir, "docker-build") - beatDir := filepath.Join(buildDir, "beat") - // TODO: defer removal of buildDir + buildDir := b.buildDir() + if err := os.RemoveAll(buildDir); err != nil { + return errors.Wrapf(err, "failed to clean existing build directory %s", buildDir) + } - elasticBeatsDir, err := ElasticBeatsDir() - if err != nil { + if err := b.copyFiles(); err != nil { return err } - templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") + if err := b.prepareBuild(); err != nil { + return errors.Wrap(err, "failed to prepare build") + } + + tag, err := b.dockerBuild() + if err != nil { + return errors.Wrap(err, "failed to build docker") + } + + if err := b.dockerSave(tag); err != nil { + return errors.Wrap(err, "failed to save docker as artifact") + } + + return nil +} + +func (b *dockerBuilder) buildDir() string { + return filepath.Join(b.packageDir, "docker-build") +} + +func (b *dockerBuilder) beatDir() string { + return filepath.Join(b.buildDir(), "beat") +} + +func (b *dockerBuilder) copyFiles() error { + beatDir := b.beatDir() for _, f := range b.Files { target := filepath.Join(beatDir, f.Target) if err := Copy(f.Source, target); err != nil { return errors.Wrapf(err, "failed to copy from %s to %s", f.Source, target) } } + return nil +} - /* TODO: - data := dockerTemplateData{ - BeatName: b.Name, - Version: b.Version, - License: b.License, +func (b *dockerBuilder) prepareBuild() error { + elasticBeatsDir, err := ElasticBeatsDir() + if err != nil { + return err } - */ + templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") + data := map[string]interface{}{ "From": "centos:7", // TODO: Parametrize this "BeatName": b.Name, "Version": b.Version, + "Vendor": b.Vendor, "License": b.License, "Env": map[string]string{}, "LinuxCapabilities": "", "User": b.Name, } - // TODO: Expand templates from packages.yml? - err = filepath.Walk(templatesDir, func(path string, info os.FileInfo, err error) error { - /* TODO: Why there is an error here? - if err != nil { - return err - } - */ + buildDir := b.buildDir() + return filepath.Walk(templatesDir, func(path string, info os.FileInfo, _ error) error { if !info.IsDir() { target := strings.TrimSuffix( filepath.Join(buildDir, filepath.Base(path)), ".tmpl", ) + err = expandFile(path, target, data) if err != nil { return errors.Wrapf(err, "expanding template '%s' to '%s'", path, target) @@ -101,12 +116,26 @@ func (b *dockerBuilder) Build() error { } return nil }) - if err != nil { +} + +func (b *dockerBuilder) dockerBuild() (string, error) { + repository := "docker.elastic.co/beats" // TODO: Parametrize this + tag := fmt.Sprintf("%s:%s", filepath.Join(repository, b.Name), b.Version) // TODO: What about OSS? + return tag, sh.Run("docker", "build", "-t", tag, b.buildDir()) +} + +func (b *dockerBuilder) dockerSave(tag string) error { + // Save the container as artifact + outputFile := b.OutputFile + if outputFile == "" { + outputTar, err := b.Expand(defaultBinaryName + ".docker.tar") + if err != nil { + return err + } + outputFile = filepath.Join(distributionsDir, outputTar) + } + if err := sh.Run("docker", "save", "-o", outputFile, tag); err != nil { return err } - - // TODO: Tag container on build - repository := "docker.elastic.co/beats" // TODO: Parametrize this - tag := fmt.Sprintf("%s/%s:%s", repository, b.Name, b.Version) - return sh.RunCmd("docker", "build", "-t", tag, buildDir)() + return errors.Wrap(CreateSHA512File(outputFile), "failed to create .sha512 file") } diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 8f3c4844eb85..ff7ebc999448 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -5,7 +5,7 @@ FROM {{ .From }} LABEL \ org.label-schema.schema-version="1.0" \ - org.label-schema.vendor="Elastic" \ + org.label-schema.vendor="{{ .Vendor }}" \ org.label-schema.name="{{ .BeatName }}" \ org.label-schema.version="{{ .Version }}" \ org.label-schema.url="https://www.elastic.co/products/beats/{{ .BeatName }}" \ From 4e07f552f8496c1cf080ca5d862f480ce2f99434 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sat, 3 Nov 2018 22:57:29 +0100 Subject: [PATCH 03/28] Reuse data for templates --- dev-tools/mage/dockerbuilder.go | 7 ++----- dev-tools/packaging/packages.yml | 6 +++--- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index 8ebcbc81df89..fc8fdcb33ca3 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -92,13 +92,10 @@ func (b *dockerBuilder) prepareBuild() error { data := map[string]interface{}{ "From": "centos:7", // TODO: Parametrize this - "BeatName": b.Name, "Version": b.Version, - "Vendor": b.Vendor, - "License": b.License, "Env": map[string]string{}, "LinuxCapabilities": "", - "User": b.Name, + "User": b.ServiceName, } buildDir := b.buildDir() @@ -109,7 +106,7 @@ func (b *dockerBuilder) prepareBuild() error { ".tmpl", ) - err = expandFile(path, target, data) + err = ExpandFile(path, target, data) if err != nil { return errors.Wrapf(err, "expanding template '%s' to '%s'", path, target) } diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index 3bdf5df611b5..61a37403abd9 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -220,7 +220,7 @@ specs: <<: *binary_spec - os: linux - types: [tgz] + types: [tgz, docker] spec: <<: *binary_spec @@ -290,7 +290,7 @@ specs: <<: *elastic_license_for_macos_pkg - os: linux - types: [tgz] + types: [tgz, docker] spec: <<: *binary_spec <<: *elastic_license_for_binaries @@ -328,7 +328,7 @@ specs: name: '{{.BeatName}}-oss' - os: linux - types: [tgz] + types: [tgz, docker] spec: <<: *binary_spec <<: *apache_license_for_binaries diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index ff7ebc999448..b7ec2a9b6622 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -5,12 +5,12 @@ FROM {{ .From }} LABEL \ org.label-schema.schema-version="1.0" \ - org.label-schema.vendor="{{ .Vendor }}" \ + org.label-schema.vendor="{{ .BeatVendor }}" \ org.label-schema.name="{{ .BeatName }}" \ org.label-schema.version="{{ .Version }}" \ org.label-schema.url="https://www.elastic.co/products/beats/{{ .BeatName }}" \ - org.label-schema.vcs-url="https://github.com/elastic/beats-docker" \ - license="{{ .License }}" + org.label-schema.vcs-url="{{ .BeatURL }}" \ + license="{{ .BeatLicense }}" ENV ELASTIC_CONTAINER "true" ENV PATH={{ $beatHome }}:$PATH From fde2cf5d3cd4c77f745041c2fc74ff4148324e7f Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sat, 3 Nov 2018 23:52:58 +0100 Subject: [PATCH 04/28] Fix permissions --- dev-tools/mage/dockerbuilder.go | 11 ++++++++++ dev-tools/mage/pkgtypes.go | 1 + .../templates/docker/Dockerfile.tmpl | 21 +++++++++++++------ filebeat/magefile.go | 14 +++++++------ metricbeat/magefile.go | 14 +++++++------ 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index fc8fdcb33ca3..bafdf6ef4c6d 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -72,6 +72,16 @@ func (b *dockerBuilder) beatDir() string { return filepath.Join(b.buildDir(), "beat") } +func (b *dockerBuilder) modulesDirs() []string { + var modulesd []string + for _, f := range b.Files { + if f.Modules { + modulesd = append(modulesd, f.Target) + } + } + return modulesd +} + func (b *dockerBuilder) copyFiles() error { beatDir := b.beatDir() for _, f := range b.Files { @@ -96,6 +106,7 @@ func (b *dockerBuilder) prepareBuild() error { "Env": map[string]string{}, "LinuxCapabilities": "", "User": b.ServiceName, + "ModulesDirs": b.modulesDirs(), } buildDir := b.buildDir() diff --git a/dev-tools/mage/pkgtypes.go b/dev-tools/mage/pkgtypes.go index b58f632b8004..8e65f558437f 100644 --- a/dev-tools/mage/pkgtypes.go +++ b/dev-tools/mage/pkgtypes.go @@ -104,6 +104,7 @@ type PackageFile struct { Target string `yaml:"target,omitempty"` // Target location in package. Relative paths are added to a package specific directory (e.g. metricbeat-7.0.0-linux-x86_64). Mode os.FileMode `yaml:"mode,omitempty"` // Target mode for file. Does not apply when source is a directory. Config bool `yaml:"config"` // Mark file as config in the package (deb and rpm only). + Modules bool `yaml:"modules"` // Mark directory as directory with modules. Dep func(PackageSpec) error `yaml:"-" hash:"-" json:"-"` // Dependency to invoke during Evaluate. } diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index b7ec2a9b6622..b75f752e1a72 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -10,7 +10,8 @@ LABEL \ org.label-schema.version="{{ .Version }}" \ org.label-schema.url="https://www.elastic.co/products/beats/{{ .BeatName }}" \ org.label-schema.vcs-url="{{ .BeatURL }}" \ - license="{{ .BeatLicense }}" + license="{{ .BeatLicense }}" \ + description="{{ .BeatDescription }}" ENV ELASTIC_CONTAINER "true" ENV PATH={{ $beatHome }}:$PATH @@ -27,14 +28,22 @@ RUN setcap {{ .LinuxCapabilities }} {{ $beatBinary }} {{- end }} RUN groupadd --gid 1000 {{ .BeatName }} + +WORKDIR {{ $beatHome }} +RUN mkdir data logs && \ + chown -R root:{{ .BeatName }} . && \ + find {{ $beatHome }} -type d -exec chmod 0750 {} \; && \ + find {{ $beatHome }} -type f -exec chmod 0640 {} \; && \ + chmod 0750 {{ $beatBinary }} && \ + chmod 0770 data logs +{{- range $i, $modulesd := .ModulesDirs }} +RUN chmod 0770 {{ $modulesd }} +{{- end }} + {{- if .User }} RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .User }} USER {{ .User }} {{- end }} -WORKDIR /usr/share/{{ .BeatName }} - -# TODO: Fix permissions in files - ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] -CMD ["-e"] +CMD ["-e"] \ No newline at end of file diff --git a/filebeat/magefile.go b/filebeat/magefile.go index de3cbeaed179..9a304d5ae548 100644 --- a/filebeat/magefile.go +++ b/filebeat/magefile.go @@ -174,14 +174,16 @@ func customizePackaging() { modulesDTarget = "modules.d" modulesD = mage.PackageFile{ - Mode: 0644, - Source: "modules.d", - Config: true, + Mode: 0644, + Source: "modules.d", + Config: true, + Modules: true, } modulesDXPack = mage.PackageFile{ - Mode: 0644, - Source: dirModulesDGeneratedXPack, - Config: true, + Mode: 0644, + Source: dirModulesDGeneratedXPack, + Config: true, + Modules: true, } ) diff --git a/metricbeat/magefile.go b/metricbeat/magefile.go index 7a9a914a8c08..b9a8f79644b4 100644 --- a/metricbeat/magefile.go +++ b/metricbeat/magefile.go @@ -131,14 +131,16 @@ func customizePackaging() { unixModulesDir = "/etc/{{.BeatName}}/modules.d" modulesDir = mage.PackageFile{ - Mode: 0644, - Source: "modules.d", - Config: true, + Mode: 0644, + Source: "modules.d", + Config: true, + Modules: true, } windowsModulesDir = mage.PackageFile{ - Mode: 0644, - Source: "{{.PackageDir}}/modules.d", - Config: true, + Mode: 0644, + Source: "{{.PackageDir}}/modules.d", + Config: true, + Modules: true, Dep: func(spec mage.PackageSpec) error { if err := mage.Copy("modules.d", spec.MustExpand("{{.PackageDir}}/modules.d")); err != nil { return errors.Wrap(err, "failed to copy modules.d dir") From c42dc23a960b06dc7094acc77c9e414330545ca2 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sun, 4 Nov 2018 13:36:10 +0100 Subject: [PATCH 05/28] Better parametrize urls in Dockerfile --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index b75f752e1a72..9e630c0420c0 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -1,5 +1,6 @@ {{- $beatHome := printf "%s/%s" "/usr/share" .BeatName }} {{- $beatBinary := printf "%s/%s" $beatHome .BeatName }} +{{- $repoInfo := repo }} FROM {{ .From }} @@ -8,8 +9,8 @@ LABEL \ org.label-schema.vendor="{{ .BeatVendor }}" \ org.label-schema.name="{{ .BeatName }}" \ org.label-schema.version="{{ .Version }}" \ - org.label-schema.url="https://www.elastic.co/products/beats/{{ .BeatName }}" \ - org.label-schema.vcs-url="{{ .BeatURL }}" \ + org.label-schema.url="{{ .BeatURL }}" \ + org.label-schema.vcs-url="{{ $repoInfo.RootImportPath }}" \ license="{{ .BeatLicense }}" \ description="{{ .BeatDescription }}" From ece0946f39ce9df3f02f3d78e7ab94871b1e4218 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sun, 4 Nov 2018 13:40:21 +0100 Subject: [PATCH 06/28] Use helper function for version --- dev-tools/mage/dockerbuilder.go | 5 ++--- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index bafdf6ef4c6d..e09dc0f50e5f 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -102,7 +102,6 @@ func (b *dockerBuilder) prepareBuild() error { data := map[string]interface{}{ "From": "centos:7", // TODO: Parametrize this - "Version": b.Version, "Env": map[string]string{}, "LinuxCapabilities": "", "User": b.ServiceName, @@ -127,8 +126,8 @@ func (b *dockerBuilder) prepareBuild() error { } func (b *dockerBuilder) dockerBuild() (string, error) { - repository := "docker.elastic.co/beats" // TODO: Parametrize this - tag := fmt.Sprintf("%s:%s", filepath.Join(repository, b.Name), b.Version) // TODO: What about OSS? + repository := "docker.elastic.co/beats" // TODO: Parametrize this + tag := fmt.Sprintf("%s:%s", filepath.Join(repository, b.Name), b.Version) return tag, sh.Run("docker", "build", "-t", tag, b.buildDir()) } diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 9e630c0420c0..72eb21924417 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -8,7 +8,7 @@ LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.vendor="{{ .BeatVendor }}" \ org.label-schema.name="{{ .BeatName }}" \ - org.label-schema.version="{{ .Version }}" \ + org.label-schema.version="{{ beat_version }}" \ org.label-schema.url="{{ .BeatURL }}" \ org.label-schema.vcs-url="{{ $repoInfo.RootImportPath }}" \ license="{{ .BeatLicense }}" \ From c614a80efb8947c48d12a184dd27714492762ae9 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sun, 4 Nov 2018 15:11:01 +0100 Subject: [PATCH 07/28] Set docker from and user from spec file --- auditbeat/magefile.go | 3 +- dev-tools/mage/dockerbuilder.go | 9 ++-- dev-tools/mage/pkgtypes.go | 7 +++ dev-tools/packaging/packages.yml | 51 +++++++++++++++++-- .../templates/docker/Dockerfile.tmpl | 12 ++--- 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/auditbeat/magefile.go b/auditbeat/magefile.go index f755fef8a0cb..9ec440ddefa4 100644 --- a/auditbeat/magefile.go +++ b/auditbeat/magefile.go @@ -202,9 +202,10 @@ func customizePackaging() { for _, args := range mage.Packages { pkgType := args.Types[0] switch pkgType { - case mage.TarGz, mage.Zip: + case mage.TarGz, mage.Zip, mage.Docker: args.Spec.ReplaceFile("{{.BeatName}}.yml", shortConfig) args.Spec.ReplaceFile("{{.BeatName}}.reference.yml", referenceConfig) + args.Spec.ExtraVar("user", "root") case mage.Deb, mage.RPM, mage.DMG: args.Spec.ReplaceFile("/etc/{{.BeatName}}/{{.BeatName}}.yml", shortConfig) args.Spec.ReplaceFile("/etc/{{.BeatName}}/{{.BeatName}}.reference.yml", referenceConfig) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index e09dc0f50e5f..432a716d741f 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -101,11 +101,8 @@ func (b *dockerBuilder) prepareBuild() error { templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") data := map[string]interface{}{ - "From": "centos:7", // TODO: Parametrize this - "Env": map[string]string{}, - "LinuxCapabilities": "", - "User": b.ServiceName, - "ModulesDirs": b.modulesDirs(), + "Env": map[string]string{}, + "ModulesDirs": b.modulesDirs(), } buildDir := b.buildDir() @@ -116,7 +113,7 @@ func (b *dockerBuilder) prepareBuild() error { ".tmpl", ) - err = ExpandFile(path, target, data) + err = b.ExpandFile(path, target, data) if err != nil { return errors.Wrapf(err, "expanding template '%s' to '%s'", path, target) } diff --git a/dev-tools/mage/pkgtypes.go b/dev-tools/mage/pkgtypes.go index 8e65f558437f..108ad2025b7d 100644 --- a/dev-tools/mage/pkgtypes.go +++ b/dev-tools/mage/pkgtypes.go @@ -293,6 +293,13 @@ func (s PackageSpec) ReplaceFile(target string, file PackageFile) { s.Files[target] = file } +func (s *PackageSpec) ExtraVar(key, value string) { + if s.ExtraVars == nil { + s.ExtraVars = make(map[string]string) + } + s.ExtraVars[key] = value +} + // Expand expands a templated string using data from the spec. func (s PackageSpec) Expand(in string, args ...map[string]interface{}) (string, error) { return expandTemplate("inline", in, FuncMap, diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index 61a37403abd9..aa32abf30d32 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -157,6 +157,13 @@ shared: template: '{{ elastic_beats_dir }}/dev-tools/packaging/templates/windows/uninstall-service.ps1.tmpl' mode: 0755 + - &docker_spec + <<: *binary_spec + extra_vars: + from: 'centos:7' + user: '{{ .BeatServiceName }}' + linux_capabilities: '' + # # License modifiers for Apache 2.0 # @@ -220,7 +227,7 @@ specs: <<: *binary_spec - os: linux - types: [tgz, docker] + types: [tgz] spec: <<: *binary_spec @@ -229,6 +236,11 @@ specs: spec: <<: *deb_rpm_spec + - os: linux + types: [docker] + spec: + <<: *docker_spec + elastic_beat_without_xpack: ### # OSS Packages @@ -255,7 +267,7 @@ specs: name: '{{.BeatName}}-oss' - os: linux - types: [tgz, docker] + types: [tgz] spec: <<: *binary_spec <<: *apache_license_for_binaries @@ -268,6 +280,13 @@ specs: <<: *apache_license_for_deb_rpm name: '{{.BeatName}}-oss' + - os: linux + types: [docker] + spec: + <<: *docker_spec + <<: *apache_license_for_binaries + name: '{{.BeatName}}-oss' + ### # Elastic Licensed Packages ### @@ -290,7 +309,7 @@ specs: <<: *elastic_license_for_macos_pkg - os: linux - types: [tgz, docker] + types: [tgz] spec: <<: *binary_spec <<: *elastic_license_for_binaries @@ -301,6 +320,12 @@ specs: <<: *deb_rpm_spec <<: *elastic_license_for_deb_rpm + - os: linux + types: [docker] + spec: + <<: *docker_spec + <<: *elastic_license_for_binaries + # Official Beats elastic_beat: ### @@ -328,7 +353,7 @@ specs: name: '{{.BeatName}}-oss' - os: linux - types: [tgz, docker] + types: [tgz] spec: <<: *binary_spec <<: *apache_license_for_binaries @@ -341,6 +366,13 @@ specs: <<: *apache_license_for_deb_rpm name: '{{.BeatName}}-oss' + - os: linux + types: [docker] + spec: + <<: *docker_spec + <<: *apache_license_for_binaries + name: '{{.BeatName}}-oss' + ### # Elastic Licensed Packages ### @@ -369,7 +401,7 @@ specs: <<: *elastic_license_for_macos_pkg - os: linux - types: [tgz, docker] + types: [tgz] spec: <<: *binary_spec <<: *elastic_license_for_binaries @@ -385,3 +417,12 @@ specs: files: /usr/share/{{.BeatName}}/bin/{{.BeatName}}{{.BinaryExt}}: source: ../x-pack/{{.BeatName}}/build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}} + + - os: linux + types: [docker] + spec: + <<: *docker_spec + <<: *elastic_license_for_binaries + files: + '{{.BeatName}}{{.BinaryExt}}': + source: ../x-pack/{{.BeatName}}/build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}} diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 72eb21924417..f22ca2f85779 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -2,7 +2,7 @@ {{- $beatBinary := printf "%s/%s" $beatHome .BeatName }} {{- $repoInfo := repo }} -FROM {{ .From }} +FROM {{ .from }} LABEL \ org.label-schema.schema-version="1.0" \ @@ -24,8 +24,8 @@ COPY beat {{ $beatHome }} COPY docker-entrypoint /usr/local/bin/docker-entrypoint RUN chmod a+x /usr/local/bin/docker-entrypoint -{{- if .LinuxCapabilities }} -RUN setcap {{ .LinuxCapabilities }} {{ $beatBinary }} +{{- if .linux_capabilities }} +RUN setcap {{ .linux_capabilities }} {{ $beatBinary }} {{- end }} RUN groupadd --gid 1000 {{ .BeatName }} @@ -41,10 +41,10 @@ RUN mkdir data logs && \ RUN chmod 0770 {{ $modulesd }} {{- end }} -{{- if .User }} -RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .User }} -USER {{ .User }} +{{- if ne .user "root" }} +RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .user }} {{- end }} +USER {{ .user }} ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] CMD ["-e"] \ No newline at end of file From c743ba8435c9a7201bdadf686887b90ac893f500 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sun, 4 Nov 2018 15:24:41 +0100 Subject: [PATCH 08/28] Set linux capabilities on heartbeat and packetbeat --- heartbeat/magefile.go | 12 ++++++++++++ packetbeat/magefile.go | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/heartbeat/magefile.go b/heartbeat/magefile.go index 314e74cd9c38..b7d08244051d 100644 --- a/heartbeat/magefile.go +++ b/heartbeat/magefile.go @@ -81,6 +81,8 @@ func Package() { defer func() { fmt.Println("package ran for", time.Since(start)) }() mage.UseElasticBeatPackaging() + customizePackaging() + mg.Deps(Update) mg.Deps(CrossBuild, CrossBuildXPack, CrossBuildGoDaemon) mg.SerialDeps(mage.Package, TestPackages) @@ -114,3 +116,13 @@ func GoTestUnit(ctx context.Context) error { func GoTestIntegration(ctx context.Context) error { return mage.GoTest(ctx, mage.DefaultGoTestIntegrationArgs()) } + +func customizePackaging() { + for _, args := range mage.Packages { + pkgType := args.Types[0] + switch pkgType { + case mage.Docker: + args.Spec.ExtraVar("linux_capabilities", "cap_net_raw=eip") + } + } +} diff --git a/packetbeat/magefile.go b/packetbeat/magefile.go index e577033b8182..bb2f6d924e39 100644 --- a/packetbeat/magefile.go +++ b/packetbeat/magefile.go @@ -448,5 +448,11 @@ func customizePackaging() { args.Spec.ReplaceFile("{{.BeatName}}.yml", configYml) args.Spec.ReplaceFile("{{.BeatName}}.reference.yml", referenceConfigYml) } + + pkgType := args.Types[0] + switch pkgType { + case mage.Docker: + args.Spec.ExtraVar("linux_capabilities", "cap_net_raw,cap_net_admin=eip") + } } } From 691bf7b2decf22cbc918b0d5ab925f90d8901880 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Sun, 4 Nov 2018 15:30:14 +0100 Subject: [PATCH 09/28] Build docker for filebeat --- filebeat/magefile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filebeat/magefile.go b/filebeat/magefile.go index 9a304d5ae548..071bccbc7253 100644 --- a/filebeat/magefile.go +++ b/filebeat/magefile.go @@ -203,7 +203,7 @@ func customizePackaging() { pkgType := args.Types[0] switch pkgType { - case mage.TarGz, mage.Zip: + case mage.TarGz, mage.Zip, mage.Docker: args.Spec.Files[moduleTarget] = mods args.Spec.Files[modulesDTarget] = modsD case mage.Deb, mage.RPM: From 530bc94bb0104aeef6e2c2bc5ed762516aa46f1d Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 10:55:49 +0100 Subject: [PATCH 10/28] Use beat name as default user name in docker --- dev-tools/packaging/packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index aa32abf30d32..ca6fd39909f6 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -161,7 +161,7 @@ shared: <<: *binary_spec extra_vars: from: 'centos:7' - user: '{{ .BeatServiceName }}' + user: '{{ .BeatName }}' linux_capabilities: '' # From c72feaf9767dd592ad4708778b23a8891b3a83e6 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 11:37:33 +0100 Subject: [PATCH 11/28] Don't rely on current directory for files chmods --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index f22ca2f85779..3a17c4071998 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -31,12 +31,12 @@ RUN setcap {{ .linux_capabilities }} {{ $beatBinary }} RUN groupadd --gid 1000 {{ .BeatName }} WORKDIR {{ $beatHome }} -RUN mkdir data logs && \ - chown -R root:{{ .BeatName }} . && \ +RUN mkdir {{ $beatHome }}/data {{ $beatHome }}/logs && \ + chown -R root:{{ .BeatName }} {{ $beatHome }} && \ find {{ $beatHome }} -type d -exec chmod 0750 {} \; && \ find {{ $beatHome }} -type f -exec chmod 0640 {} \; && \ chmod 0750 {{ $beatBinary }} && \ - chmod 0770 data logs + chmod 0770 {{ $beatHome }}/data {{ $beatHome }}/logs {{- range $i, $modulesd := .ModulesDirs }} RUN chmod 0770 {{ $modulesd }} {{- end }} From ae4239a5235156c69c92f124e15edfe670a1ca0a Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 15:12:15 +0100 Subject: [PATCH 12/28] Use proper license variable in Dockerfile --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 3a17c4071998..6799aa580243 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -11,7 +11,7 @@ LABEL \ org.label-schema.version="{{ beat_version }}" \ org.label-schema.url="{{ .BeatURL }}" \ org.label-schema.vcs-url="{{ $repoInfo.RootImportPath }}" \ - license="{{ .BeatLicense }}" \ + license="{{ .License }}" \ description="{{ .BeatDescription }}" ENV ELASTIC_CONTAINER "true" From 1900d1f63e3a3a7b4f53a966fbe803eabd619300 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 18:40:22 +0100 Subject: [PATCH 13/28] Set capabilities after setting owner and permissions --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 6799aa580243..127c0b057789 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -24,13 +24,8 @@ COPY beat {{ $beatHome }} COPY docker-entrypoint /usr/local/bin/docker-entrypoint RUN chmod a+x /usr/local/bin/docker-entrypoint -{{- if .linux_capabilities }} -RUN setcap {{ .linux_capabilities }} {{ $beatBinary }} -{{- end }} - RUN groupadd --gid 1000 {{ .BeatName }} -WORKDIR {{ $beatHome }} RUN mkdir {{ $beatHome }}/data {{ $beatHome }}/logs && \ chown -R root:{{ .BeatName }} {{ $beatHome }} && \ find {{ $beatHome }} -type d -exec chmod 0750 {} \; && \ @@ -38,7 +33,11 @@ RUN mkdir {{ $beatHome }}/data {{ $beatHome }}/logs && \ chmod 0750 {{ $beatBinary }} && \ chmod 0770 {{ $beatHome }}/data {{ $beatHome }}/logs {{- range $i, $modulesd := .ModulesDirs }} -RUN chmod 0770 {{ $modulesd }} +RUN chmod 0770 {{ $beatHome}}/{{ $modulesd }} +{{- end }} + +{{- if .linux_capabilities }} +RUN setcap {{ .linux_capabilities }} {{ $beatBinary }} {{- end }} {{- if ne .user "root" }} @@ -46,5 +45,6 @@ RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .user }} {{- end }} USER {{ .user }} +WORKDIR {{ $beatHome }} ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] CMD ["-e"] \ No newline at end of file From b15df4eda0c016b9bfc77c1052acbf580e111605 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 21:03:09 +0100 Subject: [PATCH 14/28] Add all kibana.generated directories to gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5781a1e43a3d..97ae9306071a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ /*/fields.yml /*/*.template*.json **/html_docs -/*/_meta/kibana.generated +/**/_meta/kibana.generated # Files .DS_Store From d72283cd60c7cda3d2420c21c9b10ef32eb5339e Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 21:02:32 +0100 Subject: [PATCH 15/28] Add specific configuration for docker images --- auditbeat/_meta/beat.docker.yml | 14 ++++++++++ auditbeat/auditbeat.docker.yml | 21 +++++++++++++++ auditbeat/magefile.go | 5 ++-- dev-tools/packaging/packages.yml | 5 ++++ filebeat/_meta/beat.docker.yml | 5 ++++ filebeat/filebeat.docker.yml | 12 +++++++++ heartbeat/_meta/beat.docker.yml | 13 +++++++++ heartbeat/heartbeat.docker.yml | 20 ++++++++++++++ journalbeat/_meta/beat.docker.yml | 4 +++ journalbeat/journalbeat.docker.yml | 11 ++++++++ libbeat/_meta/config.docker.yml | 7 +++++ libbeat/scripts/Makefile | 6 +++-- metricbeat/_meta/beat.docker.yml | 4 +++ metricbeat/metricbeat.docker.yml | 11 ++++++++ packetbeat/_meta/beat.docker.yml | 35 +++++++++++++++++++++++++ packetbeat/packetbeat.docker.yml | 42 ++++++++++++++++++++++++++++++ 16 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 auditbeat/_meta/beat.docker.yml create mode 100644 auditbeat/auditbeat.docker.yml create mode 100644 filebeat/_meta/beat.docker.yml create mode 100644 filebeat/filebeat.docker.yml create mode 100644 heartbeat/_meta/beat.docker.yml create mode 100644 heartbeat/heartbeat.docker.yml create mode 100644 journalbeat/_meta/beat.docker.yml create mode 100644 journalbeat/journalbeat.docker.yml create mode 100644 libbeat/_meta/config.docker.yml create mode 100644 metricbeat/_meta/beat.docker.yml create mode 100644 metricbeat/metricbeat.docker.yml create mode 100644 packetbeat/_meta/beat.docker.yml create mode 100644 packetbeat/packetbeat.docker.yml diff --git a/auditbeat/_meta/beat.docker.yml b/auditbeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..1b50298c6afb --- /dev/null +++ b/auditbeat/_meta/beat.docker.yml @@ -0,0 +1,14 @@ +auditbeat.modules: + +- module: auditd + audit_rules: | + -w /etc/passwd -p wa -k identity + -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -k access + +- module: file_integrity + paths: + - /bin + - /usr/bin + - /sbin + - /usr/sbin + - /etc diff --git a/auditbeat/auditbeat.docker.yml b/auditbeat/auditbeat.docker.yml new file mode 100644 index 000000000000..3178297b6f73 --- /dev/null +++ b/auditbeat/auditbeat.docker.yml @@ -0,0 +1,21 @@ +auditbeat.modules: + +- module: auditd + audit_rules: | + -w /etc/passwd -p wa -k identity + -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -k access + +- module: file_integrity + paths: + - /bin + - /usr/bin + - /sbin + - /usr/sbin + - /etc +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/auditbeat/magefile.go b/auditbeat/magefile.go index 9ec440ddefa4..5100db035331 100644 --- a/auditbeat/magefile.go +++ b/auditbeat/magefile.go @@ -202,13 +202,14 @@ func customizePackaging() { for _, args := range mage.Packages { pkgType := args.Types[0] switch pkgType { - case mage.TarGz, mage.Zip, mage.Docker: + case mage.TarGz, mage.Zip: args.Spec.ReplaceFile("{{.BeatName}}.yml", shortConfig) args.Spec.ReplaceFile("{{.BeatName}}.reference.yml", referenceConfig) - args.Spec.ExtraVar("user", "root") case mage.Deb, mage.RPM, mage.DMG: args.Spec.ReplaceFile("/etc/{{.BeatName}}/{{.BeatName}}.yml", shortConfig) args.Spec.ReplaceFile("/etc/{{.BeatName}}/{{.BeatName}}.reference.yml", referenceConfig) + case mage.Docker: + args.Spec.ExtraVar("user", "root") default: panic(errors.Errorf("unhandled package type: %v", pkgType)) } diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index ca6fd39909f6..a34c758795e7 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -163,6 +163,11 @@ shared: from: 'centos:7' user: '{{ .BeatName }}' linux_capabilities: '' + files: + '{{.BeatName}}.yml': + source: '{{.BeatName}}.docker.yml' + mode: 0600 + config: true # # License modifiers for Apache 2.0 diff --git a/filebeat/_meta/beat.docker.yml b/filebeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..756c2df52179 --- /dev/null +++ b/filebeat/_meta/beat.docker.yml @@ -0,0 +1,5 @@ +filebeat.config: + modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false + diff --git a/filebeat/filebeat.docker.yml b/filebeat/filebeat.docker.yml new file mode 100644 index 000000000000..99cf52e1cb66 --- /dev/null +++ b/filebeat/filebeat.docker.yml @@ -0,0 +1,12 @@ +filebeat.config: + modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false + +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/heartbeat/_meta/beat.docker.yml b/heartbeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..496602310d1b --- /dev/null +++ b/heartbeat/_meta/beat.docker.yml @@ -0,0 +1,13 @@ +heartbeat.monitors: +- type: http + schedule: '@every 5s' + urls: + - http://elasticsearch:9200 + - http://kibana:5601 + +- type: icmp + schedule: '@every 5s' + hosts: + - elasticsearch + - kibana + diff --git a/heartbeat/heartbeat.docker.yml b/heartbeat/heartbeat.docker.yml new file mode 100644 index 000000000000..9a344a539e1c --- /dev/null +++ b/heartbeat/heartbeat.docker.yml @@ -0,0 +1,20 @@ +heartbeat.monitors: +- type: http + schedule: '@every 5s' + urls: + - http://elasticsearch:9200 + - http://kibana:5601 + +- type: icmp + schedule: '@every 5s' + hosts: + - elasticsearch + - kibana + +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/journalbeat/_meta/beat.docker.yml b/journalbeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..2c87c0346b69 --- /dev/null +++ b/journalbeat/_meta/beat.docker.yml @@ -0,0 +1,4 @@ +journalbeat.inputs: +- paths: [] + seek: tail + diff --git a/journalbeat/journalbeat.docker.yml b/journalbeat/journalbeat.docker.yml new file mode 100644 index 000000000000..aa709469a724 --- /dev/null +++ b/journalbeat/journalbeat.docker.yml @@ -0,0 +1,11 @@ +journalbeat.inputs: +- paths: [] + seek: tail + +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/libbeat/_meta/config.docker.yml b/libbeat/_meta/config.docker.yml new file mode 100644 index 000000000000..241ec9906721 --- /dev/null +++ b/libbeat/_meta/config.docker.yml @@ -0,0 +1,7 @@ +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/libbeat/scripts/Makefile b/libbeat/scripts/Makefile index 941ba3d5a67a..802b64384d1c 100755 --- a/libbeat/scripts/Makefile +++ b/libbeat/scripts/Makefile @@ -325,8 +325,10 @@ update: python-env fields collect @mkdir -p _meta @# Update config files. @cat _meta/beat.yml ${ES_BEATS}/libbeat/_meta/config.yml | sed -e "s/beatname/${BEAT_NAME}/g;s/beat-index-prefix/${BEAT_INDEX_PREFIX}/g" > ${BEAT_NAME}.yml - @chmod 0640 ${BEAT_NAME}.yml - +ifneq (,$(wildcard _meta/beat.docker.yml)) + @cat _meta/beat.docker.yml ${ES_BEATS}/libbeat/_meta/config.docker.yml > ${BEAT_NAME}.docker.yml + @chmod 0640 ${BEAT_NAME}.yml ${BEAT_NAME}.docker.yml +endif @# Update reference config files. ifeq ($(BEAT_REF_YAML),true) diff --git a/metricbeat/_meta/beat.docker.yml b/metricbeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..16b19a866dd7 --- /dev/null +++ b/metricbeat/_meta/beat.docker.yml @@ -0,0 +1,4 @@ +metricbeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false + diff --git a/metricbeat/metricbeat.docker.yml b/metricbeat/metricbeat.docker.yml new file mode 100644 index 000000000000..982018eefc7a --- /dev/null +++ b/metricbeat/metricbeat.docker.yml @@ -0,0 +1,11 @@ +metricbeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false + +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' diff --git a/packetbeat/_meta/beat.docker.yml b/packetbeat/_meta/beat.docker.yml new file mode 100644 index 000000000000..4a7b12464ee1 --- /dev/null +++ b/packetbeat/_meta/beat.docker.yml @@ -0,0 +1,35 @@ +packetbeat.interfaces.device: any + +packetbeat.flows: + timeout: 30s + period: 10s + +packetbeat.protocols.dns: + ports: [53] + include_authorities: true + include_additionals: true + +packetbeat.protocols.http: + ports: [80, 5601, 9200, 8080, 8081, 5000, 8002] + +packetbeat.protocols.memcache: + ports: [11211] + +packetbeat.protocols.mysql: + ports: [3306] + +packetbeat.protocols.pgsql: + ports: [5432] + +packetbeat.protocols.redis: + ports: [6379] + +packetbeat.protocols.thrift: + ports: [9090] + +packetbeat.protocols.mongodb: + ports: [27017] + +packetbeat.protocols.cassandra: + ports: [9042] + diff --git a/packetbeat/packetbeat.docker.yml b/packetbeat/packetbeat.docker.yml new file mode 100644 index 000000000000..b475f516f499 --- /dev/null +++ b/packetbeat/packetbeat.docker.yml @@ -0,0 +1,42 @@ +packetbeat.interfaces.device: any + +packetbeat.flows: + timeout: 30s + period: 10s + +packetbeat.protocols.dns: + ports: [53] + include_authorities: true + include_additionals: true + +packetbeat.protocols.http: + ports: [80, 5601, 9200, 8080, 8081, 5000, 8002] + +packetbeat.protocols.memcache: + ports: [11211] + +packetbeat.protocols.mysql: + ports: [3306] + +packetbeat.protocols.pgsql: + ports: [5432] + +packetbeat.protocols.redis: + ports: [6379] + +packetbeat.protocols.thrift: + ports: [9090] + +packetbeat.protocols.mongodb: + ports: [27017] + +packetbeat.protocols.cassandra: + ports: [9042] + +processors: +- add_cloud_metadata: ~ + +output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}' + username: '${ELASTICSEARCH_USERNAME:}' + password: '${ELASTICSEARCH_PASSWORD:}' From 068f011174f9276c994bc9b12722ff5e3c4af16c Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Mon, 5 Nov 2018 23:02:21 +0100 Subject: [PATCH 16/28] Parametrize base docker repository --- dev-tools/mage/dockerbuilder.go | 6 ++++-- dev-tools/packaging/packages.yml | 1 + filebeat/magefile.go | 8 ++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index 432a716d741f..54fd79eee54b 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -123,8 +123,10 @@ func (b *dockerBuilder) prepareBuild() error { } func (b *dockerBuilder) dockerBuild() (string, error) { - repository := "docker.elastic.co/beats" // TODO: Parametrize this - tag := fmt.Sprintf("%s:%s", filepath.Join(repository, b.Name), b.Version) + tag := fmt.Sprintf("%s:%s", b.Name, b.Version) + if repository, _ := b.ExtraVars["repository"]; repository != "" { + tag = fmt.Sprintf("%s/%s", repository, tag) + } return tag, sh.Run("docker", "build", "-t", tag, b.buildDir()) } diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index a34c758795e7..efd603873004 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -162,6 +162,7 @@ shared: extra_vars: from: 'centos:7' user: '{{ .BeatName }}' + repository: 'docker.elastic.co/beats' linux_capabilities: '' files: '{{.BeatName}}.yml': diff --git a/filebeat/magefile.go b/filebeat/magefile.go index 071bccbc7253..bc31b29c174b 100644 --- a/filebeat/magefile.go +++ b/filebeat/magefile.go @@ -190,18 +190,22 @@ func customizePackaging() { for _, args := range mage.Packages { mods := module modsD := modulesD + pkgType := args.Types[0] if args.Spec.License == "Elastic License" { mods = moduleXPack modsD = modulesDXPack replacePackageFileSource(args, map[string]string{ "fields.yml": "../x-pack/{{.BeatName}}/fields.yml", - "{{.BeatName}}.yml": "../x-pack/{{.BeatName}}/{{.BeatName}}.yml", "{{.BeatName}}.reference.yml": "../x-pack/{{.BeatName}}/{{.BeatName}}.reference.yml", "_meta/kibana.generated": "../x-pack/{{.BeatName}}/build/kibana", }) + if pkgType != mage.Docker { + replacePackageFileSource(args, map[string]string{ + "{{.BeatName}}.yml": "../x-pack/{{.BeatName}}/{{.BeatName}}.yml", + }) + } } - pkgType := args.Types[0] switch pkgType { case mage.TarGz, mage.Zip, mage.Docker: args.Spec.Files[moduleTarget] = mods From a0568cdb4b2f440a2963543792baa58c1b0e01c5 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 11:26:09 +0100 Subject: [PATCH 17/28] Remove unused Env --- dev-tools/mage/dockerbuilder.go | 1 - dev-tools/packaging/templates/docker/Dockerfile.tmpl | 3 --- 2 files changed, 4 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index 54fd79eee54b..ed1f6bdce699 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -101,7 +101,6 @@ func (b *dockerBuilder) prepareBuild() error { templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") data := map[string]interface{}{ - "Env": map[string]string{}, "ModulesDirs": b.modulesDirs(), } diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 127c0b057789..3f3d508baa03 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -16,9 +16,6 @@ LABEL \ ENV ELASTIC_CONTAINER "true" ENV PATH={{ $beatHome }}:$PATH -{{- range $key, $value := .Env }} -ENV {{ $key }} {{ $value }} -{{- end }} COPY beat {{ $beatHome }} COPY docker-entrypoint /usr/local/bin/docker-entrypoint From 67daa1aaad693dc44458c3054fb841d2d49dc870 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 11:30:13 +0100 Subject: [PATCH 18/28] Precalculate build and beat directories --- dev-tools/mage/dockerbuilder.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index ed1f6bdce699..5eb53119dbc1 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -30,18 +30,25 @@ import ( type dockerBuilder struct { PackageSpec + + buildDir string + beatDir string } func newDockerBuilder(spec PackageSpec) (*dockerBuilder, error) { + buildDir := filepath.Join(spec.packageDir, "docker-build") + beatDir := filepath.Join(buildDir, "beat") + return &dockerBuilder{ PackageSpec: spec, + buildDir: buildDir, + beatDir: beatDir, }, nil } func (b *dockerBuilder) Build() error { - buildDir := b.buildDir() - if err := os.RemoveAll(buildDir); err != nil { - return errors.Wrapf(err, "failed to clean existing build directory %s", buildDir) + if err := os.RemoveAll(b.buildDir); err != nil { + return errors.Wrapf(err, "failed to clean existing build directory %s", b.buildDir) } if err := b.copyFiles(); err != nil { @@ -64,14 +71,6 @@ func (b *dockerBuilder) Build() error { return nil } -func (b *dockerBuilder) buildDir() string { - return filepath.Join(b.packageDir, "docker-build") -} - -func (b *dockerBuilder) beatDir() string { - return filepath.Join(b.buildDir(), "beat") -} - func (b *dockerBuilder) modulesDirs() []string { var modulesd []string for _, f := range b.Files { @@ -83,9 +82,8 @@ func (b *dockerBuilder) modulesDirs() []string { } func (b *dockerBuilder) copyFiles() error { - beatDir := b.beatDir() for _, f := range b.Files { - target := filepath.Join(beatDir, f.Target) + target := filepath.Join(b.beatDir, f.Target) if err := Copy(f.Source, target); err != nil { return errors.Wrapf(err, "failed to copy from %s to %s", f.Source, target) } @@ -104,11 +102,10 @@ func (b *dockerBuilder) prepareBuild() error { "ModulesDirs": b.modulesDirs(), } - buildDir := b.buildDir() return filepath.Walk(templatesDir, func(path string, info os.FileInfo, _ error) error { if !info.IsDir() { target := strings.TrimSuffix( - filepath.Join(buildDir, filepath.Base(path)), + filepath.Join(b.buildDir, filepath.Base(path)), ".tmpl", ) @@ -126,7 +123,7 @@ func (b *dockerBuilder) dockerBuild() (string, error) { if repository, _ := b.ExtraVars["repository"]; repository != "" { tag = fmt.Sprintf("%s/%s", repository, tag) } - return tag, sh.Run("docker", "build", "-t", tag, b.buildDir()) + return tag, sh.Run("docker", "build", "-t", tag, b.buildDir) } func (b *dockerBuilder) dockerSave(tag string) error { From c8b015d2f30305fd17f5bd6bb3413f6ade7674a3 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 11:53:30 +0100 Subject: [PATCH 19/28] Add comment --- dev-tools/mage/pkgtypes.go | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-tools/mage/pkgtypes.go b/dev-tools/mage/pkgtypes.go index 108ad2025b7d..a283828b4fc8 100644 --- a/dev-tools/mage/pkgtypes.go +++ b/dev-tools/mage/pkgtypes.go @@ -293,6 +293,7 @@ func (s PackageSpec) ReplaceFile(target string, file PackageFile) { s.Files[target] = file } +// ExtraVar adds or replaces a variable to `extra_vars` in package specs. func (s *PackageSpec) ExtraVar(key, value string) { if s.ExtraVars == nil { s.ExtraVars = make(map[string]string) From 98c8f9b4bfca3a332d06c37cb956faf2761e7ff6 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 11:56:00 +0100 Subject: [PATCH 20/28] Reorder commands in dockerfile so less layers are created --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 3f3d508baa03..75d3966fc0c5 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -28,14 +28,13 @@ RUN mkdir {{ $beatHome }}/data {{ $beatHome }}/logs && \ find {{ $beatHome }} -type d -exec chmod 0750 {} \; && \ find {{ $beatHome }} -type f -exec chmod 0640 {} \; && \ chmod 0750 {{ $beatBinary }} && \ - chmod 0770 {{ $beatHome }}/data {{ $beatHome }}/logs -{{- range $i, $modulesd := .ModulesDirs }} -RUN chmod 0770 {{ $beatHome}}/{{ $modulesd }} -{{- end }} - {{- if .linux_capabilities }} -RUN setcap {{ .linux_capabilities }} {{ $beatBinary }} + setcap {{ .linux_capabilities }} {{ $beatBinary }} && \ {{- end }} +{{- range $i, $modulesd := .ModulesDirs }} + chmod 0770 {{ $beatHome}}/{{ $modulesd }} && \ +{{- end }} + chmod 0770 {{ $beatHome }}/data {{ $beatHome }}/logs {{- if ne .user "root" }} RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .user }} From 7d6a2941fae3ced2f45021bf4ca14154703f372d Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 11:58:17 +0100 Subject: [PATCH 21/28] Added changelog entry --- CHANGELOG-developer.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-developer.asciidoc b/CHANGELOG-developer.asciidoc index ba7602a75f17..6338944abfa9 100644 --- a/CHANGELOG-developer.asciidoc +++ b/CHANGELOG-developer.asciidoc @@ -63,3 +63,4 @@ The list below covers the major changes between 6.3.0 and master only. - Add `mage.KibanaDashboards` for collecting Kibana dashboards and generating index patterns. {pull}8615[8615] - Allow to disable config resolver using the `Settings.DisableConfigResolver` field when initializing libbeat. {pull}8769[8769] - Add `mage.AddPlatforms` to allow to specify dependent platforms when building a beat. {pull}8889[8889] +- Add docker image building to `mage.Package`. {pull}8898[8898] From 51ef1f6bec27a004a639508ebb64a5b04bf95f23 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 12:24:09 +0100 Subject: [PATCH 22/28] Generate docker config for custom beats --- generator/beat/{beat}/_meta/beat.docker.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 generator/beat/{beat}/_meta/beat.docker.yml diff --git a/generator/beat/{beat}/_meta/beat.docker.yml b/generator/beat/{beat}/_meta/beat.docker.yml new file mode 100644 index 000000000000..665509ac5669 --- /dev/null +++ b/generator/beat/{beat}/_meta/beat.docker.yml @@ -0,0 +1,2 @@ +{beat}: + period: 1s From e5ca02cbba48ef007871800adcc9ba4a7658c69c Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 12:39:37 +0100 Subject: [PATCH 23/28] Add commit sha to docker labels --- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 75d3966fc0c5..8c8c32c922a2 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -11,6 +11,7 @@ LABEL \ org.label-schema.version="{{ beat_version }}" \ org.label-schema.url="{{ .BeatURL }}" \ org.label-schema.vcs-url="{{ $repoInfo.RootImportPath }}" \ + org.label-schema.vcs-ref="{{ commit }}" \ license="{{ .License }}" \ description="{{ .BeatDescription }}" From e449166379e5b00faf9ba1fa714b2b306a8320a0 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 6 Nov 2018 21:50:24 +0100 Subject: [PATCH 24/28] Add some tests for docker packaging --- dev-tools/packaging/package_test.go | 164 ++++++++++++++++++ .../templates/docker/Dockerfile.tmpl | 4 +- 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/dev-tools/packaging/package_test.go b/dev-tools/packaging/package_test.go index 715a03f9daf8..8ec90256d4d3 100644 --- a/dev-tools/packaging/package_test.go +++ b/dev-tools/packaging/package_test.go @@ -25,9 +25,11 @@ import ( "archive/zip" "bytes" "compress/gzip" + "encoding/json" "flag" "fmt" "io" + "io/ioutil" "os" "path/filepath" "regexp" @@ -91,6 +93,13 @@ func TestZip(t *testing.T) { } } +func TestDocker(t *testing.T) { + dockers := getFiles(t, regexp.MustCompile(`\.docker.tar$`)) + for _, docker := range dockers { + checkDocker(t, docker) + } +} + // Sub-tests func checkRPM(t *testing.T, file string) { @@ -159,6 +168,18 @@ func checkZip(t *testing.T, file string) { checkModulesPermissions(t, p) } +func checkDocker(t *testing.T, file string) { + p, info, err := readDocker(file) + if err != nil { + t.Error(err) + return + } + + checkDockerEntryPoint(t, p, info) + checkModulesPresent(t, "", p) + checkModulesDPresent(t, "", p) +} + // Verify that the main configuration file is installed with a 0600 file mode. func checkConfigPermissions(t *testing.T, p *packageFile) { t.Run(p.Name+" config file permissions", func(t *testing.T) { @@ -311,6 +332,30 @@ func checkModules(t *testing.T, name, prefix string, r *regexp.Regexp, p *packag }) } +func checkDockerEntryPoint(t *testing.T, p *packageFile, info *dockerInfo) { + expectedMode := os.FileMode(0755) + + t.Run(fmt.Sprintf("%s entrypoint", p.Name), func(t *testing.T) { + if len(info.Config.Entrypoint) == 0 { + t.Fatal("no entrypoint") + } + + entrypoint := info.Config.Entrypoint[0] + if strings.HasPrefix(entrypoint, "/") { + entrypoint := strings.TrimPrefix(entrypoint, "/") + entry, found := p.Contents[entrypoint] + if !found { + t.Fatalf("%s entrypoint not found in docker", entrypoint) + } + if mode := entry.Mode.Perm(); mode != expectedMode { + t.Fatalf("%s entrypoint mode is %s, expected: %s", entrypoint, mode, expectedMode) + } + } else { + t.Skip("TODO: check if binary is in $PATH") + } + }) +} + // Helpers type packageFile struct { @@ -457,3 +502,122 @@ func readZip(zipFile string) (*packageFile, error) { return p, nil } + +func readDocker(dockerFile string) (*packageFile, *dockerInfo, error) { + file, err := os.Open(dockerFile) + if err != nil { + return nil, nil, err + } + defer file.Close() + + var manifest *dockerManifest + var info *dockerInfo + layers := make(map[string]*packageFile) + + tarReader := tar.NewReader(file) + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + break + } + return nil, nil, err + } + + switch { + case header.Name == "manifest.json": + manifest, err = readDockerManifest(tarReader) + if err != nil { + return nil, nil, err + } + case strings.HasSuffix(header.Name, ".json") && header.Name != "manifest.json": + info, err = readDockerInfo(tarReader) + if err != nil { + return nil, nil, err + } + case strings.HasSuffix(header.Name, "/layer.tar"): + layer, err := readTarContents(header.Name, tarReader) + if err != nil { + return nil, nil, err + } + layers[filepath.Dir(header.Name)] = layer + } + } + + if len(info.Config.Entrypoint) == 0 { + return nil, nil, fmt.Errorf("no entrypoint") + } + + workingDir := info.Config.WorkingDir + entrypoint := info.Config.Entrypoint[0] + + // Read layers in order and for each file keep only the entry seen in the later layer + p := &packageFile{Name: filepath.Base(dockerFile), Contents: map[string]packageEntry{}} + for _, layer := range manifest.Layers { + layerID := filepath.Dir(layer) + layerFile, found := layers[layerID] + if !found { + return nil, nil, fmt.Errorf("layer not found: %s", layerID) + } + for name, entry := range layerFile.Contents { + // Check only files in working dir and entrypoint + if strings.HasPrefix("/"+name, workingDir) || "/"+name == entrypoint { + p.Contents[name] = entry + } + } + } + + if len(p.Contents) == 0 { + return nil, nil, fmt.Errorf("no files found in docker working directory (%s)", info.Config.WorkingDir) + } + + return p, info, nil +} + +type dockerManifest struct { + Config string + RepoTags []string + Layers []string +} + +func readDockerManifest(r io.Reader) (*dockerManifest, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var manifests []*dockerManifest + err = json.Unmarshal(data, &manifests) + if err != nil { + return nil, err + + } + + if len(manifests) != 1 { + return nil, fmt.Errorf("one and only one manifest expected, %d found", len(manifests)) + } + + return manifests[0], nil +} + +type dockerInfo struct { + Config struct { + WorkingDir string + Entrypoint []string + } `json:"config"` +} + +func readDockerInfo(r io.Reader) (*dockerInfo, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var info dockerInfo + err = json.Unmarshal(data, &info) + if err != nil { + return nil, err + } + + return &info, nil +} diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 8c8c32c922a2..142b9d19a507 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -20,7 +20,7 @@ ENV PATH={{ $beatHome }}:$PATH COPY beat {{ $beatHome }} COPY docker-entrypoint /usr/local/bin/docker-entrypoint -RUN chmod a+x /usr/local/bin/docker-entrypoint +RUN chmod 755 /usr/local/bin/docker-entrypoint RUN groupadd --gid 1000 {{ .BeatName }} @@ -44,4 +44,4 @@ USER {{ .user }} WORKDIR {{ $beatHome }} ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] -CMD ["-e"] \ No newline at end of file +CMD ["-e"] From 85ef19251a84032a1d77e5909ef62ff9bea00fe7 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Thu, 8 Nov 2018 12:38:18 +0100 Subject: [PATCH 25/28] Add expose_ports extra var to expose ports in dockers --- dev-tools/mage/dockerbuilder.go | 9 ++++++++- dev-tools/packaging/templates/docker/Dockerfile.tmpl | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dev-tools/mage/dockerbuilder.go b/dev-tools/mage/dockerbuilder.go index 5eb53119dbc1..d7c3cc147a73 100644 --- a/dev-tools/mage/dockerbuilder.go +++ b/dev-tools/mage/dockerbuilder.go @@ -24,7 +24,6 @@ import ( "strings" "github.com/magefile/mage/sh" - "github.com/pkg/errors" ) @@ -81,6 +80,13 @@ func (b *dockerBuilder) modulesDirs() []string { return modulesd } +func (b *dockerBuilder) exposePorts() []string { + if ports, _ := b.ExtraVars["expose_ports"]; ports != "" { + return strings.Split(ports, ",") + } + return nil +} + func (b *dockerBuilder) copyFiles() error { for _, f := range b.Files { target := filepath.Join(b.beatDir, f.Target) @@ -99,6 +105,7 @@ func (b *dockerBuilder) prepareBuild() error { templatesDir := filepath.Join(elasticBeatsDir, "dev-tools/packaging/templates/docker") data := map[string]interface{}{ + "ExposePorts": b.exposePorts(), "ModulesDirs": b.modulesDirs(), } diff --git a/dev-tools/packaging/templates/docker/Dockerfile.tmpl b/dev-tools/packaging/templates/docker/Dockerfile.tmpl index 142b9d19a507..78944029e15a 100644 --- a/dev-tools/packaging/templates/docker/Dockerfile.tmpl +++ b/dev-tools/packaging/templates/docker/Dockerfile.tmpl @@ -42,6 +42,10 @@ RUN useradd -M --uid 1000 --gid 1000 --home {{ $beatHome }} {{ .user }} {{- end }} USER {{ .user }} +{{- range $i, $port := .ExposePorts }} +EXPOSE {{ $port }} +{{- end }} + WORKDIR {{ $beatHome }} ENTRYPOINT ["/usr/local/bin/docker-entrypoint"] CMD ["-e"] From 8e6a32356df4a9b124613bd92be7932856cb30ea Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Thu, 8 Nov 2018 12:48:48 +0100 Subject: [PATCH 26/28] Set repository only for elastic dockers --- dev-tools/packaging/packages.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dev-tools/packaging/packages.yml b/dev-tools/packaging/packages.yml index efd603873004..6ffbe1557182 100644 --- a/dev-tools/packaging/packages.yml +++ b/dev-tools/packaging/packages.yml @@ -162,7 +162,6 @@ shared: extra_vars: from: 'centos:7' user: '{{ .BeatName }}' - repository: 'docker.elastic.co/beats' linux_capabilities: '' files: '{{.BeatName}}.yml': @@ -170,6 +169,10 @@ shared: mode: 0600 config: true + - &elastic_docker_spec + extra_vars: + repository: 'docker.elastic.co/beats' + # # License modifiers for Apache 2.0 # @@ -290,6 +293,7 @@ specs: types: [docker] spec: <<: *docker_spec + <<: *elastic_docker_spec <<: *apache_license_for_binaries name: '{{.BeatName}}-oss' @@ -330,6 +334,7 @@ specs: types: [docker] spec: <<: *docker_spec + <<: *elastic_docker_spec <<: *elastic_license_for_binaries # Official Beats @@ -376,6 +381,7 @@ specs: types: [docker] spec: <<: *docker_spec + <<: *elastic_docker_spec <<: *apache_license_for_binaries name: '{{.BeatName}}-oss' @@ -428,6 +434,7 @@ specs: types: [docker] spec: <<: *docker_spec + <<: *elastic_docker_spec <<: *elastic_license_for_binaries files: '{{.BeatName}}{{.BinaryExt}}': From db3987de75b3da97565a19cecf5e7fa3f3365dfe Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 13 Nov 2018 17:43:30 +0100 Subject: [PATCH 27/28] Revert "Add all kibana.generated directories to gitignore" This reverts commit b15df4eda0c016b9bfc77c1052acbf580e111605. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 97ae9306071a..5781a1e43a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ /*/fields.yml /*/*.template*.json **/html_docs -/**/_meta/kibana.generated +/*/_meta/kibana.generated # Files .DS_Store From 39f1bc2645ebb49b01ae7aeb575c867e9286948a Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 13 Nov 2018 17:44:57 +0100 Subject: [PATCH 28/28] Fail if docker entry point is not an absolute path --- dev-tools/packaging/package_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/packaging/package_test.go b/dev-tools/packaging/package_test.go index 8ec90256d4d3..d447e22ade73 100644 --- a/dev-tools/packaging/package_test.go +++ b/dev-tools/packaging/package_test.go @@ -351,7 +351,7 @@ func checkDockerEntryPoint(t *testing.T, p *packageFile, info *dockerInfo) { t.Fatalf("%s entrypoint mode is %s, expected: %s", entrypoint, mode, expectedMode) } } else { - t.Skip("TODO: check if binary is in $PATH") + t.Fatal("TODO: check if binary is in $PATH") } }) }