Compare commits

..

No commits in common. "master" and "v0.12.0" have entirely different histories.

148 changed files with 3537 additions and 6266 deletions

235
.circleci/config.yml Normal file
View File

@ -0,0 +1,235 @@
version: 2.1
jobs:
"build-test":
docker:
- image: alpine:3.16
steps:
- checkout
- setup_remote_docker: # used by integration tests that runs driverkit binary that needs docker
version: 20.10.12
- run:
name: Install deps
command: apk add gcc musl-dev make bash git go
- run:
name: Build
command: make build
- run:
name: Test
command: make test
- run:
name: Integration tests
command: make integration_test
- run:
name: Prepare Artifacts
command: |
mkdir -p /tmp/build-amd64
cp _output/bin/driverkit /tmp/build-amd64/
- store_artifacts:
path: /tmp/build-amd64/driverkit
destination: driverkit_amd64
- persist_to_workspace:
root: /tmp
paths:
- build-amd64/
"build-test-arm64":
machine:
enabled: true
image: ubuntu-2004:2022.04.1
resource_class: arm.medium
steps:
- checkout:
path: /tmp/source
- run:
name: Prepare project
command: |
docker run --rm -it -v /tmp/source:/source -v /var/run/docker.sock:/var/run/docker.sock -w /source --name alpine_sh -d alpine:3.16 sh
docker exec alpine_sh apk add gcc musl-dev make bash git go docker
docker exec alpine_sh git config --global --add safe.directory /source
- run:
name: Build
command: docker exec alpine_sh make build
- run:
name: Test
command: docker exec alpine_sh make test
- run:
name: Integration tests
command: docker exec alpine_sh make integration_test
- run:
name: Prepare Artifacts
command: |
mkdir -p /tmp/build-arm64
cp /tmp/source/_output/bin/driverkit /tmp/build-arm64/
- store_artifacts:
path: /tmp/build-arm64/driverkit
destination: driverkit_arm64
- persist_to_workspace:
root: /tmp
paths:
- build-arm64/
"build-images":
docker:
- image: alpine:3.16
steps:
- attach_workspace:
at: /
- checkout
- setup_remote_docker:
version: 20.10.12
docker_layer_caching: true
- run:
name: Install deps
command: |
apk update
apk add make bash git docker docker-cli-buildx
- run:
name: Login to registry
command: echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
- run:
name: Prepare artifact for driverkit image
command: | # driverkit dockerfile expects the binary there
mkdir -p build-amd64
cp /build-amd64/driverkit build-amd64/
- run:
name: Build and Push docker images
command: GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make push/all
- run:
name: Push latest images
command: |
if [ -n "$CIRCLE_TAG" ]
then
GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make push/latest
else
echo "Skipping (no git tag)"
fi
"build-images-arm64":
machine:
enabled: true
image: ubuntu-2004:2022.04.1
docker_layer_caching: true
resource_class: arm.medium
steps:
- attach_workspace:
at: /tmp
- checkout:
path: /tmp/source
- run:
name: Install deps
command: |
sudo apt update
sudo apt install make bash git
- run:
name: Login to registry
command: echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
- run:
name: Prepare artifact for driverkit image
command: | # driverkit dockerfile expects the binary there
mkdir -p /tmp/source/build-arm64
cp /tmp/build-arm64/driverkit /tmp/source/build-arm64/
- run:
name: Build and Push docker images
command: |
cd /tmp/source
GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make push/all
- run:
name: Push latest images if needed
command: |
cd /tmp/source
if [ -n "$CIRCLE_TAG" ]
then
GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make push/latest
else
echo "Skipping (no git tag)"
fi
"images":
docker:
- image: cimg/base:stable
user: root
steps:
- checkout
- setup_remote_docker:
version: 20.10.12
- run:
name: Prepare env
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
sudo apt update
sudo apt install make bash git
- run:
name: Build and Push manifest to registry
command: |
GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make manifest/all
- run:
name: Push latest manifest if needed
command: |
if [ -n "$CIRCLE_TAG" ]
then
GIT_BRANCH="$CIRCLE_BRANCH" GIT_TAG="$CIRCLE_TAG" make manifest/latest
else
echo "Skipping (no git tag)"
fi
"release":
docker:
- image: cimg/go:1.18
steps:
- checkout
- run:
name: Install goreleaser
command: |
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install goreleaser
- run:
name: Release
command: GIT_TAG="$CIRCLE_TAG" make release
workflows:
version: 2.1
build:
jobs:
- "build-test":
filters:
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
- "build-test-arm64":
filters:
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
- "build-images":
context: falco
filters:
branches:
only:
- master
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
requires:
- "build-test"
- "build-images-arm64":
context: falco
filters:
branches:
only:
- master
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
requires:
- "build-test-arm64"
- "images":
context: falco
filters:
branches:
only:
- master
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
requires:
- "build-images"
- "build-images-arm64"
- "release":
context: falco
filters:
branches:
ignore: /.*/
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
requires:
- "images"

View File

@ -66,5 +66,5 @@ For example, `action required: change the API interface of the rule engine`.
--> -->
```release-note ```release-note
NONE
``` ```

View File

@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
groups:
actions:
update-types:
- "minor"
- "patch"

View File

