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
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/
dist/
vendor/
.idea/
driverkit
coverage.out
coverage.out

View File

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

View File

@ -1,35 +1,81 @@
# 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
kernelrelease: 4.19.91-26.al7.x86_64
target: alinux
kernelrelease: 5.0.0-1021-aws-5.0
kernelversion: 24~18.04.1
target: ubuntu
output:
module: /tmp/falco_alinux_4.19.91-26.al7.x86_64.ko
probe: /tmp/falco_alinux_4.19.91-26.al7.x86_64.o
module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco-ubuntu-generic.o
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
kernelrelease: 5.10.84-10.4.al8.x86_64
target: alinux
kernelrelease: 4.15.0-72-generic
kernelversion: 81
target: ubuntu-generic
output:
module: /tmp/falco_alinux_4.19.91-26.al7.x86_64.ko
probe: /tmp/falco_alinux_4.19.91-26.al7.x86_64.o
module: /tmp/falco-ubuntu-generic.ko
probe: /tmp/falco-ubuntu-generic.o
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
kernelrelease: 5.14.0-162.12.1.el9_1.x86_64
target: almalinux
kernelrelease: 4.15.0-1057-aws
kernelversion: 59
target: ubuntu-aws
output:
module: /tmp/falco_almalinux_5.14.0-162.12.1.el9_1.x86_64.ko
probe: /tmp/falco_almalinux_5.14.0-162.12.1.el9_1.x86_64.o
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.
## 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
```
@ -65,58 +111,6 @@ output:
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
Example configuration file to build both the Kernel module and eBPF probe for Debian.
@ -131,17 +125,6 @@ target: debian
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
Example configuration file to build both the Kernel module and eBPF probe for Flatcar.
@ -171,15 +154,38 @@ output:
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
kernelrelease: 5.4.17-2011.3.2.1.el8uek.x86_64
kernelversion: 1
target: ol
kernelrelease: 6.0.6.arch1-1
target: arch
output:
module: /tmp/falco-ol8.ko
module: /tmp/falco-arch.ko
probe: /tmp/falco-arch.o
driverversion: master
builderimage: ${ARCH_BUILD_IMAGE_HERE}
```
## redhat 7
@ -269,86 +275,9 @@ and Dockerfile.rhel9:
FROM docker.io/redhat/ubi9
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. 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.
| :exclamation: **subscription-manager does not work on RHEL9 containers**: Host must have a valid RHEL subscription |
|--------------------------------------------------------------------------------------------------------------------|
## vanilla

View File

