mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-26 22:52:14 +00:00
Compare commits
73 Commits
test/PR546
...
0.35.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92f884e070 | ||
|
|
60a006f0b1 | ||
|
|
ea0b44dc56 | ||
|
|
e83dbe85f7 | ||
|
|
f5c7574eba | ||
|
|
b50ccd4cd1 | ||
|
|
fb8205a2f7 | ||
|
|
369f733a36 | ||
|
|
7e5a578c89 | ||
|
|
564eed2dee | ||
|
|
24693a1e1e | ||
|
|
33b0173657 | ||
|
|
d4fa8d6d91 | ||
|
|
f25c057ce8 | ||
|
|
e1492ae9df | ||
|
|
b83b1e2578 | ||
|
|
c18d545259 | ||
|
|
b47ea18736 | ||
|
|
253100ab75 | ||
|
|
293d4c51f1 | ||
|
|
f006f2e01a | ||
|
|
5237aa196c | ||
|
|
4e25367350 | ||
|
|
593404e79e | ||
|
|
6650a4f31f | ||
|
|
d1e6452ad7 | ||
|
|
6d0aff7463 | ||
|
|
a193a46981 | ||
|
|
f448023a8f | ||
|
|
c225819186 | ||
|
|
a5efbc9483 | ||
|
|
ad75c87e21 | ||
|
|
fb105c4b04 | ||
|
|
fe8899c90a | ||
|
|
2de8c06bb1 | ||
|
|
86d33ae5ab | ||
|
|
9d6a7d8ca3 | ||
|
|
d27828a0d2 | ||
|
|
89f29e6d4b | ||
|
|
2a22189222 | ||
|
|
a5620b81b2 | ||
|
|
b9c0ca3abe | ||
|
|
008d908ee0 | ||
|
|
2f11d9f506 | ||
|
|
60d8c49772 | ||
|
|
3693cd0685 | ||
|
|
31da4b4c3d | ||
|
|
9551e9f277 | ||
|
|
2af7fd9f0f | ||
|
|
1c3aa7a83b | ||
|
|
18372323d9 | ||
|
|
be13ee044e | ||
|
|
ac4e27ccde | ||
|
|
d5b72f89f0 | ||
|
|
cafb804c11 | ||
|
|
6bf6a34a59 | ||
|
|
b138e4c9e1 | ||
|
|
53c9f3a743 | ||
|
|
1f4919bfe1 | ||
|
|
4d24a02ad6 | ||
|
|
8926022035 | ||
|
|
95fa953398 | ||
|
|
0d73f9624d | ||
|
|
0f1f413221 | ||
|
|
a77a58b2a9 | ||
|
|
91cca0bd0e | ||
|
|
06d36d6e1b | ||
|
|
3b64052832 | ||
|
|
88b9537618 | ||
|
|
5c0cd6a170 | ||
|
|
306d76d06b | ||
|
|
597f07ccae | ||
|
|
de23899e49 |
@@ -755,78 +755,78 @@ workflows:
|
||||
- "tests-driver-loader-integration":
|
||||
requires:
|
||||
- "build-centos7"
|
||||
- "rpm-sign":
|
||||
context: falco
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "tests-integration"
|
||||
- "tests-integration-arm64"
|
||||
- "publish-packages-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "rpm-sign"
|
||||
- "tests-integration-static"
|
||||
- "publish-packages-deb-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "tests-integration"
|
||||
- "tests-integration-arm64"
|
||||
- "build-docker-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "publish-packages-dev"
|
||||
- "publish-packages-deb-dev"
|
||||
- "tests-driver-loader-integration"
|
||||
- "build-docker-dev-arm64":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "publish-packages-dev"
|
||||
- "publish-packages-deb-dev"
|
||||
- "tests-driver-loader-integration"
|
||||
- "publish-docker-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "build-docker-dev"
|
||||
- "build-docker-dev-arm64"
|
||||
# - "rpm-sign":
|
||||
# context: falco
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "tests-integration"
|
||||
# - "tests-integration-arm64"
|
||||
# - "publish-packages-dev":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "rpm-sign"
|
||||
# - "tests-integration-static"
|
||||
# - "publish-packages-deb-dev":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "tests-integration"
|
||||
# - "tests-integration-arm64"
|
||||
# - "build-docker-dev":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "publish-packages-dev"
|
||||
# - "publish-packages-deb-dev"
|
||||
# - "tests-driver-loader-integration"
|
||||
# - "build-docker-dev-arm64":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "publish-packages-dev"
|
||||
# - "publish-packages-deb-dev"
|
||||
# - "tests-driver-loader-integration"
|
||||
# - "publish-docker-dev":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# filters:
|
||||
# tags:
|
||||
# ignore: /.*/
|
||||
# branches:
|
||||
# only: master
|
||||
# requires:
|
||||
# - "build-docker-dev"
|
||||
# - "build-docker-dev-arm64"
|
||||
# - "quality/static-analysis" # This is temporarily disabled: https://github.com/falcosecurity/falco/issues/1526
|
||||
release:
|
||||
jobs:
|
||||
@@ -848,73 +848,73 @@ workflows:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "rpm-sign":
|
||||
context: falco
|
||||
requires:
|
||||
- "build-centos7"
|
||||
- "build-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish-packages":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build-musl"
|
||||
- "rpm-sign"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish-packages-deb":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build-centos7"
|
||||
- "build-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "build-docker":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "publish-packages"
|
||||
- "publish-packages-deb"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "build-docker-arm64":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "publish-packages"
|
||||
- "publish-packages-deb"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish-docker":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build-docker"
|
||||
- "build-docker-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
# - "rpm-sign":
|
||||
# context: falco
|
||||
# requires:
|
||||
# - "build-centos7"
|
||||
# - "build-arm64"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# - "publish-packages":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# requires:
|
||||
# - "build-musl"
|
||||
# - "rpm-sign"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# - "publish-packages-deb":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# requires:
|
||||
# - "build-centos7"
|
||||
# - "build-arm64"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# - "build-docker":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# requires:
|
||||
# - "publish-packages"
|
||||
# - "publish-packages-deb"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# - "build-docker-arm64":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# requires:
|
||||
# - "publish-packages"
|
||||
# - "publish-packages-deb"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# - "publish-docker":
|
||||
# context:
|
||||
# - falco
|
||||
# - test-infra
|
||||
# requires:
|
||||
# - "build-docker"
|
||||
# - "build-docker-arm64"
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /.*/
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
|
||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -2,10 +2,14 @@ name: CI Build
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
push:
|
||||
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-minimal:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
93
.github/workflows/master.yaml
vendored
Normal file
93
.github/workflows/master.yaml
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
name: Dev Packages and Docker images
|
||||
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:
|
||||
# We need to use an ubuntu-latest to fetch Falco version because
|
||||
# Falco version is computed by some cmake scripts that do git sorceries
|
||||
# to get the current version.
|
||||
# But centos7 jobs have a git version too old and actions/checkout does not
|
||||
# fully clone the repo, but uses http rest api instead.
|
||||
fetch-version:
|
||||
runs-on: ubuntu-latest
|
||||
# Map the job outputs to step outputs
|
||||
outputs:
|
||||
version: ${{ steps.store_version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y cmake build-essential
|
||||
|
||||
- name: Configure project
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DUSE_BUNDLED_DEPS=On ..
|
||||
|
||||
- name: Load and store Falco version output
|
||||
id: store_version
|
||||
run: |
|
||||
FALCO_VERSION=$(cat build/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
echo "version=${FALCO_VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
build-dev-packages:
|
||||
needs: [fetch-version]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_packages.yaml@master
|
||||
with:
|
||||
arch: x86_64
|
||||
version: ${{ needs.fetch-version.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
build-dev-packages-arm64:
|
||||
needs: [fetch-version]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_packages.yaml@master
|
||||
with:
|
||||
arch: aarch64
|
||||
version: ${{ needs.fetch-version.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
publish-dev-packages:
|
||||
needs: [fetch-version, build-dev-packages, build-dev-packages-arm64]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_publish_packages.yaml@master
|
||||
with:
|
||||
bucket_suffix: '-dev'
|
||||
version: ${{ needs.fetch-version.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
build-dev-docker:
|
||||
needs: [fetch-version, publish-dev-packages]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_docker.yaml@master
|
||||
with:
|
||||
arch: x86_64
|
||||
bucket_suffix: '-dev'
|
||||
version: ${{ needs.fetch-version.outputs.version }}
|
||||
tag: master
|
||||
secrets: inherit
|
||||
|
||||
build-dev-docker-arm64:
|
||||
needs: [fetch-version, publish-dev-packages]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_docker.yaml@master
|
||||
with:
|
||||
arch: aarch64
|
||||
bucket_suffix: '-dev'
|
||||
version: ${{ needs.fetch-version.outputs.version }}
|
||||
tag: master
|
||||
secrets: inherit
|
||||
|
||||
publish-dev-docker:
|
||||
needs: [fetch-version, build-dev-docker, build-dev-docker-arm64]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_publish_docker.yaml@master
|
||||
with:
|
||||
tag: master
|
||||
secrets: inherit
|
||||
105
.github/workflows/release.yaml
vendored
Normal file
105
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
name: Release Packages and Docker images
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
# Checks if any concurrent jobs is running for release CI and eventually cancel it.
|
||||
concurrency:
|
||||
group: ci-release
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-settings:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
is_latest: ${{ steps.get_settings.outputs.is_latest }}
|
||||
bucket_suffix: ${{ steps.get_settings.outputs.bucket_suffix }}
|
||||
steps:
|
||||
- name: Get latest release
|
||||
uses: rez0n/actions-github-release@v2.0
|
||||
id: latest_release
|
||||
env:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repository: ${{ github.repository }}
|
||||
type: "stable"
|
||||
|
||||
- name: Get settings for this release
|
||||
id: get_settings
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
semver_no_meta = '''^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?$'''
|
||||
tag_name = '${{ github.event.release.tag_name }}'
|
||||
|
||||
is_valid_version = re.match(semver_no_meta, tag_name) is not None
|
||||
if not is_valid_version:
|
||||
print(f'Release version {tag_name} is not a valid full or pre-release. See RELEASE.md for more information.')
|
||||
sys.exit(1)
|
||||
|
||||
is_prerelease = '-' in tag_name
|
||||
|
||||
# Safeguard: you need to both set "latest" in GH and not have suffixes to overwrite latest
|
||||
is_latest = '${{ steps.latest_release.outputs.release }}' == tag_name and not is_prerelease
|
||||
|
||||
bucket_suffix = '-dev' if is_prerelease else ''
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as ofp:
|
||||
print(f'is_latest={is_latest}'.lower(), file=ofp)
|
||||
print(f'bucket_suffix={bucket_suffix}', file=ofp)
|
||||
|
||||
build-packages:
|
||||
needs: [release-settings]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_packages.yaml@master
|
||||
with:
|
||||
arch: x86_64
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
build-packages-arm64:
|
||||
needs: [release-settings]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_packages.yaml@master
|
||||
with:
|
||||
arch: aarch64
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
publish-packages:
|
||||
needs: [release-settings, build-packages, build-packages-arm64]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_publish_packages.yaml@master
|
||||
with:
|
||||
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
# Both build-docker and its arm64 counterpart require build-packages because they use its output
|
||||
build-docker:
|
||||
needs: [release-settings, build-packages, publish-packages]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_docker.yaml@master
|
||||
with:
|
||||
arch: x86_64
|
||||
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
build-docker-arm64:
|
||||
needs: [release-settings, build-packages, publish-packages]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_build_docker.yaml@master
|
||||
with:
|
||||
arch: aarch64
|
||||
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
publish-docker:
|
||||
needs: [release-settings, build-docker, build-docker-arm64]
|
||||
uses: falcosecurity/falco/.github/workflows/reusable_publish_docker.yaml@master
|
||||
secrets: inherit
|
||||
with:
|
||||
is_latest: ${{ needs.release-settings.outputs.is_latest == 'true' }}
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
sign: true
|
||||
74
.github/workflows/reusable_build_docker.yaml
vendored
Normal file
74
.github/workflows/reusable_build_docker.yaml
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
# This is a reusable workflow used by master and release CI
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
arch:
|
||||
description: x86_64 or aarch64
|
||||
required: true
|
||||
type: string
|
||||
bucket_suffix:
|
||||
description: bucket suffix for packages
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
version:
|
||||
description: The Falco version to use when building images
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
description: The tag to use (e.g. "master" or "0.35.0")
|
||||
required: true
|
||||
type: string
|
||||
|
||||
# Here we just build all docker images as tarballs,
|
||||
# then we upload all the tarballs to be later downloaded by reusable_publish_docker workflow.
|
||||
# In this way, we don't need to publish any arch specific image,
|
||||
# and this "build" workflow is actually only building images.
|
||||
jobs:
|
||||
build-docker:
|
||||
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
|
||||
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build no-driver image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ${{ github.workspace }}/docker/no-driver/
|
||||
build-args: |
|
||||
VERSION_BUCKET=bin${{ inputs.bucket_suffix }}
|
||||
FALCO_VERSION=${{ inputs.version }}
|
||||
tags: |
|
||||
docker.io/falcosecurity/falco-no-driver:${{ inputs.arch }}-${{ inputs.tag }}
|
||||
outputs: type=docker,dest=/tmp/falco-no-driver-${{ inputs.arch }}.tar
|
||||
|
||||
- name: Build falco image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ${{ github.workspace }}/docker/falco/
|
||||
build-args: |
|
||||
VERSION_BUCKET=deb${{ inputs.bucket_suffix }}
|
||||
FALCO_VERSION=${{ inputs.version }}
|
||||
tags: |
|
||||
docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}
|
||||
outputs: type=docker,dest=/tmp/falco-${{ inputs.arch }}.tar
|
||||
|
||||
- name: Build falco-driver-loader image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ${{ github.workspace }}/docker/driver-loader/
|
||||
build-args: |
|
||||
FALCO_IMAGE_TAG=${{ inputs.arch }}-${{ inputs.tag }}
|
||||
tags: |
|
||||
docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}
|
||||
outputs: type=docker,dest=/tmp/falco-driver-loader-${{ inputs.arch }}.tar
|
||||
|
||||
- name: Upload images tarballs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: falco-images
|
||||
path: /tmp/falco-*.tar
|
||||
160
.github/workflows/reusable_build_packages.yaml
vendored
Normal file
160
.github/workflows/reusable_build_packages.yaml
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
# This is a reusable workflow used by master and release CI
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
arch:
|
||||
description: x86_64 or aarch64
|
||||
required: true
|
||||
type: string
|
||||
version:
|
||||
description: The Falco version to use when building packages
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-modern-bpf-skeleton:
|
||||
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
|
||||
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
|
||||
container: fedora:latest
|
||||
steps:
|
||||
# Always install deps before invoking checkout action, to properly perform a full clone.
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
dnf install -y bpftool ca-certificates cmake make automake gcc gcc-c++ kernel-devel clang git pkg-config autoconf automake libbpf-devel
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build modern BPF skeleton
|
||||
run: |
|
||||
mkdir skeleton-build && cd skeleton-build
|
||||
cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_FALCO_MODERN_BPF=ON -DCREATE_TEST_TARGETS=Off -DFALCO_VERSION=${{ inputs.version }} ..
|
||||
make ProbeSkeleton -j6
|
||||
|
||||
- name: Upload skeleton
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bpf_probe_${{ inputs.arch }}.skel.h
|
||||
path: skeleton-build/skel_dir/bpf_probe.skel.h
|
||||
|
||||
build-packages:
|
||||
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
|
||||
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
|
||||
needs: [build-modern-bpf-skeleton]
|
||||
container: centos:7
|
||||
steps:
|
||||
# Always install deps before invoking checkout action, to properly perform a full clone.
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
yum -y install centos-release-scl
|
||||
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++
|
||||
source /opt/rh/devtoolset-9/enable
|
||||
yum install -y wget git make m4 rpm-build
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download skeleton
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: bpf_probe_${{ inputs.arch }}.skel.h
|
||||
path: /tmp
|
||||
|
||||
- name: Install updated cmake
|
||||
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)
|
||||
|
||||
- name: Prepare project
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
source /opt/rh/devtoolset-9/enable
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DUSE_BUNDLED_DEPS=On \
|
||||
-DFALCO_ETC_DIR=/etc/falco \
|
||||
-DBUILD_FALCO_MODERN_BPF=ON \
|
||||
-DMODERN_BPF_SKEL_DIR=/tmp \
|
||||
-DBUILD_DRIVER=Off \
|
||||
-DBUILD_BPF=Off \
|
||||
-DFALCO_VERSION=${{ inputs.version }} \
|
||||
..
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd build
|
||||
source /opt/rh/devtoolset-9/enable
|
||||
make falco -j6
|
||||
|
||||
- name: Build packages
|
||||
run: |
|
||||
cd build
|
||||
source /opt/rh/devtoolset-9/enable
|
||||
make package
|
||||
|
||||
- name: Upload Falco tar.gz package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-${{ inputs.arch }}.tar.gz
|
||||
path: |
|
||||
${{ github.workspace }}/build/falco-*.tar.gz
|
||||
|
||||
- name: Upload Falco deb package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-${{ inputs.arch }}.deb
|
||||
path: |
|
||||
${{ github.workspace }}/build/falco-*.deb
|
||||
|
||||
- name: Upload Falco rpm package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-${{ inputs.arch }}.rpm
|
||||
path: |
|
||||
${{ github.workspace }}/build/falco-*.rpm
|
||||
|
||||
build-musl-package:
|
||||
# x86_64 only for now
|
||||
if: ${{ inputs.arch == 'x86_64' }}
|
||||
runs-on: ubuntu-latest
|
||||
container: alpine:3.17
|
||||
steps:
|
||||
# Always install deps before invoking checkout action, to properly perform a full clone.
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils bpftool clang
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare project
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DCPACK_GENERATOR=TGZ -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DUSE_BUNDLED_LIBELF=Off -DBUILD_LIBSCAP_MODERN_BPF=ON -DMUSL_OPTIMIZED_BUILD=On -DFALCO_ETC_DIR=/etc/falco ../ -DFALCO_VERSION=${{ inputs.version }}
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd build
|
||||
make -j6 all
|
||||
|
||||
- name: Build packages
|
||||
run: |
|
||||
cd build
|
||||
make -j6 package
|
||||
|
||||
- name: Rename static package
|
||||
run: |
|
||||
cd build
|
||||
mv falco-${{ inputs.version }}-x86_64.tar.gz falco-${{ inputs.version }}-static-x86_64.tar.gz
|
||||
|
||||
- name: Upload Falco static package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
|
||||
path: |
|
||||
${{ github.workspace }}/build/falco-${{ inputs.version }}-static-x86_64.tar.gz
|
||||
144
.github/workflows/reusable_publish_docker.yaml
vendored
Normal file
144
.github/workflows/reusable_publish_docker.yaml
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
# This is a reusable workflow used by master and release CI
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tag:
|
||||
description: The tag to push
|
||||
required: true
|
||||
type: string
|
||||
is_latest:
|
||||
description: Update the latest tag with the new image
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
sign:
|
||||
description: Add signature with cosign
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish-docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Download images tarballs
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-images
|
||||
path: /tmp/falco-images
|
||||
|
||||
- name: Load all images
|
||||
run: |
|
||||
for img in /tmp/falco-images/falco-*.tar; do docker load --input $img; done
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USER }}
|
||||
password: ${{ secrets.DOCKERHUB_SECRET }}
|
||||
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco-ecr"
|
||||
aws-region: us-east-1 # The region must be set to us-east-1 in order to access ECR Public.
|
||||
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr-public
|
||||
uses: aws-actions/amazon-ecr-login@2f9f10ea3fa2eed41ac443fee8bfbd059af2d0a4 # v1.6.0
|
||||
with:
|
||||
registry-type: public
|
||||
|
||||
- name: Setup Crane
|
||||
uses: imjasonh/setup-crane@v0.3
|
||||
with:
|
||||
version: v0.15.1
|
||||
|
||||
# We're pushing the arch-specific manifests to Docker Hub so that we'll be able to easily create the index/multiarch later
|
||||
- name: Push arch-specific images to Docker Hub
|
||||
run: |
|
||||
docker push docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }}
|
||||
docker push docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
|
||||
docker push docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }}
|
||||
docker push docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
|
||||
docker push docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}
|
||||
docker push docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
|
||||
|
||||
- name: Create no-driver manifest on Docker Hub
|
||||
uses: Noelware/docker-manifest-action@0.3.1
|
||||
with:
|
||||
inputs: docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }}
|
||||
images: docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
|
||||
push: true
|
||||
|
||||
- name: Tag slim manifest on Docker Hub
|
||||
run: |
|
||||
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} docker.io/falcosecurity/falco:${{ inputs.tag }}-slim
|
||||
|
||||
- name: Create falco manifest on Docker Hub
|
||||
uses: Noelware/docker-manifest-action@0.3.1
|
||||
with:
|
||||
inputs: docker.io/falcosecurity/falco:${{ inputs.tag }}
|
||||
images: docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
|
||||
push: true
|
||||
|
||||
- name: Create falco-driver-loader manifest on Docker Hub
|
||||
uses: Noelware/docker-manifest-action@0.3.1
|
||||
with:
|
||||
inputs: docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}
|
||||
images: docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
|
||||
push: true
|
||||
|
||||
- name: Get Digests for images
|
||||
id: digests
|
||||
run: |
|
||||
echo "falco-no-driver=$(crane digest docker.io/falcosecurity/falco-no-driver:${{ inputs.version }})" >> $GITHUB_OUTPUT
|
||||
echo "falco=$(crane digest docker.io/falcosecurity/falco:${{ inputs.version }})" >> $GITHUB_OUTPUT
|
||||
echo "falco-driver-loader=$(crane digest docker.io/falcosecurity/falco-driver-loader:${{ inputs.version }})" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish images to ECR
|
||||
run: |
|
||||
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }}
|
||||
crane copy docker.io/falcosecurity/falco:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}
|
||||
crane copy docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}
|
||||
crane copy public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim
|
||||
|
||||
- name: Tag latest on Docker Hub and ECR
|
||||
if: inputs.is_latest
|
||||
run: |
|
||||
crane tag docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
|
||||
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }} latest
|
||||
crane tag docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
|
||||
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
|
||||
|
||||
crane tag public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
|
||||
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }} latest
|
||||
crane tag public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
|
||||
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
|
||||
|
||||
- name: Setup Cosign
|
||||
if: inputs.sign
|
||||
uses: sigstore/cosign-installer@main
|
||||
with:
|
||||
cosign-release: v2.0.2
|
||||
|
||||
- name: Sign images with cosign
|
||||
if: inputs.sign
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: "true"
|
||||
COSIGN_YES: "true"
|
||||
run: |
|
||||
cosign sign docker.io/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
|
||||
cosign sign docker.io/falcosecurity/falco@${{ steps.digests.outputs.falco }}
|
||||
cosign sign docker.io/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
|
||||
|
||||
cosign sign public.ecr.aws/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
|
||||
cosign sign public.ecr.aws/falcosecurity/falco@${{ steps.digests.outputs.falco }}
|
||||
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
|
||||
150
.github/workflows/reusable_publish_packages.yaml
vendored
Normal file
150
.github/workflows/reusable_publish_packages.yaml
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
# This is a reusable workflow used by master and release CI
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
version:
|
||||
description: The Falco version to use when publishing packages
|
||||
required: true
|
||||
type: string
|
||||
bucket_suffix:
|
||||
description: bucket suffix for packages
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
env:
|
||||
AWS_S3_REGION: eu-west-1
|
||||
AWS_CLOUDFRONT_DIST_ID: E1CQNPFWRXLGQD
|
||||
|
||||
jobs:
|
||||
publish-packages:
|
||||
runs-on: ubuntu-latest
|
||||
container: docker.io/centos:7
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
yum install epel-release -y
|
||||
yum update -y
|
||||
yum install rpm-sign expect which createrepo gpg python python-pip -y
|
||||
pip install awscli==1.19.47
|
||||
|
||||
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
|
||||
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
|
||||
aws-region: ${{ env.AWS_S3_REGION }}
|
||||
|
||||
- name: Download RPM x86_64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-x86_64.rpm
|
||||
path: /tmp/falco-rpm
|
||||
|
||||
- name: Download RPM aarch64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-aarch64.rpm
|
||||
path: /tmp/falco-rpm
|
||||
|
||||
- name: Download binary x86_64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-x86_64.tar.gz
|
||||
path: /tmp/falco-bin
|
||||
|
||||
- name: Download binary aarch64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-aarch64.tar.gz
|
||||
path: /tmp/falco-bin
|
||||
|
||||
- name: Download static binary x86_64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
|
||||
path: /tmp/falco-bin-static
|
||||
|
||||
- name: Import gpg key
|
||||
env:
|
||||
GPG_KEY: ${{ secrets.GPG_KEY }}
|
||||
run: printenv GPG_KEY | gpg --import -
|
||||
|
||||
- name: Sign rpms
|
||||
run: |
|
||||
echo "%_signature gpg" > ~/.rpmmacros
|
||||
echo "%_gpg_name Falcosecurity Package Signing" >> ~/.rpmmacros
|
||||
echo "%__gpg_sign_cmd %{__gpg} --force-v3-sigs --batch --no-armor --passphrase-fd 3 --no-secmem-warning -u \"%{_gpg_name}\" -sb --digest-algo sha256 %{__plaintext_filename}'" >> ~/.rpmmacros
|
||||
cat > ~/sign <<EOF
|
||||
#!/usr/bin/expect -f
|
||||
spawn rpmsign --addsign {*}\$argv
|
||||
expect -exact "Enter pass phrase: "
|
||||
send -- "\n"
|
||||
expect eof
|
||||
EOF
|
||||
chmod +x ~/sign
|
||||
~/sign /tmp/falco-rpm/falco-*.rpm
|
||||
rpm --qf %{SIGPGP:pgpsig} -qp /tmp/falco-rpm/falco-*.rpm | grep SHA256
|
||||
|
||||
- name: Publish rpm
|
||||
run: |
|
||||
./scripts/publish-rpm -f /tmp/falco-rpm/falco-${{ inputs.version }}-x86_64.rpm -f /tmp/falco-rpm/falco-${{ inputs.version }}-aarch64.rpm -r rpm${{ inputs.bucket_suffix }}
|
||||
|
||||
- name: Publish bin
|
||||
run: |
|
||||
./scripts/publish-bin -f /tmp/falco-bin/falco-${{ inputs.version }}-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
|
||||
./scripts/publish-bin -f /tmp/falco-bin/falco-${{ inputs.version }}-aarch64.tar.gz -r bin${{ inputs.bucket_suffix }} -a aarch64
|
||||
|
||||
- name: Publish static
|
||||
run: |
|
||||
./scripts/publish-bin -f /tmp/falco-bin-static/falco-${{ inputs.version }}-static-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
|
||||
|
||||
publish-packages-deb:
|
||||
runs-on: ubuntu-latest
|
||||
container: docker.io/debian:stable
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt update -y
|
||||
apt-get install apt-utils bzip2 gpg python python3-pip -y
|
||||
pip install awscli
|
||||
|
||||
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
|
||||
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
|
||||
aws-region: ${{ env.AWS_S3_REGION }}
|
||||
|
||||
- name: Download deb x86_64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-x86_64.deb
|
||||
path: /tmp/falco-deb
|
||||
|
||||
- name: Download deb aarch64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: falco-${{ inputs.version }}-aarch64.deb
|
||||
path: /tmp/falco-deb
|
||||
|
||||
- name: Import gpg key
|
||||
env:
|
||||
GPG_KEY: ${{ secrets.GPG_KEY }}
|
||||
run: printenv GPG_KEY | gpg --import -
|
||||
|
||||
- name: Publish deb
|
||||
run: |
|
||||
./scripts/publish-deb -f /tmp/falco-deb/falco-${{ inputs.version }}-x86_64.deb -f /tmp/falco-deb/falco-${{ inputs.version }}-aarch64.deb -r deb${{ inputs.bucket_suffix }}
|
||||
40
RELEASE.md
40
RELEASE.md
@@ -113,26 +113,29 @@ The release PR is meant to be made against the respective `release/M.m.x` branch
|
||||
- Close the completed milestone as soon as the PR is merged into the release branch
|
||||
- Cherry pick the PR on master too
|
||||
|
||||
## Publishing Pre-Releases (RCs and tagged development versions)
|
||||
|
||||
Core maintainers and/or the release manager can decide to publish pre-releases at any time before the final release
|
||||
is live for development and testing purposes.
|
||||
|
||||
The prerelease tag must be formatted as `M.m.p-r`where `r` is the prerelease version information (e.g. `0.35.0-rc1`.)
|
||||
|
||||
To do so:
|
||||
|
||||
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
|
||||
- Use `M.m.p-r` both as tag version and release title.
|
||||
- Check the "Set as a pre-release" checkbox and make sure "Set as the latest release" is unchecked
|
||||
- It is recommended to add a brief description so that other contributors will understand the reason why the prerelease is published
|
||||
- Publish the prerelease!
|
||||
- The release pipeline will start automatically. Packages will be uploaded to the `-dev` bucket and container images will be tagged with the specified tag.
|
||||
|
||||
In order to check the status of the release pipeline click on the [GitHub Actions tab](https://github.com/falcosecurity/falco/actions?query=event%3Arelease) in the Falco repository and filter by release.
|
||||
|
||||
## Release
|
||||
|
||||
Assume `M.m.p` is the new version.
|
||||
|
||||
### 1. Create a tag
|
||||
|
||||
- Once the release PR has got merged both on the release branch and on master, and the master CI has done its job, git tag the new release on the release branch:
|
||||
|
||||
```
|
||||
git pull
|
||||
git checkout release/M.m.x
|
||||
git tag M.m.p
|
||||
git push origin M.m.p
|
||||
```
|
||||
|
||||
> **N.B.**: do NOT use an annotated tag. For reference https://git-scm.com/book/en/v2/Git-Basics-Tagging
|
||||
|
||||
- Wait for the CI to complete
|
||||
|
||||
### 2. Update the GitHub release
|
||||
### 1. Create the release with GitHub
|
||||
|
||||
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
|
||||
- Use `M.m.p` both as tag version and release title
|
||||
@@ -176,8 +179,11 @@ Assume `M.m.p` is the new version.
|
||||
```
|
||||
|
||||
- Finally, publish the release!
|
||||
- The release pipeline will start automatically upon publication and all packages and container images will be uploaded to the stable repositories.
|
||||
|
||||
### 3. Update the meeting notes
|
||||
In order to check the status of the release pipeline click on the [GitHub Actions tab](https://github.com/falcosecurity/falco/actions?query=event%3Arelease) in the Falco repository and filter by release.
|
||||
|
||||
### 2. Update the meeting notes
|
||||
|
||||
For each release we archive the meeting notes in git for historical purposes.
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ else()
|
||||
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
||||
if(NOT DRIVER_VERSION)
|
||||
set(DRIVER_VERSION "2024af2e264e1cd76ec8bc43924f1857937848a8")
|
||||
set(DRIVER_CHECKSUM "SHA256=af98c4c505882a899eab38a7f7b7cc92cba634d81a110a18c42243214f9ffc5f")
|
||||
set(DRIVER_VERSION "ffcd702cf22e99d4d999c278be0cc3d713c6375c")
|
||||
set(DRIVER_CHECKSUM "SHA256=7ed19cd8e13887b02c823f5167aac3d1e997b0a60e305979848dfb339e1b774d")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -27,8 +27,8 @@ else()
|
||||
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||
set(FALCOSECURITY_LIBS_VERSION "2024af2e264e1cd76ec8bc43924f1857937848a8")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=af98c4c505882a899eab38a7f7b7cc92cba634d81a110a18c42243214f9ffc5f")
|
||||
set(FALCOSECURITY_LIBS_VERSION "ffcd702cf22e99d4d999c278be0cc3d713c6375c")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=7ed19cd8e13887b02c823f5167aac3d1e997b0a60e305979848dfb339e1b774d")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -232,9 +232,8 @@ syscall_drop_failed_exit: false
|
||||
|
||||
syscall_buf_size_preset: 4
|
||||
|
||||
############## [EXPERIMENTAL] Modern BPF probe specific ##############
|
||||
# Please note: these configs regard only the modern BPF probe. They
|
||||
# are experimental so they could change over releases.
|
||||
############## Modern BPF probe specific ##############
|
||||
# Please note: these configs regard only the modern BPF probe.
|
||||
#
|
||||
# `cpus_for_each_syscall_buffer`
|
||||
#
|
||||
@@ -297,7 +296,7 @@ syscall_buf_size_preset: 4
|
||||
|
||||
modern_bpf:
|
||||
cpus_for_each_syscall_buffer: 2
|
||||
############## [EXPERIMENTAL] Modern BPF probe specific ##############
|
||||
############## Modern BPF probe specific ##############
|
||||
|
||||
# Falco continuously monitors outputs performance. When an output channel does not allow
|
||||
# to deliver an alert within a given deadline, an error is reported indicating
|
||||
|
||||
@@ -128,10 +128,38 @@ get_target_id() {
|
||||
|
||||
case "${OS_ID}" in
|
||||
("amzn")
|
||||
if [[ $VERSION_ID == "2" ]]; then
|
||||
case "${VERSION_ID}" in
|
||||
("2")
|
||||
TARGET_ID="amazonlinux2"
|
||||
else
|
||||
;;
|
||||
("2022")
|
||||
TARGET_ID="amazonlinux2022"
|
||||
;;
|
||||
("2023")
|
||||
TARGET_ID="amazonlinux2023"
|
||||
;;
|
||||
(*)
|
||||
TARGET_ID="amazonlinux"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
("debian")
|
||||
# Workaround: debian kernelreleases might now be actual kernel running;
|
||||
# instead, they might be the Debian kernel package
|
||||
# providing the compatible kernel ABI
|
||||
# See https://lists.debian.org/debian-user/2017/03/msg00485.html
|
||||
# Real kernel release is embedded inside the kernel version.
|
||||
# Moreover, kernel arch, when present, is attached to the former,
|
||||
# therefore make sure to properly take it and attach it to the latter.
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
local ARCH_extra=""
|
||||
if [[ $KERNEL_RELEASE =~ -(amd64|arm64) ]];
|
||||
then
|
||||
ARCH_extra="-${BASH_REMATCH[1]}"
|
||||
fi
|
||||
if [[ $(uname -v) =~ ([0-9]+\.[0-9]+\.[0-9]+\-[0-9]+) ]];
|
||||
then
|
||||
KERNEL_RELEASE="${BASH_REMATCH[1]}${ARCH_extra}"
|
||||
fi
|
||||
;;
|
||||
("ubuntu")
|
||||
@@ -151,7 +179,7 @@ get_target_id() {
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
;;
|
||||
("minikube")
|
||||
TARGET_ID="${OS_ID}"
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
# Extract the minikube version. Ex. With minikube version equal to "v1.26.0-1655407986-14197" the extracted version
|
||||
# will be "1.26.0"
|
||||
if [[ $(cat ${HOST_ROOT}/etc/VERSION) =~ ([0-9]+(\.[0-9]+){2}) ]]; then
|
||||
@@ -163,7 +191,7 @@ get_target_id() {
|
||||
fi
|
||||
;;
|
||||
("bottlerocket")
|
||||
TARGET_ID="${OS_ID}"
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
# variant_id has been sourced from os-release. Get only the first variant part
|
||||
if [[ -n ${VARIANT_ID} ]]; then
|
||||
# take just first part (eg: VARIANT_ID=aws-k8s-1.15 -> aws)
|
||||
@@ -232,10 +260,10 @@ load_kernel_module_compile() {
|
||||
continue
|
||||
fi
|
||||
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
|
||||
echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make
|
||||
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
|
||||
chmod +x /tmp/falco-dkms-make
|
||||
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
|
||||
echo "#!/usr/bin/env bash" > "${TMPDIR}/falco-dkms-make"
|
||||
echo "make CC=${CURRENT_GCC} \$@" >> "${TMPDIR}/falco-dkms-make"
|
||||
chmod +x "${TMPDIR}/falco-dkms-make"
|
||||
if dkms install --directive="MAKE='${TMPDIR}/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
|
||||
echo "* ${DRIVER_NAME} module installed in dkms"
|
||||
KO_FILE="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}"
|
||||
if [ -f "$KO_FILE.ko" ]; then
|
||||
@@ -659,6 +687,8 @@ if [ -v FALCO_BPF_PROBE ]; then
|
||||
DRIVER="bpf"
|
||||
fi
|
||||
|
||||
TMPDIR=${TMPDIR:-"/tmp"}
|
||||
|
||||
ENABLE_COMPILE=
|
||||
ENABLE_DOWNLOAD=
|
||||
|
||||
|
||||
Submodule submodules/falcosecurity-rules updated: 694adf59e0...f7735788b1
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
|
||||
#include <falco_engine.h>
|
||||
|
||||
#include <falco/app/app.h>
|
||||
#include <falco/app/state.h>
|
||||
#include <falco/app/actions/actions.h>
|
||||
|
||||
@@ -91,6 +92,7 @@ static std::shared_ptr<falco_engine> mock_engine_from_filters(const strset_t& fi
|
||||
|
||||
TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
|
||||
{
|
||||
|
||||
auto engine = mock_engine_from_filters(s_sample_filters);
|
||||
auto enabled_count = engine->num_rules_for_ruleset(s_sample_ruleset);
|
||||
ASSERT_EQ(enabled_count, s_sample_filters.size());
|
||||
@@ -105,39 +107,39 @@ TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
|
||||
// note, this is not supposed to contain "container", as that's an event
|
||||
// not mapped through the ppm_sc_code enumerative.
|
||||
auto rules_sc_set = engine->sc_codes_for_ruleset(s_sample_source);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_names(rules_sc_set);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_event_names(rules_sc_set);
|
||||
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, preconditions_postconditions)
|
||||
{
|
||||
falco::app::state s;
|
||||
auto mock_engine = mock_engine_from_filters(s_sample_filters);
|
||||
falco::app::state s1;
|
||||
|
||||
s.engine = mock_engine;
|
||||
s.config = nullptr;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s1.engine = mock_engine;
|
||||
s1.config = nullptr;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s1);
|
||||
ASSERT_FALSE(result.success);
|
||||
ASSERT_NE(result.errstr, "");
|
||||
|
||||
s.engine = nullptr;
|
||||
s.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s1.engine = nullptr;
|
||||
s1.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s1);
|
||||
ASSERT_FALSE(result.success);
|
||||
ASSERT_NE(result.errstr, "");
|
||||
|
||||
s.engine = mock_engine;
|
||||
s.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s1.engine = mock_engine;
|
||||
s1.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s1);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
auto prev_selection_size = s.selected_sc_set.size();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
auto prev_selection_size = s1.selected_sc_set.size();
|
||||
result = falco::app::actions::configure_interesting_sets(s1);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
ASSERT_EQ(prev_selection_size, s.selected_sc_set.size());
|
||||
ASSERT_EQ(prev_selection_size, s1.selected_sc_set.size());
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, engine_codes_nonsyscalls_set)
|
||||
@@ -164,20 +166,22 @@ TEST(ConfigureInterestingSets, engine_codes_nonsyscalls_set)
|
||||
ASSERT_NAMES_EQ(rules_event_names, expected_names);
|
||||
|
||||
auto rules_sc_set = engine->sc_codes_for_ruleset(s_sample_source);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_names(rules_sc_set);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_event_names(rules_sc_set);
|
||||
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read",
|
||||
"syncfs", "fanotify_init", // from generic event filters
|
||||
"procexit", "switch", "syncfs", "fanotify_init", // from generic event filters
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_not_allevents)
|
||||
{
|
||||
falco::app::state s2;
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s.options.all_events = false;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s2.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s2.options.all_events = false;
|
||||
|
||||
ASSERT_EQ(s2.options.all_events, false);
|
||||
auto result = falco::app::actions::configure_interesting_sets(s2);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
@@ -185,8 +189,8 @@ TEST(ConfigureInterestingSets, selection_not_allevents)
|
||||
// also check if a warning has been printed in stderr
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_GT(s.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
ASSERT_GT(s2.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s2.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to have been erased
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", // from ruleset
|
||||
@@ -196,31 +200,31 @@ TEST(ConfigureInterestingSets, selection_not_allevents)
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// check that all IO syscalls have been erased from the selection
|
||||
auto io_set = libsinsp::events::io_sc_set();
|
||||
auto erased_sc_names = libsinsp::events::sc_set_to_names(io_set);
|
||||
auto ignored_set = falco::app::ignored_sc_set();
|
||||
auto erased_sc_names = libsinsp::events::sc_set_to_event_names(ignored_set);
|
||||
ASSERT_NAMES_NOCONTAIN(selected_sc_names, erased_sc_names);
|
||||
|
||||
// check that final selected set is exactly sinsp state + ruleset
|
||||
auto rule_set = s.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto rule_set = s2.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto state_set = libsinsp::events::sinsp_state_sc_set();
|
||||
for (const auto &erased : io_set)
|
||||
for (const auto &erased : ignored_set)
|
||||
{
|
||||
rule_set.remove(erased);
|
||||
state_set.remove(erased);
|
||||
}
|
||||
auto union_set = state_set.merge(rule_set);
|
||||
auto inter_set = state_set.intersect(rule_set);
|
||||
ASSERT_EQ(s.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s.selected_sc_set, union_set);
|
||||
EXPECT_EQ(s2.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s2.selected_sc_set, union_set);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_allevents)
|
||||
{
|
||||
falco::app::state s3;
|
||||
// run app action with fake engine and with the `-A` option
|
||||
falco::app::state s;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s.options.all_events = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s3.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s3.options.all_events = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s3);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
@@ -228,8 +232,8 @@ TEST(ConfigureInterestingSets, selection_allevents)
|
||||
// also check if a warning has not been printed in stderr
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_GT(s.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
ASSERT_GT(s3.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s3.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to not be erased
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", // from ruleset
|
||||
@@ -239,29 +243,29 @@ TEST(ConfigureInterestingSets, selection_allevents)
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// check that final selected set is exactly sinsp state + ruleset
|
||||
auto rule_set = s.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto rule_set = s3.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto state_set = libsinsp::events::sinsp_state_sc_set();
|
||||
auto union_set = state_set.merge(rule_set);
|
||||
auto inter_set = state_set.intersect(rule_set);
|
||||
ASSERT_EQ(s.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s.selected_sc_set, union_set);
|
||||
EXPECT_EQ(s3.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s3.selected_sc_set, union_set);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_generic_evts)
|
||||
{
|
||||
falco::app::state s4;
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.options.all_events = false;
|
||||
s4.options.all_events = false;
|
||||
auto filters = s_sample_filters;
|
||||
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
|
||||
s.engine = mock_engine_from_filters(filters);
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s4.engine = mock_engine_from_filters(filters);
|
||||
auto result = falco::app::actions::configure_interesting_sets(s4);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_GT(s.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
ASSERT_GT(s4.selected_sc_set.size(), 1);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s4.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to not be erased
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", // from ruleset
|
||||
@@ -270,7 +274,7 @@ TEST(ConfigureInterestingSets, selection_generic_evts)
|
||||
"socket", "bind", "close" // from sinsp state set (network, files)
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set());
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
|
||||
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
|
||||
}
|
||||
|
||||
@@ -281,19 +285,19 @@ TEST(ConfigureInterestingSets, selection_generic_evts)
|
||||
// - if `-A` is not set, events from the IO set are removed from the selected set
|
||||
TEST(ConfigureInterestingSets, selection_custom_base_set)
|
||||
{
|
||||
falco::app::state s5;
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.options.all_events = true;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s5.options.all_events = true;
|
||||
s5.engine = mock_engine_from_filters(s_sample_filters);
|
||||
auto default_base_set = libsinsp::events::sinsp_state_sc_set();
|
||||
|
||||
// non-empty custom base set (both positive and negative)
|
||||
s.config->m_base_syscalls_repair = false;
|
||||
s.config->m_base_syscalls_custom_set = {"syncfs", "!accept"};
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s5.config->m_base_syscalls_repair = false;
|
||||
s5.config->m_base_syscalls_custom_set = {"syncfs", "!accept"};
|
||||
auto result = falco::app::actions::configure_interesting_sets(s5);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: `syncfs` has been added due to the custom base set, and `accept`
|
||||
// has been remove due to the negative base set.
|
||||
@@ -301,90 +305,127 @@ TEST(ConfigureInterestingSets, selection_custom_base_set)
|
||||
// note: `accept` is not included even though it is matched by the rules,
|
||||
// which means that the custom negation base set has precedence over the
|
||||
// final selection set as a whole
|
||||
// todo(jasondellaluce): add "accept4" once names_to_sc_set is polished on the libs side
|
||||
"connect", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit"
|
||||
// note(jasondellaluce): "accept4" should be added, however old versions
|
||||
// of the ACCEPT4 event are actually named "accept" in the event table
|
||||
"connect", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "procexit"
|
||||
});
|
||||
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (both positive and negative with collision)
|
||||
s.config->m_base_syscalls_repair = false;
|
||||
s.config->m_base_syscalls_custom_set = {"syncfs", "accept", "!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s5.config->m_base_syscalls_repair = false;
|
||||
s5.config->m_base_syscalls_custom_set = {"syncfs", "accept", "!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s5);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
|
||||
// note: in case of collision, negation has priority, so the expected
|
||||
// names are the same as the case above
|
||||
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (only positive)
|
||||
s.config->m_base_syscalls_custom_set = {"syncfs"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s5.config->m_base_syscalls_custom_set = {"syncfs"};
|
||||
result = falco::app::actions::configure_interesting_sets(s5);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
|
||||
expected_sc_names = strset_t({
|
||||
// note: accept is not negated anymore
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit"
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "procexit"
|
||||
});
|
||||
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (only negative)
|
||||
s.config->m_base_syscalls_custom_set = {"!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s5.config->m_base_syscalls_custom_set = {"!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s5);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
|
||||
expected_sc_names = unordered_set_union(
|
||||
libsinsp::events::sc_set_to_names(default_base_set),
|
||||
libsinsp::events::sc_set_to_event_names(default_base_set),
|
||||
strset_t({ "connect", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
|
||||
expected_sc_names.erase("accept");
|
||||
// todo(jasondellaluce): add "accept4" once names_to_sc_set is polished on the libs side
|
||||
// note(jasondellaluce): "accept4" should be included, however old versions
|
||||
// of the ACCEPT4 event are actually named "accept" in the event table
|
||||
expected_sc_names.erase("accept4");
|
||||
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (positive, without -A)
|
||||
s.options.all_events = false;
|
||||
s.config->m_base_syscalls_custom_set = {"read"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
s5.options.all_events = false;
|
||||
s5.config->m_base_syscalls_custom_set = {"read"};
|
||||
result = falco::app::actions::configure_interesting_sets(s5);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
|
||||
expected_sc_names = strset_t({
|
||||
// note: read is both part of the custom base set and the rules set,
|
||||
// but we expect the unset -A option to take precedence
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "sched_process_exit"
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit"
|
||||
});
|
||||
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set());
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
|
||||
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_custom_base_set_repair)
|
||||
{
|
||||
falco::app::state s6;
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.options.all_events = false;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s6.options.all_events = false;
|
||||
s6.engine = mock_engine_from_filters(s_sample_filters);
|
||||
|
||||
// simulate empty custom set but repair option set.
|
||||
// note: here we use file syscalls (e.g. open, openat) and have a custom
|
||||
// positive set, so we expect syscalls such as "close" to be selected as
|
||||
// repaired. Also, given that we use some network syscalls, we expect "bind"
|
||||
// to be selected event if we negate it, because repairment should have
|
||||
// take precedence.
|
||||
s.config->m_base_syscalls_custom_set = {"openat", "!bind"};
|
||||
s.config->m_base_syscalls_repair = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
s6.config->m_base_syscalls_custom_set = {"openat", "!bind"};
|
||||
s6.config->m_base_syscalls_repair = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s6);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s6.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: expecting syscalls from mock rules and `sinsp_repair_state_sc_set` enforced syscalls
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "sched_process_exit", \
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit", \
|
||||
"bind", "socket", "clone3", "close", "setuid"
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set());
|
||||
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
|
||||
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_empty_custom_base_set_repair)
|
||||
{
|
||||
falco::app::state s7;
|
||||
// run app action with fake engine and with the `-A` option
|
||||
s7.options.all_events = true;
|
||||
s7.engine = mock_engine_from_filters(s_sample_filters);
|
||||
|
||||
// simulate empty custom set but repair option set.
|
||||
s7.config->m_base_syscalls_custom_set = {};
|
||||
s7.config->m_base_syscalls_repair = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s7);
|
||||
auto s7_rules_set = s7.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s7.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: expecting syscalls from mock rules and `sinsp_repair_state_sc_set` enforced syscalls
|
||||
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit", \
|
||||
"bind", "socket", "clone3", "close", "setuid"
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
auto s7_state_set = libsinsp::events::sinsp_repair_state_sc_set(s7_rules_set);
|
||||
ASSERT_EQ(s7.selected_sc_set, s7_state_set);
|
||||
ASSERT_EQ(s7.selected_sc_set.size(), s7_state_set.size());
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, ignored_set_expected_size)
|
||||
{
|
||||
// unit test fence to make sure we don't have unexpected regressions
|
||||
// in the ignored set, to be updated in the future
|
||||
ASSERT_EQ(falco::app::ignored_sc_set().size(), 14);
|
||||
|
||||
// we don't expect to ignore any syscall in the default base set
|
||||
ASSERT_EQ(falco::app::ignored_sc_set().intersect(libsinsp::events::sinsp_state_sc_set()).size(), 0);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,18 @@ TEST(ActionSelectEventSources, pre_post_conditions)
|
||||
falco::app::state s;
|
||||
s.loaded_sources = {"syscall", "some_source"};
|
||||
EXPECT_ACTION_OK(action(s));
|
||||
EXPECT_EQ(s.loaded_sources, s.enabled_sources);
|
||||
s.loaded_sources.insert("another_source");
|
||||
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
|
||||
for (const auto& v : s.loaded_sources)
|
||||
{
|
||||
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
|
||||
}
|
||||
s.loaded_sources.push_back("another_source");
|
||||
EXPECT_ACTION_OK(action(s));
|
||||
EXPECT_EQ(s.loaded_sources, s.enabled_sources);
|
||||
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
|
||||
for (const auto& v : s.loaded_sources)
|
||||
{
|
||||
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
|
||||
}
|
||||
}
|
||||
|
||||
// enable only selected sources
|
||||
|
||||
@@ -52,7 +52,7 @@ struct falco_exception : std::exception
|
||||
|
||||
namespace falco_common
|
||||
{
|
||||
const std::string syscall_source = "syscall";
|
||||
const std::string syscall_source = sinsp_syscall_event_source_name;
|
||||
|
||||
// Same as numbers/indices into the above vector
|
||||
enum priority_type
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
// of all output expressions. You can also choose to replace
|
||||
// %container.info with the extra information or add it to the
|
||||
// end of the expression. This is used in open source falco to
|
||||
// add k8s/mesos/container information to outputs when
|
||||
// add k8s/container information to outputs when
|
||||
// available.
|
||||
//
|
||||
void set_extra(std::string &extra, bool replace_container_info);
|
||||
|
||||
@@ -21,4 +21,4 @@ limitations under the License.
|
||||
// This is the result of running "falco --list -N | sha256sum" and
|
||||
// represents the fields supported by this version of Falco. It's used
|
||||
// at build time to detect a changed set of fields.
|
||||
#define FALCO_FIELDS_CHECKSUM "8684342b994f61ca75a1a494e1197b86b53715c59ad60de3768d4d74ea4ba2c9"
|
||||
#define FALCO_FIELDS_CHECKSUM "8c28f9cdff607c308e3ba56db36f998f20119cdd7cf3da11e53c181204077da2"
|
||||
|
||||
@@ -15,6 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
#include "actions.h"
|
||||
#include "helpers.h"
|
||||
#include "../app.h"
|
||||
|
||||
using namespace falco::app;
|
||||
using namespace falco::app::actions;
|
||||
@@ -44,7 +46,7 @@ static void check_for_rules_unsupported_events(falco::app::state& s, const libsi
|
||||
{
|
||||
/* Unsupported events are those events that are used in the rules
|
||||
* but that are not part of the selected event set. For now, this
|
||||
* is expected to happen only for high volume I/O syscalls for
|
||||
* is expected to happen only for high volume syscalls for
|
||||
* performance reasons. */
|
||||
auto unsupported_sc_set = rules_sc_set.diff(s.selected_sc_set);
|
||||
if (unsupported_sc_set.empty())
|
||||
@@ -53,9 +55,9 @@ static void check_for_rules_unsupported_events(falco::app::state& s, const libsi
|
||||
}
|
||||
|
||||
/* Get the names of the events (syscall and non syscall events) that were not activated and print them. */
|
||||
auto names = libsinsp::events::sc_set_to_names(unsupported_sc_set);
|
||||
auto names = libsinsp::events::sc_set_to_event_names(unsupported_sc_set);
|
||||
std::cerr << "Loaded rules match syscalls that are not activated (e.g. were removed via config settings such as no -A flag or negative base_syscalls elements) or unsupported with current configuration: warning (unsupported-evttype): " + concat_set_in_order(names) << std::endl;
|
||||
std::cerr << "If syscalls in rules include high volume I/O syscalls (-> activate via `-A` flag), else syscalls may have been removed via base_syscalls option or might be associated with syscalls undefined on your architecture (https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html)" << std::endl;
|
||||
std::cerr << "If syscalls in rules include high volume syscalls (-> activate via `-A` flag), else syscalls may have been removed via base_syscalls option or might be associated with syscalls undefined on your architecture (https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html)" << std::endl;
|
||||
}
|
||||
|
||||
static void select_event_set(falco::app::state& s, const libsinsp::events::set<ppm_sc_code>& rules_sc_set)
|
||||
@@ -63,7 +65,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
/* PPM syscall codes (sc) can be viewed as condensed libsinsp lookup table
|
||||
* to map a system call name to it's actual system syscall id (as defined
|
||||
* by the Linux kernel). Hence here we don't need syscall enter and exit distinction. */
|
||||
auto rules_names = libsinsp::events::sc_set_to_names(rules_sc_set);
|
||||
auto rules_names = libsinsp::events::sc_set_to_event_names(rules_sc_set);
|
||||
if (!rules_sc_set.empty())
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, "(" + std::to_string(rules_names.size())
|
||||
@@ -86,8 +88,8 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
std::unordered_set<std::string> user_positive_names = {};
|
||||
std::unordered_set<std::string> user_negative_names = {};
|
||||
extract_base_syscalls_names(s.config->m_base_syscalls_custom_set, user_positive_names, user_negative_names);
|
||||
auto user_positive_sc_set = libsinsp::events::names_to_sc_set(user_positive_names);
|
||||
auto user_negative_sc_set = libsinsp::events::names_to_sc_set(user_negative_names);
|
||||
auto user_positive_sc_set = libsinsp::events::event_names_to_sc_set(user_positive_names);
|
||||
auto user_negative_sc_set = libsinsp::events::event_names_to_sc_set(user_negative_names);
|
||||
|
||||
if (!user_positive_sc_set.empty())
|
||||
{
|
||||
@@ -96,7 +98,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
|
||||
// we re-transform from sc_set to names to make
|
||||
// sure that bad user inputs are ignored
|
||||
auto user_positive_sc_set_names = libsinsp::events::sc_set_to_names(user_positive_sc_set);
|
||||
auto user_positive_sc_set_names = libsinsp::events::sc_set_to_event_names(user_positive_sc_set);
|
||||
falco_logger::log(LOG_DEBUG, "+(" + std::to_string(user_positive_sc_set_names.size())
|
||||
+ ") syscalls added (base_syscalls override): "
|
||||
+ concat_set_in_order(user_positive_sc_set_names) + "\n");
|
||||
@@ -132,7 +134,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
|
||||
// we re-transform from sc_set to names to make
|
||||
// sure that bad user inputs are ignored
|
||||
auto user_negative_sc_set_names = libsinsp::events::sc_set_to_names(user_negative_sc_set);
|
||||
auto user_negative_sc_set_names = libsinsp::events::sc_set_to_event_names(user_negative_sc_set);
|
||||
falco_logger::log(LOG_DEBUG, "-(" + std::to_string(user_negative_sc_set_names.size())
|
||||
+ ") syscalls removed (base_syscalls override): "
|
||||
+ concat_set_in_order(user_negative_sc_set_names) + "\n");
|
||||
@@ -150,7 +152,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
auto non_rules_sc_set = s.selected_sc_set.diff(rules_sc_set);
|
||||
if (!non_rules_sc_set.empty() && user_positive_sc_set.empty())
|
||||
{
|
||||
auto non_rules_sc_set_names = libsinsp::events::sc_set_to_names(non_rules_sc_set);
|
||||
auto non_rules_sc_set_names = libsinsp::events::sc_set_to_event_names(non_rules_sc_set);
|
||||
falco_logger::log(LOG_DEBUG, "+(" + std::to_string(non_rules_sc_set_names.size())
|
||||
+ ") syscalls (Falco's state engine set of syscalls): "
|
||||
+ concat_set_in_order(non_rules_sc_set_names) + "\n");
|
||||
@@ -158,17 +160,17 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
|
||||
/* -A flag behavior:
|
||||
* (1) default: all syscalls in rules included, sinsp state enforcement
|
||||
without high volume I/O syscalls
|
||||
without high volume syscalls
|
||||
* (2) -A flag set: all syscalls in rules included, sinsp state enforcement
|
||||
and allowing high volume I/O syscalls */
|
||||
and allowing high volume syscalls */
|
||||
if(!s.options.all_events)
|
||||
{
|
||||
auto ignored_sc_set = libsinsp::events::io_sc_set();
|
||||
auto ignored_sc_set = falco::app::ignored_sc_set();
|
||||
auto erased_sc_set = s.selected_sc_set.intersect(ignored_sc_set);
|
||||
s.selected_sc_set = s.selected_sc_set.diff(ignored_sc_set);
|
||||
if (!erased_sc_set.empty())
|
||||
{
|
||||
auto erased_sc_set_names = libsinsp::events::sc_set_to_names(erased_sc_set);
|
||||
auto erased_sc_set_names = libsinsp::events::sc_set_to_event_names(erased_sc_set);
|
||||
falco_logger::log(LOG_DEBUG, "-(" + std::to_string(erased_sc_set_names.size())
|
||||
+ ") ignored syscalls (-> activate via `-A` flag): "
|
||||
+ concat_set_in_order(erased_sc_set_names) + "\n");
|
||||
@@ -188,7 +190,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
auto repaired_sc_set = s.selected_sc_set.diff(selected_sc_set);
|
||||
if (!repaired_sc_set.empty())
|
||||
{
|
||||
auto repaired_sc_set_names = libsinsp::events::sc_set_to_names(repaired_sc_set);
|
||||
auto repaired_sc_set_names = libsinsp::events::sc_set_to_event_names(repaired_sc_set);
|
||||
falco_logger::log(LOG_INFO, "+(" + std::to_string(repaired_sc_set_names.size())
|
||||
+ ") repaired syscalls: " + concat_set_in_order(repaired_sc_set_names) + "\n");
|
||||
}
|
||||
@@ -203,7 +205,7 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
|
||||
if (!s.selected_sc_set.empty())
|
||||
{
|
||||
auto selected_sc_set_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto selected_sc_set_names = libsinsp::events::sc_set_to_event_names(s.selected_sc_set);
|
||||
falco_logger::log(LOG_DEBUG, "(" + std::to_string(selected_sc_set_names.size())
|
||||
+ ") syscalls selected in total (final set): "
|
||||
+ concat_set_in_order(selected_sc_set_names) + "\n");
|
||||
|
||||
@@ -64,27 +64,6 @@ falco::app::run_result falco::app::actions::init_clients(falco::app::state& s)
|
||||
}
|
||||
inspector->init_k8s_client(k8s_api_ptr, k8s_api_cert_ptr, k8s_node_name_ptr, s.options.verbose);
|
||||
}
|
||||
|
||||
//
|
||||
// DEPRECATED!
|
||||
// Run mesos, if required
|
||||
// todo(leogr): remove in Falco 0,.35
|
||||
//
|
||||
if(!s.options.mesos_api.empty())
|
||||
{
|
||||
// Differs from init_k8s_client in that it
|
||||
// passes a pointer but the inspector does
|
||||
// *not* own it and does not use it after
|
||||
// init_mesos_client() returns.
|
||||
falco_logger::log(LOG_WARNING, "Mesos support has been DEPRECATED and will be removed in the next version!\n");
|
||||
inspector->init_mesos_client(&(s.options.mesos_api), s.options.verbose);
|
||||
}
|
||||
else if(char* mesos_api_env = getenv("FALCO_MESOS_API"))
|
||||
{
|
||||
falco_logger::log(LOG_WARNING, "Mesos support has been DEPRECATED and will be removed in the next version!\n");
|
||||
std::string mesos_api_copy = mesos_api_env;
|
||||
inspector->init_mesos_client(&mesos_api_copy, s.options.verbose);
|
||||
}
|
||||
#endif
|
||||
|
||||
return run_result::ok();
|
||||
|
||||
@@ -45,11 +45,6 @@ void configure_output_format(falco::app::state& s)
|
||||
output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id vpid=%proc.vpid vtid=%thread.vtid";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(s.options.print_additional == "m" || s.options.print_additional == "mesos")
|
||||
{
|
||||
output_format = "task=%mesos.task.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(!s.options.print_additional.empty())
|
||||
{
|
||||
output_format = s.options.print_additional;
|
||||
@@ -95,20 +90,20 @@ void add_source_to_engine(falco::app::state& s, const std::string& src)
|
||||
|
||||
falco::app::run_result falco::app::actions::init_falco_engine(falco::app::state& s)
|
||||
{
|
||||
// add syscall as first source, this is also what each inspector do
|
||||
// in their own list of registered event sources
|
||||
add_source_to_engine(s, falco_common::syscall_source);
|
||||
|
||||
// add all non-syscall event sources in engine
|
||||
for (const auto& src : s.loaded_sources)
|
||||
{
|
||||
// we skip the syscall source because we already added it
|
||||
if (src != falco_common::syscall_source)
|
||||
{
|
||||
// we skip the syscall as we want it to be the one added for last
|
||||
// in the engine. This makes the source index assignment easier.
|
||||
add_source_to_engine(s, src);
|
||||
}
|
||||
}
|
||||
|
||||
// add syscall as last source
|
||||
add_source_to_engine(s, falco_common::syscall_source);
|
||||
|
||||
// note: in capture mode, we can assume that the plugin source index will
|
||||
// be the same in both the falco engine and the sinsp plugin manager.
|
||||
// This assumption stands because the plugin manager stores sources in a
|
||||
|
||||
@@ -146,7 +146,7 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
||||
// event source, we must register the plugin supporting
|
||||
// that event source and also plugins with field extraction
|
||||
// capability that are compatible with that event source
|
||||
if (is_input || (p->caps() & CAP_EXTRACTION && p->is_source_compatible(src)))
|
||||
if (is_input || (p->caps() & CAP_EXTRACTION && sinsp_plugin::is_source_compatible(p->extract_event_sources(), src)))
|
||||
{
|
||||
plugin = src_info->inspector->register_plugin(config->m_library_path);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
||||
{
|
||||
if(used_plugins.find(p->name()) == used_plugins.end()
|
||||
&& p->caps() & CAP_EXTRACTION
|
||||
&& !(p->caps() & CAP_SOURCING && p->is_source_compatible(p->event_source())))
|
||||
&& !(p->caps() & CAP_SOURCING && sinsp_plugin::is_source_compatible(p->extract_event_sources(), p->event_source())))
|
||||
{
|
||||
return run_result::fatal("Plugin '" + p->name()
|
||||
+ "' has field extraction capability but is not compatible with any known event source");
|
||||
|
||||
@@ -55,7 +55,11 @@ falco::app::run_result falco::app::actions::load_plugins(falco::app::state& s)
|
||||
{
|
||||
auto sname = plugin->event_source();
|
||||
s.source_infos.insert(empty_src_info, sname);
|
||||
s.loaded_sources.insert(sname);
|
||||
// note: this avoids duplicate values
|
||||
if (std::find(s.loaded_sources.begin(), s.loaded_sources.end(), sname) == s.loaded_sources.end())
|
||||
{
|
||||
s.loaded_sources.push_back(sname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
#include "actions.h"
|
||||
#include "helpers.h"
|
||||
#include "../app.h"
|
||||
|
||||
using namespace falco::app;
|
||||
using namespace falco::app::actions;
|
||||
@@ -27,8 +28,8 @@ falco::app::run_result falco::app::actions::print_ignored_events(falco::app::sta
|
||||
return run_result::ok();
|
||||
}
|
||||
|
||||
std::cout << "Ignored I/O syscall(s):" << std::endl;
|
||||
for(const auto& it : libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set()))
|
||||
std::cout << "Ignored syscall(s):" << std::endl;
|
||||
for(const auto& it : libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set()))
|
||||
{
|
||||
std::cout << "- " << it.c_str() << std::endl;
|
||||
}
|
||||
|
||||
@@ -140,15 +140,14 @@ static falco::app::run_result do_inspect(
|
||||
uint64_t duration_start = 0;
|
||||
uint32_t timeouts_since_last_success_or_msg = 0;
|
||||
token_bucket rate_limiter;
|
||||
bool rate_limiter_enabled = s.config->m_notifications_rate > 0;
|
||||
bool source_engine_idx_found = false;
|
||||
bool is_capture_mode = source.empty();
|
||||
bool syscall_source_engine_idx = s.source_infos.at(falco_common::syscall_source)->engine_idx;
|
||||
std::size_t source_engine_idx = 0;
|
||||
std::vector<std::string> source_names = inspector->get_plugin_manager()->sources();
|
||||
source_names.push_back(falco_common::syscall_source);
|
||||
const bool rate_limiter_enabled = s.config->m_notifications_rate > 0;
|
||||
const bool is_capture_mode = source.empty();
|
||||
size_t source_engine_idx = 0;
|
||||
|
||||
if (!is_capture_mode)
|
||||
{
|
||||
// note: in live mode, each inspector gets assigned a distinct event
|
||||
// source that does not change for the whole capture.
|
||||
source_engine_idx = s.source_infos.at(source)->engine_idx;
|
||||
}
|
||||
|
||||
@@ -260,24 +259,38 @@ static falco::app::run_result do_inspect(
|
||||
// if we are in live mode, we already have the right source engine idx
|
||||
if (is_capture_mode)
|
||||
{
|
||||
source_engine_idx = syscall_source_engine_idx;
|
||||
if (ev->get_type() == PPME_PLUGINEVENT_E)
|
||||
// note: here we can assume that the source index will be the same
|
||||
// in both the falco engine and the inspector. See the
|
||||
// comment in init_falco_engine.cpp for more details.
|
||||
source_engine_idx = ev->get_source_idx();
|
||||
if (source_engine_idx == sinsp_no_event_source_idx)
|
||||
{
|
||||
// note: here we can assume that the source index will be the same
|
||||
// in both the falco engine and the sinsp plugin manager. See the
|
||||
// comment in init_falco_engine.cpp for more details.
|
||||
source_engine_idx = inspector->get_plugin_manager()->source_idx_by_plugin_id(*(int32_t *)ev->get_param(0)->m_val, source_engine_idx_found);
|
||||
if (!source_engine_idx_found)
|
||||
std::string msg = "Unknown event source for inspector's event";
|
||||
if (ev->get_type() == PPME_PLUGINEVENT_E)
|
||||
{
|
||||
return run_result::fatal("Unknown plugin ID in inspector: " + std::to_string(*(int32_t *)ev->get_param(0)->m_val));
|
||||
auto pluginID = *(int32_t *)ev->get_param(0)->m_val;
|
||||
msg += " (plugin ID: " + std::to_string(pluginID) + ")";
|
||||
}
|
||||
return run_result::fatal(msg);
|
||||
}
|
||||
|
||||
|
||||
// for capture mode, the source name can change at every event
|
||||
stats_collector.collect(inspector, source_names[source_engine_idx]);
|
||||
stats_collector.collect(inspector, inspector->event_sources()[source_engine_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// in live mode, each inspector gets assigned a distinct event source,
|
||||
// so we report an error if we fetch an event of a different source.
|
||||
if (source_engine_idx != ev->get_source_idx())
|
||||
{
|
||||
std::string msg = "Unexpected event source for inspector's event: expected='" + source + "'";
|
||||
if (ev->get_source_name() != NULL)
|
||||
{
|
||||
msg += ", actual='" + std::string(ev->get_source_name()) + "'";
|
||||
}
|
||||
return run_result::fatal(msg);
|
||||
}
|
||||
|
||||
// for live mode, the source name is constant
|
||||
stats_collector.collect(inspector, source);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace falco::app::actions;
|
||||
|
||||
falco::app::run_result falco::app::actions::select_event_sources(falco::app::state& s)
|
||||
{
|
||||
s.enabled_sources = s.loaded_sources;
|
||||
s.enabled_sources = { s.loaded_sources.begin(), s.loaded_sources.end() };
|
||||
|
||||
// event sources selection is meaningless when reading trace files
|
||||
if (s.is_capture_mode())
|
||||
@@ -40,7 +40,7 @@ falco::app::run_result falco::app::actions::select_event_sources(falco::app::sta
|
||||
s.enabled_sources.clear();
|
||||
for(const auto &src : s.options.enable_sources)
|
||||
{
|
||||
if (s.loaded_sources.find(src) == s.loaded_sources.end())
|
||||
if (std::find(s.loaded_sources.begin(), s.loaded_sources.end(), src) == s.loaded_sources.end())
|
||||
{
|
||||
return run_result::fatal("Attempted enabling an unknown event source: " + src);
|
||||
}
|
||||
@@ -51,7 +51,7 @@ falco::app::run_result falco::app::actions::select_event_sources(falco::app::sta
|
||||
{
|
||||
for(const auto &src : s.options.disable_sources)
|
||||
{
|
||||
if (s.loaded_sources.find(src) == s.loaded_sources.end())
|
||||
if (std::find(s.loaded_sources.begin(), s.loaded_sources.end(), src) == s.loaded_sources.end())
|
||||
{
|
||||
return run_result::fatal("Attempted disabling an unknown event source: " + src);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,15 @@ falco::atomic_signal_handler falco::app::g_reopen_outputs_signal;
|
||||
|
||||
using app_action = std::function<falco::app::run_result(falco::app::state&)>;
|
||||
|
||||
libsinsp::events::set<ppm_sc_code> falco::app::ignored_sc_set()
|
||||
{
|
||||
// we ignore all the I/O syscalls that can have very high throughput and
|
||||
// that can badly impact performance. Of those, we avoid ignoring the
|
||||
// ones that are part of the base set used by libsinsp for maintaining
|
||||
// its internal state.
|
||||
return libsinsp::events::io_sc_set().diff(libsinsp::events::sinsp_state_sc_set());
|
||||
}
|
||||
|
||||
bool falco::app::run(int argc, char** argv, bool& restart, std::string& errstr)
|
||||
{
|
||||
falco::app::state s;
|
||||
|
||||
@@ -23,7 +23,10 @@ limitations under the License.
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
libsinsp::events::set<ppm_sc_code> ignored_sc_set();
|
||||
|
||||
bool run(int argc, char** argv, bool& restart, std::string& errstr);
|
||||
|
||||
bool run(falco::app::state& s, bool& restart, std::string& errstr);
|
||||
|
||||
}; // namespace app
|
||||
|
||||
@@ -164,7 +164,7 @@ void options::define(cxxopts::Options& opts)
|
||||
#else
|
||||
("c", "Configuration file. If not specified tries " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ".", cxxopts::value(conf_filename), "<path>")
|
||||
#endif
|
||||
("A", "Monitor each event defined in rules and configs + high volume I/O syscalls. Please use the -i option to list the I/O syscalls Falco supports. This option affects live captures only. Setting -A can impact performance.", cxxopts::value(all_events)->default_value("false"))
|
||||
("A", "Monitor all events supported by Falco defined in rules and configs. Please use the -i option to list the events ignored by default without -A. This option affects live captures only. Setting -A can impact performance.", cxxopts::value(all_events)->default_value("false"))
|
||||
("b,print-base64", "Print data buffers in base64. This is useful for encoding binary data that needs to be used over media designed to consume this format.")
|
||||
("cri", "Path to CRI socket for container metadata. Use the specified socket to fetch data from a CRI-compatible runtime. If not specified, uses the libs default. This option can be passed multiple times to specify socket to be tried until a successful one is found.", cxxopts::value(cri_socket_paths), "<path>")
|
||||
("d,daemon", "Run as a daemon.", cxxopts::value(daemon)->default_value("false"))
|
||||
@@ -180,9 +180,9 @@ void options::define(cxxopts::Options& opts)
|
||||
("gvisor-root", "gVisor root directory for storage of container state. Equivalent to runsc --root flag.", cxxopts::value(gvisor_root), "<gvisor_root>")
|
||||
#endif
|
||||
#ifdef HAS_MODERN_BPF
|
||||
("modern-bpf", "[EXPERIMENTAL] Use BPF modern probe to capture system events.", cxxopts::value(modern_bpf)->default_value("false"))
|
||||
("modern-bpf", "Use BPF modern probe to capture system events.", cxxopts::value(modern_bpf)->default_value("false"))
|
||||
#endif
|
||||
("i", "Print all high volume I/O syscalls that are ignored by default (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false"))
|
||||
("i", "Print all high volume syscalls that are ignored by default for performance reasons (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false"))
|
||||
#ifndef MINIMAL_BUILD
|
||||
("k,k8s-api", "Enable Kubernetes support by connecting to the API server specified as argument. E.g. \"http://admin:password@127.0.0.1:8080\". The API server can also be specified via the environment variable FALCO_K8S_API.", cxxopts::value(k8s_api), "<url>")
|
||||
("K,k8s-api-cert", "Use the provided files names to authenticate user and (optionally) verify the K8S API server identity. Each entry must specify full (absolute, or relative to the current directory) path to the respective file. Private key password is optional (needed only if key is password protected). CA certificate is optional. For all files, only PEM file format is supported. Specifying CA certificate only is obsoleted - when single entry is provided for this option, it will be interpreted as the name of a file containing bearer token. Note that the format of this command-line option prohibits use of files whose names contain ':' or '#' characters in the file name.", cxxopts::value(k8s_api_cert), "(<bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>])")
|
||||
@@ -194,9 +194,6 @@ void options::define(cxxopts::Options& opts)
|
||||
("list-syscall-events", "List all defined system call events.", cxxopts::value<bool>(list_syscall_events))
|
||||
#ifndef MUSL_OPTIMIZED
|
||||
("list-plugins", "Print info on all loaded plugins and exit.", cxxopts::value(list_plugins)->default_value("false"))
|
||||
#endif
|
||||
#ifndef MINIMAL_BUILD
|
||||
("m,mesos-api", "This feature has been DEPRECATED and will be removed in the next version.", cxxopts::value(mesos_api), "<url[,marathon_url]>")
|
||||
#endif
|
||||
("M", "Stop collecting after <num_seconds> reached.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
|
||||
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
std::string print_plugin_info;
|
||||
bool list_syscall_events;
|
||||
bool markdown;
|
||||
std::string mesos_api;
|
||||
int duration_to_tot;
|
||||
bool names_only;
|
||||
std::vector<std::string> cmdline_config_options;
|
||||
|
||||
@@ -98,8 +98,10 @@ struct state
|
||||
std::shared_ptr<falco_engine> engine;
|
||||
|
||||
// The set of loaded event sources (by default, the syscall event
|
||||
// source plus all event sources coming from the loaded plugins)
|
||||
std::unordered_set<std::string> loaded_sources;
|
||||
// source plus all event sources coming from the loaded plugins).
|
||||
// note: this has to be a vector to preserve the loading order,
|
||||
// however it's not supposed to contain duplicate values.
|
||||
std::vector<std::string> loaded_sources;
|
||||
|
||||
// The set of enabled event sources (can be altered by using
|
||||
// the --enable-source and --disable-source options)
|
||||
|
||||
@@ -336,11 +336,11 @@ void falco_configuration::load_yaml(const std::string& config_name, const yaml_h
|
||||
config.get_sequence<std::unordered_set<std::string>>(m_base_syscalls_custom_set, std::string("base_syscalls.custom_set"));
|
||||
m_base_syscalls_repair = config.get_scalar<bool>("base_syscalls.repair", false);
|
||||
|
||||
std::set<std::string> load_plugins;
|
||||
std::vector<std::string> load_plugins;
|
||||
|
||||
bool load_plugins_node_defined = config.is_defined("load_plugins");
|
||||
|
||||
config.get_sequence<std::set<std::string>>(load_plugins, "load_plugins");
|
||||
config.get_sequence<std::vector<std::string>>(load_plugins, "load_plugins");
|
||||
|
||||
std::list<falco_configuration::plugin_config> plugins;
|
||||
try
|
||||
@@ -358,14 +358,32 @@ void falco_configuration::load_yaml(const std::string& config_name, const yaml_h
|
||||
|
||||
// If load_plugins was specified, only save plugins matching those in values
|
||||
m_plugins.clear();
|
||||
for (auto &p : plugins)
|
||||
if (!load_plugins_node_defined)
|
||||
{
|
||||
// If load_plugins was not specified at all, every
|
||||
// plugin is added. Otherwise, the plugin must be in
|
||||
// the load_plugins list.
|
||||
if(!load_plugins_node_defined || load_plugins.find(p.m_name) != load_plugins.end())
|
||||
// If load_plugins was not specified at all, every plugin is added.
|
||||
// The loading order is the same as the sequence in the YAML config.
|
||||
m_plugins = { plugins.begin(), plugins.end() };
|
||||
}
|
||||
else
|
||||
{
|
||||
// If load_plugins is specified, only plugins contained in its list
|
||||
// are added, with the same order as in the list.
|
||||
for (const auto& pname : load_plugins)
|
||||
{
|
||||
m_plugins.push_back(p);
|
||||
bool found = false;
|
||||
for (const auto& p : plugins)
|
||||
{
|
||||
if (pname == p.m_name)
|
||||
{
|
||||
m_plugins.push_back(p);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
throw std::logic_error("Cannot load plugin '" + pname + "': plugin config not found for given name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user