@ -1,77 +0,0 @@
name: CI Build
on:
pull_request:
branches: [master]
workflow_dispatch:
# Checks if any concurrent jobs under the same pull request or branch are being executed
# NOTE: this will cancel every workflow that is being ran against a PR as group is just the github ref (without the workflow name)
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
build-test-dev:
strategy:
matrix:
arch: [amd64, arm64]
uses: ./.github/workflows/reusable_build_test_driverkit.yml
with:
arch: ${{ matrix.arch }}
paths-filter:
runs-on: ubuntu-latest
outputs:
docker_needs_build: ${{ steps.filter.outputs.docker }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
docker:
- 'docker/**'
build-images-dev:
needs: [build-test-dev,paths-filter]
if: needs.paths-filter.outputs.docker_needs_build == 'true'
strategy:
matrix:
arch: [ amd64, arm64 ]
uses: ./.github/workflows/reusable_build_push_images.yml
with:
arch: ${{ matrix.arch }}
push: false
secrets: inherit
gomodtidy:
name: Enforce go.mod tidiness
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: "${{ github.event.pull_request.head.sha }}"
repository: ${{github.event.pull_request.head.repo.full_name}}
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: 'go.mod'
- name: Execute go mod tidy and check the outcome
working-directory: ./
run: |
go mod tidy
exit_code=$(git diff --exit-code)
exit ${exit_code}
- name: Print a comment in case of failure
run: |
echo "The go.mod and/or go.sum files appear not to be correctly tidied.
Please, rerun go mod tidy to fix the issues."
exit 1
if: |
failure() && github.event.pull_request.head.repo.full_name == github.repository

View File

@ -1,36 +0,0 @@
name: Master CI
on:
push:
branches: [master]
# Checks if any concurrent jobs is running for master CI and eventually cancel it
concurrency:
group: ci-master
cancel-in-progress: true
jobs:
build-test-master:
strategy:
matrix:
arch: [amd64, arm64]
uses: ./.github/workflows/reusable_build_test_driverkit.yml
with:
arch: ${{ matrix.arch }}
push-images-master:
needs: build-test-master
strategy:
matrix:
arch: [amd64, arm64]
uses: ./.github/workflows/reusable_build_push_images.yml
with:
arch: ${{ matrix.arch }}
push: true
secrets: inherit
images-master:
needs: push-images-master
uses: ./.github/workflows/reusable_manifest_images.yml
secrets: inherit

View File

@ -1,68 +0,0 @@
name: Release
on:
push:
tags:
- v*
permissions:
contents: write # needed to write releases
id-token: write # needed for keyless signing
jobs:
build-test-release:
strategy:
matrix:
arch: [amd64, arm64]
uses: ./.github/workflows/reusable_build_test_driverkit.yml
with:
arch: ${{ matrix.arch }}
push-images-release:
needs: build-test-release
strategy:
matrix:
arch: [amd64, arm64]
uses: ./.github/workflows/reusable_build_push_images.yml
with:
arch: ${{ matrix.arch }}
tag: ${{ github.ref_name }}
is_latest: true
push: true
secrets: inherit
images-release:
needs: push-images-release
uses: ./.github/workflows/reusable_manifest_images.yml
with:
tag: ${{ github.ref_name }}
is_latest: true
secrets: inherit
release:
needs: images-release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Fetch
run: git fetch --prune --force --tags
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: 'go.mod'
- name: Install GoReleaser
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
with:
install-only: true
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_TAG: ${{ github.ref_name }}
run: make release

View File

@ -1,72 +0,0 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
arch:
description: amd64 or arm64
required: true
type: string
branch:
description: name of the branch
required: false
type: string
default: 'master'
tag:
description: The tag to use (e.g. "master" or "0.35.0")
required: false
type: string
default: ''
is_latest:
description: Update the latest tag with the new image
required: false
type: boolean
default: false
push:
description: Whether to also push images
required: false
type: boolean
default: false
jobs:
build-images:
runs-on: ${{ (inputs.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
env:
GIT_BRANCH: ${{ inputs.branch }}
GIT_TAG: ${{ inputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Create download folder
run: mkdir -p build-${{ inputs.arch }}
- name: Download Driverkit
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: driverkit-${{ inputs.arch }}
path: build-${{ inputs.arch }}
- name: Enforce executable bit
run: chmod +x build-${{ inputs.arch }}/driverkit
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to Docker Hub
if: inputs.push
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Build and Push docker images
if: inputs.push
run: make push/all
- name: Build docker images
if: inputs.push == false
run: make image/all
- name: Push latest images if needed
if: inputs.push && inputs.is_latest
run: make push/latest

View File

@ -1,47 +0,0 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
arch:
description: amd64 or arm64
required: true
type: string
jobs:
build-test:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: 'go.mod'
- name: Build
run: make build
- name: Test
run: make test
- name: Set integration tests DRIVERVERSIONS env
if: inputs.arch == 'amd64'
run: echo "DRIVERVERSIONS=master 6.0.1+driver 2.0.0+driver 17f5df52a7d9ed6bb12d3b1768460def8439936d" >> $GITHUB_ENV
- name: Set integration tests DRIVERVERSIONS env
if: inputs.arch == 'arm64'
run: echo "DRIVERVERSIONS=master 6.0.1+driver 2.0.0+driver" >> $GITHUB_ENV
- name: Integration tests
run: make integration_test
- name: Upload driverkit
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: driverkit-${{ inputs.arch }}
path: |
${{ github.workspace }}/_output/bin/driverkit

View File

@ -1,45 +0,0 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
branch:
description: name of the branch
required: false
type: string
default: 'master'
tag:
description: The tag to use (e.g. "master" or "0.35.0")
required: false
type: string
default: ''
is_latest:
description: Update the latest tag with the new image
required: false
type: boolean
default: false
jobs:
push-manifest:
runs-on: ubuntu-latest
env:
GIT_BRANCH: ${{ inputs.branch }}
GIT_TAG: ${{ inputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to Docker Hub
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Build and Push manifest to registry
run: make manifest/all
- name: Push latest manifest if needed
if: inputs.is_latest
run: make manifest/latest

4
.gitignore vendored
View File

@ -1,7 +1,7 @@
_output/ _output/
dist/ dist/
vendor/ vendor/
.idea/
driverkit driverkit
coverage.out coverage.out

View File

@ -1,10 +1,6 @@
version: 2
project_name: driverkit project_name: driverkit
builds: builds:
- id: "driverkit" - id: "driverkit"
env:
- GOEXPERIMENT=loopvar
goos: goos:
- linux - linux
goarch: goarch:
@ -13,6 +9,7 @@ builds:
main: . main: .
flags: flags:
- -v - -v
- -buildmode=pie
ldflags: ldflags:
- "{{.Env.LDFLAGS}}" - "{{.Env.LDFLAGS}}"
binary: driverkit binary: driverkit

View File

@ -1,35 +1,81 @@
# Example Configs # Example Configs
## aliyun linux 2 (Alibaba Cloud Linux 2) ## ubuntu
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu (works with any flavor!).
```yaml ```yaml
kernelrelease: 4.19.91-26.al7.x86_64 kernelrelease: 5.0.0-1021-aws-5.0
target: alinux kernelversion: 24~18.04.1
target: ubuntu
output: output:
module: /tmp/falco_alinux_4.19.91-26.al7.x86_64.ko module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco_alinux_4.19.91-26.al7.x86_64.o probe: /tmp/falco-ubuntu-generic.o
driverversion: master driverversion: master
``` ```
## aliyun linux 3 (Alibaba Cloud Linux 3) ## ubuntu-generic
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu generic.
```yaml ```yaml
kernelrelease: 5.10.84-10.4.al8.x86_64 kernelrelease: 4.15.0-72-generic
target: alinux kernelversion: 81
target: ubuntu-generic
output: output:
module: /tmp/falco_alinux_4.19.91-26.al7.x86_64.ko module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco_alinux_4.19.91-26.al7.x86_64.o probe: /tmp/falco-ubuntu-generic.o
driverversion: master driverversion: master
``` ```
## alma linux > **NOTE:** ubuntu-generic exists to retain backward compatibility only,
> and should not be used in new configs.
## ubuntu-aws
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu AWS.
```yaml ```yaml
kernelrelease: 5.14.0-162.12.1.el9_1.x86_64 kernelrelease: 4.15.0-1057-aws
target: almalinux kernelversion: 59
target: ubuntu-aws
output: output:
module: /tmp/falco_almalinux_5.14.0-162.12.1.el9_1.x86_64.ko module: /tmp/falco-ubuntu-aws.ko
probe: /tmp/falco_almalinux_5.14.0-162.12.1.el9_1.x86_64.o probe: /tmp/falco-ubuntu-aws.o
driverversion: master
```
> **NOTE:** ubuntu-aws exists to retain backward compatibility only,
> and should not be used in new configs.
## centos 6
```yaml
kernelrelease: 2.6.32-754.14.2.el6.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos6.ko
driverversion: master
```
## centos 7
```yaml
kernelrelease: 3.10.0-957.12.2.el7.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos7.ko
driverversion: master
```
## centos 8
```yaml
kernelrelease: 4.18.0-147.5.1.el8_1.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos8.ko
driverversion: master driverversion: master
``` ```
@ -65,58 +111,6 @@ output:
driverversion: master driverversion: master
``` ```
## archlinux
Example configuration file to build both the Kernel module and eBPF probe for Archlinux.
Note: archlinux target uses the [Arch Linux Archive](https://wiki.archlinux.org/title/Arch_Linux_Archive) to fetch
all ever supported kernel releases.
For arm64, it uses an user-provided mirror, as no official mirror is available: http://tardis.tiny-vps.com/aarm/.
The mirror has been up and updated since 2015.
```yaml
kernelversion: 1
kernelrelease: 6.0.6.arch1-1
target: arch
output:
module: /tmp/falco-arch.ko
probe: /tmp/falco-arch.o
driverversion: master
builderimage: ${ARCH_BUILD_IMAGE_HERE}
```
## centos 6
```yaml
kernelrelease: 2.6.32-754.14.2.el6.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos6.ko
driverversion: master
```
## centos 7
```yaml
kernelrelease: 3.10.0-957.12.2.el7.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos7.ko
driverversion: master
```
## centos 8
```yaml
kernelrelease: 4.18.0-147.5.1.el8_1.x86_64
kernelversion: 1
target: centos
output:
module: /tmp/falco-centos8.ko
driverversion: master
```
## debian ## debian
Example configuration file to build both the Kernel module and eBPF probe for Debian. Example configuration file to build both the Kernel module and eBPF probe for Debian.
@ -131,17 +125,6 @@ target: debian
driverversion: master driverversion: master
``` ```
## fedora
```yaml
kernelrelease: 5.19.16-200.fc36.x86_64
kernelversion: 1
target: fedora
output:
module: /tmp/falco-fedora.ko
driverversion: master
```
## flatcar ## flatcar
Example configuration file to build both the Kernel module and eBPF probe for Flatcar. Example configuration file to build both the Kernel module and eBPF probe for Flatcar.
@ -171,15 +154,38 @@ output:
kernelconfigdata: Q09ORklHX0ZBTk9USUZZPXkKQ09ORklHX0t... kernelconfigdata: Q09ORklHX0ZBTk9USUZZPXkKQ09ORklHX0t...
``` ```
## oracle linux 8 ## archlinux
Example configuration file to build both the Kernel module and eBPF probe for Archlinux.
Note: archlinux target uses the [Arch Linux Archive](https://wiki.archlinux.org/title/Arch_Linux_Archive) to fetch
all ever supported kernel releases.
For arm64, it uses an user-provided mirror, as no official mirror is available: http://tardis.tiny-vps.com/aarm/.
The mirror has been up and updated since 2015.
NOTE: ArchLinux has updated to Linux Kernel 6.0+, which appears to enforce generation of BTF for kmod too. The typical Debian container builders in the repo currently do not work for building ArchLinux drivers as a result. While an agreement is being reached on how to handle this upstream, using a custom `--builderimage` with ArchLinux drivers works for now. For example:
```Dockerfile
# archlinux builder example
# Note: ArchLinux is a rolling release, the gcc versions and such will change over time
# pinned for now for gcc 11/12
FROM archlinux:base-20221030.0.98412
RUN pacman -Sy && pacman -Sy --noconfirm \
make \
pahole \
gcc11 \
gcc && \
ln -s /usr/bin/gcc /usr/bin/gcc-12
```
```yaml ```yaml
kernelrelease: 5.4.17-2011.3.2.1.el8uek.x86_64
kernelversion: 1 kernelversion: 1
target: ol kernelrelease: 6.0.6.arch1-1
target: arch
output: output:
module: /tmp/falco-ol8.ko module: /tmp/falco-arch.ko
probe: /tmp/falco-arch.o
driverversion: master driverversion: master
builderimage: ${ARCH_BUILD_IMAGE_HERE}
``` ```
## redhat 7 ## redhat 7
@ -269,86 +275,9 @@ and Dockerfile.rhel9:
FROM docker.io/redhat/ubi9 FROM docker.io/redhat/ubi9
RUN yum install gcc elfutils-libelf-devel kmod make cpio llvm-toolset -y RUN yum install gcc elfutils-libelf-devel kmod make cpio llvm-toolset -y
RUN ln -s /usr/bin/$(uname -p)-redhat-linux-gcc-11 /usr/bin/gcc-11
``` ```
The `ln -s /usr/bin/$(uname -p)-redhat-linux-gcc-11 /usr/bin/gcc-11` command creates a symbolic link which makes sure driverkit finds the correct compiler binary. | :exclamation: **subscription-manager does not work on RHEL9 containers**: Host must have a valid RHEL subscription |
|--------------------------------------------------------------------------------------------------------------------|
| :exclamation: **subscription-manager does not work on RHEL9 containers**: Host must have a valid RHEL subscription. However, if you want to build the Docker image on a host that is not RHEL9, the container will not have access to the required repositories. In that case, the subscription manager can be enabled with some additional adjustments. |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Dockerfile.rhel9.containerSkip:
```bash
FROM docker.io/redhat/ubi9
ENV SMDEV_CONTAINER_OFF 1
ARG REDHAT_USERNAME
ARG REDHAT_PASSWORD
RUN subscription-manager register --username $REDHAT_USERNAME --password $REDHAT_PASSWORD --auto-attach
RUN yum install gcc elfutils-libelf-devel kmod make cpio llvm-toolset -y
RUN ln -s /usr/bin/$(uname -p)-redhat-linux-gcc-11 /usr/bin/gcc-11
```
Setting `SMDEV_CONTAINER_OFF 1` makes sure the container detection is skipped and therefore enables the subscription manager again.
## rocky linux
```yaml
kernelrelease: 5.14.0-162.18.1.el9_1.x86_64
target: rocky
output:
module: /tmp/falco_almalinux_5.14.0-162.18.1.el9_1.x86_64.ko
probe: /tmp/falco_almalinux_5.14.0-162.18.1.el9_1.x86_64.o
driverversion: master
```
## ubuntu
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu (works with any flavor!).
```yaml
kernelrelease: 5.0.0-1021-aws-5.0
kernelversion: 24~18.04.1
target: ubuntu
output:
module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco-ubuntu-generic.o
driverversion: master
```
## ubuntu-aws
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu AWS.
```yaml
kernelrelease: 4.15.0-1057-aws
kernelversion: 59
target: ubuntu-aws
output:
module: /tmp/falco-ubuntu-aws.ko
probe: /tmp/falco-ubuntu-aws.o
driverversion: master
```
> **NOTE:** ubuntu-aws exists to retain backward compatibility only,
> and should not be used in new configs.
## ubuntu-generic
Example configuration file to build both the Kernel module and eBPF probe for Ubuntu generic.
```yaml
kernelrelease: 4.15.0-72-generic
kernelversion: 81
target: ubuntu-generic
output:
module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco-ubuntu-generic.o
driverversion: master
```
> **NOTE:** ubuntu-generic exists to retain backward compatibility only,
> and should not be used in new configs.
## vanilla ## vanilla

View File

@ -16,8 +16,6 @@ ifeq ($(COMMITS_FROM_GIT_TAG),0)
endif endif
endif endif
DRIVERVERSIONS ?= master
DOCKER_ORG ?= falcosecurity DOCKER_ORG ?= falcosecurity
ARCH := $(shell uname -m) ARCH := $(shell uname -m)
@ -32,7 +30,8 @@ IMAGE_NAME_DRIVERKIT_REF := $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_$(ARCH)
IMAGE_NAME_DRIVERKIT_COMMIT := $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_$(ARCH) IMAGE_NAME_DRIVERKIT_COMMIT := $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_$(ARCH)
IMAGE_NAME_DRIVERKIT_LATEST := $(IMAGE_NAME_DRIVERKIT):latest_$(ARCH) IMAGE_NAME_DRIVERKIT_LATEST := $(IMAGE_NAME_DRIVERKIT):latest_$(ARCH)
LDFLAGS := -X github.com/falcosecurity/driverkit/pkg/version.buildTime=$(shell date +%s) -X github.com/falcosecurity/driverkit/pkg/version.gitCommit=${GIT_COMMIT} -X github.com/falcosecurity/driverkit/pkg/version.gitTag=$(if ${GIT_TAG},${GIT_TAG},v0.0.0) -X github.com/falcosecurity/driverkit/pkg/version.commitsFromGitTag=${COMMITS_FROM_GIT_TAG} -X github.com/falcosecurity/driverkit/pkg/driverbuilder/builder.defaultImageTag=$(GIT_COMMIT) LDFLAGS := -X github.com/falcosecurity/driverkit/pkg/version.buildTime=$(shell date +%s) -X github.com/falcosecurity/driverkit/pkg/version.gitCommit=${GIT_COMMIT} -X github.com/falcosecurity/driverkit/pkg/version.gitTag=$(if ${GIT_TAG},${GIT_TAG},v0.0.0) -X github.com/falcosecurity/driverkit/pkg/version.commitsFromGitTag=${COMMITS_FROM_GIT_TAG}
TARGET_TEST_ARCH ?= $(ARCH) TARGET_TEST_ARCH ?= $(ARCH)
test_configs := $(wildcard test/$(TARGET_TEST_ARCH)/configs/*.yaml) test_configs := $(wildcard test/$(TARGET_TEST_ARCH)/configs/*.yaml)
@ -43,7 +42,7 @@ driverkit_docgen ?= _output/bin/docgen
build: clean ${driverkit} build: clean ${driverkit}
${driverkit}: ${driverkit}:
CGO_ENABLED=0 GOEXPERIMENT=loopvar go build -v -ldflags '${LDFLAGS}' -o $@ . CGO_ENABLED=0 go build -v -buildmode=pie -ldflags '${LDFLAGS}' -o $@ .
.PHONY: release .PHONY: release
release: clean release: clean
@ -71,7 +70,7 @@ push/all: push/builder push/driverkit
.PHONY: push/builder .PHONY: push/builder
push/builder: push/builder:
$(foreach b,$(BUILDERS),\ $(foreach b,$(BUILDERS),\
$(DOCKER) buildx build --push -t "$(IMAGE_NAME_BUILDER_BASE):$b-$(GIT_REF)" -t "$(IMAGE_NAME_BUILDER_BASE):$b-$(GIT_COMMIT)" -f docker/builders/builder-$b.Dockerfile . ; \ $(DOCKER) buildx build --push -t "$(IMAGE_NAME_BUILDER_BASE)-$b:$(GIT_REF)" -t "$(IMAGE_NAME_BUILDER_BASE)-$b:$(GIT_COMMIT)" -f docker/builders/builder-$b.Dockerfile . ; \
) )
.PHONY: push/driverkit .PHONY: push/driverkit
@ -81,7 +80,7 @@ push/driverkit:
.PHONY: push/latest .PHONY: push/latest
push/latest: push/latest:
$(foreach b,$(BUILDERS),\ $(foreach b,$(BUILDERS),\
$(DOCKER) buildx build --push -t "$(IMAGE_NAME_BUILDER_BASE):$b-latest" -f docker/builders/builder-$b.Dockerfile . ; \ $(DOCKER) buildx build --push -t "$(IMAGE_NAME_BUILDER_BASE)-$b:latest" -f docker/builders/builder-$b.Dockerfile . ; \
) )
$(DOCKER) buildx build --push -t "$(IMAGE_NAME_DRIVERKIT_LATEST)" -f docker/driverkit.Dockerfile . $(DOCKER) buildx build --push -t "$(IMAGE_NAME_DRIVERKIT_LATEST)" -f docker/driverkit.Dockerfile .
@ -89,27 +88,28 @@ manifest/all: manifest/driverkit
.PHONY: manifest/driverkit .PHONY: manifest/driverkit
manifest/driverkit: manifest/driverkit:
$(DOCKER) buildx imagetools create -t $(IMAGE_NAME_DRIVERKIT):$(GIT_REF) $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_aarch64 $(DOCKER) manifest create $(IMAGE_NAME_DRIVERKIT):$(GIT_REF) $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_aarch64
$(DOCKER) buildx imagetools create -t $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT) $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_aarch64 $(DOCKER) manifest push $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)
$(DOCKER) manifest create $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT) $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_aarch64
$(DOCKER) manifest push $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)
.PHONY: manifest/latest .PHONY: manifest/latest
manifest/latest: manifest/latest:
$(DOCKER) buildx imagetools create -t $(IMAGE_NAME_DRIVERKIT):latest $(IMAGE_NAME_DRIVERKIT):latest_x86_64 $(IMAGE_NAME_DRIVERKIT):latest_aarch64 $(DOCKER) manifest create $(IMAGE_NAME_DRIVERKIT):latest $(IMAGE_NAME_DRIVERKIT):latest_x86_64 $(IMAGE_NAME_DRIVERKIT):latest_aarch64
$(DOCKER) manifest push $(IMAGE_NAME_DRIVERKIT):latest
.PHONY: test .PHONY: test
test: test:
go clean -testcache go clean -testcache
GOEXPERIMENT=loopvar go test -v -cover -race ./... go test -v -cover -race ./...
GOEXPERIMENT=loopvar go test -v -cover ./cmd go test -v -cover -buildmode=pie ./cmd
.PHONY: integration_test .PHONY: integration_test
integration_test: $(test_configs) integration_test: $(test_configs)
.PHONY: $(test_configs) .PHONY: $(test_configs)
$(test_configs): ${driverkit} $(test_configs): ${driverkit}
$(foreach d,$(DRIVERVERSIONS),\ ${driverkit} docker -c $@ --builderimage auto:master -l debug --timeout 600
${driverkit} docker -c $@ --builderimage auto:master -l debug --timeout 600 --driverversion $d; \
)
.PHONY: ${driverkit_docgen} .PHONY: ${driverkit_docgen}
${driverkit_docgen}: ${PWD}/docgen ${driverkit_docgen}: ${PWD}/docgen

3
OWNERS
View File

@ -3,8 +3,5 @@ approvers:
- dwindsor - dwindsor
- fededp - fededp
- EXONER4TED - EXONER4TED
- lowaiz
- LucaGuerra
emeritus_approvers: emeritus_approvers:
- fntlnz - fntlnz

View File

@ -1,7 +1,5 @@
# driverkit # driverkit
[![Falco Ecosystem Repository](https://github.com/falcosecurity/evolution/blob/main/repos/badges/falco-ecosystem-blue.svg)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#ecosystem-scope) [![Incubating](https://img.shields.io/badge/status-incubating-orange?style=for-the-badge)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#incubating)
[![Latest](https://img.shields.io/github/v/release/falcosecurity/driverkit?style=for-the-badge)](https://github.com/falcosecurity/driverkit/releases/latest) [![Latest](https://img.shields.io/github/v/release/falcosecurity/driverkit?style=for-the-badge)](https://github.com/falcosecurity/driverkit/releases/latest)
![Architectures](https://img.shields.io/badge/ARCHS-x86__64%7Caarch64-blueviolet?style=for-the-badge) ![Architectures](https://img.shields.io/badge/ARCHS-x86__64%7Caarch64-blueviolet?style=for-the-badge)
[![Go Report Card](https://goreportcard.com/badge/github.com/falcosecurity/driverkit?style=for-the-badge)](https://goreportcard.com/report/github.com/falcosecurity/driverkit) [![Go Report Card](https://goreportcard.com/badge/github.com/falcosecurity/driverkit?style=for-the-badge)](https://goreportcard.com/report/github.com/falcosecurity/driverkit)

View File

@ -1,6 +1,6 @@
# Release Process # Release Process
Our release process is fully automated using [Github actions](.github/workflows/release.yml) and [goreleaser](https://github.com/goreleaser/goreleaser) tool for artifacts. Our release process is based upon [CircleCI](https://app.circleci.com/pipelines/github/falcosecurity/driverkit) and [goreleaser](https://github.com/goreleaser/goreleaser) tool for artifacts.
When we release we do the following process: When we release we do the following process:

View File

@ -1,24 +1,13 @@
//go:build !race //go:build !race
// +build !race // +build !race
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes" "bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -27,9 +16,6 @@ import (
"testing" "testing"
"text/template" "text/template"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/acarl005/stripansi" "github.com/acarl005/stripansi"
"gotest.tools/assert" "gotest.tools/assert"
) )
@ -130,8 +116,6 @@ var tests = []testCase{
"ubuntu-aws", "ubuntu-aws",
"--output-module", "--output-module",
"/tmp/falco-ubuntu-aws.ko", "/tmp/falco-ubuntu-aws.ko",
"--output-probe",
"/tmp/falco-ubuntu-aws.o",
"--loglevel", "--loglevel",
"debug", "debug",
}, },
@ -144,7 +128,6 @@ var tests = []testCase{
env: map[string]string{ env: map[string]string{
"DRIVERKIT_KERNELVERSION": "59", "DRIVERKIT_KERNELVERSION": "59",
"DRIVERKIT_OUTPUT_MODULE": "/tmp/falco-ubuntu-aws.ko", "DRIVERKIT_OUTPUT_MODULE": "/tmp/falco-ubuntu-aws.ko",
"DRIVERKIT_OUTPUT_PROBE": "/tmp/falco-ubuntu-aws.o",
}, },
args: []string{ args: []string{
"docker", "docker",
@ -316,14 +299,9 @@ var tests = []testCase{
func run(t *testing.T, test testCase) { func run(t *testing.T, test testCase) {
// Setup // Setup
configOpts, err := NewConfigOptions() c := NewRootCmd()
assert.NilError(t, err) b := bytes.NewBufferString("")
rootOpts, err := NewRootOptions() c.SetOutput(b)
assert.NilError(t, err)
var buf bytes.Buffer
configOpts.setOutput(&buf, true)
c := NewRootCmd(configOpts, rootOpts)
c.SetOutput(&buf)
if len(test.args) == 0 || (test.args[0] != "__complete" && test.args[0] != "__completeNoDesc" && test.args[0] != "help" && test.args[0] != "completion") { if len(test.args) == 0 || (test.args[0] != "__complete" && test.args[0] != "__completeNoDesc" && test.args[0] != "help" && test.args[0] != "completion") {
test.args = append(test.args, "--dryrun") test.args = append(test.args, "--dryrun")
} }
@ -334,18 +312,19 @@ func run(t *testing.T, test testCase) {
} }
} }
// Test // Test
err = c.Execute() err := c.Execute()
if err != nil { if err != nil {
if test.expect.err == "" { if test.expect.err == "" {
t.Fatalf("error executing CLI: %v", err) t.Fatalf("error executing CLI: %v", err)
} else { } else {
assert.Error(t, err, test.expect.err) assert.Error(t, err, test.expect.err)
} }
// Exactly same behavior as rootCmd.Start(), but here we use ERROR instead of FATAL to avoid leaving
configOpts.Printer.Logger.Error("error executing driverkit", configOpts.Printer.Logger.Args("err", err.Error()))
} }
out := buf.String() out, err := ioutil.ReadAll(b)
res := stripansi.Strip(out) if err != nil {
t.Fatalf("error reading CLI output: %v", err)
}
res := stripansi.Strip(string(out))
assert.Equal(t, test.expect.out, res) assert.Equal(t, test.expect.out, res)
// Teardown // Teardown
for k := range test.env { for k := range test.env {
@ -370,7 +349,7 @@ type testTemplateData struct {
} }
func readTemplateFile(t *testing.T, s string) string { func readTemplateFile(t *testing.T, s string) string {
out, err := os.ReadFile("testdata/templates/" + s) out, err := ioutil.ReadFile("testdata/templates/" + s)
assert.NilError(t, err) assert.NilError(t, err)
return string(out) return string(out)
} }
@ -399,7 +378,7 @@ type flagsTemplateData struct {
} }
func initFlagsTemplateData(args []string) flagsTemplateData { func initFlagsTemplateData(args []string) flagsTemplateData {
targets := builder.Targets() targets := builder.BuilderByTarget.Targets()
sort.Strings(targets) sort.Strings(targets)
cmd := "driverkit" cmd := "driverkit"
@ -440,7 +419,7 @@ func TestCLI(t *testing.T) {
test.descr = strings.TrimSuffix(filepath.Base(test.expect.out), ".txt") test.descr = strings.TrimSuffix(filepath.Base(test.expect.out), ".txt")
} }
if test.expect.out != "" { if test.expect.out != "" {
out, err := os.ReadFile(test.expect.out) out, err := ioutil.ReadFile(test.expect.out)
if err != nil { if err != nil {
t.Fatalf("output fixture not found: %v", err) t.Fatalf("output fixture not found: %v", err)
} }

View File

@ -1,23 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/spf13/pflag"
"os" "os"
"strings" "strings"
"text/template" "text/template"
@ -47,12 +32,12 @@ func validateArgs() cobra.PositionalArgs {
if len(args) == 0 { if len(args) == 0 {
return nil return nil
} }
return cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)(c, args) return cobra.ExactValidArgs(1)(c, args)
} }
} }
// NewCompletionCmd ... // NewCompletionCmd ...
func NewCompletionCmd(_ *ConfigOptions, _ *RootOptions, _ *pflag.FlagSet) *cobra.Command { func NewCompletionCmd() *cobra.Command {
var long bytes.Buffer var long bytes.Buffer
tmpl := template.Must(template.New("long").Parse(longUsageTemplate)) tmpl := template.Must(template.New("long").Parse(longUsageTemplate))
tmpl.Execute(&long, map[string]interface{}{ tmpl.Execute(&long, map[string]interface{}{
@ -66,23 +51,25 @@ func NewCompletionCmd(_ *ConfigOptions, _ *RootOptions, _ *pflag.FlagSet) *cobra
Args: validateArgs(), Args: validateArgs(),
ValidArgs: cmdArgs, ValidArgs: cmdArgs,
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(c *cobra.Command, args []string) error { Run: func(c *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
return c.Help() c.Help()
return
} }
arg := args[0] arg := args[0]
switch arg { switch arg {
case "bash": case "bash":
return c.Root().GenBashCompletion(os.Stdout) c.Root().GenBashCompletion(os.Stdout)
break
case "zsh": case "zsh":
return c.Root().GenZshCompletion(os.Stdout) c.Root().GenZshCompletion(os.Stdout)
break
case "fish": case "fish":
return c.Root().GenFishCompletion(os.Stdout, true) c.Root().GenFishCompletion(os.Stdout, true)
case "help": case "help":
return c.Help() c.Help()
} }
return nil
}, },
} }

View File

@ -1,155 +1,49 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"errors" "fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/mitchellh/go-homedir"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"io"
"os"
"strings"
"github.com/creasty/defaults" "github.com/creasty/defaults"
"github.com/falcosecurity/driverkit/validate" "github.com/falcosecurity/driverkit/validate"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/pterm/pterm" logger "github.com/sirupsen/logrus"
) )
var validProcessors = []string{"docker", "kubernetes", "kubernetes-in-cluster", "local"} var validProcessors = []string{"docker", "kubernetes", "kubernetes-in-cluster"}
var aliasProcessors = []string{"docker", "k8s", "k8s-ic"} var aliasProcessors = []string{"docker", "k8s", "k8s-ic"}
var configOptions *ConfigOptions
// ConfigOptions represent the persistent configuration flags of driverkit. // ConfigOptions represent the persistent configuration flags of driverkit.
type ConfigOptions struct { type ConfigOptions struct {
configFile string ConfigFile string
LogLevel string `validate:"logrus" name:"log level" default:"info"`
Timeout int `validate:"number,min=30" default:"120" name:"timeout"` Timeout int `validate:"number,min=30" default:"120" name:"timeout"`
ProxyURL string `validate:"omitempty,proxy" name:"proxy url"` ProxyURL string `validate:"omitempty,proxy" name:"proxy url"`
dryRun bool DryRun bool
// Printer used by all commands to output messages. configErrors bool
Printer *output.Printer
// writer is used to write the output of the printer.
writer io.Writer
logLevel *output.LogLevel
disableStyling bool
}
func (co *ConfigOptions) initPrinter() {
// DisableStyling is only enforced by tests.
if co.disableStyling {
pterm.DisableStyling()
}
co.Printer = output.NewPrinter(co.logLevel.ToPtermLogLevel(), pterm.LogFormatterColorful, co.writer)
if co.disableStyling {
// Disable time print for tests
co.Printer.Logger = co.Printer.Logger.WithTime(false)
}
}
// Called by tests to disable styling and set bytes buffer as output
func (co *ConfigOptions) setOutput(writer io.Writer, disableStyling bool) {
co.writer = writer
co.disableStyling = disableStyling
co.initPrinter()
} }
// NewConfigOptions creates an instance of ConfigOptions. // NewConfigOptions creates an instance of ConfigOptions.
func NewConfigOptions() (*ConfigOptions, error) { func NewConfigOptions() *ConfigOptions {
o := &ConfigOptions{ o := &ConfigOptions{}
writer: os.Stdout,
logLevel: output.NewLogLevel(),
disableStyling: false,
}
o.initPrinter()
if err := defaults.Set(o); err != nil { if err := defaults.Set(o); err != nil {
// Return ConfigOptions anyway because we need the logger logger.WithError(err).WithField("options", "ConfigOptions").Fatal("error setting driverkit options defaults")
return o, err
} }
return o, nil return o
} }
// Validate validates the ConfigOptions fields. // Validate validates the ConfigOptions fields.
func (co *ConfigOptions) validate() []error { func (co *ConfigOptions) Validate() []error {
if err := validate.V.Struct(co); err != nil { if err := validate.V.Struct(co); err != nil {
var errs validator.ValidationErrors errors := err.(validator.ValidationErrors)
errors.As(err, &errs) errArr := []error{}
var errArr []error for _, e := range errors {
for _, e := range errs {
// Translate each error one at a time // Translate each error one at a time
errArr = append(errArr, errors.New(e.Translate(validate.T))) errArr = append(errArr, fmt.Errorf(e.Translate(validate.T)))
} }
co.configErrors = true
return errArr return errArr
} }
return nil return nil
} }
// AddFlags registers the common flags.
func (co *ConfigOptions) AddFlags(flags *pflag.FlagSet) {
flags.StringVarP(&co.configFile, "config", "c", co.configFile, "config file path (default $HOME/.driverkit.yaml if exists)")
flags.VarP(co.logLevel, "loglevel", "l", "set level for logs "+co.logLevel.Allowed())
flags.IntVar(&co.Timeout, "timeout", co.Timeout, "timeout in seconds")
flags.StringVar(&co.ProxyURL, "proxy", co.ProxyURL, "the proxy to use to download data")
flags.BoolVar(&co.dryRun, "dryrun", co.dryRun, "do not actually perform the action")
}
// Init reads in config file and ENV variables if set.
func (co *ConfigOptions) Init() bool {
configErr := false
if errs := co.validate(); errs != nil {
for _, err := range errs {
co.Printer.Logger.Error("error validating config options",
co.Printer.Logger.Args("err", err.Error()))
}
configErr = true
}
if co.configFile != "" {
viper.SetConfigFile(co.configFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
co.Printer.Logger.Error("error getting the home directory",
co.Printer.Logger.Args("err", err.Error()))
// not setting configErr = true because we fallback to `$HOME/.driverkit.yaml` and try with it
}
viper.AddConfigPath(home)
viper.SetConfigName(".driverkit")
}
viper.AutomaticEnv()
viper.SetEnvPrefix("driverkit")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
// If a config file is found, read it in.
err := viper.ReadInConfig()
// Init printer with either read or existent one,
// so that we can further log considering log level set.
co.initPrinter()
if err == nil {
co.Printer.Logger.Info("using config file",
co.Printer.Logger.Args("file", viper.ConfigFileUsed()))
} else {
var configFileNotFoundError viper.ConfigFileNotFoundError
if errors.As(err, &configFileNotFoundError) {
// Config file not found, ignore ...
co.Printer.Logger.Debug("running without a configuration file")
}
}
return configErr
}

View File

@ -1,56 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder" "github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder" logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/spf13/viper"
) )
// NewDockerCmd creates the `driverkit docker` command. // NewDockerCmd creates the `driverkit docker` command.
func NewDockerCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command { func NewDockerCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
dockerCmd := &cobra.Command{ dockerCmd := &cobra.Command{
Use: "docker", Use: "docker",
Short: "Build Falco kernel modules and eBPF probes against a docker daemon.", Short: "Build Falco kernel modules and eBPF probes against a docker daemon.",
RunE: func(c *cobra.Command, args []string) error { Run: func(c *cobra.Command, args []string) {
configOpts.Printer.Logger.Info("starting build", logger.WithField("processor", c.Name()).Info("driver building, it will take a few seconds")
configOpts.Printer.Logger.Args("processor", c.Name())) if !configOptions.DryRun {
if !configOpts.dryRun { if err := driverbuilder.NewDockerBuildProcessor(viper.GetInt("timeout"), viper.GetString("proxy")).Start(rootOpts.toBuild()); err != nil {
if !rootOpts.Output.HasOutputs() { logger.WithError(err).Fatal("exiting")
configOpts.Printer.Logger.Info("no output specified")
return nil
} }
// Since we use a spinner, cache log data to a bytesbuffer;
// we will later print it once we stop the spinner.
var b *builder.Build
if configOpts.disableStyling {
b = rootOpts.ToBuild(configOpts.Printer)
} else {
var buf bytes.Buffer
b = rootOpts.ToBuild(configOpts.Printer.WithWriter(&buf))
configOpts.Printer.Spinner, _ = configOpts.Printer.Spinner.Start("driver building, it will take a few seconds")
defer func() {
configOpts.Printer.DefaultText.Print(buf.String())
}()
}
return driverbuilder.NewDockerBuildProcessor(configOpts.Timeout, configOpts.ProxyURL).Start(b)
} }
return nil
}, },
} }
// Add root flags // Add root flags

View File

@ -1,54 +1,22 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"os"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"os"
) )
// NewImagesCmd creates the `driverkit images` command. // NewImagesCmd creates the `driverkit images` command.
func NewImagesCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command { func NewImagesCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
imagesCmd := &cobra.Command{ imagesCmd := &cobra.Command{
Use: "images", Use: "images",
Short: "List builder images", Short: "List builder images",
RunE: func(c *cobra.Command, args []string) error { Run: func(c *cobra.Command, args []string) {
configOpts.Printer.Logger.Info("starting loading images", logger.WithField("processor", c.Name()).Info("listing images")
configOpts.Printer.Logger.Args("processor", c.Name())) b := rootOpts.toBuild()
// Since we use a spinner, cache log data to a bytesbuffer;
// we will later print it once we stop the spinner.
var (
buf bytes.Buffer
b *builder.Build
)
if configOpts.disableStyling {
b = rootOpts.ToBuild(configOpts.Printer)
} else {
b = rootOpts.ToBuild(configOpts.Printer.WithWriter(&buf))
configOpts.Printer.Spinner, _ = configOpts.Printer.Spinner.Start("listing images, it will take a few seconds")
}
b.LoadImages() b.LoadImages()
if !configOpts.disableStyling {
_ = configOpts.Printer.Spinner.Stop()
configOpts.Printer.DefaultText.Print(buf.String())
}
table := tablewriter.NewWriter(os.Stdout) table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Image", "Target", "Arch", "GCC"}) table.SetHeader([]string{"Image", "Target", "Arch", "GCC"})
@ -64,7 +32,6 @@ func NewImagesCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *p
table.Append(data) table.Append(data)
} }
table.Render() // Send output table.Render() // Send output
return nil
}, },
} }
// Add root flags // Add root flags

View File

@ -1,34 +1,20 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"regexp" "regexp"
"strings" "strings"
"github.com/falcosecurity/driverkit/pkg/driverbuilder" "github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/kubernetes/factory" "github.com/falcosecurity/driverkit/pkg/kubernetes/factory"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/spf13/viper"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
) )
// NewKubernetesCmd creates the `driverkit kubernetes` command. // NewKubernetesCmd creates the `driverkit kubernetes` command.
func NewKubernetesCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command { func NewKubernetesCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
kubernetesCmd := &cobra.Command{ kubernetesCmd := &cobra.Command{
Use: "kubernetes", Use: "kubernetes",
Short: "Build Falco kernel modules and eBPF probes against a Kubernetes cluster.", Short: "Build Falco kernel modules and eBPF probes against a Kubernetes cluster.",
@ -57,39 +43,30 @@ func NewKubernetesCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlag
kubefactory := factory.NewFactory(configFlags) kubefactory := factory.NewFactory(configFlags)
kubernetesCmd.RunE = func(c *cobra.Command, args []string) error { kubernetesCmd.Run = func(cmd *cobra.Command, args []string) {
configOpts.Printer.Logger.Info("starting build", logger.WithField("processor", cmd.Name()).Info("driver building, it will take a few seconds")
configOpts.Printer.Logger.Args("processor", c.Name())) if !configOptions.DryRun {
if !configOpts.dryRun { if err := kubernetesRun(cmd, args, kubefactory, rootOpts); err != nil {
if !rootOpts.Output.HasOutputs() { logger.WithError(err).Fatal("exiting")
configOpts.Printer.Logger.Info("no output specified")
return nil
} }
// Since we use a spinner, cache log data to a bytesbuffer;
// we will later print it once we stop the spinner.
var b *builder.Build
if configOpts.disableStyling {
b = rootOpts.ToBuild(configOpts.Printer)
} else {
var buf bytes.Buffer
b = rootOpts.ToBuild(configOpts.Printer.WithWriter(&buf))
configOpts.Printer.Spinner, _ = configOpts.Printer.Spinner.Start("driver building, it will take a few seconds")
defer func() {
configOpts.Printer.DefaultText.Print(buf.String())
}()
}
return kubernetesRun(kubefactory, b, configOpts)
} }
return nil
} }
return kubernetesCmd return kubernetesCmd
} }
func kubernetesRun(kubefactory factory.Factory, func kubernetesRun(cmd *cobra.Command, args []string, kubefactory factory.Factory, rootOpts *RootOptions) error {
b *builder.Build, f := cmd.Flags()
configOpts *ConfigOptions, b := rootOpts.toBuild()
) error {
namespaceStr, err := f.GetString("namespace")
if err != nil {
return err
}
if len(namespaceStr) == 0 {
namespaceStr = "default"
}
kc, err := kubefactory.KubernetesClientSet() kc, err := kubefactory.KubernetesClientSet()
if err != nil { if err != nil {
return err return err
@ -102,12 +79,6 @@ func kubernetesRun(kubefactory factory.Factory,
return err return err
} }
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), clientConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
clientConfig,
kubernetesOptions.RunAsUser,
kubernetesOptions.Namespace,
kubernetesOptions.ImagePullSecret,
configOpts.Timeout,
configOpts.ProxyURL)
return buildProcessor.Start(b) return buildProcessor.Start(b)
} }

View File

@ -1,32 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder" "github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kubernetes/factory" "github.com/falcosecurity/driverkit/pkg/kubernetes/factory"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/spf13/viper"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
) )
// NewKubernetesInClusterCmd creates the `driverkit kubernetes` command. // NewKubernetesInClusterCmd creates the `driverkit kubernetes` command.
func NewKubernetesInClusterCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command { func NewKubernetesInClusterCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
kubernetesInClusterCmd := &cobra.Command{ kubernetesInClusterCmd := &cobra.Command{
Use: "kubernetes-in-cluster", Use: "kubernetes-in-cluster",
Short: "Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.", Short: "Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.",
@ -40,55 +26,34 @@ func NewKubernetesInClusterCmd(configOpts *ConfigOptions, rootOpts *RootOptions,
// Add root flags // Add root flags
kubernetesInClusterCmd.PersistentFlags().AddFlagSet(rootFlags) kubernetesInClusterCmd.PersistentFlags().AddFlagSet(rootFlags)
kubernetesInClusterCmd.RunE = func(c *cobra.Command, args []string) error { kubernetesInClusterCmd.Run = func(cmd *cobra.Command, args []string) {
configOpts.Printer.Logger.Info("starting build", logger.WithField("processor", cmd.Name()).Info("driver building, it will take a few seconds")
configOpts.Printer.Logger.Args("processor", c.Name())) if !configOptions.DryRun {
if !configOpts.dryRun { config, err := rest.InClusterConfig()
if !rootOpts.Output.HasOutputs() { if err != nil {
configOpts.Printer.Logger.Info("no output specified") logger.WithError(err).Fatal("exiting")
return nil
} }
// Since we use a spinner, cache log data to a bytesbuffer; if err = factory.SetKubernetesDefaults(config); err != nil {
// we will later print it once we stop the spinner. logger.WithError(err).Fatal("exiting")
var b *builder.Build }
if configOpts.disableStyling { if err = kubernetesInClusterRun(cmd, args, config, rootOpts); err != nil {
b = rootOpts.ToBuild(configOpts.Printer) logger.WithError(err).Fatal("exiting")
} else {
var buf bytes.Buffer
b = rootOpts.ToBuild(configOpts.Printer.WithWriter(&buf))
configOpts.Printer.Spinner, _ = configOpts.Printer.Spinner.Start("driver building, it will take a few seconds")
defer func() {
configOpts.Printer.DefaultText.Print(buf.String())
}()
} }
return kubernetesInClusterRun(b, configOpts)
} }
return nil
} }
return kubernetesInClusterCmd return kubernetesInClusterCmd
} }
func kubernetesInClusterRun(b *builder.Build, configOpts *ConfigOptions) error { func kubernetesInClusterRun(_ *cobra.Command, _ []string, kubeConfig *rest.Config, rootOpts *RootOptions) error {
kubeConfig, err := rest.InClusterConfig() b := rootOpts.toBuild()
if err != nil {
return err
}
if err = factory.SetKubernetesDefaults(kubeConfig); err != nil {
return err
}
kc, err := kubernetes.NewForConfig(kubeConfig) kc, err := kubernetes.NewForConfig(kubeConfig)
if err != nil { if err != nil {
return err return err
} }
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), kubeConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
kubeConfig,
kubernetesOptions.RunAsUser,
kubernetesOptions.Namespace,
kubernetesOptions.ImagePullSecret,
configOpts.Timeout,
configOpts.ProxyURL)
return buildProcessor.Start(b) return buildProcessor.Start(b)
} }

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import flag "github.com/spf13/pflag" import flag "github.com/spf13/pflag"

View File

@ -1,81 +0,0 @@
package cmd
import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type localCmdOptions struct {
useDKMS bool
downloadHeaders bool
srcDir string
envMap map[string]string
}
// NewLocalCmd creates the `driverkit local` command.
func NewLocalCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
opts := localCmdOptions{}
localCmd := &cobra.Command{
Use: "local",
Short: "Build Falco kernel modules and eBPF probes in local env with local kernel sources and gcc/clang.",
RunE: func(c *cobra.Command, args []string) error {
configOpts.Printer.Logger.Info("starting build",
configOpts.Printer.Logger.Args("processor", c.Name()))
if !configOpts.dryRun {
if !rootOpts.Output.HasOutputs() {
configOpts.Printer.Logger.Info("no output specified")
return nil
}
// Since we use a spinner, cache log data to a bytesbuffer;
// we will later print it once we stop the spinner.
var b *builder.Build
if configOpts.disableStyling {
b = rootOpts.ToBuild(configOpts.Printer)
} else {
var buf bytes.Buffer
b = rootOpts.ToBuild(configOpts.Printer.WithWriter(&buf))
configOpts.Printer.Spinner, _ = configOpts.Printer.Spinner.Start("driver building, it will take a few seconds")
defer func() {
configOpts.Printer.DefaultText.Print(buf.String())
}()
}
return driverbuilder.NewLocalBuildProcessor(opts.useDKMS,
opts.downloadHeaders,
false,
opts.srcDir,
opts.envMap,
configOpts.Timeout).Start(b)
}
return nil
},
}
// Add root flags, but not the ones unneeded
unusedFlagsSet := map[string]struct{}{
"architecture": {},
"kernelurls": {},
"builderrepo": {},
"builderimage": {},
"gccversion": {},
"kernelconfigdata": {},
"proxy": {},
"registry-name": {},
"registry-password": {},
"registry-plain-http": {},
"registry-user": {},
}
flagSet := pflag.NewFlagSet("local", pflag.ExitOnError)
rootFlags.VisitAll(func(flag *pflag.Flag) {
if _, ok := unusedFlagsSet[flag.Name]; !ok {
flagSet.AddFlag(flag)
}
})
flagSet.BoolVar(&opts.useDKMS, "dkms", false, "Enforce usage of DKMS to build the kernel module.")
flagSet.BoolVar(&opts.downloadHeaders, "download-headers", false, "Try to automatically download kernel headers.")
flagSet.StringVar(&opts.srcDir, "src-dir", "", "Enforce usage of local source dir to build drivers.")
flagSet.StringToStringVar(&opts.envMap, "env", make(map[string]string), "Env variables to be enforced during the driver build.")
localCmd.PersistentFlags().AddFlagSet(flagSet)
return localCmd
}

View File

@ -1,43 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"errors"
"fmt" "fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io" "io"
"os" "os"
"runtime"
"sort" "sort"
"strings" "strings"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder" "github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/falcosecurity/driverkit/pkg/version" "github.com/falcosecurity/driverkit/pkg/version"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
homedir "github.com/mitchellh/go-homedir"
logger "github.com/sirupsen/logrus"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
func persistentValidateFunc(rootCommand *RootCmd, configOpts *ConfigOptions, rootOpts *RootOptions) func(c *cobra.Command, args []string) error { func persistentValidateFunc(rootCommand *RootCmd, rootOpts *RootOptions) func(c *cobra.Command, args []string) error {
return func(c *cobra.Command, args []string) error { return func(c *cobra.Command, args []string) error {
var validationError = errors.New("exiting for validation errors")
configErr := configOpts.Init()
// Early exit if detect some error into config flags // Early exit if detect some error into config flags
if configErr { if configOptions.configErrors {
return validationError return fmt.Errorf("exiting for validation errors")
} }
// Merge environment variables or config file values into the RootOptions instance // Merge environment variables or config file values into the RootOptions instance
skip := map[string]bool{ // do not merge these skip := map[string]bool{ // do not merge these
@ -58,13 +44,13 @@ func persistentValidateFunc(rootCommand *RootCmd, configOpts *ConfigOptions, roo
// rather than replace, it appends. Since viper will already have the cli options set // rather than replace, it appends. Since viper will already have the cli options set
// if supplied, we only need this step if rootCommand doesn't already have them e.g. // if supplied, we only need this step if rootCommand doesn't already have them e.g.
// not set on CLI so read from config. // not set on CLI so read from config.
if cliURLs, err := rootCommand.c.Flags().GetStringSlice(name); err == nil && len(cliURLs) != 0 { if cli_urls, err := rootCommand.c.Flags().GetStringSlice(name); err == nil && len(cli_urls) != 0 {
return return
} }
value := viper.GetStringSlice(name) value := viper.GetStringSlice(name)
if len(value) != 0 { if len(value) != 0 {
strValue := strings.Join(value, ",") strValue := strings.Join(value, ",")
_ = rootCommand.c.Flags().Set(name, strValue) rootCommand.c.Flags().Set(name, strValue)
} }
} else { } else {
value := viper.GetString(name) value := viper.GetString(name)
@ -76,7 +62,7 @@ func persistentValidateFunc(rootCommand *RootCmd, configOpts *ConfigOptions, roo
} }
// set the value, if any, otherwise let the default // set the value, if any, otherwise let the default
if value != "" { if value != "" {
_ = rootCommand.c.Flags().Set(name, value) rootCommand.c.Flags().Set(name, value)
} }
} }
} }
@ -85,16 +71,20 @@ func persistentValidateFunc(rootCommand *RootCmd, configOpts *ConfigOptions, roo
// Avoid sensitive info into default values help line // Avoid sensitive info into default values help line
rootCommand.StripSensitive() rootCommand.StripSensitive()
// We just use ubuntu internally
if strings.HasPrefix(rootOpts.Target, "ubuntu") {
rootOpts.Target = "ubuntu"
}
// Do not block root or help command to exec disregarding the root flags validity // Do not block root or help command to exec disregarding the root flags validity
if c.Root() != c && c.Name() != "help" && c.Name() != "__complete" && c.Name() != "__completeNoDesc" && c.Name() != "completion" { if c.Root() != c && c.Name() != "help" && c.Name() != "__complete" && c.Name() != "__completeNoDesc" && c.Name() != "completion" {
if errs := rootOpts.Validate(); errs != nil { if errs := rootOpts.Validate(); errs != nil {
for _, err := range errs { for _, err := range errs {
configOpts.Printer.Logger.Error("error validating build options", logger.WithError(err).Error("error validating build options")
configOpts.Printer.Logger.Args("err", err.Error()))
} }
return validationError return fmt.Errorf("exiting for validation errors")
} }
rootOpts.Log(configOpts.Printer) rootOpts.Log()
} }
return nil return nil
} }
@ -106,7 +96,9 @@ type RootCmd struct {
} }
// NewRootCmd instantiates the root command. // NewRootCmd instantiates the root command.
func NewRootCmd(configOpts *ConfigOptions, rootOpts *RootOptions) *RootCmd { func NewRootCmd() *RootCmd {
configOptions = NewConfigOptions()
rootOpts := NewRootOptions()
rootCmd := &cobra.Command{ rootCmd := &cobra.Command{
Use: "driverkit", Use: "driverkit",
Short: "A command line tool to build Falco kernel modules and eBPF probes.", Short: "A command line tool to build Falco kernel modules and eBPF probes.",
@ -115,51 +107,68 @@ func NewRootCmd(configOpts *ConfigOptions, rootOpts *RootOptions) *RootCmd {
Args: cobra.OnlyValidArgs, Args: cobra.OnlyValidArgs,
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
DisableAutoGenTag: true, DisableAutoGenTag: true,
SilenceErrors: true,
SilenceUsage: true,
Version: version.String(), Version: version.String(),
RunE: func(c *cobra.Command, args []string) error { Run: func(c *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
configOpts.Printer.Logger.Info("specify a valid processor", configOpts.Printer.Logger.Args("processors", validProcessors)) logger.WithField("processors", validProcessors).Info("specify a valid processor")
} }
// Fallback to help // Fallback to help
return c.Help() c.Help()
}, },
} }
ret := &RootCmd{ ret := &RootCmd{
c: rootCmd, c: rootCmd,
} }
rootCmd.PersistentPreRunE = persistentValidateFunc(ret, configOpts, rootOpts) rootCmd.PersistentPreRunE = persistentValidateFunc(ret, rootOpts)
flags := rootCmd.Flags() flags := rootCmd.Flags()
targets := builder.Targets() targets := builder.BuilderByTarget.Targets()
sort.Strings(targets) sort.Strings(targets)
configOpts.AddFlags(flags) flags.StringVarP(&configOptions.ConfigFile, "config", "c", configOptions.ConfigFile, "config file path (default $HOME/.driverkit.yaml if exists)")
rootOpts.AddFlags(flags, targets) flags.StringVarP(&configOptions.LogLevel, "loglevel", "l", configOptions.LogLevel, "log level")
flags.IntVar(&configOptions.Timeout, "timeout", configOptions.Timeout, "timeout in seconds")
flags.BoolVar(&configOptions.DryRun, "dryrun", configOptions.DryRun, "do not actually perform the action")
flags.StringVar(&configOptions.ProxyURL, "proxy", configOptions.ProxyURL, "the proxy to use to download data")
if err := viper.BindPFlags(flags); err != nil { flags.StringVar(&rootOpts.Output.Module, "output-module", rootOpts.Output.Module, "filepath where to save the resulting kernel module")
panic(err) flags.StringVar(&rootOpts.Output.Probe, "output-probe", rootOpts.Output.Probe, "filepath where to save the resulting eBPF probe")
} flags.StringVar(&rootOpts.Architecture, "architecture", runtime.GOARCH, "target architecture for the built driver, one of "+kernelrelease.SupportedArchs.String())
flags.StringVar(&rootOpts.DriverVersion, "driverversion", rootOpts.DriverVersion, "driver version as a git commit hash or as a git tag")
flags.StringVar(&rootOpts.KernelVersion, "kernelversion", rootOpts.KernelVersion, "kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v'")
flags.StringVar(&rootOpts.KernelRelease, "kernelrelease", rootOpts.KernelRelease, "kernel release to build the module for, it can be found by executing 'uname -v'")
flags.StringVarP(&rootOpts.Target, "target", "t", rootOpts.Target, "the system to target the build for, one of ["+strings.Join(targets, ",")+"]")
flags.StringVar(&rootOpts.KernelConfigData, "kernelconfigdata", rootOpts.KernelConfigData, "base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc")
flags.StringVar(&rootOpts.ModuleDeviceName, "moduledevicename", rootOpts.ModuleDeviceName, "kernel module device name (the default is falco, so the device will be under /dev/falco*)")
flags.StringVar(&rootOpts.ModuleDriverName, "moduledrivername", rootOpts.ModuleDriverName, "kernel module driver name, i.e. the name you see when you check installed modules via lsmod")
flags.StringVar(&rootOpts.BuilderImage, "builderimage", rootOpts.BuilderImage, "docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.")
flags.StringSliceVar(&rootOpts.BuilderRepos, "builderrepo", rootOpts.BuilderRepos, "list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit")
flags.StringVar(&rootOpts.GCCVersion, "gccversion", rootOpts.GCCVersion, "enforce a specific gcc version for the build")
flags.StringSliceVar(&rootOpts.KernelUrls, "kernelurls", nil, "list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls \"<URL3>,<URL4>\")")
flags.StringVar(&rootOpts.Repo.Org, "repo-org", rootOpts.Repo.Org, "repository github organization")
flags.StringVar(&rootOpts.Repo.Name, "repo-name", rootOpts.Repo.Name, "repository github name")
viper.BindPFlags(flags)
// Flag annotations and custom completions // Flag annotations and custom completions
_ = rootCmd.MarkFlagFilename("config", viper.SupportedExts...) rootCmd.MarkFlagFilename("config", viper.SupportedExts...)
_ = rootCmd.RegisterFlagCompletionFunc("target", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { rootCmd.RegisterFlagCompletionFunc("target", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return targets, cobra.ShellCompDirectiveDefault return targets, cobra.ShellCompDirectiveDefault
}) })
_ = rootCmd.RegisterFlagCompletionFunc("architecture", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { rootCmd.RegisterFlagCompletionFunc("architecture", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return kernelrelease.SupportedArchs.Strings(), cobra.ShellCompDirectiveDefault return kernelrelease.SupportedArchs.Strings(), cobra.ShellCompDirectiveDefault
}) })
// Subcommands // Subcommands
rootCmd.AddCommand(NewKubernetesCmd(configOpts, rootOpts, flags)) rootCmd.AddCommand(NewKubernetesCmd(rootOpts, flags))
rootCmd.AddCommand(NewKubernetesInClusterCmd(configOpts, rootOpts, flags)) rootCmd.AddCommand(NewKubernetesInClusterCmd(rootOpts, flags))
rootCmd.AddCommand(NewDockerCmd(configOpts, rootOpts, flags)) rootCmd.AddCommand(NewDockerCmd(rootOpts, flags))
rootCmd.AddCommand(NewLocalCmd(configOpts, rootOpts, flags)) rootCmd.AddCommand(NewImagesCmd(rootOpts, flags))
rootCmd.AddCommand(NewImagesCmd(configOpts, rootOpts, flags)) rootCmd.AddCommand(NewCompletionCmd())
rootCmd.AddCommand(NewCompletionCmd(configOpts, rootOpts, flags))
ret.StripSensitive() ret.StripSensitive()
@ -188,15 +197,16 @@ func (r *RootCmd) Command() *cobra.Command {
return r.c return r.c
} }
// SetArgs proxies the arguments to the underlying cobra.Command.
func (r *RootCmd) SetArgs(args []string) {
r.c.SetArgs(args)
}
// SetOutput sets the main command output writer. // SetOutput sets the main command output writer.
func (r *RootCmd) SetOutput(w io.Writer) { func (r *RootCmd) SetOutput(w io.Writer) {
r.c.SetOut(w) r.c.SetOut(w)
r.c.SetErr(w) r.c.SetErr(w)
logger.SetOutput(w)
}
// SetArgs proxies the arguments to the underlying cobra.Command.
func (r *RootCmd) SetArgs(args []string) {
r.c.SetArgs(args)
} }
// Execute proxies the cobra.Command execution. // Execute proxies the cobra.Command execution.
@ -206,30 +216,59 @@ func (r *RootCmd) Execute() error {
// Start creates the root command and runs it. // Start creates the root command and runs it.
func Start() { func Start() {
configOpts, err := NewConfigOptions() root := NewRootCmd()
if err != nil { if err := root.Execute(); err != nil {
// configOpts will never be nil here logger.WithError(err).Fatal("error executing driverkit")
if configOpts != nil { }
configOpts.Printer.Logger.Fatal("error setting driverkit config options defaults", }
configOpts.Printer.Logger.Args("err", err.Error()))
} else { func init() {
os.Exit(1) logger.SetFormatter(&logger.TextFormatter{
} ForceColors: true,
} DisableLevelTruncation: false,
rootOpts, err := NewRootOptions() DisableTimestamp: true,
if err != nil { })
configOpts.Printer.Logger.Fatal("error setting driverkit root options defaults",
configOpts.Printer.Logger.Args("err", err.Error())) cobra.OnInitialize(initConfig)
} }
// Cleanup spinner upon leaving if any // initConfig reads in config file and ENV variables if set.
defer func() { func initConfig() {
if configOpts.Printer.Spinner != nil { if errs := configOptions.Validate(); errs != nil {
_ = configOpts.Printer.Spinner.Stop() for _, err := range errs {
} logger.WithError(err).Error("error validating config options")
}() }
root := NewRootCmd(configOpts, rootOpts) // configOptions.configErrors should be true here
if err = root.Execute(); err != nil { }
configOpts.Printer.Logger.Fatal("error executing driverkit", configOpts.Printer.Logger.Args("err", err.Error())) if configOptions.ConfigFile != "" {
viper.SetConfigFile(configOptions.ConfigFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
logger.WithError(err).Debug("error getting the home directory")
// not setting configOptions.configErrors = true because we fallback to `$HOME/.driverkit.yaml` and try with it
}
viper.AddConfigPath(home)
viper.SetConfigName(".driverkit")
}
viper.AutomaticEnv()
viper.SetEnvPrefix("driverkit")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
logger.WithField("file", viper.ConfigFileUsed()).Info("using config file")
} else {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found, ignore ...
logger.Debug("running without a configuration file")
} else {
// Config file was found but another error was produced
logger.WithField("file", viper.ConfigFileUsed()).WithError(err).Debug("error running with config file")
configOptions.configErrors = true
}
} }
} }

View File

@ -1,32 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 cmd package cmd
import ( import (
"errors" "fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/spf13/pflag"
"os"
"runtime"
"strings"
"github.com/creasty/defaults" "github.com/creasty/defaults"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder" "github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/falcosecurity/driverkit/validate" "github.com/falcosecurity/driverkit/validate"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
logger "github.com/sirupsen/logrus"
) )
// OutputOptions wraps the two drivers that driverkit builds. // OutputOptions wraps the two drivers that driverkit builds.
@ -35,22 +17,11 @@ type OutputOptions struct {
Probe string `validate:"required_without=Module,filepath,omitempty,endswith=.o" name:"output probe path"` Probe string `validate:"required_without=Module,filepath,omitempty,endswith=.o" name:"output probe path"`
} }
func (oo *OutputOptions) HasOutputs() bool {
return oo.Module != "" || oo.Probe != ""
}
type RepoOptions struct { type RepoOptions struct {
Org string `default:"falcosecurity" name:"organization name"` Org string `default:"falcosecurity" name:"organization name"`
Name string `default:"libs" name:"repo name"` Name string `default:"libs" name:"repo name"`
} }
type Registry struct {
Name string `validate:"required_with=Username Password" name:"registry name"`
Username string `validate:"required_with=Registry Password" name:"registry username"`
Password string `validate:"required_with=Username Registry" name:"registry password"`
PlainHTTP bool `default:"false" name:"registry plain http"`
}
// RootOptions ... // RootOptions ...
type RootOptions struct { type RootOptions struct {
Architecture string `validate:"required,architecture" name:"architecture"` Architecture string `validate:"required,architecture" name:"architecture"`
@ -62,12 +33,11 @@ type RootOptions struct {
Target string `validate:"required,target" name:"target"` Target string `validate:"required,target" name:"target"`
KernelConfigData string `validate:"omitempty,base64" name:"kernel config data"` // fixme > tag "name" does not seem to work when used at struct level, but works when used at inner level KernelConfigData string `validate:"omitempty,base64" name:"kernel config data"` // fixme > tag "name" does not seem to work when used at struct level, but works when used at inner level
BuilderImage string `validate:"omitempty,imagename" name:"builder image"` BuilderImage string `validate:"omitempty,imagename" name:"builder image"`
BuilderRepos []string `default:"[\"docker.io/falcosecurity/driverkit-builder\"]" validate:"omitempty" name:"docker repositories to look for builder images or absolute path pointing to a yaml file containing builder images index"` BuilderRepos []string `validate:"omitempty" name:"docker repositories to look for builder images"`
GCCVersion string `validate:"omitempty,semvertolerant" name:"gcc version"` GCCVersion string `validate:"omitempty,semvertolerant" name:"gcc version"`
KernelUrls []string `name:"kernel header urls"` KernelUrls []string `name:"kernel header urls"`
Repo RepoOptions Repo RepoOptions
Output OutputOptions Output OutputOptions
Registry Registry
} }
func init() { func init() {
@ -75,23 +45,22 @@ func init() {
} }
// NewRootOptions ... // NewRootOptions ...
func NewRootOptions() (*RootOptions, error) { func NewRootOptions() *RootOptions {
rootOpts := &RootOptions{} rootOpts := &RootOptions{}
if err := defaults.Set(rootOpts); err != nil { if err := defaults.Set(rootOpts); err != nil {
return nil, err logger.WithError(err).WithField("options", "RootOptions").Fatal("error setting driverkit options defaults")
} }
return rootOpts, nil return rootOpts
} }
// Validate validates the RootOptions fields. // Validate validates the RootOptions fields.
func (ro *RootOptions) Validate() []error { func (ro *RootOptions) Validate() []error {
if err := validate.V.Struct(ro); err != nil { if err := validate.V.Struct(ro); err != nil {
var errs validator.ValidationErrors errors := err.(validator.ValidationErrors)
errors.As(err, &errs)
errArr := []error{} errArr := []error{}
for _, e := range errs { for _, e := range errors {
// Translate each error one at a time // Translate each error one at a time
errArr = append(errArr, errors.New(e.Translate(validate.T))) errArr = append(errArr, fmt.Errorf(e.Translate(validate.T)))
} }
return errArr return errArr
} }
@ -100,120 +69,86 @@ func (ro *RootOptions) Validate() []error {
kr := kernelrelease.FromString(ro.KernelRelease) kr := kernelrelease.FromString(ro.KernelRelease)
kr.Architecture = kernelrelease.Architecture(ro.Architecture) kr.Architecture = kernelrelease.Architecture(ro.Architecture)
if !kr.SupportsModule() && !kr.SupportsProbe() { if !kr.SupportsModule() && !kr.SupportsProbe() {
return []error{errors.New("both module and probe are not supported by given options")} return []error{fmt.Errorf("both module and probe are not supported by given options")}
} }
return nil return nil
} }
func (ro *RootOptions) AddFlags(flags *pflag.FlagSet, targets []string) {
flags.StringVar(&ro.Output.Module, "output-module", ro.Output.Module, "filepath where to save the resulting kernel module")
flags.StringVar(&ro.Output.Probe, "output-probe", ro.Output.Probe, "filepath where to save the resulting eBPF probe")
flags.StringVar(&ro.Architecture, "architecture", runtime.GOARCH, "target architecture for the built driver, one of "+kernelrelease.SupportedArchs.String())
flags.StringVar(&ro.DriverVersion, "driverversion", ro.DriverVersion, "driver version as a git commit hash or as a git tag")
flags.StringVar(&ro.KernelVersion, "kernelversion", ro.KernelVersion, "kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v'")
flags.StringVar(&ro.KernelRelease, "kernelrelease", ro.KernelRelease, "kernel release to build the module for, it can be found by executing 'uname -v'")
flags.StringVarP(&ro.Target, "target", "t", ro.Target, "the system to target the build for, one of ["+strings.Join(targets, ",")+"]")
flags.StringVar(&ro.KernelConfigData, "kernelconfigdata", ro.KernelConfigData, "base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc")
flags.StringVar(&ro.ModuleDeviceName, "moduledevicename", ro.ModuleDeviceName, "kernel module device name (the default is falco, so the device will be under /dev/falco*)")
flags.StringVar(&ro.ModuleDriverName, "moduledrivername", ro.ModuleDriverName, "kernel module driver name, i.e. the name you see when you check installed modules via lsmod")
flags.StringVar(&ro.BuilderImage, "builderimage", ro.BuilderImage, "docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.")
flags.StringSliceVar(&ro.BuilderRepos, "builderrepo", ro.BuilderRepos, "list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'.")
flags.StringVar(&ro.GCCVersion, "gccversion", ro.GCCVersion, "enforce a specific gcc version for the build")
flags.StringSliceVar(&ro.KernelUrls, "kernelurls", nil, "list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls \"<URL3>,<URL4>\")")
flags.StringVar(&ro.Repo.Org, "repo-org", ro.Repo.Org, "repository github organization")
flags.StringVar(&ro.Repo.Name, "repo-name", ro.Repo.Name, "repository github name")
flags.StringVar(&ro.Registry.Name, "registry-name", ro.Registry.Name, "registry name to which authenticate")
flags.StringVar(&ro.Registry.Username, "registry-user", ro.Registry.Username, "registry username")
flags.StringVar(&ro.Registry.Password, "registry-password", ro.Registry.Password, "registry password")
flags.BoolVar(&ro.Registry.PlainHTTP, "registry-plain-http", ro.Registry.PlainHTTP, "allows interacting with remote registry via plain http requests")
}
// Log emits a log line containing the receiving RootOptions for debugging purposes. // Log emits a log line containing the receiving RootOptions for debugging purposes.
// //
// Call it only after validation. // Call it only after validation.
func (ro *RootOptions) Log(printer *output.Printer) { func (ro *RootOptions) Log() {
printer.Logger.Debug("running with options", fields := logger.Fields{}
printer.Logger.Args( if ro.Output.Module != "" {
"output-module", ro.Output.Module, fields["output-module"] = ro.Output.Module
"output-probe", ro.Output.Probe, }
"driverversion", ro.DriverVersion, if ro.Output.Probe != "" {
"kernelrelease", ro.KernelRelease, fields["output-probe"] = ro.Output.Probe
"kernelversion", ro.KernelVersion,
"target", ro.Target, }
"arch", ro.Architecture, if ro.DriverVersion != "" {
"kernelurls", ro.KernelUrls, fields["driverversion"] = ro.DriverVersion
"repo-org", ro.Repo.Org, }
"repo-name", ro.Repo.Name, if ro.KernelRelease != "" {
)) fields["kernelrelease"] = ro.KernelRelease
}
if ro.KernelVersion != "" {
fields["kernelversion"] = ro.KernelVersion
}
if ro.Target != "" {
fields["target"] = ro.Target
}
fields["arch"] = ro.Architecture
if len(ro.KernelUrls) > 0 {
fields["kernelurls"] = ro.KernelUrls
}
fields["repo-org"] = ro.Repo.Org
fields["repo-name"] = ro.Repo.Name
logger.WithFields(fields).Debug("running with options")
} }
func (ro *RootOptions) ToBuild(printer *output.Printer) *builder.Build { func (ro *RootOptions) toBuild() *builder.Build {
kernelConfigData := ro.KernelConfigData kernelConfigData := ro.KernelConfigData
if len(kernelConfigData) == 0 { if len(kernelConfigData) == 0 {
kernelConfigData = "bm8tZGF0YQ==" // no-data kernelConfigData = "bm8tZGF0YQ==" // no-data
} }
build := &builder.Build{ build := &builder.Build{
TargetType: builder.Type(ro.Target), TargetType: builder.Type(ro.Target),
DriverVersion: ro.DriverVersion, DriverVersion: ro.DriverVersion,
KernelVersion: ro.KernelVersion, KernelVersion: ro.KernelVersion,
KernelRelease: ro.KernelRelease, KernelRelease: ro.KernelRelease,
Architecture: ro.Architecture, Architecture: ro.Architecture,
KernelConfigData: kernelConfigData, KernelConfigData: kernelConfigData,
ModuleFilePath: ro.Output.Module, ModuleFilePath: ro.Output.Module,
ProbeFilePath: ro.Output.Probe, ProbeFilePath: ro.Output.Probe,
ModuleDriverName: ro.ModuleDriverName, ModuleDriverName: ro.ModuleDriverName,
ModuleDeviceName: ro.ModuleDeviceName, ModuleDeviceName: ro.ModuleDeviceName,
GCCVersion: ro.GCCVersion, GCCVersion: ro.GCCVersion,
BuilderImage: ro.BuilderImage, BuilderImage: ro.BuilderImage,
BuilderRepos: ro.BuilderRepos, BuilderRepos: ro.BuilderRepos,
KernelUrls: ro.KernelUrls, KernelUrls: ro.KernelUrls,
RepoOrg: ro.Repo.Org, RepoOrg: ro.Repo.Org,
RepoName: ro.Repo.Name, RepoName: ro.Repo.Name,
Images: make(builder.ImagesMap),
RegistryName: ro.Registry.Name,
RegistryUser: ro.Registry.Username,
RegistryPassword: ro.Registry.Password,
RegistryPlainHTTP: ro.Registry.PlainHTTP,
Printer: printer,
} }
// loop over BuilderRepos to build the list ImagesListers based on the value of the builderRepo: // Always append falcosecurity repo; Note: this is a prio first slice
// if it's a local path use FileImagesLister, otherwise use RepoImagesLister // therefore, default falcosecurity repo has lowest prio.
var ( build.BuilderRepos = append(build.BuilderRepos, "docker.io/falcosecurity/driverkit")
imageLister builder.ImagesLister
err error
)
for _, builderRepo := range build.BuilderRepos {
if _, err = os.Stat(builderRepo); err == nil {
imageLister, err = builder.NewFileImagesLister(builderRepo, build)
} else {
imageLister, err = builder.NewRepoImagesLister(builderRepo, build)
}
if err != nil {
printer.Logger.Warn("skipping repo",
printer.Logger.Args("repo", builderRepo, "err", err.Error()))
} else {
build.ImagesListers = append(build.ImagesListers, imageLister)
}
}
// attempt the build in case it comes from an invalid config // attempt the build in case it comes from an invalid config
kr := build.KernelReleaseFromBuildConfig() kr := build.KernelReleaseFromBuildConfig()
if len(build.ModuleFilePath) > 0 && !kr.SupportsModule() { if len(build.ModuleFilePath) > 0 && !kr.SupportsModule() {
build.ModuleFilePath = "" build.ModuleFilePath = ""
printer.Logger.Warn("skipping build attempt of module for unsupported kernel release", logger.Warningf("Skipping build attempt of module for unsupported kernel version %s", kr.String())
printer.Logger.Args("kernelrelease", kr.String()))
} }
if len(build.ProbeFilePath) > 0 && !kr.SupportsProbe() { if len(build.ProbeFilePath) > 0 && !kr.SupportsProbe() {
build.ProbeFilePath = "" build.ProbeFilePath = ""
printer.Logger.Warn("skipping build attempt of probe for unsupported kernel release", logger.Warningf("Skipping build attempt of probe for unsupported kernel version %s", kr.String())
printer.Logger.Args("kernelrelease", kr.String()))
} }
return build return build
} }

View File

@ -1,5 +1,4 @@
INFO specify a valid processor INFO specify a valid processor processors="[docker kubernetes kubernetes-in-cluster]"
└ processors: [docker kubernetes kubernetes-in-cluster local]
{{ .Desc }} {{ .Desc }}
{{ .Usage }} {{ .Usage }}
@ -7,6 +6,6 @@ INFO specify a valid processor
{{ .Commands }} {{ .Commands }}
{{ .Flags }} {{ .Flags }}
-v, --version version for driverkit -v, --version version for driverkit
{{ .Info }} {{ .Info }}

View File

@ -3,5 +3,4 @@ kernelversion: 59
target: ubuntu-aws target: ubuntu-aws
output: output:
module: /tmp/falco-ubuntu-aws.ko module: /tmp/falco-ubuntu-aws.ko
probe: /tmp/falco-ubuntu-aws.o
driverversion: master driverversion: master

View File

@ -7,5 +7,4 @@ kernelurls: [
target: ubuntu-aws target: ubuntu-aws
output: output:
module: /tmp/falco-ubuntu-aws.ko module: /tmp/falco-ubuntu-aws.ko
probe: /tmp/falco-ubuntu-aws.o
driverversion: master driverversion: master

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/1.yaml INFO using config file file=testdata/configs/1.yaml
DEBUG running with options DEBU running with options arch={{ .CurrentArch }} driverversion=master kernelrelease=4.15.0-1057-aws kernelversion=59 output-module=/tmp/falco-ubuntu-aws.ko repo-name=libs repo-org=falcosecurity target=ubuntu
├ output-module: /tmp/falco-ubuntu-aws.ko INFO driver building, it will take a few seconds processor=docker
├ output-probe: /tmp/falco-ubuntu-aws.o
├ driverversion: master
├ kernelrelease: 4.15.0-1057-aws
├ kernelversion: 59
├ target: ubuntu-aws
├ arch: {{ .CurrentArch }}
├ kernelurls: []
├ repo-org: falcosecurity
└ repo-name: libs
INFO starting build processor: docker

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/1.yaml INFO using config file file=testdata/configs/1.yaml
DEBUG running with options DEBU running with options arch={{ .CurrentArch }} driverversion=master kernelrelease=4.15.0-1057-aws kernelversion=229 output-module=/tmp/override.ko repo-name=libs repo-org=falcosecurity target=ubuntu
├ output-module: /tmp/override.ko INFO driver building, it will take a few seconds processor=docker
├ output-probe: /tmp/falco-ubuntu-aws.o
├ driverversion: master
├ kernelrelease: 4.15.0-1057-aws
├ kernelversion: 229
├ target: ubuntu-aws
├ arch: {{ .CurrentArch }}
├ kernelurls: []
├ repo-org: falcosecurity
└ repo-name: libs
INFO starting build processor: docker

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/2.yaml INFO using config file file=testdata/configs/2.yaml
DEBUG running with options DEBU running with options arch={{ .CurrentArch }} driverversion=master kernelrelease=4.15.0-1057-aws kernelurls="[https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-aws-headers-4.15.0-1057_4.15.0-1057.59_all.deb https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-headers-4.15.0-1057-aws_4.15.0-1057.59_amd64.deb]" kernelversion=59 output-module=/tmp/falco-ubuntu-aws.ko repo-name=libs repo-org=falcosecurity target=ubuntu
├ output-module: /tmp/falco-ubuntu-aws.ko INFO driver building, it will take a few seconds processor=docker
├ output-probe: /tmp/falco-ubuntu-aws.o
├ driverversion: master
├ kernelrelease: 4.15.0-1057-aws
├ kernelversion: 59
├ target: ubuntu-aws
├ arch: {{ .CurrentArch }}
├ kernelurls: [https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-aws-headers-4.15.0-1057_4.15.0-1057.59_all.deb https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-headers-4.15.0-1057-aws_4.15.0-1057.59_amd64.deb]
├ repo-org: falcosecurity
└ repo-name: libs
INFO starting build processor: docker

View File

@ -1,13 +1,3 @@
DEBUG running without a configuration file DEBU running without a configuration file
DEBUG running with options DEBU running with options arch={{ .CurrentArch }} driverversion=master kernelrelease=4.15.0-1057-azure kernelurls="[http://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-azure/linux-azure-headers-4.15.0-1057_4.15.0-1057.62_all.deb http://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-azure/linux-headers-4.15.0-1057-azure_4.15.0-1057.62_amd64.deb]" kernelversion=62 output-module=/tmp/falco-ubuntu-azure.ko repo-name=libs repo-org=falcosecurity target=ubuntu
├ output-module: /tmp/falco-ubuntu-azure.ko INFO driver building, it will take a few seconds processor=docker
├ output-probe: /tmp/falco-ubuntu-aws.o
├ driverversion: master
├ kernelrelease: 4.15.0-1057-azure
├ kernelversion: 62
├ target: ubuntu-azure
├ arch: {{ .CurrentArch }}
├ kernelurls: [http://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-azure/linux-azure-headers-4.15.0-1057_4.15.0-1057.62_all.deb http://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-azure/linux-headers-4.15.0-1057-azure_4.15.0-1057.62_amd64.deb]
├ repo-org: falcosecurity
└ repo-name: libs
INFO starting build processor: docker

View File

@ -1,4 +1,8 @@
DEBUG running without a configuration file DEBU running without a configuration file
ERROR error validating build options ERRO error validating build options error="builder image is a required field when target is redhat"
└ err: builder image is a required field when target is redhat Error: exiting for validation errors
ERROR error executing driverkit err: exiting for validation errors Usage:
driverkit docker [flags]
{{ .Flags }}

View File

@ -1,13 +1,3 @@
DEBUG running without a configuration file DEBU running without a configuration file
DEBUG running with options DEBU running with options arch={{ .CurrentArch }} driverversion=master kernelrelease=4.15.0-1057-aws kernelurls="[https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-aws-headers-4.15.0-1057_4.15.0-1057.59_all.deb https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-headers-4.15.0-1057-aws_4.15.0-1057.59_amd64.deb]" kernelversion=59 output-module=/tmp/falco-ubuntu-aws.ko repo-name=libs repo-org=falcosecurity target=ubuntu
├ output-module: /tmp/falco-ubuntu-aws.ko INFO driver building, it will take a few seconds processor=docker
├ output-probe: /tmp/falco-ubuntu-aws.o
├ driverversion: master
├ kernelrelease: 4.15.0-1057-aws
├ kernelversion: 59
├ target: ubuntu-aws
├ arch: {{ .CurrentArch }}
├ kernelurls: [https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-aws-headers-4.15.0-1057_4.15.0-1057.59_all.deb https://mirrors.edge.kernel.org/ubuntu/pool/main/l/linux-aws/linux-headers-4.15.0-1057-aws_4.15.0-1057.59_amd64.deb]
├ repo-org: falcosecurity
└ repo-name: libs
INFO starting build processor: docker

View File

@ -1 +1 @@
INFO starting build processor: docker INFO driver building, it will take a few seconds processor=docker

View File

@ -1,7 +1,10 @@
ERROR error validating build options err: kernel release is a required field ERRO error validating build options error="kernel release is a required field"
ERROR error validating build options err: target is a required field ERRO error validating build options error="target is a required field"
ERROR error validating build options ERRO error validating build options error="output module path is required when probe is missing"
└ err: output module path is required when probe is missing ERRO error validating build options error="output probe path is required when module is missing"
ERROR error validating build options Error: exiting for validation errors
└ err: output probe path is required when module is missing Usage:
ERROR error executing driverkit err: exiting for validation errors driverkit docker [flags]
{{ .Flags }}

View File

@ -5,6 +5,6 @@
{{ .Commands }} {{ .Commands }}
{{ .Flags }} {{ .Flags }}
-v, --version version for driverkit -v, --version version for driverkit
{{ .Info }} {{ .Info }}

View File

@ -5,6 +5,5 @@
{{ .Commands }} {{ .Commands }}
{{ .Flags }} {{ .Flags }}
-v, --version version for driverkit
{{ .Info }} {{ .Info }}

View File

@ -1,3 +1,11 @@
ERROR error validating config options ERRO error validating config options error="proxy url must start with http:// or https:// or socks5:// prefix"
└ err: proxy url must start with http:// or https:// or socks5:// prefix Error: exiting for validation errors
ERROR error executing driverkit err: exiting for validation errors {{ .Usage }}
{{ .Commands }}
{{ .Flags }}
-v, --version version for driverkit
{{ .Info }}

View File

@ -1 +1,10 @@
ERROR error executing driverkit err: invalid argument "abc" for "driverkit" Error: invalid argument "abc" for "driverkit"
{{ .Usage }}
{{ .Commands }}
{{ .Flags }}
-v, --version version for driverkit
{{ .Info }}

View File

@ -4,5 +4,4 @@ Available Commands:
help Help about any command help Help about any command
images List builder images images List builder images
kubernetes Build Falco kernel modules and eBPF probes against a Kubernetes cluster. kubernetes Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
kubernetes-in-cluster Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster. kubernetes-in-cluster Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.
local Build Falco kernel modules and eBPF probes in local env with local kernel sources and gcc/clang.

View File

@ -1,27 +1,23 @@
Flags: Flags:
--architecture string target architecture for the built driver, one of {{ .Architectures }} (default "{{ .CurrentArch }}") --architecture string target architecture for the built driver, one of {{ .Architectures }} (default "{{ .CurrentArch }}")
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build --gccversion string enforce a specific gcc version for the build
-h, --help help for {{ .Cmd }} -h, --help help for {{ .Cmd }}
--kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc --kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v' --kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate --repo-name string repository github name (default "libs")
--registry-password string registry password --repo-org string repository github organization (default "falcosecurity")
--registry-plain-http allows interacting with remote registry via plain http requests -t, --target string the system to target the build for, one of {{ .Targets }}
--registry-user string registry username --timeout int timeout in seconds (default 120)
--repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity")
-t, --target string the system to target the build for, one of {{ .Targets }}
--timeout int timeout in seconds (default 120)

View File

@ -1,28 +1,16 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 main package main
import ( import (
"bytes" "bytes"
"flag" "flag"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
"github.com/falcosecurity/driverkit/cmd" "github.com/falcosecurity/driverkit/cmd"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra/doc" "github.com/spf13/cobra/doc"
) )
@ -59,22 +47,7 @@ func main() {
flag.Parse() flag.Parse()
// Get root command // Get root command
configOpts, err := cmd.NewConfigOptions() driverkit := cmd.NewRootCmd()
if err != nil {
// configOpts will never be nil here
if configOpts != nil {
configOpts.Printer.Logger.Fatal("error setting driverkit config options defaults",
configOpts.Printer.Logger.Args("err", err.Error()))
} else {
os.Exit(1)
}
}
rootOpts, err := cmd.NewRootOptions()
if err != nil {
configOpts.Printer.Logger.Fatal("error setting driverkit root options defaults",
configOpts.Printer.Logger.Args("err", err.Error()))
}
driverkit := cmd.NewRootCmd(configOpts, rootOpts)
root := driverkit.Command() root := driverkit.Command()
num := len(root.Commands()) + 1 num := len(root.Commands()) + 1
@ -97,20 +70,20 @@ func main() {
} }
// Generate markdown docs // Generate markdown docs
err = doc.GenMarkdownTreeCustom(root, outputDir, prepender(num), linker) err := doc.GenMarkdownTreeCustom(root, outputDir, prepender(num), linker)
if err != nil { if err != nil {
configOpts.Printer.Logger.Fatal("markdown generation", configOpts.Printer.Logger.Args("err", err.Error())) logger.WithError(err).Fatal("markdown generation")
} }
if targetWebsite { if targetWebsite {
err = os.Rename(path.Join(outputDir, "driverkit.md"), path.Join(outputDir, "_index.md")) err := os.Rename(path.Join(outputDir, "driverkit.md"), path.Join(outputDir, "_index.md"))
if err != nil { if err != nil {
configOpts.Printer.Logger.Fatal("renaming main docs page", configOpts.Printer.Logger.Args("err", err.Error())) logger.WithError(err).Fatal("renaming main docs page")
} }
} }
if err = stripSensitive(); err != nil { if err := stripSensitive(); err != nil {
configOpts.Printer.Logger.Fatal("error replacing sensitive data", configOpts.Printer.Logger.Args("err", err.Error())) logger.WithError(err).Fatal("error replacing sensitive data")
} }
} }
@ -127,7 +100,7 @@ func stripSensitive() error {
for _, file := range files { for _, file := range files {
filePath := path.Join(outputDir, file.Name()) filePath := path.Join(outputDir, file.Name())
file, err := os.ReadFile(filePath) file, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
return err return err
} }
@ -137,7 +110,7 @@ func stripSensitive() error {
target := []byte(os.Getenv(s)) target := []byte(os.Getenv(s))
file = bytes.ReplaceAll(file, target, append(envMark, []byte(s)...)) file = bytes.ReplaceAll(file, target, append(envMark, []byte(s)...))
} }
if err = os.WriteFile(filePath, file, 0666); err != nil { if err = ioutil.WriteFile(filePath, file, 0666); err != nil {
return err return err
} }
} }

View File

@ -1,32 +0,0 @@
FROM amazonlinux:2.0.20240529.0
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
RUN yum -y install gcc10 \
clang \
llvm \
bash-completion \
bc \
ca-certificates \
curl \
gnupg2 \
libc6-dev \
elfutils-libelf-devel \
xz \
cpio \
flex \
bison \
openssl \
openssl-devel \
wget \
binutils \
which \
make \
cmake3 \
tar \
zstd \
git
# Properly create soft links
RUN ln -s /usr/bin/gcc10-cc /usr/bin/gcc-10.0.0
RUN ln -s /usr/bin/cmake3 /usr/bin/cmake

View File

@ -1 +0,0 @@
builder-any-x86_64_gcc13.0.0.Dockerfile

View File

@ -1 +0,0 @@
builder-any-x86_64_gcc14.0.0.Dockerfile

View File

@ -39,10 +39,8 @@ RUN apt-get update \
software-properties-common \ software-properties-common \
gpg \ gpg \
zstd \ zstd \
cmake \ && rm -rf /var/lib/apt/lists/*
git \
&& rm -rf /var/lib/apt/lists/*
# Properly create soft link # Properly create soft link
RUN ln -s /usr/bin/gcc-9 /usr/bin/gcc-9.0.0 RUN ln -s /usr/bin/gcc-9 /usr/bin/gcc-9.0.0
RUN ln -s /usr/bin/gcc-10 /usr/bin/gcc-10.0.0 RUN ln -s /usr/bin/gcc-10 /usr/bin/gcc-10.0.0

View File

@ -39,9 +39,7 @@ RUN apt-get update \
software-properties-common \ software-properties-common \
gpg \ gpg \
zstd \ zstd \
cmake \ && rm -rf /var/lib/apt/lists/*
git \
&& rm -rf /var/lib/apt/lists/*
# Properly create soft links # Properly create soft links
RUN ln -s /usr/bin/gcc-11 /usr/bin/gcc-11.0.0 RUN ln -s /usr/bin/gcc-11 /usr/bin/gcc-11.0.0

View File

@ -1,40 +0,0 @@
FROM fedora:39
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
ARG TARGETARCH
RUN dnf install -y \
bash-completion \
bc \
clang \
llvm \
ca-certificates \
curl \
dkms \
dwarves \
gnupg2 \
gcc \
jq \
glibc-devel \
elfutils-libelf-devel \
netcat \
xz \
cpio \
flex \
bison \
openssl \
openssl-devel \
ncurses-devel \
systemd-devel \
pciutils-devel \
binutils-devel \
lsb-release \
wget \
gpg \
zstd \
cmake \
git
# Properly create soft links
RUN ln -s /usr/bin/gcc /usr/bin/gcc-13.0.0

View File

@ -1,40 +0,0 @@
FROM fedora:41
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
ARG TARGETARCH
RUN dnf install -y \
bash-completion \
bc \
clang \
llvm \
ca-certificates \
curl \
dkms \
dwarves \
gnupg2 \
gcc \
jq \
glibc-devel \
elfutils-libelf-devel \
netcat \
xz \
cpio \
flex \
bison \
openssl \
openssl-devel \
ncurses-devel \
systemd-devel \
pciutils-devel \
binutils-devel \
lsb-release \
wget \
gpg \
zstd \
cmake \
git
# Properly create soft links
RUN ln -s /usr/bin/gcc /usr/bin/gcc-14.0.0

View File

@ -5,24 +5,18 @@ LABEL maintainer="cncf-falco-dev@lists.cncf.io"
ARG TARGETARCH ARG TARGETARCH
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
RUN echo 'deb http://deb.debian.org/debian buster-backports main' >>/etc/apt/sources.list
# Use 20250630T203427Z debian apt snapshot as it still contains support for buster.
RUN cat <<EOF > /etc/apt/sources.list
deb http://snapshot.debian.org/archive/debian/20250630T203427Z buster main
deb http://snapshot.debian.org/archive/debian-security/20250630T203427Z buster/updates main
deb http://snapshot.debian.org/archive/debian/20250630T203427Z buster-updates main
EOF
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends \ && apt-get install -y --no-install-recommends \
bash-completion \ bash-completion \
bc \ bc \
clang \ clang \
llvm \ llvm \
ca-certificates \ ca-certificates \
curl \ curl \
dkms \ dkms \
dwarves \ dwarves/buster-backports \
gnupg2 \ gnupg2 \
gcc \ gcc \
jq \ jq \
@ -45,18 +39,14 @@ RUN apt-get update \
software-properties-common \ software-properties-common \
gpg \ gpg \
zstd \ zstd \
gawk \ && rm -rf /var/lib/apt/lists/*
mawk \
git \
&& rm -rf /var/lib/apt/lists/*
RUN if [ "$TARGETARCH" = "amd64" ] ; then apt-get install -y --no-install-recommends libmpx2; fi RUN if [ "$TARGETARCH" = "amd64" ] ; then apt-get install -y --no-install-recommends libmpx2; fi
# gcc 4.9 is required on x86 to build some 3.10+ kernels # gcc 4.9 is required on x86 to build some 3.10+ kernels
# note: on arm gcc 4.9 could not be found. # note: on arm gcc 4.9 could not be found.
RUN echo 'deb http://dk.archive.ubuntu.com/ubuntu/ xenial main' >> /etc/apt/sources.list && \ RUN echo 'deb http://deb.debian.org/debian jessie main' >>/etc/apt/sources.list # gcc 4.9 on x86_64
echo 'deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe' >> /etc/apt/sources.list # jessie repo is unsigned therefore the APT options
# repo is unsigned therefore the APT options
RUN if [ "$TARGETARCH" = "amd64" ] ; then apt-get -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true update && apt-get -o APT::Get::AllowUnauthenticated=true install -y --no-install-recommends gcc-4.9; fi RUN if [ "$TARGETARCH" = "amd64" ] ; then apt-get -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true update && apt-get -o APT::Get::AllowUnauthenticated=true install -y --no-install-recommends gcc-4.9; fi
# gcc 6 is no longer included in debian stable, but we need it to # gcc 6 is no longer included in debian stable, but we need it to
@ -131,16 +121,9 @@ RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dep
&& dpkg -i *binutils*.deb \ && dpkg -i *binutils*.deb \
&& rm -f *binutils*.deb && rm -f *binutils*.deb
# Install a recent version of cmake (debian buster has at most 3.13)
RUN curl -L -o /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-$(uname -m).tar.gz; \
gzip -d /tmp/cmake.tar.gz; \
tar -xpf /tmp/cmake.tar --directory=/tmp; \
cp -R /tmp/cmake-3.22.5-linux-$(uname -m)/* /usr; \
rm -rf /tmp/cmake-3.22.5-linux-$(uname -m)/
# Properly create soft link # Properly create soft link
RUN ln -s /usr/bin/gcc-4.8 /usr/bin/gcc-4.8.0 RUN ln -s /usr/bin/gcc-4.8 /usr/bin/gcc-4.8.0
RUN if [ "$TARGETARCH" = "amd64" ] ; then ln -s /usr/bin/gcc-4.9 /usr/bin/gcc-4.9.0; fi; RUN if [ "$TARGETARCH" = "amd64" ] ; then ln -s /usr/bin/gcc-4.9 /usr/bin/gcc-4.9.0; fi;
RUN ln -s /usr/bin/gcc-5 /usr/bin/gcc-5.0.0 RUN ln -s /usr/bin/gcc-5 /usr/bin/gcc-5.0.0
RUN ln -s /usr/bin/gcc-6 /usr/bin/gcc-6.0.0 RUN ln -s /usr/bin/gcc-6 /usr/bin/gcc-6.0.0
RUN ln -s /usr/bin/gcc-8 /usr/bin/gcc-8.0.0 RUN ln -s /usr/bin/gcc-8 /usr/bin/gcc-8.0.0

View File

@ -2,19 +2,8 @@ FROM centos:7
LABEL maintainer="cncf-falco-dev@lists.cncf.io" LABEL maintainer="cncf-falco-dev@lists.cncf.io"
# Fix broken mirrors - centos:7 eol RUN yum -y install centos-release-scl && \
RUN sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo; \ yum -y install gcc \
sed -i s/^#.*baseurl=http/baseurl=https/g /etc/yum.repos.d/*.repo; \
sed -i s/^mirrorlist=http/#mirrorlist=https/g /etc/yum.repos.d/*.repo
RUN yum -y install centos-release-scl
# fix broken mirrors (again)
RUN sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo; \
sed -i s/^#.*baseurl=http/baseurl=https/g /etc/yum.repos.d/*.repo; \
sed -i s/^mirrorlist=http/#mirrorlist=https/g /etc/yum.repos.d/*.repo
RUN yum -y install gcc \
llvm-toolset-7.0 \ llvm-toolset-7.0 \
bash-completion \ bash-completion \
bc \ bc \
@ -32,15 +21,7 @@ RUN yum -y install gcc \
wget \ wget \
binutils \ binutils \
which \ which \
make \ make
git
# Install cmake3.x (on centos7 `cmake` package installs cmake2.x)
RUN curl -L -o /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-$(uname -m).tar.gz; \
gzip -d /tmp/cmake.tar.gz; \
tar -xpf /tmp/cmake.tar --directory=/tmp; \
cp -R /tmp/cmake-3.22.5-linux-$(uname -m)/* /usr; \
rm -rf /tmp/cmake-3.22.5-linux-$(uname -m)/
# Properly create soft link # Properly create soft link
RUN ln -s /usr/bin/gcc /usr/bin/gcc-4.8.5 RUN ln -s /usr/bin/gcc /usr/bin/gcc-4.8.5

View File

@ -13,8 +13,7 @@ If that distribution is not yet supported by driverkit, the Falco Drivers Build
Adding support for a new distro is a multiple-step work: Adding support for a new distro is a multiple-step work:
* first of all, a new builder on driverkit must be created * first of all, a new builder on driverkit must be created
* secondly, [kernel-crawler](https://github.com/falcosecurity/kernel-crawler) must also be updated to support the new distro; see [below](#5-kernel-crawler) section * secondly, [kernel-crawler](https://github.com/falcosecurity/kernel-crawler) must also be updated to support the new distro; see [below](#5-kernel-crawler) section
* third, [dbg-go](https://github.com/falcosecurity/dbg-go) must [bump driverkit](https://github.com/falcosecurity/dbg-go?tab=readme-ov-file#bumping-driverkit) and enable support to generate configs for the new distro: https://github.com/falcosecurity/dbg-go/blob/main/pkg/root/distro.go#L30. * lastly, [test-infra](https://github.com/falcosecurity/test-infra) must be updated to add the new [prow config](https://github.com/falcosecurity/test-infra/tree/master/config/jobs/build-drivers) for new distro related jobs
* lastly, [test-infra](https://github.com/falcosecurity/test-infra) must be updated to add the new [prow config](https://github.com/falcosecurity/test-infra/tree/master/config/jobs/build-drivers) for new distro related jobs and `dbg-go` images must be bumped, see https://github.com/falcosecurity/test-infra/tree/master/images/build-drivers and https://github.com/falcosecurity/test-infra/tree/master/images/update-dbg.
Here, we will only focus about driverkit part. Here, we will only focus about driverkit part.
@ -38,7 +37,7 @@ Your builder will need a constant for the target it implements. Usually that con
can just be the ID of the distribution you are implementing, as taken reading `/etc/os-release` file. can just be the ID of the distribution you are implementing, as taken reading `/etc/os-release` file.
A builder can implement more than one target at time. For example, the minikube builder is just a vanilla one. A builder can implement more than one target at time. For example, the minikube builder is just a vanilla one.
Once you have the constant, you will need to add it to the [byTarget](https://github.com/falcosecurity/driverkit/blob/master/pkg/driverbuilder/builder/target.go) map. Once you have the constant, you will need to add it to the `BuilderByTarget` map.
Open your file and you will need to add something like this: Open your file and you will need to add something like this:
```go ```go
@ -49,7 +48,7 @@ type archLinux struct {
} }
func init() { func init() {
byTarget[TargetTypeArchLinux] = &archLinux{} BuilderByTarget[TargetTypeArchLinux] = &archLinux{}
} }
``` ```
@ -59,19 +58,15 @@ you just registered.
Here's a very minimalistic example: Here's a very minimalistic example:
```go ```go
func (c *archlinux) Name() string { func (c archlinux) Name() string {
return TargetTypeArchlinux.String() return TargetTypeArchlinux.String()
} }
func (c *archlinux) TemplateKernelUrlsScript() string { func (c archlinux) TemplateScript() string {
return archlinuxKernelTemplate return archlinuxTemplate
} }
func (c *archlinux) TemplateScript() string { func (c archlinux) URLs(cfg Config, kr kernelrelease.KernelRelease) ([]string, error) {
return archlinuxTemplate
}
func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls := []string{} urls := []string{}
if kr.Architecture == kernelrelease.ArchitectureAmd64 { if kr.Architecture == kernelrelease.ArchitectureAmd64 {
urls = append(urls, fmt.Sprintf("https://archive.archlinux.org/packages/l/linux-headers/linux-headers-%s.%s-%d-%s.pkg.tar.xz", urls = append(urls, fmt.Sprintf("https://archive.archlinux.org/packages/l/linux-headers/linux-headers-%s.%s-%d-%s.pkg.tar.xz",
@ -80,7 +75,7 @@ func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
cfg.KernelVersion, cfg.KernelVersion,
kr.Architecture.ToNonDeb())) kr.Architecture.ToNonDeb()))
} else { } else {
urls = append(urls, fmt.Sprintf("https://alaa.ad24.cz/packages/l/linux-%s-headers/linux-%s-headers-%s-%d-%s.pkg.tar.xz", urls = append(urls, fmt.Sprintf("http://tardis.tiny-vps.com/aarm/packages/l/linux-%s-headers/linux-%s-headers-%s-%d-%s.pkg.tar.xz",
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
kr.Fullversion, kr.Fullversion,
@ -90,17 +85,17 @@ func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return urls, nil return urls, nil
} }
func (c *archlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c archlinux) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return archlinuxTemplateData{ return archlinuxTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(),
KernelDownloadURL: urls[0],
} }
} }
``` ```
Essentially, the various methods that you are implementing are needed to: Essentially, the various methods that you are implementing are needed to:
* fill the kernel download/extract script template, a `bash` script responsible to fetch and extract the kernel headers for the distro * fill the script template (see below), that is a `bash` script that will be executed by driverkit at build time
* fill the build script template (see below), that is a `bash` script that will be executed by driverkit at build time * fetch kernel headers urls that will later be downloaded inside the builder container, and used for the driver build
* return a list of possible kernel headers urls that will later be downloaded by the kernel download script, and then used for the driver build
Under `pkg/driverbuilder/builder/templates` folder, you can find all the template scripts for the supported builders. Under `pkg/driverbuilder/builder/templates` folder, you can find all the template scripts for the supported builders.
Adding a new template there and using `go:embed` to include it in your builder, allows leaner code Adding a new template there and using `go:embed` to include it in your builder, allows leaner code
@ -108,57 +103,14 @@ without mixing up templates and builder logic.
For example: For example:
```go ```go
//go:embed templates/archlinux_kernel.sh
var archlinuxKernelTemplate string
//go:embed templates/archlinux.sh //go:embed templates/archlinux.sh
var archlinuxTemplate string var archlinuxTemplate string
``` ```
Depending on how the distro works, the "kernel" template script will fetch the kernel headers for it at the specific kernel version specified Depending on how the distro works, the script will need to fetch the kernel headers for it at the specific kernel version specified
in the `Config` struct at `c.Build.KernelVersion`, and then extracting them. in the `Config` struct at `c.Build.KernelVersion`.
Finally, the script will also `export` the `KERNELDIR` variable to be consumed by the actual build script.
Example kernel download template for archlinux:
```bash
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.pkg.tar.xz -SL {{ .KernelDownloadURL }}
tar -xf kernel-devel.pkg.tar.xz
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/lib/modules/*/build/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel
```
Once you have those, based on what that kernel can do and based on what was configured Once you have those, based on what that kernel can do and based on what was configured
by the user, the build script will build the kernel module driver and/or the eBPF probe driver. by the user you will need to build the kernel module driver and/or the eBPF probe driver.
Example build template for archlinux:
```bash
set -xeuo pipefail
cd {{ .DriverBuildDir }}
mkdir -p build && cd build
{{ .CmakeCmd }}
{{ if .BuildModule }}
# Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} driver
strip -g {{ .ModuleFullPath }}
# Print results
modinfo {{ .ModuleFullPath }}
{{ end }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
{{ end }}
```
How does this work? How does this work?
@ -193,4 +145,4 @@ can also support collecting the new builders kernel versions and header package
for the new builder are automatically built by [test-infra](https://github.com/falcosecurity/test-infra). If required, add a feature request for the new builder are automatically built by [test-infra](https://github.com/falcosecurity/test-infra). If required, add a feature request
for support for the new builder on the kernel-crawler repository. for support for the new builder on the kernel-crawler repository.
> **NOTE**: be sure that the crawler you are going to add is interesting for the community as a whole. > **NOTE**: be sure that the crawler you are going to add is interesting for the community as a whole.

View File

@ -19,20 +19,14 @@ This is needed because driverkit logic must be able to differentiate eg: between
an image that provides gcc4 and one that provides 4.8, in a reliable manner. an image that provides gcc4 and one that provides 4.8, in a reliable manner.
The makefile will be then automatically able to collect the new docker images and pushing it as part of the CI. The makefile will be then automatically able to collect the new docker images and pushing it as part of the CI.
Note: the images will be pushed under the `falcosecurity/driverkit-builder` repository, each with a tag reflecting its name, eg:
* `falcosecurity/driverkit-builder:centos-x86_64_gcc5.8.0_gcc6.0.0-latest`
* `falcosecurity/driverkit-builder:any-x86_64_gcc12.0.0-454eff8fcc7d9abc615d312e9eccbd41abffb810`
As you can see, the last part of the image tag is the real versioned tag (ie: `-latest` or `-$commithash`).
## Selection algorithm ## Selection algorithm
Once pushed, driverkit will be able to correctly load the image during startup, using [falcoctl](https://github.com/falcosecurity/falcoctl/) OCI utilities. Once pushed, driverkit will be able to correctly load the image during startup, using a `docker search`.
Then, it will map images whose target and architecture are correct for the current build, storing the provided GCCs list. Then, it will map images whose target and architecture are correct for the current build, storing the provided GCCs list.
Moreover, it will also take care of only using images with correct tag (ie: `latest` or `commithash`), as requested by user or automatically set by Makefile.
The algorithm goes as follows: The algorithm goes as follows:
* load any image for the build arch, tag and target * load any image for the build arch and build target
* load any image for the build arch, tag and "any" target * load any image for the build arch and "any" target
* if any of the target-specific image provides the targetGCC for the build, we are over * if any of the target-specific image provides the targetGCC for the build, we are over
* if any of the "any" fallback image provides the targetGCC for the build, we are over * if any of the "any" fallback image provides the targetGCC for the build, we are over
* else, find the image between target-specific and fallback ones, that provides nearest GCC. * else, find the image between target-specific and fallback ones, that provides nearest GCC.
@ -41,12 +35,8 @@ In this latest step, there is no distinction between/different priority given to
## Customize builder images repos ## Customize builder images repos
Moreover, users can also ship their own builder images in their own docker repositories, by using `--builderrepo` CLI option. Moreover, users can also ship their own builder images in their own docker repositories, by using `--builderrepo` CLI option.
One can use this option multiple times; builder repos are a priority first list of docker repositories that can each provide up to 100 builder images.
Instead of passing a docker repo, one can also pass the full path to a so-called builder images index yaml file. Note that default falcosecurity repo will always be enforced as lowest priority repo.
It is mostly convenient in "static" scenarios, but it also gives the ability to freely define images name since all required infos are explicitly stated in the index file.
For an example of such a file, see [index.yaml](./index.yaml).
One can use this option multiple times; builder repos are a priority first list of docker repositories or builder images indexes (they can be mixed too!).
## Force use a builder image ## Force use a builder image
@ -58,6 +48,8 @@ instead of relying on the internal algorithm, by using `--builderimage` CLI opti
A special value for builder image is available: A special value for builder image is available:
* `auto:$tag`, that is used to tell driverkit to use the automatic algorithm, but forcing a certain image tag * `auto:$tag`, that is used to tell driverkit to use the automatic algorithm, but forcing a certain image tag
> **NOTE**: since `docker search` has no way to differentiate between image tags, all builder images are expected to be tagged together.
## Force use a gcc version ## Force use a gcc version
Users can specify the target gcc version of the build, using `--gccversion` option. Users can specify the target gcc version of the build, using `--gccversion` option.

View File

@ -9,32 +9,28 @@ driverkit
### Options ### Options
``` ```
--architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64") --architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64")
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build --gccversion string enforce a specific gcc version for the build
-h, --help help for driverkit -h, --help help for driverkit
--kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc --kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v' --kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate --repo-name string repository github name (default "libs")
--registry-password string registry password --repo-org string repository github organization (default "falcosecurity")
--registry-plain-http allows interacting with remote registry via plain http requests -t, --target string the system to target the build for, one of [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--registry-user string registry username --timeout int timeout in seconds (default 120)
--repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity")
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
``` ```
### SEE ALSO ### SEE ALSO
@ -44,5 +40,4 @@ driverkit
* [driverkit images](driverkit_images.md) - List builder images * [driverkit images](driverkit_images.md) - List builder images
* [driverkit kubernetes](driverkit_kubernetes.md) - Build Falco kernel modules and eBPF probes against a Kubernetes cluster. * [driverkit kubernetes](driverkit_kubernetes.md) - Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
* [driverkit kubernetes-in-cluster](driverkit_kubernetes-in-cluster.md) - Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster. * [driverkit kubernetes-in-cluster](driverkit_kubernetes-in-cluster.md) - Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.
* [driverkit local](driverkit_local.md) - Build Falco kernel modules and eBPF probes in local env with local kernel sources and gcc/clang.

View File

@ -9,32 +9,28 @@ driverkit docker [flags]
### Options ### Options
``` ```
--architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64") --architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64")
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build --gccversion string enforce a specific gcc version for the build
-h, --help help for docker -h, --help help for docker
--kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc --kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v' --kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate --repo-name string repository github name (default "libs")
--registry-password string registry password --repo-org string repository github organization (default "falcosecurity")
--registry-plain-http allows interacting with remote registry via plain http requests -t, --target string the system to target the build for, one of [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--registry-user string registry username --timeout int timeout in seconds (default 120)
--repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity")
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
``` ```
### SEE ALSO ### SEE ALSO

View File

@ -9,32 +9,28 @@ driverkit images [flags]
### Options ### Options
``` ```
--architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64") --architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64")
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build --gccversion string enforce a specific gcc version for the build
-h, --help help for images -h, --help help for images
--kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc --kernelconfigdata string base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v' --kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate --repo-name string repository github name (default "libs")
--registry-password string registry password --repo-org string repository github organization (default "falcosecurity")
--registry-plain-http allows interacting with remote registry via plain http requests -t, --target string the system to target the build for, one of [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--registry-user string registry username --timeout int timeout in seconds (default 120)
--repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity")
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
``` ```
### SEE ALSO ### SEE ALSO

View File

@ -11,7 +11,7 @@ driverkit kubernetes-in-cluster [flags]
``` ```
--architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64") --architecture string target architecture for the built driver, one of [amd64,arm64] (default "amd64")
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
@ -22,21 +22,17 @@ driverkit kubernetes-in-cluster [flags]
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v' --kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
-n, --namespace string If present, the namespace scope for the pods and its config (default "default") -n, --namespace string If present, the namespace scope for the pods and its config (default "default")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate
--registry-password string registry password
--registry-plain-http allows interacting with remote registry via plain http requests
--registry-user string registry username
--repo-name string repository github name (default "libs") --repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity") --repo-org string repository github organization (default "falcosecurity")
--run-as-user int Pods runner user --run-as-user int Pods runner user
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla] -t, --target string the system to target the build for, one of [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--timeout int timeout in seconds (default 120) --timeout int timeout in seconds (default 120)
``` ```

View File

@ -14,7 +14,7 @@ driverkit kubernetes [flags]
--as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups --as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups
--as-uid string uID to impersonate for the operation --as-uid string uID to impersonate for the operation
--builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used. --builderimage string docker image to be used to build the kernel module and eBPF probe. If not provided, an automatically selected image will be used.
--builderrepo strings list of docker repositories or yaml file (absolute path) containing builder images index with the format 'images: [ { target:<target>, name:<image-name>, arch: <arch>, tag: <imagetag>, gcc_versions: [ <gcc-tag> ] },...]', in descending priority order. Used to search for builder images. eg: --builderrepo myorg/driverkit-builder --builderrepo falcosecurity/driverkit-builder --builderrepo '/path/to/my/index.yaml'. (default [docker.io/falcosecurity/driverkit-builder]) --builderrepo strings list of docker repositories in descending priority order, used to search for builder images. Default falcosecurity/driverkit will always be enforced as lowest priority repo. eg: --builderrepo myorg/driverkit --builderrepo falcosecurity/driverkit
--cache-dir string default cache directory (default "$HOME/.kube/cache") --cache-dir string default cache directory (default "$HOME/.kube/cache")
--certificate-authority string path to a cert file for the certificate authority --certificate-authority string path to a cert file for the certificate authority
--client-certificate string path to a client certificate file for TLS --client-certificate string path to a client certificate file for TLS
@ -22,7 +22,6 @@ driverkit kubernetes [flags]
--cluster string the name of the kubeconfig cluster to use --cluster string the name of the kubeconfig cluster to use
-c, --config string config file path (default $HOME/.driverkit.yaml if exists) -c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--context string the name of the kubeconfig context to use --context string the name of the kubeconfig context to use
--disable-compression if true, opt-out of response compression for all requests to the server
--driverversion string driver version as a git commit hash or as a git tag (default "master") --driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action --dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build --gccversion string enforce a specific gcc version for the build
@ -34,23 +33,19 @@ driverkit kubernetes [flags]
--kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>") --kernelurls strings list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1") --kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
--kubeconfig string path to the kubeconfig file to use for CLI requests --kubeconfig string path to the kubeconfig file to use for CLI requests
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info") -l, --loglevel string log level (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco") --moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco") --moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
-n, --namespace string If present, the namespace scope for the pods and its config (default "default") -n, --namespace string If present, the namespace scope for the pods and its config (default "default")
--output-module string filepath where to save the resulting kernel module --output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe --output-probe string filepath where to save the resulting eBPF probe
--proxy string the proxy to use to download data --proxy string the proxy to use to download data
--registry-name string registry name to which authenticate
--registry-password string registry password
--registry-plain-http allows interacting with remote registry via plain http requests
--registry-user string registry username
--repo-name string repository github name (default "libs") --repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity") --repo-org string repository github organization (default "falcosecurity")
--request-timeout string the length of time to wait before giving up on a single server request, non-zero values should contain a corresponding time unit (e.g, 1s, 2m, 3h), a value of zero means don't timeout requests (default "0") --request-timeout string the length of time to wait before giving up on a single server request, non-zero values should contain a corresponding time unit (e.g, 1s, 2m, 3h), a value of zero means don't timeout requests (default "0")
--run-as-user int Pods runner user --run-as-user int Pods runner user
-s, --server string the address and port of the Kubernetes API server -s, --server string the address and port of the Kubernetes API server
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla] -t, --target string the system to target the build for, one of [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--timeout int timeout in seconds (default 120) --timeout int timeout in seconds (default 120)
--tls-server-name string server name to use for server certificate validation, if it is not provided, the hostname used to contact the server is used --tls-server-name string server name to use for server certificate validation, if it is not provided, the hostname used to contact the server is used
--token string bearer token for authentication to the API server --token string bearer token for authentication to the API server

View File

@ -1,36 +0,0 @@
## driverkit local
Build Falco kernel modules and eBPF probes in local env with local kernel sources and gcc/clang.
```
driverkit local [flags]
```
### Options
```
-c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--dkms Enforce usage of DKMS to build the kernel module.
--download-headers Try to automatically download kernel headers.
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action
--env stringToString Env variables to be enforced during the driver build. (default [])
-h, --help help for local
--kernelrelease string kernel release to build the module for, it can be found by executing 'uname -v'
--kernelversion string kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
-l, --loglevel string set level for logs (info, warn, debug, trace) (default "info")
--moduledevicename string kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
--moduledrivername string kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
--output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe
--repo-name string repository github name (default "libs")
--repo-org string repository github organization (default "falcosecurity")
--src-dir string Enforce usage of local source dir to build drivers.
-t, --target string the system to target the build for, one of [alinux,almalinux,amazonlinux,amazonlinux2,amazonlinux2022,amazonlinux2023,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,ol,opensuse,photon,redhat,rocky,sles,talos,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
```
### SEE ALSO
* [driverkit](driverkit.md) - A command line tool to build Falco kernel modules and eBPF probes.

View File

@ -1,31 +0,0 @@
images:
- name: docker.io/falcosecurity/driverkit-builder:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest
target: any
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- 6.0.0
- 5.0.0
- 4.9.0
- 4.8.0
# Name is just the image name that will be used to download the image.
# Contrarily to normal repo lister there is no constraint on it,
# since all fields are already explicitly available
- name: docker.io/foo/bar:mytag
target: arch
arch: x86_64
tag: mytag
gcc_versions:
- 13.1.1
# Image name tag ("mytag" in this case)
# is not even required to match "tag" property below,
# since the latter is used to match against the desired builder image tag for the build,
# while the former is the real image tag that will be used.
- name: docker.io/foo/baz:mytag
target: arch
arch: x86_64
tag: latest
gcc_versions:
- 13.1.1

248
go.mod
View File

@ -1,162 +1,140 @@
module github.com/falcosecurity/driverkit module github.com/falcosecurity/driverkit
go 1.24.1 go 1.18
toolchain go1.24.2
require ( require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/blang/semver/v4 v4.0.0 github.com/blang/semver v3.5.1+incompatible
github.com/creasty/defaults v1.7.0 github.com/containerd/containerd v1.6.18 // indirect
github.com/docker/docker v28.3.3+incompatible github.com/creasty/defaults v1.6.0
github.com/falcosecurity/falcoctl v0.11.1 github.com/docker/docker v20.10.14+incompatible
github.com/go-playground/locales v0.14.1 github.com/go-playground/locales v0.14.0
github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/universal-translator v0.18.0
github.com/go-playground/validator/v10 v10.24.0 github.com/go-playground/validator/v10 v10.10.1
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/olekukonko/tablewriter v0.0.5 github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
github.com/opencontainers/image-spec v1.1.1 github.com/sirupsen/logrus v1.8.1
github.com/pterm/pterm v0.12.80 github.com/spf13/cobra v1.4.0
github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.5
github.com/spf13/pflag v1.0.6 github.com/spf13/viper v1.11.0
github.com/spf13/viper v1.20.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
k8s.io/api v0.32.3 k8s.io/api v0.23.6
k8s.io/apimachinery v0.32.3 k8s.io/apimachinery v0.23.6
k8s.io/cli-runtime v0.30.0 k8s.io/cli-runtime v0.23.6
k8s.io/client-go v0.32.3 k8s.io/client-go v0.23.6
k8s.io/kubectl v0.30.0 k8s.io/kubectl v0.23.6
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
modernc.org/sqlite v1.29.9 modernc.org/sqlite v1.17.3
oras.land/oras-go/v2 v2.5.0
) )
require github.com/olekukonko/tablewriter v0.0.4
require ( require (
atomicgo.dev/cursor v0.2.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
atomicgo.dev/schedule v0.1.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Microsoft/hcsshim v0.9.6 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/containerd/console v1.0.4 // indirect github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/errdefs v1.0.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/containerd/log v0.1.0 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/docker/go-connections v0.4.0 // indirect
github.com/creack/pty v1.1.21 // indirect github.com/docker/go-units v0.4.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/distribution/reference v0.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/camelcase v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect github.com/go-errors/errors v1.0.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.2.2 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-errors/errors v1.5.1 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-openapi/swag v0.19.14 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/btree v1.1.3 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/btree v1.0.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-cmp v0.5.7 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/gookit/color v1.5.4 // indirect github.com/googleapis/gnostic v0.5.5 // indirect
github.com/gorilla/websocket v1.5.1 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/moby/go-archive v0.1.0 // indirect github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/mount v0.3.3 // indirect
github.com/moby/spdystream v0.5.0 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/opencontainers/runc v1.1.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a // indirect github.com/russross/blackfriday v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/spf13/afero v1.8.2 // indirect
github.com/sergi/go-diff v1.3.1 // indirect github.com/spf13/cast v1.4.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect github.com/stretchr/testify v1.7.1 // indirect
github.com/spf13/afero v1.12.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect
github.com/spf13/cast v1.7.1 // indirect github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
github.com/subosito/gotenv v1.6.0 // indirect go.opencensus.io v0.23.0 // indirect
github.com/x448/float16 v0.8.4 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
github.com/xlab/treeprint v1.2.0 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect golang.org/x/net v0.7.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect golang.org/x/sys v0.5.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect golang.org/x/term v0.5.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect golang.org/x/text v0.7.0 // indirect
go.starlark.net v0.0.0-20240507195648-35fe9f26b4bc // indirect golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
go.uber.org/multierr v1.11.0 // indirect golang.org/x/tools v0.1.12 // indirect
golang.org/x/crypto v0.36.0 // indirect google.golang.org/appengine v1.6.7 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
golang.org/x/net v0.38.0 // indirect google.golang.org/grpc v1.47.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect google.golang.org/protobuf v1.28.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.11.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools/v3 v3.5.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.30.0 // indirect gotest.tools/v3 v3.2.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/component-base v0.23.6 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect k8s.io/klog/v2 v2.30.0 // indirect
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
modernc.org/libc v1.50.5 // indirect lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/mathutil v1.6.0 // indirect modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/memory v1.8.0 // indirect modernc.org/ccgo/v3 v3.16.6 // indirect
modernc.org/strutil v1.2.0 // indirect modernc.org/libc v1.16.7 // indirect
modernc.org/token v1.1.0 // indirect modernc.org/mathutil v1.4.1 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect modernc.org/memory v1.1.1 // indirect
sigs.k8s.io/kustomize/api v0.17.1 // indirect modernc.org/opt v0.1.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect modernc.org/strutil v1.1.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect modernc.org/token v1.0.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
sigs.k8s.io/kustomize/api v0.10.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
) )

1831
go.sum

File diff suppressed because it is too large Load Diff

14
main.go
View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 main package main
import ( import (

View File

@ -1,84 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder
import (
_ "embed"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/alinux_kernel.sh
var alinuxKernelTemplate string
//go:embed templates/alinux.sh
var alinuxTemplate string
// TargetTypeAlinux identifies the AliyunLinux 2 and 3 target.
const TargetTypeAlinux Type = "alinux"
func init() {
byTarget[TargetTypeAlinux] = &alinux{}
}
type alinuxTemplateData struct {
KernelDownloadURL string
}
type alinux struct {
}
func (c *alinux) Name() string {
return TargetTypeAlinux.String()
}
func (c *alinux) TemplateKernelUrlsScript() string {
return alinuxKernelTemplate
}
func (c *alinux) TemplateScript() string {
return alinuxTemplate
}
func (c *alinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAlinuxKernelURLS(kr), nil
}
func (c *alinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return alinuxTemplateData{
KernelDownloadURL: urls[0],
}
}
func fetchAlinuxKernelURLS(kr kernelrelease.KernelRelease) []string {
alinuxReleases := []string{
"2",
"2.1903",
"3",
}
urls := []string{}
for _, r := range alinuxReleases {
urls = append(urls, fmt.Sprintf(
"http://mirrors.aliyun.com/alinux/%s/os/%s/Packages/kernel-devel-%s%s.rpm",
r,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
))
}
return urls
}

View File

@ -1,29 +1,11 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/almalinux_kernel.sh
var almaKernelTemplate string
//go:embed templates/almalinux.sh //go:embed templates/almalinux.sh
var almaTemplate string var almaTemplate string
@ -31,10 +13,11 @@ var almaTemplate string
const TargetTypeAlma Type = "almalinux" const TargetTypeAlma Type = "almalinux"
func init() { func init() {
byTarget[TargetTypeAlma] = &alma{} BuilderByTarget[TargetTypeAlma] = &alma{}
} }
type almaTemplateData struct { type almaTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -46,21 +29,18 @@ func (c *alma) Name() string {
return TargetTypeAlma.String() return TargetTypeAlma.String()
} }
func (c *alma) TemplateKernelUrlsScript() string {
return almaKernelTemplate
}
func (c *alma) TemplateScript() string { func (c *alma) TemplateScript() string {
return almaTemplate return almaTemplate
} }
func (c *alma) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (c *alma) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAlmaKernelURLS(kr), nil return fetchAlmaKernelURLS(kr), nil
} }
func (c *alma) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c *alma) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return almaTemplateData{ return almaTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
} }
} }
@ -82,7 +62,7 @@ func fetchAlmaKernelURLS(kr kernelrelease.KernelRelease) []string {
kr.Fullversion, kr.Fullversion,
kr.FullExtraversion, kr.FullExtraversion,
)) ))
} else { }else{
urls = append(urls, fmt.Sprintf( urls = append(urls, fmt.Sprintf(
"https://repo.almalinux.org/almalinux/%s/BaseOS/%s/os/Packages/kernel-devel-%s%s.rpm", "https://repo.almalinux.org/almalinux/%s/BaseOS/%s/os/Packages/kernel-devel-%s%s.rpm",
r, r,

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
@ -22,8 +8,8 @@ import (
"database/sql" "database/sql"
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/blang/semver/v4"
"io" "io"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -32,11 +18,9 @@ import (
_ "modernc.org/sqlite" _ "modernc.org/sqlite"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
logger "github.com/sirupsen/logrus"
) )
//go:embed templates/amazonlinux_kernel.sh
var amazonlinuxKernelTemplate string
//go:embed templates/amazonlinux.sh //go:embed templates/amazonlinux.sh
var amazonlinuxTemplate string var amazonlinuxTemplate string
@ -58,13 +42,6 @@ type amazonlinux2022 struct {
amazonlinux amazonlinux
} }
type amazonlinux2023 struct {
amazonlinux
}
// TargetTypeAmazonLinux2023 identifies the AmazonLinux2023 target.
const TargetTypeAmazonLinux2023 Type = "amazonlinux2023"
// TargetTypeAmazonLinux2022 identifies the AmazonLinux2022 target. // TargetTypeAmazonLinux2022 identifies the AmazonLinux2022 target.
const TargetTypeAmazonLinux2022 Type = "amazonlinux2022" const TargetTypeAmazonLinux2022 Type = "amazonlinux2022"
@ -75,13 +52,13 @@ const TargetTypeAmazonLinux2 Type = "amazonlinux2"
const TargetTypeAmazonLinux Type = "amazonlinux" const TargetTypeAmazonLinux Type = "amazonlinux"
func init() { func init() {
byTarget[TargetTypeAmazonLinux2023] = &amazonlinux2023{} BuilderByTarget[TargetTypeAmazonLinux2022] = &amazonlinux2022{}
byTarget[TargetTypeAmazonLinux2022] = &amazonlinux2022{} BuilderByTarget[TargetTypeAmazonLinux2] = &amazonlinux2{}
byTarget[TargetTypeAmazonLinux2] = &amazonlinux2{} BuilderByTarget[TargetTypeAmazonLinux] = &amazonlinux{}
byTarget[TargetTypeAmazonLinux] = &amazonlinux{}
} }
type amazonlinuxTemplateData struct { type amazonlinuxTemplateData struct {
commonTemplateData
KernelDownloadURLs []string KernelDownloadURLs []string
} }
@ -89,18 +66,17 @@ func (a *amazonlinux) Name() string {
return TargetTypeAmazonLinux.String() return TargetTypeAmazonLinux.String()
} }
func (a *amazonlinux) TemplateKernelUrlsScript() string { return amazonlinuxKernelTemplate }
func (a *amazonlinux) TemplateScript() string { func (a *amazonlinux) TemplateScript() string {
return amazonlinuxTemplate return amazonlinuxTemplate
} }
func (a *amazonlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (a *amazonlinux) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAmazonLinuxPackagesURLs(a, kr) return fetchAmazonLinuxPackagesURLs(a, kr)
} }
func (a *amazonlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (a *amazonlinux) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return amazonlinuxTemplateData{ return amazonlinuxTemplateData{
commonTemplateData: c.toTemplateData(a, kr),
KernelDownloadURLs: urls, KernelDownloadURLs: urls,
} }
} }
@ -130,7 +106,7 @@ func (a *amazonlinux2022) Name() string {
return TargetTypeAmazonLinux2022.String() return TargetTypeAmazonLinux2022.String()
} }
func (a *amazonlinux2022) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (a *amazonlinux2022) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAmazonLinuxPackagesURLs(a, kr) return fetchAmazonLinuxPackagesURLs(a, kr)
} }
@ -149,44 +125,14 @@ func (a *amazonlinux2022) ext() string {
return "gz" return "gz"
} }
func (a *amazonlinux2023) Name() string {
return TargetTypeAmazonLinux2023.String()
}
func (a *amazonlinux2023) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAmazonLinuxPackagesURLs(a, kr)
}
func (a *amazonlinux2023) repos() []string {
return []string{
"latest",
}
}
func (a *amazonlinux2023) baseUrl() string {
return "https://cdn.amazonlinux.com/al2023/core/mirrors"
}
func (a *amazonlinux2023) ext() string {
return "gz"
}
func (a *amazonlinux2) Name() string { func (a *amazonlinux2) Name() string {
return TargetTypeAmazonLinux2.String() return TargetTypeAmazonLinux2.String()
} }
func (a *amazonlinux2) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (a *amazonlinux2) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAmazonLinuxPackagesURLs(a, kr) return fetchAmazonLinuxPackagesURLs(a, kr)
} }
func (a *amazonlinux2) GCCVersion(kr kernelrelease.KernelRelease) semver.Version {
// 5.10 amazonlinux2 kernels need gcc 10
if kr.Major == 5 && kr.Minor == 10 {
return semver.Version{Major: 10}
}
return semver.Version{}
}
func (a *amazonlinux2) repos() []string { func (a *amazonlinux2) repos() []string {
return []string{ return []string{
"core/2.0", "core/2.0",
@ -210,13 +156,16 @@ func buildMirror(a amazonBuilder, r string, kv kernelrelease.KernelRelease) (str
switch a.(type) { switch a.(type) {
case *amazonlinux: case *amazonlinux:
baseURL = fmt.Sprintf("%s/%s", a.baseUrl(), r) baseURL = fmt.Sprintf("%s/%s", a.baseUrl(), r)
case *amazonlinux2, *amazonlinux2022, *amazonlinux2023: case *amazonlinux2:
baseURL = fmt.Sprintf("%s/%s/%s", a.baseUrl(), r, kv.Architecture.ToNonDeb())
case *amazonlinux2022:
baseURL = fmt.Sprintf("%s/%s/%s", a.baseUrl(), r, kv.Architecture.ToNonDeb()) baseURL = fmt.Sprintf("%s/%s/%s", a.baseUrl(), r, kv.Architecture.ToNonDeb())
default: default:
return "", fmt.Errorf("unsupported target") return "", fmt.Errorf("unsupported target")
} }
mirror := fmt.Sprintf("%s/%s", baseURL, "mirror.list") mirror := fmt.Sprintf("%s/%s", baseURL, "mirror.list")
logger.WithField("url", mirror).WithField("version", r).Debug("looking for repo...")
return mirror, nil return mirror, nil
} }
@ -237,92 +186,92 @@ func fetchAmazonLinuxPackagesURLs(a amazonBuilder, kv kernelrelease.KernelReleas
visited := make(map[string]struct{}) visited := make(map[string]struct{})
for _, v := range a.repos() { for _, v := range a.repos() {
err := func() error { mirror, err := buildMirror(a, v, kv)
mirror, err := buildMirror(a, v, kv)
if err != nil {
return err
}
// Obtain the repo URL by getting mirror URL content
mirrorRes, err := http.Get(mirror)
if err != nil {
return err
}
defer mirrorRes.Body.Close()
var repo string
scanner := bufio.NewScanner(mirrorRes.Body)
if scanner.Scan() {
repo = scanner.Text()
}
if repo == "" {
return fmt.Errorf("repository not found")
}
repo = strings.ReplaceAll(strings.TrimSuffix(repo, "\n"), "$basearch", kv.Architecture.ToNonDeb())
repo = strings.TrimSuffix(repo, "/")
repoDatabaseURL := fmt.Sprintf("%s/repodata/primary.sqlite.%s", repo, a.ext())
if _, ok := visited[repoDatabaseURL]; ok {
return nil
}
// Download the repo database
repoRes, err := http.Get(repoDatabaseURL)
if err != nil {
return err
}
defer repoRes.Body.Close()
visited[repoDatabaseURL] = struct{}{}
unzip, err := unzipFuncFromBuilder(a)
if err != nil {
return err
}
dbBytes, err := unzip(repoRes.Body)
if err != nil {
return err
}
// Create the temporary database file
dbFile, err := os.CreateTemp(os.TempDir(), fmt.Sprintf("%s-*.sqlite", a.Name()))
if err != nil {
return err
}
defer os.Remove(dbFile.Name())
if _, err := dbFile.Write(dbBytes); err != nil {
return err
}
// Open the database
db, err := sql.Open("sqlite", dbFile.Name())
if err != nil {
return err
}
defer db.Close()
// Query the database
rel := strings.TrimPrefix(strings.TrimSuffix(kv.FullExtraversion, fmt.Sprintf(".%s", kv.Architecture.ToNonDeb())), "-")
q := fmt.Sprintf("SELECT location_href FROM packages WHERE name LIKE 'kernel-devel%%' AND version='%s' AND release='%s'", kv.Fullversion, rel)
stmt, err := db.Prepare(q)
if err != nil {
return err
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var href string
err = rows.Scan(&href)
if err != nil {
log.Fatal(err)
}
urls = append(urls, fmt.Sprintf("%s/%s", repo, href))
}
return dbFile.Close()
}()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Obtain the repo URL by getting mirror URL content
mirrorRes, err := http.Get(mirror)
if err != nil {
return nil, err
}
defer mirrorRes.Body.Close()
var repo string
scanner := bufio.NewScanner(mirrorRes.Body)
if scanner.Scan() {
repo = scanner.Text()
}
if repo == "" {
return nil, fmt.Errorf("repository not found")
}
repo = strings.ReplaceAll(strings.TrimSuffix(repo, "\n"), "$basearch", kv.Architecture.ToNonDeb())
repo = strings.TrimSuffix(repo, "/")
repoDatabaseURL := fmt.Sprintf("%s/repodata/primary.sqlite.%s", repo, a.ext())
if _, ok := visited[repoDatabaseURL]; ok {
continue
}
// Download the repo database
repoRes, err := http.Get(repoDatabaseURL)
logger.WithField("url", repoDatabaseURL).Debug("downloading...")
if err != nil {
return nil, err
}
defer repoRes.Body.Close()
visited[repoDatabaseURL] = struct{}{}
unzip, err := unzipFuncFromBuilder(a)
if err != nil {
return nil, err
}
dbBytes, err := unzip(repoRes.Body)
if err != nil {
return nil, err
}
// Create the temporary database file
dbFile, err := ioutil.TempFile(os.TempDir(), fmt.Sprintf("%s-*.sqlite", a.Name()))
if err != nil {
return nil, err
}
defer os.Remove(dbFile.Name())
if _, err := dbFile.Write(dbBytes); err != nil {
return nil, err
}
// Open the database
db, err := sql.Open("sqlite", dbFile.Name())
if err != nil {
return nil, err
}
defer db.Close()
logger.WithField("db", dbFile.Name()).Debug("connecting to database...")
// Query the database
rel := strings.TrimPrefix(strings.TrimSuffix(kv.FullExtraversion, fmt.Sprintf(".%s", kv.Architecture.ToNonDeb())), "-")
q := fmt.Sprintf("SELECT location_href FROM packages WHERE name LIKE 'kernel-devel%%' AND version='%s' AND release='%s'", kv.Fullversion, rel)
stmt, err := db.Prepare(q)
if err != nil {
return nil, err
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var href string
err = rows.Scan(&href)
if err != nil {
log.Fatal(err)
}
urls = append(urls, fmt.Sprintf("%s/%s", repo, href))
}
if err := dbFile.Close(); err != nil {
return nil, err
}
// Found, do not continue // Found, do not continue
if len(urls) > 0 { if len(urls) > 0 {
break break

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/archlinux_kernel.sh
var archlinuxKernelTemplate string
//go:embed templates/archlinux.sh //go:embed templates/archlinux.sh
var archlinuxTemplate string var archlinuxTemplate string
@ -32,7 +15,7 @@ var archlinuxTemplate string
const TargetTypeArchlinux Type = "arch" const TargetTypeArchlinux Type = "arch"
func init() { func init() {
byTarget[TargetTypeArchlinux] = &archlinux{} BuilderByTarget[TargetTypeArchlinux] = &archlinux{}
} }
// archlinux is a driverkit target. // archlinux is a driverkit target.
@ -40,6 +23,7 @@ type archlinux struct {
} }
type archlinuxTemplateData struct { type archlinuxTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -47,19 +31,11 @@ func (c *archlinux) Name() string {
return TargetTypeArchlinux.String() return TargetTypeArchlinux.String()
} }
func (c *archlinux) TemplateKernelUrlsScript() string { return archlinuxKernelTemplate }
func (c *archlinux) TemplateScript() string { func (c *archlinux) TemplateScript() string {
return archlinuxTemplate return archlinuxTemplate
} }
func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (c *archlinux) URLs(cfg Config, kr kernelrelease.KernelRelease) ([]string, error) {
// uname -r returns "6.8.1-arch1-1" but headers URL is "6.8.1.arch1-1"
// Also, for 0-patch releases, like: "6.8.0-arch1-1", headers url is "6.8.arch1-1"
kr.FullExtraversion = strings.Replace(kr.FullExtraversion, "-arch", ".arch", 1)
if kr.Patch == 0 {
kr.Fullversion = strings.TrimSuffix(kr.Fullversion, ".0")
}
urls := []string{} urls := []string{}
possibleCompressionSuffixes := []string{ possibleCompressionSuffixes := []string{
@ -75,10 +51,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append( urls = append(
urls, urls,
fmt.Sprintf( fmt.Sprintf(
"%s/linux-headers-%s-%s-%s.pkg.tar.%s", "%s/linux-headers-%s%s-%s.pkg.tar.%s",
baseURL, baseURL,
kr.String(), kr.Fullversion,
kr.KernelVersion, kr.FullExtraversion,
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
compressionAlgo, compressionAlgo,
), ),
@ -90,10 +66,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append( urls = append(
urls, urls,
fmt.Sprintf( fmt.Sprintf(
"%s/linux-hardened-headers-%s-%s-%s.pkg.tar.%s", "%s/linux-hardened-headers-%s%s-%s.pkg.tar.%s",
baseURL, baseURL,
kr.String(), kr.Fullversion,
kr.KernelVersion, kr.FullExtraversion,
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
compressionAlgo, compressionAlgo,
), ),
@ -105,10 +81,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append( urls = append(
urls, urls,
fmt.Sprintf( fmt.Sprintf(
"%s/linux-zen-headers-%s-%s-%s.pkg.tar.%s", "%s/linux-zen-headers-%s%s-%s.pkg.tar.%s",
baseURL, baseURL,
kr.String(), kr.Fullversion,
kr.KernelVersion, kr.FullExtraversion,
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
compressionAlgo, compressionAlgo,
), ),
@ -120,10 +96,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append( urls = append(
urls, urls,
fmt.Sprintf( fmt.Sprintf(
"%s/linux-lts-headers-%s-%s-%s.pkg.tar.%s", "%s/linux-lts-headers-%s%s-%s.pkg.tar.%s",
baseURL, baseURL,
kr.String(), kr.Fullversion,
kr.KernelVersion, kr.FullExtraversion,
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
compressionAlgo, compressionAlgo,
), ),
@ -131,15 +107,15 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
} }
} }
} else if kr.Architecture.ToNonDeb() == "aarch64" { } else if kr.Architecture.ToNonDeb() == "aarch64" {
baseURL := "https://alaa.ad24.cz/packages/l/linux-aarch64-headers/" baseURL := "http://tardis.tiny-vps.com/aarm/packages/l/linux-aarch64-headers/"
for _, compressionAlgo := range possibleCompressionSuffixes { for _, compressionAlgo := range possibleCompressionSuffixes {
urls = append( urls = append(
urls, urls,
fmt.Sprintf( fmt.Sprintf(
"%s/linux-aarch64-headers-%s-%s-%s.pkg.tar.%s", "%s/linux-aarch64-headers-%s%s-%s.pkg.tar.%s",
baseURL, baseURL,
kr.String(), kr.Fullversion,
kr.KernelVersion, kr.FullExtraversion,
kr.Architecture.ToNonDeb(), kr.Architecture.ToNonDeb(),
compressionAlgo, compressionAlgo,
), ),
@ -150,8 +126,9 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return urls, nil return urls, nil
} }
func (c *archlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c *archlinux) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return archlinuxTemplateData{ return archlinuxTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
} }
} }

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
@ -22,7 +8,7 @@ import (
const TargetTypeBottlerocket Type = "bottlerocket" const TargetTypeBottlerocket Type = "bottlerocket"
func init() { func init() {
byTarget[TargetTypeBottlerocket] = &bottlerocket{ BuilderByTarget[TargetTypeBottlerocket] = &bottlerocket{
vanilla{}, vanilla{},
} }
} }
@ -35,8 +21,9 @@ func (b *bottlerocket) Name() string {
return TargetTypeBottlerocket.String() return TargetTypeBottlerocket.String()
} }
func (b *bottlerocket) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} { func (b *bottlerocket) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return vanillaTemplateData{ return vanillaTemplateData{
commonTemplateData: c.toTemplateData(b, kr),
KernelDownloadURL: urls[0], KernelDownloadURL: urls[0],
KernelLocalVersion: kr.FullExtraversion, KernelLocalVersion: kr.FullExtraversion,
} }

View File

@ -1,63 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
"context"
"fmt" "fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"strings"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
"oras.land/oras-go/v2/registry/remote/auth"
) )
var defaultImageTag = "latest" // This is overwritten when using the Makefile to build
// Build contains the info about the on-going build. // Build contains the info about the on-going build.
type Build struct { type Build struct {
TargetType Type TargetType Type
KernelConfigData string KernelConfigData string
KernelRelease string KernelRelease string
KernelVersion string KernelVersion string
DriverVersion string DriverVersion string
Architecture string Architecture string
ModuleFilePath string ModuleFilePath string
ProbeFilePath string ProbeFilePath string
ModuleDriverName string ModuleDriverName string
ModuleDeviceName string ModuleDeviceName string
BuilderImage string BuilderImage string
BuilderRepos []string BuilderRepos []string
ImagesListers []ImagesLister KernelUrls []string
KernelUrls []string GCCVersion string
GCCVersion string RepoOrg string
RepoOrg string RepoName string
RepoName string Images ImagesMap
Images ImagesMap
RegistryName string
RegistryUser string
RegistryPassword string
RegistryPlainHTTP bool
*output.Printer
} }
func (b *Build) KernelReleaseFromBuildConfig() kernelrelease.KernelRelease { func (b *Build) KernelReleaseFromBuildConfig() kernelrelease.KernelRelease {
kv := kernelrelease.FromString(b.KernelRelease) kv := kernelrelease.FromString(b.KernelRelease)
kv.Architecture = kernelrelease.Architecture(b.Architecture) kv.Architecture = kernelrelease.Architecture(b.Architecture)
kv.KernelVersion = b.KernelVersion
return kv return kv
} }
@ -73,41 +44,3 @@ func (b *Build) ToConfig() Config {
Build: b, Build: b,
} }
} }
// hasCustomBuilderImage return true if a custom builder image has been set by the user.
func (b *Build) hasCustomBuilderImage() bool {
if len(b.BuilderImage) > 0 {
customNames := strings.Split(b.BuilderImage, ":")
return customNames[0] != "auto"
}
return false
}
// builderImageTag returns the tag(latest, master or hash) to be used for the builder image.
func (b *Build) builderImageTag() string {
if len(b.BuilderImage) > 0 {
customNames := strings.Split(b.BuilderImage, ":")
// Updated image tag if "auto:tag" is passed
if len(customNames) > 1 {
return customNames[1]
}
}
return defaultImageTag
}
func (b *Build) ClientForRegistry(registry string) *auth.Client {
client := auth.DefaultClient
client.SetUserAgent("driverkit")
client.Credential = func(ctx context.Context, reg string) (auth.Credential, error) {
if b.RegistryName == registry {
return auth.Credential{
Username: b.RegistryUser,
Password: b.RegistryPassword,
}, nil
}
return auth.EmptyCredential, nil
}
return client
}

View File

@ -1,58 +1,35 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
"bytes" "bytes"
_ "embed"
"errors" "errors"
"fmt" "fmt"
"github.com/falcosecurity/falcoctl/pkg/output" "github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"log"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"strings" "strings"
"text/template" "text/template"
"github.com/blang/semver/v4" logger "github.com/sirupsen/logrus"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
// DriverDirectory is the directory the processor uses to store the driver. // DriverDirectory is the directory the processor uses to store the driver.
const ( const DriverDirectory = "/tmp/driver"
DriverDirectory = "/tmp/driver"
cmakeCmdFmt = `cmake -Wno-dev \
-DUSE_BUNDLED_DEPS=On \
-DCREATE_TEST_TARGETS=Off \
-DBUILD_LIBSCAP_GVISOR=Off \
-DBUILD_LIBSCAP_MODERN_BPF=Off \
-DENABLE_DRIVERS_TESTS=Off \
-DDRIVER_NAME=%s \
-DPROBE_NAME=%s \
-DBUILD_BPF=On \
-DDRIVER_VERSION=%s \
-DPROBE_VERSION=%s \
-DGIT_COMMIT=%s \
-DDRIVER_DEVICE_NAME=%s \
-DPROBE_DEVICE_NAME=%s \
.. && \
sed -i s/'DRIVER_COMMIT ""'/'DRIVER_COMMIT "%s"'/g driver/src/driver_config.h`
)
//go:embed templates/libs_download.sh // ModuleFileName is the standard file name for the kernel module.
var libsDownloadTemplate string const ModuleFileName = "module.ko"
// ProbeFileName is the standard file name for the eBPF probe.
const ProbeFileName = "probe.o"
// ModuleFullPath is the standard path for the kernel module. Builders must place the compiled module at this location.
var ModuleFullPath = path.Join(DriverDirectory, ModuleFileName)
// ProbeFullPath is the standard path for the eBPF probe. Builders must place the compiled probe at this location.
var ProbeFullPath = path.Join(DriverDirectory, "bpf", ProbeFileName)
var HeadersNotFoundErr = errors.New("kernel headers not found") var HeadersNotFoundErr = errors.New("kernel headers not found")
@ -64,92 +41,45 @@ type Config struct {
*Build *Build
} }
func (c Config) ToDriverFullPath() string {
return path.Join(DriverDirectory, "build", "driver", fmt.Sprintf("%s.ko", c.DriverName))
}
func (c Config) ToProbeFullPath() string {
return path.Join(DriverDirectory, "build", "driver", "bpf", "probe.o")
}
type commonTemplateData struct { type commonTemplateData struct {
DriverBuildDir string DriverBuildDir string
ModuleDriverName string ModuleDownloadURL string
ModuleFullPath string ModuleDriverName string
BuildModule bool ModuleFullPath string
BuildProbe bool BuildModule bool
GCCVersion string BuildProbe bool
CmakeCmd string GCCVersion string
} }
// Builder represents a builder capable of generating a script for a driverkit target. // Builder represents a builder capable of generating a script for a driverkit target.
type Builder interface { type Builder interface {
Name() string Name() string
TemplateKernelUrlsScript() string
TemplateScript() string TemplateScript() string
URLs(kr kernelrelease.KernelRelease) ([]string, error) URLs(c Config, kr kernelrelease.KernelRelease) ([]string, error)
KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} // error return type is managed TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} // error return type is managed
} }
// MinimumURLsBuilder is an optional interface implemented by builders // MinimumURLsBuilder is an optional interface
// to specify minimum number of requested headers urls // to specify minimum number of requested headers urls
type MinimumURLsBuilder interface { type MinimumURLsBuilder interface {
MinimumURLs() int MinimumURLs() int
} }
// TemplateDataSpecifier is an optional interface implemented by builders func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error) {
// to specify a custom template data instead of the default one. t := template.New(b.Name())
type TemplateDataSpecifier interface { parsed, err := t.Parse(b.TemplateScript())
TemplateData(c Config, kr kernelrelease.KernelRelease) interface{}
}
type libsDownloadTemplateData struct {
DriverBuildDir string
ModuleDownloadURL string
}
// LibsDownloadScript returns the script that downloads and configures libs repo at requested commit/tag
func LibsDownloadScript(c Config) (string, error) {
t := template.New("download-libs")
parsed, err := t.Parse(libsDownloadTemplate)
if err != nil { if err != nil {
return "", err return "", err
} }
td := libsDownloadTemplateData{
DriverBuildDir: DriverDirectory,
ModuleDownloadURL: fmt.Sprintf("%s/%s.tar.gz", c.DownloadBaseURL, c.DriverVersion),
}
buf := bytes.NewBuffer(nil)
err = parsed.Execute(buf, td)
if err != nil {
return "", err
}
return buf.String(), nil
}
// KernelDownloadScript returns the script that will download and extract kernel headers
func KernelDownloadScript(b Builder,
kernelurls []string,
kr kernelrelease.KernelRelease,
printer *output.Printer,
) (string, error) {
t := template.New("download-kernel")
parsed, err := t.Parse(b.TemplateKernelUrlsScript())
if err != nil {
return "", err
}
var urls []string
minimumURLs := 1 minimumURLs := 1
if bb, ok := b.(MinimumURLsBuilder); ok { if bb, ok := b.(MinimumURLsBuilder); ok {
minimumURLs = bb.MinimumURLs() minimumURLs = bb.MinimumURLs()
} }
if kernelurls == nil { var urls []string
urls, err = b.URLs(kr) if c.KernelUrls == nil {
urls, err = b.URLs(c, kr)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -157,10 +87,10 @@ func KernelDownloadScript(b Builder,
// Otherwise, it is up to the builder to return an error // Otherwise, it is up to the builder to return an error
if len(urls) > 0 { if len(urls) > 0 {
// Check (and filter) existing kernels before continuing // Check (and filter) existing kernels before continuing
urls, err = GetResolvingURLs(urls) urls, err = getResolvingURLs(urls)
} }
} else { } else {
urls, err = GetResolvingURLs(kernelurls) urls, err = getResolvingURLs(c.KernelUrls)
} }
if err != nil { if err != nil {
return "", err return "", err
@ -170,10 +100,7 @@ func KernelDownloadScript(b Builder,
return "", fmt.Errorf("not enough headers packages found; expected %d, found %d", minimumURLs, len(urls)) return "", fmt.Errorf("not enough headers packages found; expected %d, found %d", minimumURLs, len(urls))
} }
printer.Logger.Debug("kernel headers found", td := b.TemplateData(c, kr, urls)
printer.Logger.Args("urls", urls))
td := b.KernelTemplateData(kr, urls)
if tdErr, ok := td.(error); ok { if tdErr, ok := td.(error); ok {
return "", tdErr return "", tdErr
} }
@ -183,31 +110,6 @@ func KernelDownloadScript(b Builder,
if err != nil { if err != nil {
return "", err return "", err
} }
return buf.String(), nil
}
// Script retrieves the actually drivers building script
func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error) {
t := template.New(b.Name())
parsed, err := t.Parse(b.TemplateScript())
if err != nil {
return "", err
}
var td interface{}
if bb, ok := b.(TemplateDataSpecifier); ok {
td = bb.TemplateData(c, kr)
} else {
td = c.toTemplateData(b, kr)
}
buf := bytes.NewBuffer(nil)
err = parsed.Execute(buf, td)
if err != nil {
return "", err
}
return buf.String(), nil return buf.String(), nil
} }
@ -219,16 +121,8 @@ type GCCVersionRequestor interface {
func defaultGCC(kr kernelrelease.KernelRelease) semver.Version { func defaultGCC(kr kernelrelease.KernelRelease) semver.Version {
switch kr.Major { switch kr.Major {
case 6:
if kr.Minor >= 9 {
return semver.Version{Major: 14}
}
if kr.Minor >= 5 {
return semver.Version{Major: 13}
}
return semver.Version{Major: 12}
case 5: case 5:
if kr.Minor >= 15 { if kr.Minor >= 18 {
return semver.Version{Major: 12} return semver.Version{Major: 12}
} }
return semver.Version{Major: 11} return semver.Version{Major: 11}
@ -242,7 +136,7 @@ func defaultGCC(kr kernelrelease.KernelRelease) semver.Version {
case 2: case 2:
return semver.Version{Major: 4, Minor: 8} return semver.Version{Major: 4, Minor: 8}
default: default:
return semver.Version{Major: 14} return semver.Version{Major: 12}
} }
} }
@ -260,9 +154,7 @@ func mustParseTolerant(gccStr string) semver.Version {
// * otherwise, try to fix the best-match gcc version provided by any of the loaded images; // * otherwise, try to fix the best-match gcc version provided by any of the loaded images;
// see below for algorithm explanation // see below for algorithm explanation
func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) { func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) {
if !b.hasCustomBuilderImage() { b.LoadImages()
b.LoadImages()
}
if len(b.GCCVersion) > 0 { if len(b.GCCVersion) > 0 {
// If set from user, go on // If set from user, go on
@ -286,11 +178,6 @@ func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) {
targetGCC = defaultGCC(kr) targetGCC = defaultGCC(kr)
} }
if b.hasCustomBuilderImage() {
b.GCCVersion = targetGCC.String()
return
}
// Step 1: // Step 1:
// If we are able to either find a specific-target image, // If we are able to either find a specific-target image,
// or "any" target image that provide desired gcc, // or "any" target image that provide desired gcc,
@ -298,45 +185,50 @@ func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) {
image, ok := b.Images.findImage(b.TargetType, targetGCC) image, ok := b.Images.findImage(b.TargetType, targetGCC)
if ok { if ok {
b.GCCVersion = image.GCCVersion.String() b.GCCVersion = image.GCCVersion.String()
} else {
// Step 2:
// Build the list of "proposed" GCC versions,
// that is, the list of available gccs from images
// for each builder image
proposedGCCs := make([]semver.Version, 0)
for _, img := range b.Images {
proposedGCCs = append(proposedGCCs, img.GCCVersion)
b.Logger.Debug("proposed GCC",
b.Logger.Args("image", img.Name,
"targetGCC", targetGCC.String(),
"proposedGCC", img.GCCVersion.String()))
}
// Now, sort versions and fetch
// the nearest gcc, that is also < targetGCC
semver.Sort(proposedGCCs)
lastGCC := proposedGCCs[0]
for _, gcc := range proposedGCCs {
if gcc.GT(targetGCC) {
break
}
lastGCC = gcc
}
b.GCCVersion = lastGCC.String()
} }
b.Logger.Debug("found GCC",
b.Logger.Args("targetGCC", targetGCC.String(), "version", b.GCCVersion))
}
type BuilderImageNetworkMode interface { // Step 2:
// sets the network mode of the builder image, allows individual builders to override // Build the list of "proposed" GCC versions,
BuilderImageNetMode() string // that is, the list of available gccs from images
// for each builder image
proposedGCCs := make([]semver.Version, 0)
for _, img := range b.Images {
proposedGCCs = append(proposedGCCs, img.GCCVersion)
logger.WithField("image", img.Name).
WithField("targetGCC", targetGCC.String()).
Debug("proposedGCC=", img.GCCVersion.String())
}
// Now, sort versions and fetch
// the nearest gcc, that is also < targetGCC
semver.Sort(proposedGCCs)
lastGCC := proposedGCCs[0]
for _, gcc := range proposedGCCs {
if gcc.GT(targetGCC) {
break
}
lastGCC = gcc
}
b.GCCVersion = lastGCC.String()
logger.WithField("targetGCC", targetGCC.String()).
Debug("foundGCC=", b.GCCVersion)
} }
func (b *Build) GetBuilderImage() string { func (b *Build) GetBuilderImage() string {
if b.hasCustomBuilderImage() { imageTag := "latest"
// BuilderImage MUST have requested GCC installed inside if len(b.BuilderImage) > 0 {
return b.BuilderImage customNames := strings.Split(b.BuilderImage, ":")
if customNames[0] != "auto" {
// BuilderImage MUST have requested GCC installed inside
return b.BuilderImage
}
// Updated image tag if "auto:tag" is passed
if len(customNames) > 1 {
imageTag = customNames[1]
} else {
imageTag = "latest"
}
} }
// NOTE: here below we are already sure that we are going // NOTE: here below we are already sure that we are going
@ -344,72 +236,44 @@ func (b *Build) GetBuilderImage() string {
// has already set an existent gcc version // has already set an existent gcc version
// (ie: one provided by an image) for us // (ie: one provided by an image) for us
image, _ := b.Images.findImage(b.TargetType, mustParseTolerant(b.GCCVersion)) image, _ := b.Images.findImage(b.TargetType, mustParseTolerant(b.GCCVersion))
return image.Name return image.Name + ":" + imageTag
} }
// Factory returns a builder for the given target. // Factory returns a builder for the given target.
func Factory(target Type) (Builder, error) { func Factory(target Type) (Builder, error) {
// Workaround for "local" target (that is not exposed to users, b, ok := BuilderByTarget[target]
// nor registered in byTarget map)".
if target.String() == "local" {
return &LocalBuilder{}, nil
}
// Driverkit builder is named "ubuntu"; there is no ubuntu-foo
if strings.HasPrefix(target.String(), "ubuntu") {
target = Type("ubuntu")
}
b, ok := byTarget[target]
if !ok { if !ok {
return nil, fmt.Errorf("no builder found for target: %s", target) return nil, fmt.Errorf("no builder found for target: %s", target)
} }
return b, nil return b, nil
} }
// Targets returns the list of all the supported targets.
func Targets() []string {
res := []string{}
for k := range byTarget {
res = append(res, k.String())
}
return res
}
func (c Config) toTemplateData(b Builder, kr kernelrelease.KernelRelease) commonTemplateData { func (c Config) toTemplateData(b Builder, kr kernelrelease.KernelRelease) commonTemplateData {
c.setGCCVersion(b, kr) c.setGCCVersion(b, kr)
return commonTemplateData{ return commonTemplateData{
DriverBuildDir: DriverDirectory, DriverBuildDir: DriverDirectory,
ModuleDriverName: c.DriverName, ModuleDownloadURL: fmt.Sprintf("%s/%s.tar.gz", c.DownloadBaseURL, c.DriverVersion),
ModuleFullPath: c.ToDriverFullPath(), ModuleDriverName: c.DriverName,
BuildModule: len(c.ModuleFilePath) > 0, ModuleFullPath: ModuleFullPath,
BuildProbe: len(c.ProbeFilePath) > 0, BuildModule: len(c.ModuleFilePath) > 0,
GCCVersion: c.GCCVersion, BuildProbe: len(c.ProbeFilePath) > 0,
CmakeCmd: fmt.Sprintf(cmakeCmdFmt, GCCVersion: c.GCCVersion,
c.DriverName,
c.DriverName,
c.DriverVersion,
c.DriverVersion,
c.DriverVersion,
c.DeviceName,
c.DeviceName,
c.DriverVersion),
} }
} }
func resolveURLReference(u string) string { func resolveURLReference(u string) string {
uu, err := url.Parse(u) uu, err := url.Parse(u)
if err != nil { if err != nil {
panic(err) log.Fatal(err)
} }
base, err := url.Parse(uu.Host) base, err := url.Parse(uu.Host)
if err != nil { if err != nil {
panic(err) log.Fatal(err)
} }
return base.ResolveReference(uu).String() return base.ResolveReference(uu).String()
} }
func GetResolvingURLs(urls []string) ([]string, error) { func getResolvingURLs(urls []string) ([]string, error) {
var results []string var results []string
for _, u := range urls { for _, u := range urls {
// in case url has some relative paths // in case url has some relative paths
@ -424,6 +288,7 @@ func GetResolvingURLs(urls []string) ([]string, error) {
} }
if res.StatusCode == http.StatusOK { if res.StatusCode == http.StatusOK {
results = append(results, u) results = append(results, u)
logger.WithField("url", u).Debug("kernel header url found")
} }
} }
if len(results) == 0 { if len(results) == 0 {

View File

@ -1,24 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
"testing" "github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
"testing"
) )
var gccTests = []struct { var gccTests = []struct {
@ -54,7 +39,7 @@ var gccTests = []struct {
Architecture: kernelrelease.ArchitectureAmd64, Architecture: kernelrelease.ArchitectureAmd64,
}, },
expectedGCC: semver.Version{ expectedGCC: semver.Version{
Major: 12, Major: 11,
}, },
}, },
{ {

View File

@ -1,30 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/centos_kernel.sh
var centosKernelTemplate string
//go:embed templates/centos.sh //go:embed templates/centos.sh
var centosTemplate string var centosTemplate string
@ -32,7 +14,7 @@ var centosTemplate string
const TargetTypeCentos Type = "centos" const TargetTypeCentos Type = "centos"
func init() { func init() {
byTarget[TargetTypeCentos] = &centos{} BuilderByTarget[TargetTypeCentos] = &centos{}
} }
// centos is a driverkit target. // centos is a driverkit target.
@ -40,6 +22,7 @@ type centos struct {
} }
type centosTemplateData struct { type centosTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -47,13 +30,11 @@ func (c *centos) Name() string {
return TargetTypeCentos.String() return TargetTypeCentos.String()
} }
func (c *centos) TemplateKernelUrlsScript() string { return centosKernelTemplate }
func (c *centos) TemplateScript() string { func (c *centos) TemplateScript() string {
return centosTemplate return centosTemplate
} }
func (c *centos) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (c *centos) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
vaultReleases := []string{ vaultReleases := []string{
"6.0/os", "6.0/os",
"6.0/updates", "6.0/updates",
@ -180,17 +161,14 @@ func (c *centos) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return urls, nil return urls, nil
} }
func (c *centos) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c *centos) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return centosTemplateData{ return centosTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
} }
} }
func (c *centos) GCCVersion(kr kernelrelease.KernelRelease) semver.Version { func (c *centos) GCCVersion(kr kernelrelease.KernelRelease) semver.Version {
// 4.18+ centos 8 kernels need gcc 9
if kr.Major == 4 && kr.Minor >= 18 {
return semver.Version{Major: 9}
}
// 3.10.X kernels need 4.8.5 gcc version; see: // 3.10.X kernels need 4.8.5 gcc version; see:
// https://github.com/falcosecurity/driverkit/issues/236 // https://github.com/falcosecurity/driverkit/issues/236
if kr.Major == 3 && kr.Minor == 10 { if kr.Major == 3 && kr.Minor == 10 {

View File

@ -1,34 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"io" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/debian_kernel.sh
var debianKernelTemplate string
//go:embed templates/debian.sh //go:embed templates/debian.sh
var debianTemplate string var debianTemplate string
@ -42,10 +23,11 @@ const TargetTypeDebian Type = "debian"
const debianRequiredURLs = 3 const debianRequiredURLs = 3
func init() { func init() {
byTarget[TargetTypeDebian] = &debian{} BuilderByTarget[TargetTypeDebian] = &debian{}
} }
type debianTemplateData struct { type debianTemplateData struct {
commonTemplateData
KernelDownloadURLS []string KernelDownloadURLS []string
KernelLocalVersion string KernelLocalVersion string
KernelHeadersPattern string KernelHeadersPattern string
@ -59,27 +41,24 @@ func (v *debian) Name() string {
return TargetTypeDebian.String() return TargetTypeDebian.String()
} }
func (v *debian) TemplateKernelUrlsScript() string { return debianKernelTemplate }
func (v *debian) TemplateScript() string { func (v *debian) TemplateScript() string {
return debianTemplate return debianTemplate
} }
func (v *debian) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (v *debian) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchDebianKernelURLs(kr) return fetchDebianKernelURLs(kr)
} }
func (v *debian) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} { func (v *debian) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
var KernelHeadersPattern string var KernelHeadersPattern string
if strings.HasSuffix(kr.Extraversion, "pve") { if strings.HasSuffix(kr.Extraversion, "pve") {
KernelHeadersPattern = "linux-headers-*pve" KernelHeadersPattern = "linux-headers-*pve"
} else if strings.Contains(kr.FullExtraversion, "rpi") {
KernelHeadersPattern = "linux-headers-*-rpi-v*"
} else { } else {
KernelHeadersPattern = "linux-headers-*" + kr.Architecture.String() KernelHeadersPattern = "linux-headers-*" + kr.Architecture.String()
} }
return debianTemplateData{ return debianTemplateData{
commonTemplateData: c.toTemplateData(v, kr),
KernelDownloadURLS: urls, KernelDownloadURLS: urls,
KernelLocalVersion: kr.FullExtraversion, KernelLocalVersion: kr.FullExtraversion,
KernelHeadersPattern: KernelHeadersPattern, KernelHeadersPattern: KernelHeadersPattern,
@ -135,18 +114,9 @@ func fetchDebianHeadersURLFromRelease(baseURL string, kr kernelrelease.KernelRel
matchExtraGroupCommon := "common" matchExtraGroupCommon := "common"
// match for kernel versions like 4.19.0-6-cloud-amd64 // match for kernel versions like 4.19.0-6-cloud-amd64
supportedExtraFlavors := []string{"cloud", "rt", "rpi"} if strings.Contains(kr.FullExtraversion, "-cloud") {
for _, supportedExtraFlavor := range supportedExtraFlavors { extraVersionPartial = strings.TrimSuffix(extraVersionPartial, "-cloud")
if strings.Contains(kr.FullExtraversion, "-"+supportedExtraFlavor) { matchExtraGroup = "cloud-" + matchExtraGroup
extraVersionPartial = strings.TrimSuffix(extraVersionPartial, "-"+supportedExtraFlavor)
matchExtraGroup = supportedExtraFlavor + "-" + matchExtraGroup
// rpi and rt have a different common package, named `common-{rt,rpi}`
if supportedExtraFlavor == "rt" || supportedExtraFlavor == "rpi" {
matchExtraGroupCommon += "-" + supportedExtraFlavor
}
break
}
} }
// download index // download index
@ -155,7 +125,7 @@ func fetchDebianHeadersURLFromRelease(baseURL string, kr kernelrelease.KernelRel
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/fedora_kernel.sh
var fedoraKernelTemplate string
//go:embed templates/fedora.sh //go:embed templates/fedora.sh
var fedoraTemplate string var fedoraTemplate string
@ -32,7 +15,7 @@ var fedoraTemplate string
const TargetTypeFedora Type = "fedora" const TargetTypeFedora Type = "fedora"
func init() { func init() {
byTarget[TargetTypeFedora] = &fedora{} BuilderByTarget[TargetTypeFedora] = &fedora{}
} }
// fedora is a driverkit target. // fedora is a driverkit target.
@ -40,6 +23,7 @@ type fedora struct {
} }
type fedoraTemplateData struct { type fedoraTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -47,13 +31,11 @@ func (c *fedora) Name() string {
return TargetTypeFedora.String() return TargetTypeFedora.String()
} }
func (c *fedora) TemplateKernelUrlsScript() string { return fedoraKernelTemplate }
func (c *fedora) TemplateScript() string { func (c *fedora) TemplateScript() string {
return fedoraTemplate return fedoraTemplate
} }
func (c *fedora) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (c *fedora) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
// fedora FullExtraversion looks like "-200.fc36.x86_64" // fedora FullExtraversion looks like "-200.fc36.x86_64"
// need to get the "fc36" out of the middle // need to get the "fc36" out of the middle
@ -85,21 +67,15 @@ func (c *fedora) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
kr.Fullversion, kr.Fullversion,
kr.FullExtraversion, kr.FullExtraversion,
), ),
fmt.Sprintf( // updates-archive
"https://fedoraproject-updates-archive.fedoraproject.org/fedora/%s/%s/kernel-devel-%s%s.rpm",
version,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
} }
// return out all possible urls // return out all possible urls
return urls, nil return urls, nil
} }
func (c *fedora) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c *fedora) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return fedoraTemplateData{ return fedoraTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
} }
} }

View File

@ -1,33 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"github.com/blang/semver/v4"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/flatcar_kernel.sh
var flatcarKernelTemplate string
//go:embed templates/flatcar.sh //go:embed templates/flatcar.sh
var flatcarTemplate string var flatcarTemplate string
@ -35,10 +17,11 @@ var flatcarTemplate string
const TargetTypeFlatcar Type = "flatcar" const TargetTypeFlatcar Type = "flatcar"
func init() { func init() {
byTarget[TargetTypeFlatcar] = &flatcar{} BuilderByTarget[TargetTypeFlatcar] = &flatcar{}
} }
type flatcarTemplateData struct { type flatcarTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -51,22 +34,18 @@ func (f *flatcar) Name() string {
return TargetTypeFlatcar.String() return TargetTypeFlatcar.String()
} }
func (f *flatcar) TemplateKernelUrlsScript() string {
return flatcarKernelTemplate
}
func (f *flatcar) TemplateScript() string { func (f *flatcar) TemplateScript() string {
return flatcarTemplate return flatcarTemplate
} }
func (f *flatcar) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (f *flatcar) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
if err := f.fillFlatcarInfos(kr); err != nil { if err := f.fillFlatcarInfos(kr); err != nil {
return nil, err return nil, err
} }
return fetchFlatcarKernelURLS(f.info.KernelVersion), nil return fetchFlatcarKernelURLS(f.info.KernelVersion), nil
} }
func (f *flatcar) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} { func (f *flatcar) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
// This happens when `kernelurls` option is passed, // This happens when `kernelurls` option is passed,
// therefore URLs() method is not called. // therefore URLs() method is not called.
if f.info == nil { if f.info == nil {
@ -76,7 +55,8 @@ func (f *flatcar) KernelTemplateData(kr kernelrelease.KernelRelease, urls []stri
} }
return flatcarTemplateData{ return flatcarTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: c.toTemplateData(f, kr),
KernelDownloadURL: urls[0],
} }
} }
@ -107,7 +87,7 @@ func fetchFlatcarKernelURLS(kernelVersion string) []string {
func fetchFlatcarMetadata(kr kernelrelease.KernelRelease) (*flatcarReleaseInfo, error) { func fetchFlatcarMetadata(kr kernelrelease.KernelRelease) (*flatcarReleaseInfo, error) {
flatcarInfo := flatcarReleaseInfo{} flatcarInfo := flatcarReleaseInfo{}
flatcarVersion := kr.Fullversion flatcarVersion := kr.Fullversion
packageIndexUrl, err := GetResolvingURLs(fetchFlatcarPackageListURL(kr.Architecture, flatcarVersion)) packageIndexUrl, err := getResolvingURLs(fetchFlatcarPackageListURL(kr.Architecture, flatcarVersion))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,66 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/falcosecurity/falcoctl/pkg/output" "github.com/blang/semver"
"os" "github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
logger "github.com/sirupsen/logrus"
"log"
"regexp" "regexp"
"strings" "strings"
"github.com/blang/semver/v4"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/falcosecurity/falcoctl/pkg/oci/repository"
"gopkg.in/yaml.v3"
) )
type YAMLImage struct {
Target string `yaml:"target"`
GCCVersions []string `yaml:"gcc_versions"` // we expect images to internally link eg: gcc5 to gcc5.0.0
Name string `yaml:"name"`
Arch string `yaml:"arch"`
Tag string `yaml:"tag"`
}
type YAMLImagesList struct {
Images []YAMLImage `yaml:"images"`
}
type Image struct { type Image struct {
Target Type Target Type
GCCVersion semver.Version // we expect images to internally link eg: gcc5 to gcc5.0.0 GCCVersion semver.Version // we expect images to internally link eg: gcc5 to gcc5.0.0
Name string Name string
} }
type ImagesLister interface {
LoadImages(printer *output.Printer) []Image
}
type FileImagesLister struct {
FilePath string
Arch string
Tag string
Target string
}
type RepoImagesLister struct {
*repository.Repository
}
type ImageKey string type ImageKey string
func (i *Image) toKey() ImageKey { func (i *Image) toKey() ImageKey {
@ -69,8 +27,6 @@ func (i *Image) toKey() ImageKey {
type ImagesMap map[ImageKey]Image type ImagesMap map[ImageKey]Image
var tagReg *regexp.Regexp
func (im ImagesMap) findImage(target Type, gccVers semver.Version) (Image, bool) { func (im ImagesMap) findImage(target Type, gccVers semver.Version) (Image, bool) {
targetImage := Image{ targetImage := Image{
Target: target, Target: target,
@ -89,175 +45,78 @@ func (im ImagesMap) findImage(target Type, gccVers semver.Version) (Image, bool)
return Image{}, false return Image{}, false
} }
func NewFileImagesLister(filePath string, build *Build) (*FileImagesLister, error) {
return &FileImagesLister{
FilePath: filePath,
Arch: kernelrelease.Architecture(build.Architecture).ToNonDeb(),
Tag: build.builderImageTag(),
Target: build.TargetType.String(),
}, nil
}
func (f *FileImagesLister) LoadImages(printer *output.Printer) []Image {
var (
res []Image
imageList YAMLImagesList
)
// loop over lines in file to print them
fileData, err := os.ReadFile(f.FilePath)
if err != nil {
printer.Logger.Warn("error opening builder repo file",
printer.Logger.Args("err", err.Error(), "filepath", f.FilePath))
return res
}
err = yaml.Unmarshal(fileData, &imageList)
if err != nil {
printer.Logger.Warn("error unmarshalling builder repo file",
printer.Logger.Args("err", err.Error(), "filepath", f.FilePath))
return res
}
for _, image := range imageList.Images {
// Values checks
if image.Arch != f.Arch {
printer.Logger.Debug("skipping wrong-arch image",
printer.Logger.Args("filepath", f.FilePath, "image", image))
continue
}
if image.Tag != f.Tag {
printer.Logger.Debug("skipping wrong-tag image",
printer.Logger.Args("filepath", f.FilePath, "image", image))
continue
}
if image.Target != "any" && image.Target != f.Target {
printer.Logger.Debug("skipping wrong-target image",
printer.Logger.Args("filepath", f.FilePath, "image", image))
continue
}
if image.Name == "" {
printer.Logger.Debug("skipping empty name image",
printer.Logger.Args("filepath", f.FilePath, "image", image))
continue
}
if len(image.GCCVersions) == 0 {
printer.Logger.Debug("expected at least 1 gcc version",
printer.Logger.Args("filepath", f.FilePath, "image", image))
continue
}
for _, gcc := range image.GCCVersions {
buildImage := Image{
Name: image.Name,
Target: Type(image.Target),
GCCVersion: mustParseTolerant(gcc),
}
res = append(res, buildImage)
}
}
return res
}
func NewRepoImagesLister(repo string, build *Build) (*RepoImagesLister, error) {
// Lazy inizialization
if tagReg == nil {
imageTag := build.builderImageTag()
// Create the proper regexes to load "any" and target-specific images for requested arch
arch := kernelrelease.Architecture(build.Architecture).ToNonDeb()
targetFmt := fmt.Sprintf("^(?P<target>%s|any)-%s(?P<gccVers>(_gcc[0-9]+.[0-9]+.[0-9]+)+)-%s$", build.TargetType.String(), arch, imageTag)
tagReg = regexp.MustCompile(targetFmt)
}
// Get the registry URL from repository.
registry, err := getRegistryFromRef(repo)
if err != nil {
return nil, err
}
repoOCI, err := repository.NewRepository(repo,
repository.WithPlainHTTP(build.RegistryPlainHTTP),
repository.WithClient(build.ClientForRegistry(registry)))
if err != nil {
return nil, err
}
return &RepoImagesLister{repoOCI}, nil
}
func (repo *RepoImagesLister) LoadImages(printer *output.Printer) []Image {
tags, err := repo.Tags(context.Background())
if err != nil {
printer.Logger.Warn("skipping repo",
printer.Logger.Args("repo", repo.Reference, "err", err.Error()))
return nil
}
var res []Image
for _, t := range tags {
img := fmt.Sprintf("%s:%s", repo.Reference, t)
match := tagReg.FindStringSubmatch(t)
if len(match) == 0 {
continue
}
var (
target string
gccVers []string
)
for i, name := range tagReg.SubexpNames() {
if i > 0 && i <= len(match) {
switch name {
case "gccVers":
gccVers = strings.Split(match[i], "_gcc")
gccVers = gccVers[1:] // remove initial whitespace
case "target":
target = match[i]
}
}
}
// Note: we store "any" target images as "any",
// instead of adding them to the target,
// because we always prefer specific target images,
// and we cannot guarantee here that any subsequent docker repos
// does not provide a target-specific image that offers same gcc version
for _, gccVer := range gccVers {
// If user set a fixed gcc version, only load images that provide it.
buildImage := Image{
GCCVersion: mustParseTolerant(gccVer),
Name: img,
Target: Type(target),
}
res = append(res, buildImage)
}
}
return res
}
func (b *Build) LoadImages() { func (b *Build) LoadImages() {
for _, imagesLister := range b.ImagesListers { cli, err := client.NewClientWithOpts(client.FromEnv)
for _, image := range imagesLister.LoadImages(b.Printer) { if err != nil {
// User forced a gcc version? Only load images matching the requested gcc version. log.Fatal(err)
if b.GCCVersion != "" && b.GCCVersion != image.GCCVersion.String() { }
continue
} // Create the proper regexes to load "any" and target-specific images for requested arch
// Skip if key already exists: we have a descending prio list of docker repos! arch := kernelrelease.Architecture(b.Architecture).ToNonDeb()
if _, ok := b.Images[image.toKey()]; !ok { regs := make([]*regexp.Regexp, 0)
b.Images[image.toKey()] = image targetFmt := fmt.Sprintf("driverkit-builder-%s-%s(?P<gccVers>(_gcc[0-9]+.[0-9]+.[0-9]+)+)$", b.TargetType.String(), arch)
regs = append(regs, regexp.MustCompile(targetFmt))
genericFmt := fmt.Sprintf("driverkit-builder-any-%s(?P<gccVers>(_gcc[0-9]+.[0-9]+.[0-9]+)+)$", arch)
regs = append(regs, regexp.MustCompile(genericFmt))
b.Images = make(ImagesMap)
for _, repo := range b.BuilderRepos {
imgs, err := cli.ImageSearch(context.Background(), repo, types.ImageSearchOptions{Limit: 100})
if err != nil {
logger.Warnf("Skipping repo %s: %s\n", repo, err.Error())
continue
}
for _, img := range imgs {
for regIdx, reg := range regs {
match := reg.FindStringSubmatch(img.Name)
if len(match) == 0 {
continue
}
var gccVers []string
for i, name := range reg.SubexpNames() {
if i > 0 && i <= len(match) {
switch name {
case "gccVers":
gccVers = strings.Split(match[i], "_gcc")
gccVers = gccVers[1:] // remove initial whitespace
}
}
}
if len(gccVers) == 0 {
logger.Debug("Malformed image name: ", img.Name, len(match))
continue
}
// Note: we store "any" target images as "any",
// instead of adding them to the target,
// because we always prefer specific target images,
// and we cannot guarantee here that any subsequent docker repos
// does not provide a target-specific image that offers same gcc version
for _, gccVer := range gccVers {
// If user set a fixed gcc version, only load images that provide it.
if b.GCCVersion != "" && b.GCCVersion != gccVer {
continue
}
buildImage := Image{
GCCVersion: mustParseTolerant(gccVer),
Name: img.Name,
}
if regIdx == 0 {
buildImage.Target = b.TargetType
} else {
buildImage.Target = Type("any")
}
// Skip if key already exists: we have a descending prio list of docker repos!
if _, ok := b.Images[buildImage.toKey()]; !ok {
b.Images[buildImage.toKey()] = buildImage
}
}
} }
} }
} }
if len(b.Images) == 0 { if len(b.Images) == 0 {
b.Printer.Logger.Fatal("Could not load any builder image. Leaving.") log.Fatal("Could not load any builder image. Leaving.")
} }
} }
// getRegistryFromRef extracts the registry from a ref string.
func getRegistryFromRef(ref string) (string, error) {
index := strings.Index(ref, "/")
if index <= 0 {
return "", fmt.Errorf("cannot extract registry name from ref %q", ref)
}
return ref[0:index], nil
}

View File

@ -1,311 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder
import (
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/pterm/pterm"
"io"
"net/http"
"os"
"testing"
"github.com/blang/semver/v4"
"github.com/docker/docker/testutil/registry"
"gotest.tools/assert"
)
var imagesTests = []struct {
yamlData string
jsonData string
expected []Image
}{
// Test that multiple gcc versions are correctly mapped to multiple images
{
yamlData: `
images:
- name: foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest
target: any
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- 6.0.0
- 5.0.0
- 4.9.0
- 4.8.0
`,
jsonData: `
{
"name": "foo/test",
"tags": [
"any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest"
]
}
`,
expected: []Image{
{
Target: "any",
GCCVersion: semver.MustParse("8.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest",
},
{
Target: "any",
GCCVersion: semver.MustParse("6.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest",
},
{
Target: "any",
GCCVersion: semver.MustParse("5.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest",
},
{
Target: "any",
GCCVersion: semver.MustParse("4.9.0"),
Name: "foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest",
},
{
Target: "any",
GCCVersion: semver.MustParse("4.8.0"),
Name: "foo/test:any-x86_64_gcc8.0.0_gcc6.0.0_gcc5.0.0_gcc4.9.0_gcc4.8.0-latest",
},
},
},
// Test that arm64 is correctly skipped on amd64 images listing
{
yamlData: `
images:
- name: foo/test:any-x86_64_gcc8.0.0-latest
target: any
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- name: foo/test:any-aarch64_gcc8.0.0-latest
target: any
arch: aarch64
tag: latest
gcc_versions:
- 8.0.0
`,
jsonData: `
{
"name": "foo/test",
"tags": [
"any-x86_64_gcc8.0.0-latest",
"any-aarch64_gcc8.0.0-latest"
]
}
`,
expected: []Image{
{
Target: "any",
GCCVersion: semver.MustParse("8.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0-latest",
},
},
},
// Test empty gcc versions image is skipped
{
yamlData: `
images:
- name: foo/test:any-x86_64_gcc8.0.0-latest
target: any
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- name: bar/test:any-x86_64-latest
target: any
arch: x86_64
tag: latest
`,
jsonData: `
{
"name": "foo/test",
"tags": [
"any-x86_64_gcc8.0.0-latest",
"any-x86_64-latest"
]
}
`,
expected: []Image{
{
Target: "any",
GCCVersion: semver.MustParse("8.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0-latest",
},
},
},
// Test wrong target image is skipped
{
yamlData: `
images:
- name: foo/test:centos-x86_64_gcc8.0.0-latest
target: centos
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- name: foo/test:wrongtarget-x86_64_gcc6.0.0-latest
target: wrongtarget
arch: x86_64
tag: latest
gcc_versions:
- 6.0.0
`,
jsonData: `
{
"name": "foo/test",
"tags": [
"centos-x86_64_gcc8.0.0-latest",
"wrongtarget-x86_64_gcc8.0.0-latest"
]
}
`,
expected: []Image{
{
Target: "centos",
GCCVersion: semver.MustParse("8.0.0"),
Name: "foo/test:centos-x86_64_gcc8.0.0-latest",
},
},
},
// Test empty name image is skipped
{
yamlData: `
images:
- name: foo/test:any-x86_64_gcc8.0.0-latest
target: any
arch: x86_64
tag: latest
gcc_versions:
- 8.0.0
- target: any
arch: x86_64
tag: latest
gcc_versions:
- 6.0.0
`,
jsonData: "",
expected: []Image{
{
Target: "any",
GCCVersion: semver.MustParse("8.0.0"),
Name: "foo/test:any-x86_64_gcc8.0.0-latest",
},
},
},
// Test empty list returned for yaml/json with no images
{
yamlData: `
images:
`,
jsonData: `
{
"name": "foo/test",
"tags": [
]
}
`,
expected: nil,
},
// Test empty list returned for malformed yaml/json answer
{
yamlData: `
images:
* name: foo/test
target: any
arch: x86_64
gcc_versions:
* 8.0.0
`,
jsonData: "malformedresponse",
expected: nil,
},
}
func TestFileImagesLister(t *testing.T) {
printer := output.NewPrinter(pterm.LogLevelInfo, pterm.LogFormatterColorful, os.Stdout)
// setup images file
f, err := os.CreateTemp(t.TempDir(), "imagetest")
if err != nil {
t.Fatal(err)
}
defer os.Remove(f.Name())
lister, err := NewFileImagesLister(f.Name(), &Build{
TargetType: Type("centos"),
Architecture: "amd64",
BuilderImage: "auto:latest",
})
assert.NilError(t, err)
for _, test := range imagesTests {
if test.yamlData == "" {
t.Log("Skipping unsuitable test for FileImagesLister")
continue
}
err = f.Truncate(0)
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(test.yamlData)
if err != nil {
t.Fatal(err)
}
assert.DeepEqual(t, test.expected, lister.LoadImages(printer))
}
}
func TestRepoImagesLister(t *testing.T) {
printer := output.NewPrinter(pterm.LogLevelInfo, pterm.LogFormatterColorful, os.Stdout)
mock, err := registry.NewMock(t)
assert.NilError(t, err)
defer mock.Close()
lister, err := NewRepoImagesLister(mock.URL()+"/foo/test", &Build{
TargetType: Type("centos"),
Architecture: "amd64",
BuilderImage: "auto:latest",
RegistryPlainHTTP: true,
})
assert.NilError(t, err)
for _, test := range imagesTests {
if test.jsonData == "" {
t.Log("Skipping unsuitable test for RepoImagesLister")
continue
}
// Update expected names adding the mocked server URL as prefix
for idx, _ := range test.expected {
test.expected[idx].Name = mock.URL() + "/" + test.expected[idx].Name
}
mock.RegisterHandler("/v2/foo/test/tags/list", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(test.jsonData))
})
assert.DeepEqual(t, test.expected, lister.LoadImages(printer))
}
}

View File

@ -1,106 +0,0 @@
package builder
import (
_ "embed"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"path/filepath"
)
// NOTE: since this is only used by local build,
// it is not exposed in `target` array,
// so no init() function to register it is present.
//go:embed templates/local.sh
var localTemplate string
type LocalBuilder struct {
GccPath string
UseDKMS bool
SrcDir string
}
func (l *LocalBuilder) Name() string {
return "local"
}
func (l *LocalBuilder) TemplateKernelUrlsScript() string {
panic("cannot be called on local builder")
}
func (l *LocalBuilder) TemplateScript() string {
return localTemplate
}
func (l *LocalBuilder) URLs(_ kernelrelease.KernelRelease) ([]string, error) {
return nil, nil
}
func (l *LocalBuilder) MinimumURLs() int {
// We don't need any url
return 0
}
type localTemplateData struct {
commonTemplateData
UseDKMS bool
DownloadSrc bool
DriverVersion string
KernelRelease string
}
func (l *LocalBuilder) KernelTemplateData(_ kernelrelease.KernelRelease, _ []string) interface{} {
panic("cannot be called on local builder")
}
func (l *LocalBuilder) TemplateData(c Config, kr kernelrelease.KernelRelease) interface{} {
return localTemplateData{
commonTemplateData: commonTemplateData{
DriverBuildDir: l.GetDriverBuildDir(),
ModuleDriverName: c.DriverName,
ModuleFullPath: l.GetModuleFullPath(c, kr),
BuildModule: len(c.ModuleFilePath) > 0,
BuildProbe: len(c.ProbeFilePath) > 0,
GCCVersion: l.GccPath,
CmakeCmd: fmt.Sprintf(cmakeCmdFmt,
c.DriverName,
c.DriverName,
c.DriverVersion,
c.DriverVersion,
c.DriverVersion,
c.DeviceName,
c.DeviceName,
c.DriverVersion),
},
UseDKMS: l.UseDKMS,
DownloadSrc: len(l.SrcDir) == 0, // if no srcdir is provided, download src!
DriverVersion: c.DriverVersion,
KernelRelease: c.KernelRelease,
}
}
func (l *LocalBuilder) GetModuleFullPath(c Config, kr kernelrelease.KernelRelease) string {
if l.UseDKMS {
// When using dkms, we will use a GLOB to match the pattern; ModuleFullPath won't be used in the templated script anyway.
return fmt.Sprintf("/var/lib/dkms/%s/%s/%s/%s/module/%s.*", c.DriverName, c.DriverVersion, kr.String(), kr.Architecture.ToNonDeb(), c.DriverName)
}
if l.SrcDir != "" {
return filepath.Join(l.SrcDir, fmt.Sprintf("%s.ko", c.DriverName))
}
return c.ToDriverFullPath()
}
func (l *LocalBuilder) GetProbeFullPath(c Config) string {
if l.SrcDir != "" {
return filepath.Join(l.SrcDir, "bpf", "probe.o")
}
return c.ToProbeFullPath()
}
func (l *LocalBuilder) GetDriverBuildDir() string {
driverBuildDir := DriverDirectory
if l.SrcDir != "" {
driverBuildDir = l.SrcDir
}
return driverBuildDir
}

View File

@ -1,21 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
"github.com/blang/semver/v4" "github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
@ -23,7 +9,7 @@ import (
const TargetTypeMinikube Type = "minikube" const TargetTypeMinikube Type = "minikube"
func init() { func init() {
byTarget[TargetTypeMinikube] = &minikube{ BuilderByTarget[TargetTypeMinikube] = &minikube{
vanilla{}, vanilla{},
} }
} }
@ -36,8 +22,9 @@ func (m *minikube) Name() string {
return TargetTypeMinikube.String() return TargetTypeMinikube.String()
} }
func (m *minikube) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} { func (m *minikube) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return vanillaTemplateData{ return vanillaTemplateData{
commonTemplateData: c.toTemplateData(m, kr),
KernelDownloadURL: urls[0], KernelDownloadURL: urls[0],
KernelLocalVersion: kr.FullExtraversion, KernelLocalVersion: kr.FullExtraversion,
} }

View File

@ -1,17 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/opensuse_kernel.sh
var opensuseKernelTemplate string
//go:embed templates/opensuse.sh //go:embed templates/opensuse.sh
var opensuseTemplate string var opensuseTemplate string
@ -47,7 +30,7 @@ var baseURLs []string = []string{
} }
// all known releases - will need to expand as more are added // all known releases - will need to expand as more are added
var releases = []string{ var releases []string = []string{
// openSUSE leap // openSUSE leap
"43.2", "43.2",
"15.0", "15.0",
@ -64,7 +47,7 @@ var releases = []string{
} }
func init() { func init() {
byTarget[TargetTypeOpenSUSE] = &opensuse{} BuilderByTarget[TargetTypeOpenSUSE] = &opensuse{}
} }
// opensuse is a driverkit target. // opensuse is a driverkit target.
@ -72,6 +55,7 @@ type opensuse struct {
} }
type opensuseTemplateData struct { type opensuseTemplateData struct {
commonTemplateData
KernelDownloadURLs []string KernelDownloadURLs []string
} }
@ -83,15 +67,11 @@ func (o *opensuse) Name() string {
return TargetTypeOpenSUSE.String() return TargetTypeOpenSUSE.String()
} }
func (o *opensuse) TemplateKernelUrlsScript() string {
return opensuseKernelTemplate
}
func (o *opensuse) TemplateScript() string { func (o *opensuse) TemplateScript() string {
return opensuseTemplate return opensuseTemplate
} }
func (o *opensuse) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (o *opensuse) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
// SUSE requires 2 urls: a kernel-default-devel*{arch}.rpm and a kernel-devel*noarch.rpm // SUSE requires 2 urls: a kernel-default-devel*{arch}.rpm and a kernel-devel*noarch.rpm
kernelDefaultDevelPattern := fmt.Sprintf("kernel-default-devel-%s%s.rpm", kr.Fullversion, kr.FullExtraversion) kernelDefaultDevelPattern := fmt.Sprintf("kernel-default-devel-%s%s.rpm", kr.Fullversion, kr.FullExtraversion)
@ -105,7 +85,7 @@ func (o *opensuse) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
possibleURLs := buildURLs(kr, kernelDefaultDevelPattern, kernelDevelNoArchPattern) possibleURLs := buildURLs(kr, kernelDefaultDevelPattern, kernelDevelNoArchPattern)
// trim the list to only resolving URLs // trim the list to only resolving URLs
urls, err := GetResolvingURLs(possibleURLs) urls, err := getResolvingURLs(possibleURLs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -265,8 +245,9 @@ func validateURLs(urls []string, kernelDefaultDevelPattern string, kernelDevelNo
} }
func (o *opensuse) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (o *opensuse) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return opensuseTemplateData{ return opensuseTemplateData{
commonTemplateData: cfg.toTemplateData(o, kr),
KernelDownloadURLs: urls, KernelDownloadURLs: urls,
} }
} }

View File

@ -1,132 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder
import (
_ "embed"
"fmt"
"strings"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/oracle_kernel.sh
var oracleKernelTemplate string
//go:embed templates/oracle.sh
var oracleTemplate string
// TargetTypeoracle identifies the oracle target ("ol" is the ID from /etc/os-release that Oracle uses)
const TargetTypeoracle Type = "ol"
func init() {
byTarget[TargetTypeoracle] = &oracle{}
}
// oracle is a driverkit target.
type oracle struct {
}
type oracleTemplateData struct {
KernelDownloadURL string
}
func (c *oracle) Name() string {
return TargetTypeoracle.String()
}
func (c *oracle) TemplateKernelUrlsScript() string {
return oracleKernelTemplate
}
func (c *oracle) TemplateScript() string {
return oracleTemplate
}
func (c *oracle) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
// oracle FullExtraversion looks like "-2047.510.5.5.el7uek.x86_64"
// need to get the "el7uek" out of the middle
splitVersion := strings.Split(kr.FullExtraversion, ".")
oracleVersion := splitVersion[len(splitVersion)-2] // [ "-2047", "510", "5", "5", "el7uek","x86_64" ] want -2
// trim off the "el" and "uek" from oracleVersion
version := strings.Trim(strings.Trim(oracleVersion, "el"), "uek")
// sometimes Oracle 8 does "8_x" for version, only want the "8"
if strings.Contains(version, "_") {
version = strings.Split(version, "_")[0]
}
// list of possible UEK versions, which are used in the URL - ex: "UEKR3"
// may need to evolve over time if Oracle adds more
ueks := []string{"R3", "R4", "R5", "R6", "R7"}
// template the kernel info into all possible URL strings
urls := []string{
fmt.Sprintf( // latest (Oracle 7)
"http://yum.oracle.com/repo/OracleLinux/OL%s/latest/%s/getPackage/kernel-devel-%s%s.rpm",
version,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
fmt.Sprintf( // latest + baseos (Oracle 8 + 9)
"http://yum.oracle.com/repo/OracleLinux/OL%s/baseos/latest/%s/getPackage/kernel-devel-%s%s.rpm",
version,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
fmt.Sprintf( // appstream (Oracle 8 + 9)
"http://yum.oracle.com/repo/OracleLinux/OL%s/appstream/%s/getPackage/kernel-devel-%s%s.rpm",
version,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
fmt.Sprintf( // MODRHCK (Oracle 7)
"http://yum.oracle.com/repo/OracleLinux/OL%s/MODRHCK/%s/getPackage/kernel-devel-%s%s.rpm",
version,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
}
// add in all the UEK versions
for _, uekVers := range ueks {
urls = append(
urls,
fmt.Sprintf( // UEK versions URL
"http://yum.oracle.com/repo/OracleLinux/OL%s/UEK%s/%s/getPackage/kernel-uek-devel-%s%s.rpm",
version,
uekVers,
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
),
)
}
// return out all possible urls
return urls, nil
}
func (c *oracle) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return oracleTemplateData{
KernelDownloadURL: urls[0],
}
}

View File

@ -1,37 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
// TargetTypePhoton identifies the Photon target. // TargetTypePhoton identifies the Photon target.
const TargetTypePhoton Type = "photon" const TargetTypePhoton Type = "photon"
//go:embed templates/photonos_kernel.sh
var photonKernelTemplate string
//go:embed templates/photonos.sh //go:embed templates/photonos.sh
var photonTemplate string var photonTemplate string
func init() { func init() {
byTarget[TargetTypePhoton] = &photon{} BuilderByTarget[TargetTypePhoton] = &photon{}
} }
// photon is a driverkit target. // photon is a driverkit target.
@ -39,6 +21,7 @@ type photon struct {
} }
type photonTemplateData struct { type photonTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -46,21 +29,18 @@ func (p *photon) Name() string {
return TargetTypePhoton.String() return TargetTypePhoton.String()
} }
func (p *photon) TemplateKernelUrlsScript() string {
return photonKernelTemplate
}
func (p *photon) TemplateScript() string { func (p *photon) TemplateScript() string {
return photonTemplate return photonTemplate
} }
func (p *photon) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (p *photon) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchPhotonKernelURLS(kr), nil return fetchPhotonKernelURLS(kr), nil
} }
func (p *photon) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (p *photon) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return photonTemplateData{ return photonTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(p, kr),
KernelDownloadURL: urls[0],
} }
} }
@ -68,38 +48,43 @@ func fetchPhotonKernelURLS(kr kernelrelease.KernelRelease) []string {
photonReleases := []string{ photonReleases := []string{
"3.0", "3.0",
"4.0", "4.0",
"5.0",
} }
var urls []string urls := []string{}
for _, r := range photonReleases { for _, r := range photonReleases {
urls = append(urls, fmt.Sprintf( switch r {
"https://packages.vmware.com/photon/%s/photon_%s_%s/%s/linux-devel-%s%s.x86_64.rpm", case "3.0":
r, urls = append(urls, fmt.Sprintf(
r, "https://packages.vmware.com/photon/%s/photon_updates_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
kr.Architecture.ToNonDeb(), r,
kr.Architecture.ToNonDeb(), r,
kr.Fullversion, kr.Fullversion,
kr.FullExtraversion, kr.FullExtraversion,
)) ))
urls = append(urls, fmt.Sprintf( urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_release_%s_%s/%s/linux-devel-%s%s.x86_64.rpm", "https://packages.vmware.com/photon/%s/photon_release_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
r, r,
r, r,
kr.Architecture.ToNonDeb(), kr.Fullversion,
kr.Architecture.ToNonDeb(), kr.FullExtraversion,
kr.Fullversion, ))
kr.FullExtraversion,
)) case "4.0":
urls = append(urls, fmt.Sprintf( urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_updates_%s_%s/%s/linux-devel-%s%s.x86_64.rpm", "https://packages.vmware.com/photon/%s/photon_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
r, r,
r, r,
kr.Architecture.ToNonDeb(), kr.Fullversion,
kr.Architecture.ToNonDeb(), kr.FullExtraversion,
kr.Fullversion, ))
kr.FullExtraversion, urls = append(urls, fmt.Sprintf(
)) "https://packages.vmware.com/photon/%s/photon_release_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
r,
r,
kr.Fullversion,
kr.FullExtraversion,
))
}
} }
return urls return urls
} }

View File

@ -1,28 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/redhat_kernel.sh
var redhatKernelTemplate string
//go:embed templates/redhat.sh //go:embed templates/redhat.sh
var redhatTemplate string var redhatTemplate string
@ -34,10 +16,11 @@ type redhat struct {
} }
func init() { func init() {
byTarget[TargetTypeRedhat] = &redhat{} BuilderByTarget[TargetTypeRedhat] = &redhat{}
} }
type redhatTemplateData struct { type redhatTemplateData struct {
commonTemplateData
KernelPackage string KernelPackage string
} }
@ -45,15 +28,11 @@ func (v *redhat) Name() string {
return TargetTypeRedhat.String() return TargetTypeRedhat.String()
} }
func (v *redhat) TemplateKernelUrlsScript() string {
return redhatKernelTemplate
}
func (v *redhat) TemplateScript() string { func (v *redhat) TemplateScript() string {
return redhatTemplate return redhatTemplate
} }
func (v *redhat) URLs(_ kernelrelease.KernelRelease) ([]string, error) { func (v *redhat) URLs(_ Config, _ kernelrelease.KernelRelease) ([]string, error) {
return nil, nil return nil, nil
} }
@ -62,8 +41,9 @@ func (v *redhat) MinimumURLs() int {
return 0 return 0
} }
func (v *redhat) KernelTemplateData(kr kernelrelease.KernelRelease, _ []string) interface{} { func (v *redhat) TemplateData(c Config, kr kernelrelease.KernelRelease, _ []string) interface{} {
return redhatTemplateData{ return redhatTemplateData{
KernelPackage: kr.Fullversion + kr.FullExtraversion, commonTemplateData: c.toTemplateData(v, kr),
KernelPackage: kr.Fullversion + kr.FullExtraversion,
} }
} }

View File

@ -1,29 +1,11 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
import ( import (
_ "embed" _ "embed"
"fmt" "fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease" "github.com/falcosecurity/driverkit/pkg/kernelrelease"
) )
//go:embed templates/rocky_kernel.sh
var rockyKernelTemplate string
//go:embed templates/rocky.sh //go:embed templates/rocky.sh
var rockyTemplate string var rockyTemplate string
@ -31,10 +13,11 @@ var rockyTemplate string
const TargetTypeRocky Type = "rocky" const TargetTypeRocky Type = "rocky"
func init() { func init() {
byTarget[TargetTypeRocky] = &rocky{} BuilderByTarget[TargetTypeRocky] = &rocky{}
} }
type rockyTemplateData struct { type rockyTemplateData struct {
commonTemplateData
KernelDownloadURL string KernelDownloadURL string
} }
@ -46,21 +29,18 @@ func (c *rocky) Name() string {
return TargetTypeRocky.String() return TargetTypeRocky.String()
} }
func (c *rocky) TemplateKernelUrlsScript() string {
return rockyKernelTemplate
}
func (c *rocky) TemplateScript() string { func (c *rocky) TemplateScript() string {
return rockyTemplate return rockyTemplate
} }
func (c *rocky) URLs(kr kernelrelease.KernelRelease) ([]string, error) { func (c *rocky) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
return fetchRockyKernelURLS(kr), nil return fetchRockyKernelURLS(kr), nil
} }
func (c *rocky) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} { func (c *rocky) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return rockyTemplateData{ return rockyTemplateData{
KernelDownloadURL: urls[0], commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
} }
} }

View File

@ -1,75 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder
import (
_ "embed"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/sles_kernel.sh
var slesKernelTemplate string
//go:embed templates/sles.sh
var slesTemplate string
// TargetTypeSLES identifies the sles target.
const TargetTypeSLES Type = "sles"
// sles is a driverkit target.
type sles struct {
}
func init() {
byTarget[TargetTypeSLES] = &sles{}
}
type slesTemplateData struct {
KernelPackage string
}
func (v *sles) Name() string {
return TargetTypeSLES.String()
}
func (v *sles) TemplateKernelUrlsScript() string {
return slesKernelTemplate
}
func (v *sles) TemplateScript() string {
return slesTemplate
}
func (v *sles) URLs(_ kernelrelease.KernelRelease) ([]string, error) {
return nil, nil
}
func (v *sles) MinimumURLs() int {
// We don't need any url
return 0
}
func (v *sles) KernelTemplateData(kr kernelrelease.KernelRelease, _ []string) interface{} {
return slesTemplateData{
KernelPackage: kr.Fullversion + kr.FullExtraversion,
}
}
// sles requires docker to run with `--net=host` for builder images to work
// for more info, see the suse container connect README: https://github.com/SUSE/container-suseconnect
func (v *sles) BuilderImageNetMode() string {
return "host"
}

View File

@ -1,43 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder
import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
// TargetTypeTalos identifies the Talos target.
const TargetTypeTalos Type = "talos"
func init() {
byTarget[TargetTypeTalos] = &talos{
vanilla{},
}
}
type talos struct {
vanilla
}
func (b *talos) Name() string {
return TargetTypeTalos.String()
}
func (b *talos) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} {
return vanillaTemplateData{
KernelDownloadURL: urls[0],
KernelLocalVersion: kr.FullExtraversion,
}
}

View File

@ -1,21 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Licensed 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 builder package builder
// byTarget maps targets to their builder. // BuilderByTarget maps targets to their builder.
var byTarget = map[Type]Builder{} var BuilderByTarget = Targets{}
// Type is a type representing targets. // Type is a type representing targets.
type Type string type Type string
@ -23,3 +9,15 @@ type Type string
func (t Type) String() string { func (t Type) String() string {
return string(t) return string(t)
} }
// Targets is a type representing the list of the supported targets.
type Targets map[Type]Builder
// Targets returns the list of all the supported targets.
func (t Targets) Targets() []string {
res := []string{}
for k := range t {
res = append(res, k.String())
}
return res
}

View File

@ -1,41 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
cd {{ .DriverBuildDir }}
mkdir -p build && cd build
{{ .CmakeCmd }}
{{ if .BuildModule }}
# Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} driver
strip -g {{ .ModuleFullPath }}
# Print results
modinfo {{ .ModuleFullPath }}
{{ end }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
{{ end }}

View File

@ -1,35 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.rpm -SL {{ .KernelDownloadURL }}
rpm2cpio kernel-devel.rpm | cpio --extract --make-directories
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel

View File

@ -1,34 +1,31 @@
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail set -xeuo pipefail
cd {{ .DriverBuildDir }} rm -Rf {{ .DriverBuildDir }}
mkdir -p build && cd build mkdir {{ .DriverBuildDir }}
{{ .CmakeCmd }} rm -Rf /tmp/module-download
mkdir -p /tmp/module-download
curl --silent -SL {{ .ModuleDownloadURL }} | tar -xzf - -C /tmp/module-download
mv /tmp/module-download/*/driver/* {{ .DriverBuildDir }}
cp /driverkit/module-Makefile {{ .DriverBuildDir }}/Makefile
bash /driverkit/fill-driver-config.sh {{ .DriverBuildDir }}
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.rpm -SL {{ .KernelDownloadURL }}
rpm2cpio kernel-devel.rpm | cpio --extract --make-directories
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
{{ if .BuildModule }} {{ if .BuildModule }}
# Build the module # Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} driver cd {{ .DriverBuildDir }}
make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
strip -g {{ .ModuleFullPath }} strip -g {{ .ModuleFullPath }}
# Print results # Print results
modinfo {{ .ModuleFullPath }} modinfo {{ .ModuleFullPath }}
@ -36,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }} {{ if .BuildProbe }}
# Build the eBPF probe # Build the eBPF probe
make bpf cd {{ .DriverBuildDir }}/bpf
ls -l driver/bpf/probe.o make KERNELDIR=/tmp/kernel
ls -l probe.o
{{ end }} {{ end }}

View File

@ -1,35 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.rpm -SL {{ .KernelDownloadURL }}
rpm2cpio kernel-devel.rpm | cpio --extract --make-directories
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel

View File

@ -1,41 +1,42 @@
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail set -xeuo pipefail
cd {{ .DriverBuildDir }} rm -Rf {{ .DriverBuildDir }}
mkdir -p build && cd build mkdir {{ .DriverBuildDir }}
{{ .CmakeCmd }} rm -Rf /tmp/module-download
mkdir -p /tmp/module-download
curl --silent -SL {{ .ModuleDownloadURL }} | tar -xzf - -C /tmp/module-download
mv /tmp/module-download/*/driver/* {{ .DriverBuildDir }}
cp /driverkit/module-Makefile {{ .DriverBuildDir }}/Makefile
bash /driverkit/fill-driver-config.sh {{ .DriverBuildDir }}
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
{{ range $url := .KernelDownloadURLs }}
curl --silent -o kernel.rpm -SL {{ $url }}
rpm2cpio kernel.rpm | cpio --extract --make-directories
rm -rf kernel.rpm
{{ end }}
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
{{ if .BuildModule }} {{ if .BuildModule }}
# Build the module # Build the kernel module
make CC=/usr/bin/gcc-{{ .GCCVersion }} LD=/usr/bin/ld.bfd CROSS_COMPILE="" driver cd {{ .DriverBuildDir }}
strip -g {{ .ModuleFullPath }}
make KERNELDIR=/tmp/kernel CC=/usr/bin/gcc-{{ .GCCVersion }} LD=/usr/bin/ld.bfd CROSS_COMPILE=""
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
# Print results # Print results
modinfo {{ .ModuleFullPath }} modinfo {{ .ModuleFullPath }}
{{ end }} {{ end }}
{{ if .BuildProbe }} {{ if .BuildProbe }}
# Build the eBPF probe # Build the eBPF probe
make bpf cd {{ .DriverBuildDir }}/bpf
ls -l driver/bpf/probe.o make KERNELDIR=/tmp/kernel
ls -l probe.o
{{ end }} {{ end }}

View File

@ -1,38 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
{{ range $url := .KernelDownloadURLs }}
curl --silent -o kernel.rpm -SL {{ $url }}
rpm2cpio kernel.rpm | cpio --extract --make-directories
rm -rf kernel.rpm
{{ end }}
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel

View File

@ -1,34 +1,31 @@
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail set -xeuo pipefail
cd {{ .DriverBuildDir }} rm -Rf {{ .DriverBuildDir }}
mkdir -p build && cd build mkdir {{ .DriverBuildDir }}
{{ .CmakeCmd }} rm -Rf /tmp/module-download
mkdir -p /tmp/module-download
curl --silent -SL {{ .ModuleDownloadURL }} | tar -xzf - -C /tmp/module-download
mv /tmp/module-download/*/driver/* {{ .DriverBuildDir }}
cp /driverkit/module-Makefile {{ .DriverBuildDir }}/Makefile
bash /driverkit/fill-driver-config.sh {{ .DriverBuildDir }}
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.pkg.tar.xz -SL {{ .KernelDownloadURL }}
tar -xf kernel-devel.pkg.tar.xz
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/lib/modules/*/build/* /tmp/kernel
{{ if .BuildModule }} {{ if .BuildModule }}
# Build the module # Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} driver cd {{ .DriverBuildDir }}
make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
strip -g {{ .ModuleFullPath }} strip -g {{ .ModuleFullPath }}
# Print results # Print results
modinfo {{ .ModuleFullPath }} modinfo {{ .ModuleFullPath }}
@ -36,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }} {{ if .BuildProbe }}
# Build the eBPF probe # Build the eBPF probe
make bpf cd {{ .DriverBuildDir }}/bpf
ls -l driver/bpf/probe.o make KERNELDIR=/tmp/kernel
ls -l probe.o
{{ end }} {{ end }}

View File

@ -1,35 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.pkg.tar.xz -SL {{ .KernelDownloadURL }}
tar -xf kernel-devel.pkg.tar.xz
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/lib/modules/*/build/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel

View File

@ -1,35 +1,31 @@
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail set -xeuo pipefail
cd {{ .DriverBuildDir }} rm -Rf {{ .DriverBuildDir }}
sed -i 's/$(MAKE) -C $(KERNELDIR)/$(MAKE) KCFLAGS="-Wno-incompatible-pointer-types" -C $(KERNELDIR)/g' driver/Makefile.in mkdir {{ .DriverBuildDir }}
mkdir -p build && cd build rm -Rf /tmp/module-download
{{ .CmakeCmd }} mkdir -p /tmp/module-download
curl --silent -SL {{ .ModuleDownloadURL }} | tar -xzf - -C /tmp/module-download
mv /tmp/module-download/*/driver/* {{ .DriverBuildDir }}
cp /driverkit/module-Makefile {{ .DriverBuildDir }}/Makefile
bash /driverkit/fill-driver-config.sh {{ .DriverBuildDir }}
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.rpm -SL {{ .KernelDownloadURL }}
rpm2cpio kernel-devel.rpm | cpio --extract --make-directories
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
{{ if .BuildModule }} {{ if .BuildModule }}
# Build the module # Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} driver cd {{ .DriverBuildDir }}
make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
strip -g {{ .ModuleFullPath }} strip -g {{ .ModuleFullPath }}
# Print results # Print results
modinfo {{ .ModuleFullPath }} modinfo {{ .ModuleFullPath }}
@ -37,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }} {{ if .BuildProbe }}
# Build the eBPF probe # Build the eBPF probe
make bpf cd {{ .DriverBuildDir }}/bpf
ls -l driver/bpf/probe.o make KERNELDIR=/tmp/kernel
ls -l probe.o
{{ end }} {{ end }}

View File

@ -1,35 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed 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.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
set -xeuo pipefail
# Fetch the kernel
mkdir /tmp/kernel-download
cd /tmp/kernel-download
curl --silent -o kernel-devel.rpm -SL {{ .KernelDownloadURL }}
rpm2cpio kernel-devel.rpm | cpio --extract --make-directories
rm -Rf /tmp/kernel
mkdir -p /tmp/kernel
mv usr/src/kernels/*/* /tmp/kernel
# exit value
export KERNELDIR=/tmp/kernel

Some files were not shown because too many files have changed in this diff Show More