@ -16,8 +16,6 @@ ifeq ($(COMMITS_FROM_GIT_TAG),0)
endif
endif
DRIVERVERSIONS ?= master
DOCKER_ORG ?= falcosecurity
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_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)
test_configs := $(wildcard test/$(TARGET_TEST_ARCH)/configs/*.yaml)
@ -43,7 +42,7 @@ driverkit_docgen ?= _output/bin/docgen
build: clean ${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
release: clean
@ -71,7 +70,7 @@ push/all: push/builder push/driverkit
.PHONY: push/builder
push/builder:
$(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
@ -81,7 +80,7 @@ push/driverkit:
.PHONY: push/latest
push/latest:
$(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 .
@ -89,27 +88,28 @@ manifest/all: manifest/driverkit
.PHONY: 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) buildx imagetools create -t $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT) $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_COMMIT)_aarch64
$(DOCKER) manifest create $(IMAGE_NAME_DRIVERKIT):$(GIT_REF) $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_x86_64 $(IMAGE_NAME_DRIVERKIT):$(GIT_REF)_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
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
test:
go clean -testcache
GOEXPERIMENT=loopvar go test -v -cover -race ./...
GOEXPERIMENT=loopvar go test -v -cover ./cmd
go test -v -cover -race ./...
go test -v -cover -buildmode=pie ./cmd
.PHONY: integration_test
integration_test: $(test_configs)
.PHONY: $(test_configs)
$(test_configs): ${driverkit}
$(foreach d,$(DRIVERVERSIONS),\
${driverkit} docker -c $@ --builderimage auto:master -l debug --timeout 600 --driverversion $d; \
)
${driverkit} docker -c $@ --builderimage auto:master -l debug --timeout 600
.PHONY: ${driverkit_docgen}
${driverkit_docgen}: ${PWD}/docgen

3
OWNERS
View File

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

View File

@ -1,7 +1,5 @@
# 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)
![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)

View File

@ -1,6 +1,6 @@
# 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:

View File

@ -1,24 +1,13 @@
//go: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
import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -27,9 +16,6 @@ import (
"testing"
"text/template"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/acarl005/stripansi"
"gotest.tools/assert"
)
@ -130,8 +116,6 @@ var tests = []testCase{
"ubuntu-aws",
"--output-module",
"/tmp/falco-ubuntu-aws.ko",
"--output-probe",
"/tmp/falco-ubuntu-aws.o",
"--loglevel",
"debug",
},
@ -144,7 +128,6 @@ var tests = []testCase{
env: map[string]string{
"DRIVERKIT_KERNELVERSION": "59",
"DRIVERKIT_OUTPUT_MODULE": "/tmp/falco-ubuntu-aws.ko",
"DRIVERKIT_OUTPUT_PROBE": "/tmp/falco-ubuntu-aws.o",
},
args: []string{
"docker",
@ -316,14 +299,9 @@ var tests = []testCase{
func run(t *testing.T, test testCase) {
// Setup
configOpts, err := NewConfigOptions()
assert.NilError(t, err)
rootOpts, err := NewRootOptions()
assert.NilError(t, err)
var buf bytes.Buffer
configOpts.setOutput(&buf, true)
c := NewRootCmd(configOpts, rootOpts)
c.SetOutput(&buf)
c := NewRootCmd()
b := bytes.NewBufferString("")
c.SetOutput(b)
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")
}
@ -334,18 +312,19 @@ func run(t *testing.T, test testCase) {
}
}
// Test
err = c.Execute()
err := c.Execute()
if err != nil {
if test.expect.err == "" {
t.Fatalf("error executing CLI: %v", err)
} else {
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()
res := stripansi.Strip(out)
out, err := ioutil.ReadAll(b)
if err != nil {
t.Fatalf("error reading CLI output: %v", err)
}
res := stripansi.Strip(string(out))
assert.Equal(t, test.expect.out, res)
// Teardown
for k := range test.env {
@ -370,7 +349,7 @@ type testTemplateData struct {
}
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)
return string(out)
}
@ -399,7 +378,7 @@ type flagsTemplateData struct {
}
func initFlagsTemplateData(args []string) flagsTemplateData {
targets := builder.Targets()
targets := builder.BuilderByTarget.Targets()
sort.Strings(targets)
cmd := "driverkit"
@ -440,7 +419,7 @@ func TestCLI(t *testing.T) {
test.descr = strings.TrimSuffix(filepath.Base(test.expect.out), ".txt")
}
if test.expect.out != "" {
out, err := os.ReadFile(test.expect.out)
out, err := ioutil.ReadFile(test.expect.out)
if err != nil {
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
import (
"bytes"
"fmt"
"github.com/spf13/pflag"
"os"
"strings"
"text/template"
@ -47,12 +32,12 @@ func validateArgs() cobra.PositionalArgs {
if len(args) == 0 {
return nil
}
return cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)(c, args)
return cobra.ExactValidArgs(1)(c, args)
}
}
// NewCompletionCmd ...
func NewCompletionCmd(_ *ConfigOptions, _ *RootOptions, _ *pflag.FlagSet) *cobra.Command {
func NewCompletionCmd() *cobra.Command {
var long bytes.Buffer
tmpl := template.Must(template.New("long").Parse(longUsageTemplate))
tmpl.Execute(&long, map[string]interface{}{
@ -66,23 +51,25 @@ func NewCompletionCmd(_ *ConfigOptions, _ *RootOptions, _ *pflag.FlagSet) *cobra
Args: validateArgs(),
ValidArgs: cmdArgs,
DisableAutoGenTag: true,
RunE: func(c *cobra.Command, args []string) error {
Run: func(c *cobra.Command, args []string) {
if len(args) == 0 {
return c.Help()
c.Help()
return
}
arg := args[0]
switch arg {
case "bash":
return c.Root().GenBashCompletion(os.Stdout)
c.Root().GenBashCompletion(os.Stdout)
break
case "zsh":
return c.Root().GenZshCompletion(os.Stdout)
c.Root().GenZshCompletion(os.Stdout)
break
case "fish":
return c.Root().GenFishCompletion(os.Stdout, true)
c.Root().GenFishCompletion(os.Stdout, true)
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
import (
"errors"
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/mitchellh/go-homedir"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"io"
"os"
"strings"
"fmt"
"github.com/creasty/defaults"
"github.com/falcosecurity/driverkit/validate"
"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 configOptions *ConfigOptions
// ConfigOptions represent the persistent configuration flags of driverkit.
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"`
ProxyURL string `validate:"omitempty,proxy" name:"proxy url"`
dryRun bool
DryRun bool
// Printer used by all commands to output messages.
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()
configErrors bool
}
// NewConfigOptions creates an instance of ConfigOptions.
func NewConfigOptions() (*ConfigOptions, error) {
o := &ConfigOptions{
writer: os.Stdout,
logLevel: output.NewLogLevel(),
disableStyling: false,
}
o.initPrinter()
func NewConfigOptions() *ConfigOptions {
o := &ConfigOptions{}
if err := defaults.Set(o); err != nil {
// Return ConfigOptions anyway because we need the logger
return o, err
logger.WithError(err).WithField("options", "ConfigOptions").Fatal("error setting driverkit options defaults")
}
return o, nil
return o
}
// Validate validates the ConfigOptions fields.
func (co *ConfigOptions) validate() []error {
func (co *ConfigOptions) Validate() []error {
if err := validate.V.Struct(co); err != nil {
var errs validator.ValidationErrors
errors.As(err, &errs)
var errArr []error
for _, e := range errs {
errors := err.(validator.ValidationErrors)
errArr := []error{}
for _, e := range errors {
// 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 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
import (
"bytes"
"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/pflag"
"github.com/spf13/viper"
)
// 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{
Use: "docker",
Short: "Build Falco kernel modules and eBPF probes against a docker daemon.",
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
Run: func(c *cobra.Command, args []string) {
logger.WithField("processor", c.Name()).Info("driver building, it will take a few seconds")
if !configOptions.DryRun {
if err := driverbuilder.NewDockerBuildProcessor(viper.GetInt("timeout"), viper.GetString("proxy")).Start(rootOpts.toBuild()); err != nil {
logger.WithError(err).Fatal("exiting")
}
// 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

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
import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"os"
"github.com/olekukonko/tablewriter"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"os"
)
// 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{
Use: "images",
Short: "List builder images",
RunE: func(c *cobra.Command, args []string) error {
configOpts.Printer.Logger.Info("starting loading images",
configOpts.Printer.Logger.Args("processor", c.Name()))
// 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")
}
Run: func(c *cobra.Command, args []string) {
logger.WithField("processor", c.Name()).Info("listing images")
b := rootOpts.toBuild()
b.LoadImages()
if !configOpts.disableStyling {
_ = configOpts.Printer.Spinner.Stop()
configOpts.Printer.DefaultText.Print(buf.String())
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Image", "Target", "Arch", "GCC"})
@ -64,7 +32,6 @@ func NewImagesCmd(configOpts *ConfigOptions, rootOpts *RootOptions, rootFlags *p
table.Append(data)
}
table.Render() // Send output
return nil
},
}
// 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
import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"regexp"
"strings"
"github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/kubernetes/factory"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"k8s.io/cli-runtime/pkg/genericclioptions"
)
// 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{
Use: "kubernetes",
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)
kubernetesCmd.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
kubernetesCmd.Run = func(cmd *cobra.Command, args []string) {
logger.WithField("processor", cmd.Name()).Info("driver building, it will take a few seconds")
if !configOptions.DryRun {
if err := kubernetesRun(cmd, args, kubefactory, rootOpts); err != nil {
logger.WithError(err).Fatal("exiting")
}
// 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
}
func kubernetesRun(kubefactory factory.Factory,
b *builder.Build,
configOpts *ConfigOptions,
) error {
func kubernetesRun(cmd *cobra.Command, args []string, kubefactory factory.Factory, rootOpts *RootOptions) error {
f := cmd.Flags()
b := rootOpts.toBuild()
namespaceStr, err := f.GetString("namespace")
if err != nil {
return err
}
if len(namespaceStr) == 0 {
namespaceStr = "default"
}
kc, err := kubefactory.KubernetesClientSet()
if err != nil {
return err
@ -102,12 +79,6 @@ func kubernetesRun(kubefactory factory.Factory,
return err
}
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(),
clientConfig,
kubernetesOptions.RunAsUser,
kubernetesOptions.Namespace,
kubernetesOptions.ImagePullSecret,
configOpts.Timeout,
configOpts.ProxyURL)
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), clientConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
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
import (
"bytes"
"github.com/falcosecurity/driverkit/pkg/driverbuilder"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kubernetes/factory"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
// 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{
Use: "kubernetes-in-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
kubernetesInClusterCmd.PersistentFlags().AddFlagSet(rootFlags)
kubernetesInClusterCmd.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
kubernetesInClusterCmd.Run = func(cmd *cobra.Command, args []string) {
logger.WithField("processor", cmd.Name()).Info("driver building, it will take a few seconds")
if !configOptions.DryRun {
config, err := rest.InClusterConfig()
if err != nil {
logger.WithError(err).Fatal("exiting")
}
// 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())
}()
if err = factory.SetKubernetesDefaults(config); err != nil {
logger.WithError(err).Fatal("exiting")
}
if err = kubernetesInClusterRun(cmd, args, config, rootOpts); err != nil {
logger.WithError(err).Fatal("exiting")
}
return kubernetesInClusterRun(b, configOpts)
}
return nil
}
return kubernetesInClusterCmd
}
func kubernetesInClusterRun(b *builder.Build, configOpts *ConfigOptions) error {
kubeConfig, err := rest.InClusterConfig()
if err != nil {
return err
}
if err = factory.SetKubernetesDefaults(kubeConfig); err != nil {
return err
}
func kubernetesInClusterRun(_ *cobra.Command, _ []string, kubeConfig *rest.Config, rootOpts *RootOptions) error {
b := rootOpts.toBuild()
kc, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return err
}
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(),
kubeConfig,
kubernetesOptions.RunAsUser,
kubernetesOptions.Namespace,
kubernetesOptions.ImagePullSecret,
configOpts.Timeout,
configOpts.ProxyURL)
buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), kubeConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
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
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
import (
"errors"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io"
"os"
"runtime"
"sort"
"strings"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/falcosecurity/driverkit/pkg/version"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
homedir "github.com/mitchellh/go-homedir"
logger "github.com/sirupsen/logrus"
"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 {
var validationError = errors.New("exiting for validation errors")
configErr := configOpts.Init()
// Early exit if detect some error into config flags
if configErr {
return validationError
if configOptions.configErrors {
return fmt.Errorf("exiting for validation errors")
}
// Merge environment variables or config file values into the RootOptions instance
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
// if supplied, we only need this step if rootCommand doesn't already have them e.g.
// 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
}
value := viper.GetStringSlice(name)
if len(value) != 0 {
strValue := strings.Join(value, ",")
_ = rootCommand.c.Flags().Set(name, strValue)
rootCommand.c.Flags().Set(name, strValue)
}
} else {
value := viper.GetString(name)
@ -76,7 +62,7 @@ func persistentValidateFunc(rootCommand *RootCmd, configOpts *ConfigOptions, roo
}
// set the value, if any, otherwise let the default
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
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
if c.Root() != c && c.Name() != "help" && c.Name() != "__complete" && c.Name() != "__completeNoDesc" && c.Name() != "completion" {
if errs := rootOpts.Validate(); errs != nil {
for _, err := range errs {
configOpts.Printer.Logger.Error("error validating build options",
configOpts.Printer.Logger.Args("err", err.Error()))
logger.WithError(err).Error("error validating build options")
}
return validationError
return fmt.Errorf("exiting for validation errors")
}
rootOpts.Log(configOpts.Printer)
rootOpts.Log()
}
return nil
}
@ -106,7 +96,9 @@ type RootCmd struct {
}
// NewRootCmd instantiates the root command.
func NewRootCmd(configOpts *ConfigOptions, rootOpts *RootOptions) *RootCmd {
func NewRootCmd() *RootCmd {
configOptions = NewConfigOptions()
rootOpts := NewRootOptions()
rootCmd := &cobra.Command{
Use: "driverkit",
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,
DisableFlagsInUseLine: true,
DisableAutoGenTag: true,
SilenceErrors: true,
SilenceUsage: true,
Version: version.String(),
RunE: func(c *cobra.Command, args []string) error {
Run: func(c *cobra.Command, args []string) {
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
return c.Help()
c.Help()
},
}
ret := &RootCmd{
c: rootCmd,
}
rootCmd.PersistentPreRunE = persistentValidateFunc(ret, configOpts, rootOpts)
rootCmd.PersistentPreRunE = persistentValidateFunc(ret, rootOpts)
flags := rootCmd.Flags()
targets := builder.Targets()
targets := builder.BuilderByTarget.Targets()
sort.Strings(targets)
configOpts.AddFlags(flags)
rootOpts.AddFlags(flags, targets)
flags.StringVarP(&configOptions.ConfigFile, "config", "c", configOptions.ConfigFile, "config file path (default $HOME/.driverkit.yaml if exists)")
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 {
panic(err)
}
flags.StringVar(&rootOpts.Output.Module, "output-module", rootOpts.Output.Module, "filepath where to save the resulting kernel module")
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
_ = rootCmd.MarkFlagFilename("config", viper.SupportedExts...)
_ = rootCmd.RegisterFlagCompletionFunc("target", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
rootCmd.MarkFlagFilename("config", viper.SupportedExts...)
rootCmd.RegisterFlagCompletionFunc("target", func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
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
})
// Subcommands
rootCmd.AddCommand(NewKubernetesCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewKubernetesInClusterCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewDockerCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewLocalCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewImagesCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewCompletionCmd(configOpts, rootOpts, flags))
rootCmd.AddCommand(NewKubernetesCmd(rootOpts, flags))
rootCmd.AddCommand(NewKubernetesInClusterCmd(rootOpts, flags))
rootCmd.AddCommand(NewDockerCmd(rootOpts, flags))
rootCmd.AddCommand(NewImagesCmd(rootOpts, flags))
rootCmd.AddCommand(NewCompletionCmd())
ret.StripSensitive()
@ -188,15 +197,16 @@ func (r *RootCmd) Command() *cobra.Command {
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.
func (r *RootCmd) SetOutput(w io.Writer) {
r.c.SetOut(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.
@ -206,30 +216,59 @@ func (r *RootCmd) Execute() error {
// Start creates the root command and runs it.
func Start() {
configOpts, err := NewConfigOptions()
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 := NewRootOptions()
if err != nil {
configOpts.Printer.Logger.Fatal("error setting driverkit root options defaults",
configOpts.Printer.Logger.Args("err", err.Error()))
}
// Cleanup spinner upon leaving if any
defer func() {
if configOpts.Printer.Spinner != nil {
_ = configOpts.Printer.Spinner.Stop()
}
}()
root := NewRootCmd(configOpts, rootOpts)
if err = root.Execute(); err != nil {
configOpts.Printer.Logger.Fatal("error executing driverkit", configOpts.Printer.Logger.Args("err", err.Error()))
root := NewRootCmd()
if err := root.Execute(); err != nil {
logger.WithError(err).Fatal("error executing driverkit")
}
}
func init() {
logger.SetFormatter(&logger.TextFormatter{
ForceColors: true,
DisableLevelTruncation: false,
DisableTimestamp: true,
})
cobra.OnInitialize(initConfig)
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if errs := configOptions.Validate(); errs != nil {
for _, err := range errs {
logger.WithError(err).Error("error validating config options")
}
// configOptions.configErrors should be true here
}
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
import (
"errors"
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/spf13/pflag"
"os"
"runtime"
"strings"
"fmt"
"github.com/creasty/defaults"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"github.com/falcosecurity/driverkit/validate"
"github.com/go-playground/validator/v10"
logger "github.com/sirupsen/logrus"
)
// 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"`
}
func (oo *OutputOptions) HasOutputs() bool {
return oo.Module != "" || oo.Probe != ""
}
type RepoOptions struct {
Org string `default:"falcosecurity" name:"organization 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 ...
type RootOptions struct {
Architecture string `validate:"required,architecture" name:"architecture"`
@ -62,12 +33,11 @@ type RootOptions struct {
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
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"`
KernelUrls []string `name:"kernel header urls"`
Repo RepoOptions
Output OutputOptions
Registry Registry
}
func init() {
@ -75,23 +45,22 @@ func init() {
}
// NewRootOptions ...
func NewRootOptions() (*RootOptions, error) {
func NewRootOptions() *RootOptions {
rootOpts := &RootOptions{}
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.
func (ro *RootOptions) Validate() []error {
if err := validate.V.Struct(ro); err != nil {
var errs validator.ValidationErrors
errors.As(err, &errs)
errors := err.(validator.ValidationErrors)
errArr := []error{}
for _, e := range errs {
for _, e := range errors {
// 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
}
@ -100,120 +69,86 @@ func (ro *RootOptions) Validate() []error {
kr := kernelrelease.FromString(ro.KernelRelease)
kr.Architecture = kernelrelease.Architecture(ro.Architecture)
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
}
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.
//
// Call it only after validation.
func (ro *RootOptions) Log(printer *output.Printer) {
printer.Logger.Debug("running with options",
printer.Logger.Args(
"output-module", ro.Output.Module,
"output-probe", ro.Output.Probe,
"driverversion", ro.DriverVersion,
"kernelrelease", ro.KernelRelease,
"kernelversion", ro.KernelVersion,
"target", ro.Target,
"arch", ro.Architecture,
"kernelurls", ro.KernelUrls,
"repo-org", ro.Repo.Org,
"repo-name", ro.Repo.Name,
))
func (ro *RootOptions) Log() {
fields := logger.Fields{}
if ro.Output.Module != "" {
fields["output-module"] = ro.Output.Module
}
if ro.Output.Probe != "" {
fields["output-probe"] = ro.Output.Probe
}
if ro.DriverVersion != "" {
fields["driverversion"] = ro.DriverVersion
}
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
if len(kernelConfigData) == 0 {
kernelConfigData = "bm8tZGF0YQ==" // no-data
}
build := &builder.Build{
TargetType: builder.Type(ro.Target),
DriverVersion: ro.DriverVersion,
KernelVersion: ro.KernelVersion,
KernelRelease: ro.KernelRelease,
Architecture: ro.Architecture,
KernelConfigData: kernelConfigData,
ModuleFilePath: ro.Output.Module,
ProbeFilePath: ro.Output.Probe,
ModuleDriverName: ro.ModuleDriverName,
ModuleDeviceName: ro.ModuleDeviceName,
GCCVersion: ro.GCCVersion,
BuilderImage: ro.BuilderImage,
BuilderRepos: ro.BuilderRepos,
KernelUrls: ro.KernelUrls,
RepoOrg: ro.Repo.Org,
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,
TargetType: builder.Type(ro.Target),
DriverVersion: ro.DriverVersion,
KernelVersion: ro.KernelVersion,
KernelRelease: ro.KernelRelease,
Architecture: ro.Architecture,
KernelConfigData: kernelConfigData,
ModuleFilePath: ro.Output.Module,
ProbeFilePath: ro.Output.Probe,
ModuleDriverName: ro.ModuleDriverName,
ModuleDeviceName: ro.ModuleDeviceName,
GCCVersion: ro.GCCVersion,
BuilderImage: ro.BuilderImage,
BuilderRepos: ro.BuilderRepos,
KernelUrls: ro.KernelUrls,
RepoOrg: ro.Repo.Org,
RepoName: ro.Repo.Name,
}
// loop over BuilderRepos to build the list ImagesListers based on the value of the builderRepo:
// if it's a local path use FileImagesLister, otherwise use RepoImagesLister
var (
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)
}
}
// Always append falcosecurity repo; Note: this is a prio first slice
// therefore, default falcosecurity repo has lowest prio.
build.BuilderRepos = append(build.BuilderRepos, "docker.io/falcosecurity/driverkit")
// attempt the build in case it comes from an invalid config
kr := build.KernelReleaseFromBuildConfig()
if len(build.ModuleFilePath) > 0 && !kr.SupportsModule() {
build.ModuleFilePath = ""
printer.Logger.Warn("skipping build attempt of module for unsupported kernel release",
printer.Logger.Args("kernelrelease", kr.String()))
logger.Warningf("Skipping build attempt of module for unsupported kernel version %s", kr.String())
}
if len(build.ProbeFilePath) > 0 && !kr.SupportsProbe() {
build.ProbeFilePath = ""
printer.Logger.Warn("skipping build attempt of probe for unsupported kernel release",
printer.Logger.Args("kernelrelease", kr.String()))
logger.Warningf("Skipping build attempt of probe for unsupported kernel version %s", kr.String())
}
return build
}

View File

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

View File

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

View File

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

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/1.yaml
DEBUG running with options
├ output-module: /tmp/falco-ubuntu-aws.ko
├ 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
INFO using config file file=testdata/configs/1.yaml
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
INFO driver building, it will take a few seconds processor=docker

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/1.yaml
DEBUG running with options
├ output-module: /tmp/override.ko
├ 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
INFO using config file file=testdata/configs/1.yaml
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
INFO driver building, it will take a few seconds processor=docker

View File

@ -1,13 +1,3 @@
INFO using config file file: testdata/configs/2.yaml
DEBUG running with options
├ output-module: /tmp/falco-ubuntu-aws.ko
├ 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
INFO using config file file=testdata/configs/2.yaml
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
INFO driver building, it will take a few seconds processor=docker

View File

@ -1,13 +1,3 @@
DEBUG running without a configuration file
DEBUG running with options
├ output-module: /tmp/falco-ubuntu-azure.ko
├ 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
DEBU running without a configuration file
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
INFO driver building, it will take a few seconds processor=docker

View File

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

View File

@ -1,13 +1,3 @@
DEBUG running without a configuration file
DEBUG running with options
├ output-module: /tmp/falco-ubuntu-aws.ko
├ 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
DEBU running without a configuration file
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
INFO driver building, it will take a few seconds 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
ERROR error validating build options err: target is a required field
ERROR error validating build options
└ err: output module path is required when probe is missing
ERROR error validating build options
└ err: output probe path is required when module is missing
ERROR error executing driverkit err: exiting for validation errors
ERRO error validating build options error="kernel release is a required field"
ERRO error validating build options error="target is a required field"
ERRO error validating build options error="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: exiting for validation errors
Usage:
driverkit docker [flags]
{{ .Flags }}

View File

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

View File

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

View File

@ -1,3 +1,11 @@
ERROR error validating config options
└ err: proxy url must start with http:// or https:// or socks5:// prefix
ERROR error executing driverkit err: exiting for validation errors
ERRO error validating config options error="proxy url must start with http:// or https:// or socks5:// prefix"
Error: 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
images List builder images
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.
local Build Falco kernel modules and eBPF probes in local env with local kernel sources and gcc/clang.
kubernetes-in-cluster Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.

View File

@ -1,27 +1,23 @@
Flags:
--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.
--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])
-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")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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
--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-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)
--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.
--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)
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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 log level (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
--proxy string the proxy to use to download data
--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
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"github.com/falcosecurity/driverkit/cmd"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra/doc"
)
@ -59,22 +47,7 @@ func main() {
flag.Parse()
// Get root command
configOpts, err := cmd.NewConfigOptions()
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)
driverkit := cmd.NewRootCmd()
root := driverkit.Command()
num := len(root.Commands()) + 1
@ -97,20 +70,20 @@ func main() {
}
// Generate markdown docs
err = doc.GenMarkdownTreeCustom(root, outputDir, prepender(num), linker)
err := doc.GenMarkdownTreeCustom(root, outputDir, prepender(num), linker)
if err != nil {
configOpts.Printer.Logger.Fatal("markdown generation", configOpts.Printer.Logger.Args("err", err.Error()))
logger.WithError(err).Fatal("markdown generation")
}
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 {
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 {
configOpts.Printer.Logger.Fatal("error replacing sensitive data", configOpts.Printer.Logger.Args("err", err.Error()))
if err := stripSensitive(); err != nil {
logger.WithError(err).Fatal("error replacing sensitive data")
}
}
@ -127,7 +100,7 @@ func stripSensitive() error {
for _, file := range files {
filePath := path.Join(outputDir, file.Name())
file, err := os.ReadFile(filePath)
file, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
@ -137,7 +110,7 @@ func stripSensitive() error {
target := []byte(os.Getenv(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
}
}

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 \
gpg \
zstd \
cmake \
git \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/*
# Properly create soft link
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 \
gpg \
zstd \
cmake \
git \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/*
# Properly create soft links
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
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
# 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 echo 'deb http://deb.debian.org/debian buster-backports main' >>/etc/apt/sources.list
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash-completion \
bc \
clang \
llvm \
llvm \
ca-certificates \
curl \
dkms \
dwarves \
dwarves/buster-backports \
gnupg2 \
gcc \
jq \
@ -45,18 +39,14 @@ RUN apt-get update \
software-properties-common \
gpg \
zstd \
gawk \
mawk \
git \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/*
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
# 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 && \
echo 'deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe' >> /etc/apt/sources.list
# repo is unsigned therefore the APT options
RUN echo 'deb http://deb.debian.org/debian jessie main' >>/etc/apt/sources.list # gcc 4.9 on x86_64
# jessie 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
# 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 \
&& 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
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 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-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"
# Fix broken mirrors - centos:7 eol
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 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 \
RUN yum -y install centos-release-scl && \
yum -y install gcc \
llvm-toolset-7.0 \
bash-completion \
bc \
@ -32,15 +21,7 @@ RUN yum -y install gcc \
wget \
binutils \
which \
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)/
make
# Properly create soft link
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:
* 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
* 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 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.
* 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
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.
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:
```go
@ -49,7 +48,7 @@ type archLinux struct {
}
func init() {
byTarget[TargetTypeArchLinux] = &archLinux{}
BuilderByTarget[TargetTypeArchLinux] = &archLinux{}
}
```
@ -59,19 +58,15 @@ you just registered.
Here's a very minimalistic example:
```go
func (c *archlinux) Name() string {
func (c archlinux) Name() string {
return TargetTypeArchlinux.String()
}
func (c *archlinux) TemplateKernelUrlsScript() string {
return archlinuxKernelTemplate
func (c archlinux) TemplateScript() string {
return archlinuxTemplate
}
func (c *archlinux) TemplateScript() string {
return archlinuxTemplate
}
func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
func (c archlinux) URLs(cfg Config, kr kernelrelease.KernelRelease) ([]string, error) {
urls := []string{}
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",
@ -80,7 +75,7 @@ func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
cfg.KernelVersion,
kr.Architecture.ToNonDeb()))
} 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.Fullversion,
@ -90,17 +85,17 @@ func (c archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
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{
KernelDownloadURL: urls[0],
commonTemplateData: cfg.toTemplateData(),
KernelDownloadURL: urls[0],
}
}
```
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 build script template (see below), that is a `bash` script that will be executed by driverkit at build time
* 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
* fill the 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
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
@ -108,57 +103,14 @@ without mixing up templates and builder logic.
For example:
```go
//go:embed templates/archlinux_kernel.sh
var archlinuxKernelTemplate string
//go:embed templates/archlinux.sh
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
in the `Config` struct at `c.Build.KernelVersion`, and then extracting them.
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
```
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`.
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.
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 }}
```
by the user you will need to build the kernel module driver and/or the eBPF probe driver.
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 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.
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
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.
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:
* load any image for the build arch, tag and target
* load any image for the build arch, tag and "any" target
* load any image for the build arch and build 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 "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.
@ -41,12 +35,8 @@ In this latest step, there is no distinction between/different priority given to
## Customize builder images repos
Moreover, users can also ship their own builder images in their own docker repositories, by using `--builderrepo` CLI option.
Instead of passing a docker repo, one can also pass the full path to a so-called builder images index yaml file.
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!).
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.
Note that default falcosecurity repo will always be enforced as lowest priority repo.
## 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:
* `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
Users can specify the target gcc version of the build, using `--gccversion` option.

View File

@ -9,32 +9,28 @@ driverkit
### Options
```
--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.
--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])
-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")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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
--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-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)
--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.
--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)
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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 log level (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
--proxy string the proxy to use to download data
--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 [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
```
### SEE ALSO
@ -44,5 +40,4 @@ driverkit
* [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-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
```
--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.
--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])
-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")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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
--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-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)
--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.
--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)
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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 log level (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
--proxy string the proxy to use to download data
--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 [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
```
### SEE ALSO

View File

@ -9,32 +9,28 @@ driverkit images [flags]
### Options
```
--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.
--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])
-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")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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
--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-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)
--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.
--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)
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--dryrun do not actually perform the action
--gccversion string enforce a specific gcc version for the build
-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
--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>")
--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 log level (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
--proxy string the proxy to use to download data
--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 [almalinux,amazonlinux,amazonlinux2,amazonlinux2022,arch,bottlerocket,centos,debian,fedora,flatcar,minikube,opensuse,photon,redhat,rocky,ubuntu,vanilla]
--timeout int timeout in seconds (default 120)
```
### 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")
--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)
--driverversion string driver version as a git commit hash or as a git tag (default "master")
--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'
--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")
-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")
--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")
--output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe
--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-org string repository github organization (default "falcosecurity")
--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)
```

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-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.
--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")
--certificate-authority string path to a cert file for the certificate authority
--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
-c, --config string config file path (default $HOME/.driverkit.yaml if exists)
--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")
--dryrun do not actually perform the action
--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>")
--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
-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")
--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")
--output-module string filepath where to save the resulting kernel module
--output-probe string filepath where to save the resulting eBPF probe
--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-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")
--run-as-user int Pods runner user
-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)
--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

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
go 1.24.1
toolchain go1.24.2
go 1.18
require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/blang/semver/v4 v4.0.0
github.com/creasty/defaults v1.7.0
github.com/docker/docker v28.3.3+incompatible
github.com/falcosecurity/falcoctl v0.11.1
github.com/go-playground/locales v0.14.1
github.com/go-playground/universal-translator v0.18.1
github.com/go-playground/validator/v10 v10.24.0
github.com/blang/semver v3.5.1+incompatible
github.com/containerd/containerd v1.6.18 // indirect
github.com/creasty/defaults v1.6.0
github.com/docker/docker v20.10.14+incompatible
github.com/go-playground/locales v0.14.0
github.com/go-playground/universal-translator v0.18.0
github.com/go-playground/validator/v10 v10.10.1
github.com/mitchellh/go-homedir v1.1.0
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/image-spec v1.1.1
github.com/pterm/pterm v0.12.80
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/spf13/viper v1.20.0
gopkg.in/yaml.v3 v3.0.1
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.4.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.11.0
gotest.tools v2.2.0+incompatible
k8s.io/api v0.32.3
k8s.io/apimachinery v0.32.3
k8s.io/cli-runtime v0.30.0
k8s.io/client-go v0.32.3
k8s.io/kubectl v0.30.0
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
modernc.org/sqlite v1.29.9
oras.land/oras-go/v2 v2.5.0
k8s.io/api v0.23.6
k8s.io/apimachinery v0.23.6
k8s.io/cli-runtime v0.23.6
k8s.io/client-go v0.23.6
k8s.io/kubectl v0.23.6
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
modernc.org/sqlite v1.17.3
)
require github.com/olekukonko/tablewriter v0.0.4
require (
atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.1.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect
github.com/containerd/console v1.0.4 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/creack/pty v1.1.21 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/distribution/reference v0.6.0 // 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/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.6 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-logr/logr v1.4.2 // 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/fsnotify/fsnotify v1.5.1 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-logr/logr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.1.0 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // 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/magiconair/properties v1.8.6 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mount v0.3.3 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // 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/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/pkg/errors v0.9.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.starlark.net v0.0.0-20240507195648-35fe9f26b4bc // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.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
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/stretchr/testify v1.7.1 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
go.opencensus.io v0.23.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.0 // 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
gotest.tools/v3 v3.5.2 // indirect
k8s.io/component-base v0.30.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
modernc.org/libc v1.50.5 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/kustomize/api v0.17.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.2.0 // indirect
k8s.io/component-base v0.23.6 // indirect
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/ccgo/v3 v3.16.6 // indirect
modernc.org/libc v1.16.7 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.1.1 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.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
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
import (
_ "embed"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/almalinux_kernel.sh
var almaKernelTemplate string
//go:embed templates/almalinux.sh
var almaTemplate string
@ -31,10 +13,11 @@ var almaTemplate string
const TargetTypeAlma Type = "almalinux"
func init() {
byTarget[TargetTypeAlma] = &alma{}
BuilderByTarget[TargetTypeAlma] = &alma{}
}
type almaTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -46,21 +29,18 @@ func (c *alma) Name() string {
return TargetTypeAlma.String()
}
func (c *alma) TemplateKernelUrlsScript() string {
return almaKernelTemplate
}
func (c *alma) TemplateScript() string {
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
}
func (c *alma) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
func (c *alma) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
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.FullExtraversion,
))
} else {
}else{
urls = append(urls, fmt.Sprintf(
"https://repo.almalinux.org/almalinux/%s/BaseOS/%s/os/Packages/kernel-devel-%s%s.rpm",
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
import (
@ -22,8 +8,8 @@ import (
"database/sql"
_ "embed"
"fmt"
"github.com/blang/semver/v4"
"io"
"io/ioutil"
"log"
"net/http"
"os"
@ -32,11 +18,9 @@ import (
_ "modernc.org/sqlite"
"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
var amazonlinuxTemplate string
@ -58,13 +42,6 @@ type amazonlinux2022 struct {
amazonlinux
}
type amazonlinux2023 struct {
amazonlinux
}
// TargetTypeAmazonLinux2023 identifies the AmazonLinux2023 target.
const TargetTypeAmazonLinux2023 Type = "amazonlinux2023"
// TargetTypeAmazonLinux2022 identifies the AmazonLinux2022 target.
const TargetTypeAmazonLinux2022 Type = "amazonlinux2022"
@ -75,13 +52,13 @@ const TargetTypeAmazonLinux2 Type = "amazonlinux2"
const TargetTypeAmazonLinux Type = "amazonlinux"
func init() {
byTarget[TargetTypeAmazonLinux2023] = &amazonlinux2023{}
byTarget[TargetTypeAmazonLinux2022] = &amazonlinux2022{}
byTarget[TargetTypeAmazonLinux2] = &amazonlinux2{}
byTarget[TargetTypeAmazonLinux] = &amazonlinux{}
BuilderByTarget[TargetTypeAmazonLinux2022] = &amazonlinux2022{}
BuilderByTarget[TargetTypeAmazonLinux2] = &amazonlinux2{}
BuilderByTarget[TargetTypeAmazonLinux] = &amazonlinux{}
}
type amazonlinuxTemplateData struct {
commonTemplateData
KernelDownloadURLs []string
}
@ -89,18 +66,17 @@ func (a *amazonlinux) Name() string {
return TargetTypeAmazonLinux.String()
}
func (a *amazonlinux) TemplateKernelUrlsScript() string { return amazonlinuxKernelTemplate }
func (a *amazonlinux) TemplateScript() string {
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)
}
func (a *amazonlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
func (a *amazonlinux) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
return amazonlinuxTemplateData{
commonTemplateData: c.toTemplateData(a, kr),
KernelDownloadURLs: urls,
}
}
@ -130,7 +106,7 @@ func (a *amazonlinux2022) Name() 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)
}
@ -149,44 +125,14 @@ func (a *amazonlinux2022) ext() string {
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 {
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)
}
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 {
return []string{
"core/2.0",
@ -210,13 +156,16 @@ func buildMirror(a amazonBuilder, r string, kv kernelrelease.KernelRelease) (str
switch a.(type) {
case *amazonlinux:
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())
default:
return "", fmt.Errorf("unsupported target")
}
mirror := fmt.Sprintf("%s/%s", baseURL, "mirror.list")
logger.WithField("url", mirror).WithField("version", r).Debug("looking for repo...")
return mirror, nil
}
@ -237,92 +186,92 @@ func fetchAmazonLinuxPackagesURLs(a amazonBuilder, kv kernelrelease.KernelReleas
visited := make(map[string]struct{})
for _, v := range a.repos() {
err := func() error {
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()
}()
mirror, err := buildMirror(a, v, kv)
if err != nil {
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
if len(urls) > 0 {
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
import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/archlinux_kernel.sh
var archlinuxKernelTemplate string
//go:embed templates/archlinux.sh
var archlinuxTemplate string
@ -32,7 +15,7 @@ var archlinuxTemplate string
const TargetTypeArchlinux Type = "arch"
func init() {
byTarget[TargetTypeArchlinux] = &archlinux{}
BuilderByTarget[TargetTypeArchlinux] = &archlinux{}
}
// archlinux is a driverkit target.
@ -40,6 +23,7 @@ type archlinux struct {
}
type archlinuxTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -47,19 +31,11 @@ func (c *archlinux) Name() string {
return TargetTypeArchlinux.String()
}
func (c *archlinux) TemplateKernelUrlsScript() string { return archlinuxKernelTemplate }
func (c *archlinux) TemplateScript() string {
return archlinuxTemplate
}
func (c *archlinux) URLs(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")
}
func (c *archlinux) URLs(cfg Config, kr kernelrelease.KernelRelease) ([]string, error) {
urls := []string{}
possibleCompressionSuffixes := []string{
@ -75,10 +51,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append(
urls,
fmt.Sprintf(
"%s/linux-headers-%s-%s-%s.pkg.tar.%s",
"%s/linux-headers-%s%s-%s.pkg.tar.%s",
baseURL,
kr.String(),
kr.KernelVersion,
kr.Fullversion,
kr.FullExtraversion,
kr.Architecture.ToNonDeb(),
compressionAlgo,
),
@ -90,10 +66,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append(
urls,
fmt.Sprintf(
"%s/linux-hardened-headers-%s-%s-%s.pkg.tar.%s",
"%s/linux-hardened-headers-%s%s-%s.pkg.tar.%s",
baseURL,
kr.String(),
kr.KernelVersion,
kr.Fullversion,
kr.FullExtraversion,
kr.Architecture.ToNonDeb(),
compressionAlgo,
),
@ -105,10 +81,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append(
urls,
fmt.Sprintf(
"%s/linux-zen-headers-%s-%s-%s.pkg.tar.%s",
"%s/linux-zen-headers-%s%s-%s.pkg.tar.%s",
baseURL,
kr.String(),
kr.KernelVersion,
kr.Fullversion,
kr.FullExtraversion,
kr.Architecture.ToNonDeb(),
compressionAlgo,
),
@ -120,10 +96,10 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
urls = append(
urls,
fmt.Sprintf(
"%s/linux-lts-headers-%s-%s-%s.pkg.tar.%s",
"%s/linux-lts-headers-%s%s-%s.pkg.tar.%s",
baseURL,
kr.String(),
kr.KernelVersion,
kr.Fullversion,
kr.FullExtraversion,
kr.Architecture.ToNonDeb(),
compressionAlgo,
),
@ -131,15 +107,15 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
}
}
} 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 {
urls = append(
urls,
fmt.Sprintf(
"%s/linux-aarch64-headers-%s-%s-%s.pkg.tar.%s",
"%s/linux-aarch64-headers-%s%s-%s.pkg.tar.%s",
baseURL,
kr.String(),
kr.KernelVersion,
kr.Fullversion,
kr.FullExtraversion,
kr.Architecture.ToNonDeb(),
compressionAlgo,
),
@ -150,8 +126,9 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
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{
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
import (
@ -22,7 +8,7 @@ import (
const TargetTypeBottlerocket Type = "bottlerocket"
func init() {
byTarget[TargetTypeBottlerocket] = &bottlerocket{
BuilderByTarget[TargetTypeBottlerocket] = &bottlerocket{
vanilla{},
}
}
@ -35,8 +21,9 @@ func (b *bottlerocket) Name() 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{
commonTemplateData: c.toTemplateData(b, kr),
KernelDownloadURL: urls[0],
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
import (
"context"
"fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"strings"
"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.
type Build struct {
TargetType Type
KernelConfigData string
KernelRelease string
KernelVersion string
DriverVersion string
Architecture string
ModuleFilePath string
ProbeFilePath string
ModuleDriverName string
ModuleDeviceName string
BuilderImage string
BuilderRepos []string
ImagesListers []ImagesLister
KernelUrls []string
GCCVersion string
RepoOrg string
RepoName string
Images ImagesMap
RegistryName string
RegistryUser string
RegistryPassword string
RegistryPlainHTTP bool
*output.Printer
TargetType Type
KernelConfigData string
KernelRelease string
KernelVersion string
DriverVersion string
Architecture string
ModuleFilePath string
ProbeFilePath string
ModuleDriverName string
ModuleDeviceName string
BuilderImage string
BuilderRepos []string
KernelUrls []string
GCCVersion string
RepoOrg string
RepoName string
Images ImagesMap
}
func (b *Build) KernelReleaseFromBuildConfig() kernelrelease.KernelRelease {
kv := kernelrelease.FromString(b.KernelRelease)
kv.Architecture = kernelrelease.Architecture(b.Architecture)
kv.KernelVersion = b.KernelVersion
return kv
}
@ -73,41 +44,3 @@ func (b *Build) ToConfig() Config {
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
import (
"bytes"
_ "embed"
"errors"
"fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"log"
"net/http"
"net/url"
"path"
"strings"
"text/template"
"github.com/blang/semver/v4"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
logger "github.com/sirupsen/logrus"
)
// DriverDirectory is the directory the processor uses to store the driver.
const (
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`
)
const DriverDirectory = "/tmp/driver"
//go:embed templates/libs_download.sh
var libsDownloadTemplate string
// ModuleFileName is the standard file name for the kernel module.
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")
@ -64,92 +41,45 @@ type Config struct {
*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 {
DriverBuildDir string
ModuleDriverName string
ModuleFullPath string
BuildModule bool
BuildProbe bool
GCCVersion string
CmakeCmd string
DriverBuildDir string
ModuleDownloadURL string
ModuleDriverName string
ModuleFullPath string
BuildModule bool
BuildProbe bool
GCCVersion string
}
// Builder represents a builder capable of generating a script for a driverkit target.
type Builder interface {
Name() string
TemplateKernelUrlsScript() string
TemplateScript() string
URLs(kr kernelrelease.KernelRelease) ([]string, error)
KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} // error return type is managed
URLs(c Config, kr kernelrelease.KernelRelease) ([]string, error)
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
type MinimumURLsBuilder interface {
MinimumURLs() int
}
// TemplateDataSpecifier is an optional interface implemented by builders
// to specify a custom template data instead of the default one.
type TemplateDataSpecifier interface {
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)
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
}
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
if bb, ok := b.(MinimumURLsBuilder); ok {
minimumURLs = bb.MinimumURLs()
}
if kernelurls == nil {
urls, err = b.URLs(kr)
var urls []string
if c.KernelUrls == nil {
urls, err = b.URLs(c, kr)
if err != nil {
return "", err
}
@ -157,10 +87,10 @@ func KernelDownloadScript(b Builder,
// Otherwise, it is up to the builder to return an error
if len(urls) > 0 {
// Check (and filter) existing kernels before continuing
urls, err = GetResolvingURLs(urls)
urls, err = getResolvingURLs(urls)
}
} else {
urls, err = GetResolvingURLs(kernelurls)
urls, err = getResolvingURLs(c.KernelUrls)
}
if err != nil {
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))
}
printer.Logger.Debug("kernel headers found",
printer.Logger.Args("urls", urls))
td := b.KernelTemplateData(kr, urls)
td := b.TemplateData(c, kr, urls)
if tdErr, ok := td.(error); ok {
return "", tdErr
}
@ -183,31 +110,6 @@ func KernelDownloadScript(b Builder,
if err != nil {
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
}
@ -219,16 +121,8 @@ type GCCVersionRequestor interface {
func defaultGCC(kr kernelrelease.KernelRelease) semver.Version {
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:
if kr.Minor >= 15 {
if kr.Minor >= 18 {
return semver.Version{Major: 12}
}
return semver.Version{Major: 11}
@ -242,7 +136,7 @@ func defaultGCC(kr kernelrelease.KernelRelease) semver.Version {
case 2:
return semver.Version{Major: 4, Minor: 8}
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;
// see below for algorithm explanation
func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) {
if !b.hasCustomBuilderImage() {
b.LoadImages()
}
b.LoadImages()
if len(b.GCCVersion) > 0 {
// If set from user, go on
@ -286,11 +178,6 @@ func (b *Build) setGCCVersion(builder Builder, kr kernelrelease.KernelRelease) {
targetGCC = defaultGCC(kr)
}
if b.hasCustomBuilderImage() {
b.GCCVersion = targetGCC.String()
return
}
// Step 1:
// If we are able to either find a specific-target image,
// 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)
if ok {
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 {
// sets the network mode of the builder image, allows individual builders to override
BuilderImageNetMode() string
// 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)
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 {
if b.hasCustomBuilderImage() {
// BuilderImage MUST have requested GCC installed inside
return b.BuilderImage
imageTag := "latest"
if len(b.BuilderImage) > 0 {
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
@ -344,72 +236,44 @@ func (b *Build) GetBuilderImage() string {
// has already set an existent gcc version
// (ie: one provided by an image) for us
image, _ := b.Images.findImage(b.TargetType, mustParseTolerant(b.GCCVersion))
return image.Name
return image.Name + ":" + imageTag
}
// Factory returns a builder for the given target.
func Factory(target Type) (Builder, error) {
// Workaround for "local" target (that is not exposed to users,
// 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]
b, ok := BuilderByTarget[target]
if !ok {
return nil, fmt.Errorf("no builder found for target: %s", target)
}
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 {
c.setGCCVersion(b, kr)
return commonTemplateData{
DriverBuildDir: DriverDirectory,
ModuleDriverName: c.DriverName,
ModuleFullPath: c.ToDriverFullPath(),
BuildModule: len(c.ModuleFilePath) > 0,
BuildProbe: len(c.ProbeFilePath) > 0,
GCCVersion: c.GCCVersion,
CmakeCmd: fmt.Sprintf(cmakeCmdFmt,
c.DriverName,
c.DriverName,
c.DriverVersion,
c.DriverVersion,
c.DriverVersion,
c.DeviceName,
c.DeviceName,
c.DriverVersion),
DriverBuildDir: DriverDirectory,
ModuleDownloadURL: fmt.Sprintf("%s/%s.tar.gz", c.DownloadBaseURL, c.DriverVersion),
ModuleDriverName: c.DriverName,
ModuleFullPath: ModuleFullPath,
BuildModule: len(c.ModuleFilePath) > 0,
BuildProbe: len(c.ProbeFilePath) > 0,
GCCVersion: c.GCCVersion,
}
}
func resolveURLReference(u string) string {
uu, err := url.Parse(u)
if err != nil {
panic(err)
log.Fatal(err)
}
base, err := url.Parse(uu.Host)
if err != nil {
panic(err)
log.Fatal(err)
}
return base.ResolveReference(uu).String()
}
func GetResolvingURLs(urls []string) ([]string, error) {
func getResolvingURLs(urls []string) ([]string, error) {
var results []string
for _, u := range urls {
// in case url has some relative paths
@ -424,6 +288,7 @@ func GetResolvingURLs(urls []string) ([]string, error) {
}
if res.StatusCode == http.StatusOK {
results = append(results, u)
logger.WithField("url", u).Debug("kernel header url found")
}
}
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
import (
"testing"
"github.com/blang/semver/v4"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"testing"
)
var gccTests = []struct {
@ -54,7 +39,7 @@ var gccTests = []struct {
Architecture: kernelrelease.ArchitectureAmd64,
},
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
import (
_ "embed"
"fmt"
"github.com/blang/semver/v4"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/centos_kernel.sh
var centosKernelTemplate string
//go:embed templates/centos.sh
var centosTemplate string
@ -32,7 +14,7 @@ var centosTemplate string
const TargetTypeCentos Type = "centos"
func init() {
byTarget[TargetTypeCentos] = &centos{}
BuilderByTarget[TargetTypeCentos] = &centos{}
}
// centos is a driverkit target.
@ -40,6 +22,7 @@ type centos struct {
}
type centosTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -47,13 +30,11 @@ func (c *centos) Name() string {
return TargetTypeCentos.String()
}
func (c *centos) TemplateKernelUrlsScript() string { return centosKernelTemplate }
func (c *centos) TemplateScript() string {
return centosTemplate
}
func (c *centos) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
func (c *centos) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
vaultReleases := []string{
"6.0/os",
"6.0/updates",
@ -180,17 +161,14 @@ func (c *centos) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
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{
KernelDownloadURL: urls[0],
commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
}
}
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:
// https://github.com/falcosecurity/driverkit/issues/236
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
import (
_ "embed"
"fmt"
"io"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil"
"net/http"
"regexp"
"strings"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/debian_kernel.sh
var debianKernelTemplate string
//go:embed templates/debian.sh
var debianTemplate string
@ -42,10 +23,11 @@ const TargetTypeDebian Type = "debian"
const debianRequiredURLs = 3
func init() {
byTarget[TargetTypeDebian] = &debian{}
BuilderByTarget[TargetTypeDebian] = &debian{}
}
type debianTemplateData struct {
commonTemplateData
KernelDownloadURLS []string
KernelLocalVersion string
KernelHeadersPattern string
@ -59,27 +41,24 @@ func (v *debian) Name() string {
return TargetTypeDebian.String()
}
func (v *debian) TemplateKernelUrlsScript() string { return debianKernelTemplate }
func (v *debian) TemplateScript() string {
return debianTemplate
}
func (v *debian) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
func (v *debian) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) {
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
if strings.HasSuffix(kr.Extraversion, "pve") {
KernelHeadersPattern = "linux-headers-*pve"
} else if strings.Contains(kr.FullExtraversion, "rpi") {
KernelHeadersPattern = "linux-headers-*-rpi-v*"
} else {
KernelHeadersPattern = "linux-headers-*" + kr.Architecture.String()
}
return debianTemplateData{
commonTemplateData: c.toTemplateData(v, kr),
KernelDownloadURLS: urls,
KernelLocalVersion: kr.FullExtraversion,
KernelHeadersPattern: KernelHeadersPattern,
@ -135,18 +114,9 @@ func fetchDebianHeadersURLFromRelease(baseURL string, kr kernelrelease.KernelRel
matchExtraGroupCommon := "common"
// match for kernel versions like 4.19.0-6-cloud-amd64
supportedExtraFlavors := []string{"cloud", "rt", "rpi"}
for _, supportedExtraFlavor := range supportedExtraFlavors {
if strings.Contains(kr.FullExtraversion, "-"+supportedExtraFlavor) {
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
}
if strings.Contains(kr.FullExtraversion, "-cloud") {
extraVersionPartial = strings.TrimSuffix(extraVersionPartial, "-cloud")
matchExtraGroup = "cloud-" + matchExtraGroup
}
// download index
@ -155,7 +125,7 @@ func fetchDebianHeadersURLFromRelease(baseURL string, kr kernelrelease.KernelRel
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
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
import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/fedora_kernel.sh
var fedoraKernelTemplate string
//go:embed templates/fedora.sh
var fedoraTemplate string
@ -32,7 +15,7 @@ var fedoraTemplate string
const TargetTypeFedora Type = "fedora"
func init() {
byTarget[TargetTypeFedora] = &fedora{}
BuilderByTarget[TargetTypeFedora] = &fedora{}
}
// fedora is a driverkit target.
@ -40,6 +23,7 @@ type fedora struct {
}
type fedoraTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -47,13 +31,11 @@ func (c *fedora) Name() string {
return TargetTypeFedora.String()
}
func (c *fedora) TemplateKernelUrlsScript() string { return fedoraKernelTemplate }
func (c *fedora) TemplateScript() string {
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"
// 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.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 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{
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
import (
_ "embed"
"fmt"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"io/ioutil"
"net/http"
"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
var flatcarTemplate string
@ -35,10 +17,11 @@ var flatcarTemplate string
const TargetTypeFlatcar Type = "flatcar"
func init() {
byTarget[TargetTypeFlatcar] = &flatcar{}
BuilderByTarget[TargetTypeFlatcar] = &flatcar{}
}
type flatcarTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -51,22 +34,18 @@ func (f *flatcar) Name() string {
return TargetTypeFlatcar.String()
}
func (f *flatcar) TemplateKernelUrlsScript() string {
return flatcarKernelTemplate
}
func (f *flatcar) TemplateScript() string {
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 {
return nil, err
}
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,
// therefore URLs() method is not called.
if f.info == nil {
@ -76,7 +55,8 @@ func (f *flatcar) KernelTemplateData(kr kernelrelease.KernelRelease, urls []stri
}
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) {
flatcarInfo := flatcarReleaseInfo{}
flatcarVersion := kr.Fullversion
packageIndexUrl, err := GetResolvingURLs(fetchFlatcarPackageListURL(kr.Architecture, flatcarVersion))
packageIndexUrl, err := getResolvingURLs(fetchFlatcarPackageListURL(kr.Architecture, flatcarVersion))
if err != nil {
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
import (
"context"
"fmt"
"github.com/falcosecurity/falcoctl/pkg/output"
"os"
"github.com/blang/semver"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
logger "github.com/sirupsen/logrus"
"log"
"regexp"
"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 {
Target Type
GCCVersion semver.Version // we expect images to internally link eg: gcc5 to gcc5.0.0
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
func (i *Image) toKey() ImageKey {
@ -69,8 +27,6 @@ func (i *Image) toKey() ImageKey {
type ImagesMap map[ImageKey]Image
var tagReg *regexp.Regexp
func (im ImagesMap) findImage(target Type, gccVers semver.Version) (Image, bool) {
targetImage := Image{
Target: target,
@ -89,175 +45,78 @@ func (im ImagesMap) findImage(target Type, gccVers semver.Version) (Image, bool)
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() {
for _, imagesLister := range b.ImagesListers {
for _, image := range imagesLister.LoadImages(b.Printer) {
// User forced a gcc version? Only load images matching the requested gcc version.
if b.GCCVersion != "" && b.GCCVersion != image.GCCVersion.String() {
continue
}
// Skip if key already exists: we have a descending prio list of docker repos!
if _, ok := b.Images[image.toKey()]; !ok {
b.Images[image.toKey()] = image
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
log.Fatal(err)
}
// Create the proper regexes to load "any" and target-specific images for requested arch
arch := kernelrelease.Architecture(b.Architecture).ToNonDeb()
regs := make([]*regexp.Regexp, 0)
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 {
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
import (
"github.com/blang/semver/v4"
"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
@ -23,7 +9,7 @@ import (
const TargetTypeMinikube Type = "minikube"
func init() {
byTarget[TargetTypeMinikube] = &minikube{
BuilderByTarget[TargetTypeMinikube] = &minikube{
vanilla{},
}
}
@ -36,8 +22,9 @@ func (m *minikube) Name() 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{
commonTemplateData: c.toTemplateData(m, kr),
KernelDownloadURL: urls[0],
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
import (
@ -22,9 +8,6 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/opensuse_kernel.sh
var opensuseKernelTemplate string
//go:embed templates/opensuse.sh
var opensuseTemplate string
@ -47,7 +30,7 @@ var baseURLs []string = []string{
}
// all known releases - will need to expand as more are added
var releases = []string{
var releases []string = []string{
// openSUSE leap
"43.2",
"15.0",
@ -64,7 +47,7 @@ var releases = []string{
}
func init() {
byTarget[TargetTypeOpenSUSE] = &opensuse{}
BuilderByTarget[TargetTypeOpenSUSE] = &opensuse{}
}
// opensuse is a driverkit target.
@ -72,6 +55,7 @@ type opensuse struct {
}
type opensuseTemplateData struct {
commonTemplateData
KernelDownloadURLs []string
}
@ -83,15 +67,11 @@ func (o *opensuse) Name() string {
return TargetTypeOpenSUSE.String()
}
func (o *opensuse) TemplateKernelUrlsScript() string {
return opensuseKernelTemplate
}
func (o *opensuse) TemplateScript() string {
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
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)
// trim the list to only resolving URLs
urls, err := GetResolvingURLs(possibleURLs)
urls, err := getResolvingURLs(possibleURLs)
if err != nil {
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{
commonTemplateData: cfg.toTemplateData(o, kr),
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
import (
_ "embed"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
// TargetTypePhoton identifies the Photon target.
const TargetTypePhoton Type = "photon"
//go:embed templates/photonos_kernel.sh
var photonKernelTemplate string
//go:embed templates/photonos.sh
var photonTemplate string
func init() {
byTarget[TargetTypePhoton] = &photon{}
BuilderByTarget[TargetTypePhoton] = &photon{}
}
// photon is a driverkit target.
@ -39,6 +21,7 @@ type photon struct {
}
type photonTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -46,21 +29,18 @@ func (p *photon) Name() string {
return TargetTypePhoton.String()
}
func (p *photon) TemplateKernelUrlsScript() string {
return photonKernelTemplate
}
func (p *photon) TemplateScript() string {
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
}
func (p *photon) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
func (p *photon) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
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{
"3.0",
"4.0",
"5.0",
}
var urls []string
urls := []string{}
for _, r := range photonReleases {
urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_%s_%s/%s/linux-devel-%s%s.x86_64.rpm",
r,
r,
kr.Architecture.ToNonDeb(),
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
))
urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_release_%s_%s/%s/linux-devel-%s%s.x86_64.rpm",
r,
r,
kr.Architecture.ToNonDeb(),
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
))
urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_updates_%s_%s/%s/linux-devel-%s%s.x86_64.rpm",
r,
r,
kr.Architecture.ToNonDeb(),
kr.Architecture.ToNonDeb(),
kr.Fullversion,
kr.FullExtraversion,
))
switch r {
case "3.0":
urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_updates_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
r,
r,
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,
))
case "4.0":
urls = append(urls, fmt.Sprintf(
"https://packages.vmware.com/photon/%s/photon_%s_x86_64/x86_64/linux-devel-%s%s.x86_64.rpm",
r,
r,
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
}

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
import (
_ "embed"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/redhat_kernel.sh
var redhatKernelTemplate string
//go:embed templates/redhat.sh
var redhatTemplate string
@ -34,10 +16,11 @@ type redhat struct {
}
func init() {
byTarget[TargetTypeRedhat] = &redhat{}
BuilderByTarget[TargetTypeRedhat] = &redhat{}
}
type redhatTemplateData struct {
commonTemplateData
KernelPackage string
}
@ -45,15 +28,11 @@ func (v *redhat) Name() string {
return TargetTypeRedhat.String()
}
func (v *redhat) TemplateKernelUrlsScript() string {
return redhatKernelTemplate
}
func (v *redhat) TemplateScript() string {
return redhatTemplate
}
func (v *redhat) URLs(_ kernelrelease.KernelRelease) ([]string, error) {
func (v *redhat) URLs(_ Config, _ kernelrelease.KernelRelease) ([]string, error) {
return nil, nil
}
@ -62,8 +41,9 @@ func (v *redhat) MinimumURLs() int {
return 0
}
func (v *redhat) KernelTemplateData(kr kernelrelease.KernelRelease, _ []string) interface{} {
func (v *redhat) TemplateData(c Config, kr kernelrelease.KernelRelease, _ []string) interface{} {
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
import (
_ "embed"
"fmt"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)
//go:embed templates/rocky_kernel.sh
var rockyKernelTemplate string
//go:embed templates/rocky.sh
var rockyTemplate string
@ -31,10 +13,11 @@ var rockyTemplate string
const TargetTypeRocky Type = "rocky"
func init() {
byTarget[TargetTypeRocky] = &rocky{}
BuilderByTarget[TargetTypeRocky] = &rocky{}
}
type rockyTemplateData struct {
commonTemplateData
KernelDownloadURL string
}
@ -46,21 +29,18 @@ func (c *rocky) Name() string {
return TargetTypeRocky.String()
}
func (c *rocky) TemplateKernelUrlsScript() string {
return rockyKernelTemplate
}
func (c *rocky) TemplateScript() string {
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
}
func (c *rocky) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
func (c *rocky) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
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
// byTarget maps targets to their builder.
var byTarget = map[Type]Builder{}
// BuilderByTarget maps targets to their builder.
var BuilderByTarget = Targets{}
// Type is a type representing targets.
type Type string
@ -23,3 +9,15 @@ type Type string
func (t Type) String() string {
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
# 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 }}
rm -Rf {{ .DriverBuildDir }}
mkdir {{ .DriverBuildDir }}
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 }}
# 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 }}
# Print results
modinfo {{ .ModuleFullPath }}
@ -36,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
cd {{ .DriverBuildDir }}/bpf
make KERNELDIR=/tmp/kernel
ls -l 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,41 +1,42 @@
#!/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 }}
rm -Rf {{ .DriverBuildDir }}
mkdir {{ .DriverBuildDir }}
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 }}
# Build the module
make CC=/usr/bin/gcc-{{ .GCCVersion }} LD=/usr/bin/ld.bfd CROSS_COMPILE="" driver
strip -g {{ .ModuleFullPath }}
# Build the kernel module
cd {{ .DriverBuildDir }}
make KERNELDIR=/tmp/kernel CC=/usr/bin/gcc-{{ .GCCVersion }} LD=/usr/bin/ld.bfd CROSS_COMPILE=""
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
# Print results
modinfo {{ .ModuleFullPath }}
{{ end }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
cd {{ .DriverBuildDir }}/bpf
make KERNELDIR=/tmp/kernel
ls -l probe.o
{{ 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
# 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 }}
rm -Rf {{ .DriverBuildDir }}
mkdir {{ .DriverBuildDir }}
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 }}
# 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 }}
# Print results
modinfo {{ .ModuleFullPath }}
@ -36,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
cd {{ .DriverBuildDir }}/bpf
make KERNELDIR=/tmp/kernel
ls -l 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.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
# 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 }}
sed -i 's/$(MAKE) -C $(KERNELDIR)/$(MAKE) KCFLAGS="-Wno-incompatible-pointer-types" -C $(KERNELDIR)/g' driver/Makefile.in
mkdir -p build && cd build
{{ .CmakeCmd }}
rm -Rf {{ .DriverBuildDir }}
mkdir {{ .DriverBuildDir }}
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 }}
# 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 }}
# Print results
modinfo {{ .ModuleFullPath }}
@ -37,6 +33,7 @@ modinfo {{ .ModuleFullPath }}
{{ if .BuildProbe }}
# Build the eBPF probe
make bpf
ls -l driver/bpf/probe.o
cd {{ .DriverBuildDir }}/bpf
make KERNELDIR=/tmp/kernel
ls -l 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

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