Full Code of Azure/eraser for AI

main 20576a24c512 cached
345 files
1.0 MB
290.3k tokens
930 symbols
1 requests
Download .txt
Showing preview only (1,130K chars total). Download the full file or copy to clipboard to get everything.
Repository: Azure/eraser
Branch: main
Commit: 20576a24c512
Files: 345
Total size: 1.0 MB

Directory structure:
gitextract_ygu3dx5m/

├── .dockerignore
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   └── feature-request.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── dependabot.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── README.md
│       ├── build-id.yaml
│       ├── codeql.yaml
│       ├── dep-review.yaml
│       ├── deploy_docs.yaml
│       ├── e2e-build.yaml
│       ├── e2e-test.yaml
│       ├── patch-docs.yaml
│       ├── release-pr.yaml
│       ├── release.yaml
│       ├── scan-images.yaml
│       ├── scorecard.yml
│       ├── test.yaml
│       └── upgrade.yaml
├── .gitignore
├── .golangci.yaml
├── .trivyignore
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── Dockerfile
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── PROJECT
├── README.md
├── api/
│   ├── group.go
│   ├── unversioned/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1/
│   │   ├── doc.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1alpha1/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── custom_conversions.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1alpha2/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── custom_conversions.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   └── v1alpha3/
│       ├── config/
│       │   └── config.go
│       ├── doc.go
│       ├── eraserconfig_types.go
│       ├── groupversion_info.go
│       ├── runtime_spec_test.go
│       ├── zz_generated.conversion.go
│       └── zz_generated.deepcopy.go
├── build/
│   └── version.sh
├── config/
│   ├── crd/
│   │   ├── bases/
│   │   │   ├── _.yaml
│   │   │   ├── eraser.sh_imagejobs.yaml
│   │   │   └── eraser.sh_imagelists.yaml
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches/
│   │       ├── cainjection_in_eraserconfigs.yaml
│   │       ├── cainjection_in_imagelists.yaml
│   │       ├── webhook_in_eraserconfigs.yaml
│   │       └── webhook_in_imagelists.yaml
│   ├── default/
│   │   ├── kustomization.yaml
│   │   └── manager_auth_proxy_patch.yaml
│   ├── manager/
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   ├── manager.yaml
│   │   └── patch.yaml
│   ├── prometheus/
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   └── rbac/
│       ├── auth_proxy_client_clusterrole.yaml
│       ├── auth_proxy_role.yaml
│       ├── auth_proxy_role_binding.yaml
│       ├── auth_proxy_service.yaml
│       ├── cluster_role_binding.yaml
│       ├── imagejob_pods_service.yaml
│       ├── imagelist_editor_role.yaml
│       ├── imagelist_viewer_role.yaml
│       ├── kustomization.yaml
│       ├── leader_election_role.yaml
│       ├── leader_election_role_binding.yaml
│       ├── role.yaml
│       ├── role_binding.yaml
│       └── service_account.yaml
├── controllers/
│   ├── configmap/
│   │   └── configmap.go
│   ├── controller.go
│   ├── imagecollector/
│   │   └── imagecollector_controller.go
│   ├── imagejob/
│   │   └── imagejob_controller.go
│   ├── imagelist/
│   │   └── imagelist_controller.go
│   ├── suite_test.go
│   └── util/
│       └── util.go
├── demo/
│   ├── README.md
│   ├── demo-magic.sh
│   ├── demo.sh
│   └── ds.yaml
├── deploy/
│   └── eraser.yaml
├── docs/
│   ├── README.md
│   ├── babel.config.js
│   ├── design/
│   │   └── README.md
│   ├── docs/
│   │   ├── architecture.md
│   │   ├── code-of-conduct.md
│   │   ├── contributing.md
│   │   ├── custom-scanner.md
│   │   ├── customization.md
│   │   ├── exclusion.md
│   │   ├── faq.md
│   │   ├── installation.md
│   │   ├── introduction.md
│   │   ├── manual-removal.md
│   │   ├── metrics.md
│   │   ├── quick-start.md
│   │   ├── release-management.md
│   │   ├── releasing.md
│   │   ├── setup.md
│   │   └── trivy.md
│   ├── docusaurus.config.js
│   ├── package.json
│   ├── sidebars.js
│   ├── src/
│   │   └── css/
│   │       └── custom.css
│   ├── static/
│   │   └── .nojekyll
│   ├── versioned_docs/
│   │   ├── version-v0.4.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v0.5.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.0.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.1.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.2.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.3.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── release-management.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   └── version-v1.4.x/
│   │       ├── architecture.md
│   │       ├── code-of-conduct.md
│   │       ├── contributing.md
│   │       ├── custom-scanner.md
│   │       ├── customization.md
│   │       ├── exclusion.md
│   │       ├── faq.md
│   │       ├── installation.md
│   │       ├── introduction.md
│   │       ├── manual-removal.md
│   │       ├── metrics.md
│   │       ├── quick-start.md
│   │       ├── release-management.md
│   │       ├── releasing.md
│   │       ├── setup.md
│   │       └── trivy.md
│   ├── versioned_sidebars/
│   │   ├── version-v0.4.x-sidebars.json
│   │   ├── version-v0.5.x-sidebars.json
│   │   ├── version-v1.0.x-sidebars.json
│   │   ├── version-v1.1.x-sidebars.json
│   │   ├── version-v1.2.x-sidebars.json
│   │   ├── version-v1.3.x-sidebars.json
│   │   └── version-v1.4.x-sidebars.json
│   └── versions.json
├── go.mod
├── go.sum
├── hack/
│   ├── boilerplate.go.txt
│   ├── go-install.sh
│   └── rootless_docker.sh
├── main.go
├── manifest_staging/
│   └── deploy/
│       └── eraser.yaml
├── pkg/
│   ├── collector/
│   │   ├── collector.go
│   │   └── helpers.go
│   ├── cri/
│   │   ├── client.go
│   │   ├── client_v1.go
│   │   ├── client_v1alpha2.go
│   │   └── util.go
│   ├── logger/
│   │   └── zap.go
│   ├── metrics/
│   │   ├── metrics.go
│   │   └── metrics_test.go
│   ├── scanners/
│   │   ├── template/
│   │   │   └── scanner_template.go
│   │   └── trivy/
│   │       ├── helpers.go
│   │       ├── trivy.go
│   │       ├── trivy_test.go
│   │       ├── types.go
│   │       └── types_test.go
│   └── utils/
│       ├── flag.go
│       ├── pod_info.go
│       ├── security_context.go
│       ├── utils.go
│       └── utils_test.go
├── test/
│   └── e2e/
│       ├── kind-config-custom-runtime.yaml
│       ├── kind-config.yaml
│       ├── test-data/
│       │   ├── Dockerfile.busybox
│       │   ├── Dockerfile.customNode
│       │   ├── Dockerfile.dummyCollector
│       │   ├── eraser_v1_imagelist.yaml
│       │   ├── eraser_v1alpha1_imagelist.yaml
│       │   ├── eraser_v1alpha1_imagelist_updated.yaml
│       │   ├── helm-empty-values.yaml
│       │   ├── helm-test-config.yaml
│       │   ├── imagelist_alpine.yaml
│       │   └── otelcollector.yaml
│       ├── tests/
│       │   ├── collector_delete_deployment/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_delete_manager/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_disable_scan/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_ensure_scan/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_pipeline/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_runtime_config/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_skip_excluded/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── configmap_update/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── helm_pull_secret/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── helm_pull_secret_imagelist/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_alias/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_change/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_exclusion_list/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_include_nodes/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_prune_images/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_rm_images/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_skip_nodes/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── metrics_test_disable_scanner/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── metrics_test_eraser/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   └── metrics_test_scanner/
│       │       ├── eraser_test.go
│       │       └── main_test.go
│       └── util/
│           ├── kubectl.go
│           ├── utils.go
│           └── utils_test.go
├── third_party/
│   └── open-policy-agent/
│       └── gatekeeper/
│           └── helmify/
│               ├── LICENSE
│               ├── README.md
│               ├── kustomization.yaml
│               ├── kustomize-for-helm.yaml
│               ├── main.go
│               ├── replacements.go
│               └── static/
│                   ├── .helmignore
│                   ├── Chart.yaml
│                   ├── README.md
│                   ├── templates/
│                   │   ├── _helpers.tpl
│                   │   └── configmap.yaml
│                   └── values.yaml
└── version/
    ├── version.go
    └── version_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
# Ignore all files which are not go type
!**/*.go
!**/*.mod
!**/*.sum


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: Bug Report
description: Report a bug in Eraser
title: "[BUG] <title>"
labels:
  - "bug"
body:
  - type: markdown
    attributes:
      value: |
        Please search to see if an issue already exists for your bug before continuing.
        > If you need to report a security issue please see https://github.com/eraser-dev/eraser/security/policy instead.
  - type: input
    attributes:
      label: Version of Eraser
      placeholder: Release version (e.g. v1.0.0) or `git describe --dirty` output if built from source
  - type: textarea
    attributes:
      label: Expected Behavior
      description: Briefly describe what you expect to happen.
  - type: textarea
    attributes:
      label: Actual Behavior
      description: Briefly describe what is actually happening.
  - type: textarea
    attributes:
      label: Steps To Reproduce
      description: Detailed steps to reproduce the behavior.
      placeholder: |
        1. In Kubernetes v1.27.0 ...
        2. With this config...
        3. Run '...'
        4. See error...
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out a bug report!
  - type: checkboxes
    id: idea
    attributes:
      label: "Are you willing to submit PRs to contribute to this bug fix?"
      description: "This is absolutely not required, but we are happy to guide you in the contribution process especially when you already have a good proposal or understanding of how to implement it. Join us at the `#eraser` channel on the [Kubernetes Slack](https://kubernetes.slack.com/archives/C03Q8KV8YQ4) if you have any questions."
      options:
        - label: Yes, I am willing to implement it.


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: Request
description: Request a new feature or propose an enhancement to Eraser
title: "[REQ] <title>"
labels:
  - "enhancement"
body:
  - type: markdown
    attributes:
      value: |
        Please search to see if an issue already exists for your request before continuing.
  - type: dropdown
    attributes:
      label: What kind of request is this?
      multiple: false
      options:
        - New feature
        - Improvement of existing experience
        - Other
  - type: textarea
    attributes:
      label: What is your request or suggestion?
      placeholder: |
        e.g. I would like Eraser to add this <feature> so that I can use it in my <scenario>.
        e.g. When using Eraser the <current behavior> has this <limitation> and it would be better if it has this <improvement>.
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out a request!
  - type: checkboxes
    id: idea
    attributes:
      label: "Are you willing to submit PRs to contribute to this feature request?"
      description: "This is absolutely not required, but we are happy to guide you in the contribution process especially when you already have a good proposal or understanding of how to implement it. Join us at the `#eraser` channel on the [Kubernetes Slack](https://kubernetes.slack.com/archives/C03Q8KV8YQ4) if you have any questions."
      options:
        - label: Yes, I am willing to implement it.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
**What this PR does / why we need it**:

**Which issue(s) this PR fixes** *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes #

**Special notes for your reviewer**:


================================================
FILE: .github/dependabot.yml
================================================
version: 2

updates:
  - package-ecosystem: "npm"
    directory: "/docs"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "chore"
    groups:
      docusaurus:
        patterns:
        - "@docusaurus/*"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "chore"
    groups:
      all:
        patterns:
        - "*"

  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "chore"
    ignore:
      - dependency-name: "*"
        update-types:
        - "version-update:semver-major"
        - "version-update:semver-minor"
    groups:
      k8s:
        patterns:
        - "k8s.io/*"
        exclude-patterns:
        - "k8s.io/cri-api"

  - package-ecosystem: docker
    directory: /
    schedule:
      interval: weekly

  - package-ecosystem: docker
    directory: /build/tooling
    schedule:
      interval: weekly


================================================
FILE: .github/semantic.yml
================================================
titleOnly: true
types:
  - build
  - chore
  - ci
  - docs
  - feat
  - fix
  - perf
  - refactor
  - revert
  - style
  - test


================================================
FILE: .github/workflows/README.md
================================================
# GitHub Workflows

This directory contains all of our workflows used in our GitHub CI/CD pipeline.

## Descriptions

### [Scan Images for Vulnerabilities (Trivy)](scan-images.yaml)
Our images are scheduled to be scanned for vulnerabilities using Trivy every Monday at 07:00 UTC.

#### Weekly Scans
By default, our images are built from the `main` branch, and any vulnerabilities caught are published in the [Github Security tab](https://github.com/eraser-dev/eraser/security).

#### Dispatching a Scan
We can do a manual dispatch of the workflow and specify the released version to scan, e.g. `v1.3.0-beta.0`. If left blank, the image will be built off of the branch the workflow is dispatched from.

If we want to publish those results to our [Github Security tab](https://github.com/eraser-dev/eraser/security), we need to toggle the `upload-results` input to `true`.

#### Scan Results
The scan results are automatically stored in the run artifacts. Those can be accessed by going into the workflow run, and under the run's **Summary** there is an **Artifacts** section storing all the images' scan results.

If the `upload-results` input is set to `true`, any vulnerabilities found will be published in the [Github Security tab](https://github.com/eraser-dev/eraser/security).


================================================
FILE: .github/workflows/build-id.yaml
================================================
name: Image build definitions for e2e tests

on:
  workflow_call:
    outputs:
      build-id:
        description: "random build id to keep things together"
        value: ${{ jobs.generate-build-id.outputs.image-build-id }}
      bucket-id:
        description: "docker-images-<build-id>"
        value: ${{ jobs.generate-build-id.outputs.bucket-id }}

permissions:
  contents: read

jobs:
  generate-build-id:
    name: "Generate Build ID"
    runs-on: ubuntu-latest
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - id: build-id
        run: |
          build_id="$(date +%s)"
          echo build-id=$build_id | tee -a $GITHUB_OUTPUT
          echo bucket-id=docker-images-$build_id | tee -a $GITHUB_OUTPUT
    outputs:
      image-build-id: ${{ steps.build-id.outputs.build-id }}
      bucket-id: ${{ steps.build-id.outputs.bucket-id }}


================================================
FILE: .github/workflows/codeql.yaml
================================================
name: "CodeQL"

on:
  push:
    branches: [ main ]
  schedule:
    - cron: '0 7 * * 1' # Monday at 7:00 AM

permissions: read-all

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'go' ]

    steps:
    - name: Harden Runner
      uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
      with:
        egress-policy: audit

    - name: Checkout repository
      uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3

    - name: Initialize CodeQL
      uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2
      with:
        languages: ${{ matrix.language }}

    - name: Autobuild
      uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2


================================================
FILE: .github/workflows/dep-review.yaml
================================================
name: 'Dependency Review'
on: [pull_request]

permissions:
  contents: read

jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit

      - name: 'Checkout Repository'
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3

      - name: 'Dependency Review'
        uses: actions/dependency-review-action@0659a74c94536054bfa5aeb92241f70d680cc78e


================================================
FILE: .github/workflows/deploy_docs.yaml
================================================
name: Generate docs website to GitHub Pages

on:
  push:
    branches:
      - main
    paths:
      - '.github/workflows/deploy_docs.yaml'
      - 'docs/**'
  pull_request:
    branches:
      - main
    paths:
      - '.github/workflows/deploy_docs.yaml'
      - 'docs/**'

permissions:
  contents: read

jobs:
  deploy:
    name: Generate docs website to GitHub Pages
    runs-on: ubuntu-latest
    permissions:
      contents: write
    defaults:
      run:
        working-directory: docs
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0

      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit

      - name: Setup Node
        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
        with:
          node-version: 20.x

      - name: Get yarn cache
        id: yarn-cache
        run: echo "dir=$(yarn cache dir)" > $GITHUB_OUTPUT

      - name: Cache dependencies
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: ${{ steps.yarn-cache.outputs.dir }}
          key: ${{ runner.os }}-website-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-website-

      - run: yarn install --frozen-lockfile
      - run: yarn build

      - name: Deploy to GitHub Pages
        if: github.ref == 'refs/heads/main' && github.event_name == 'push' && github.repository == 'eraser-dev/eraser'
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs/build
          destination_dir: ./docs


================================================
FILE: .github/workflows/e2e-build.yaml
================================================
name: Image build definitions for e2e tests

on:
  workflow_call:
    inputs:
      bucket-id:
        required: true
        type: string

jobs:
  build-remover:
    name: "Build remover image for e2e tests"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Setup buildx instance
        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
        with:
          use: true
      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - run: 'echo ${{ inputs.bucket-id }}'
      - name: Set env
        run: |
          echo REMOVER_REPO=remover >> $GITHUB_ENV
          echo REMOVER_TAG=test >> $GITHUB_ENV
      - name: Build remover
        run: 'make docker-build-remover OUTPUT_TYPE=type=oci,dest=./${REMOVER_REPO}_${REMOVER_TAG}.tar,name=${REMOVER_REPO}:${REMOVER_TAG}'
      - name: Upload Build Artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: ${{ inputs.bucket-id }}-remover
          path: remover_test.tar
          overwrite: true

  build-trivy-scanner:
    name: "Build trivy-scanner image for e2e tests"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Setup buildx instance
        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
        with:
          use: true
      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Set env
        run: |
          echo TRIVY_SCANNER_REPO=scanner >> $GITHUB_ENV
          echo TRIVY_SCANNER_TAG=test >> $GITHUB_ENV
      - name: Build trivy-scanner
        run: 'make docker-build-trivy-scanner OUTPUT_TYPE=type=oci,dest=./${TRIVY_SCANNER_REPO}_${TRIVY_SCANNER_TAG}.tar,name=${TRIVY_SCANNER_REPO}:${TRIVY_SCANNER_TAG}'
      - name: Upload Build Artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: ${{ inputs.bucket-id }}-scanner
          path: scanner_test.tar
          overwrite: true

  build-manager:
    name: "Build manager image for e2e tests"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Setup buildx instance
        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
        with:
          use: true
      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Set env
        run: |
          echo MANAGER_REPO=manager >> $GITHUB_ENV
          echo MANAGER_TAG=test >> $GITHUB_ENV
      - name: Build manager
        run: 'make docker-build-manager OUTPUT_TYPE=type=oci,dest=./${MANAGER_REPO}_${MANAGER_TAG}.tar,name=${MANAGER_REPO}:${MANAGER_TAG}'
      - name: Upload Build Artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: ${{ inputs.bucket-id }}-manager
          path: manager_test.tar
          overwrite: true

  build-collector:
    name: "Build collector image for e2e tests"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Setup buildx instance
        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
        with:
          use: true
      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Set env
        run: |
          echo COLLECTOR_REPO=collector >> $GITHUB_ENV
          echo COLLECTOR_TAG=test >> $GITHUB_ENV
      - name: Build collector
        run: 'make docker-build-collector OUTPUT_TYPE=type=oci,dest=./${COLLECTOR_REPO}_${COLLECTOR_TAG}.tar,name=${COLLECTOR_REPO}:${COLLECTOR_TAG}'
      - name: Upload Build Artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: ${{ inputs.bucket-id }}-collector
          path: collector_test.tar
          overwrite: true


================================================
FILE: .github/workflows/e2e-test.yaml
================================================
name: Run E2E tests

on:
  workflow_call:
    inputs:
      upgrade-test:
        required: false
        type: string
      bucket-id:
        required: true
        type: string

permissions:
  contents: read

jobs:
  build-e2e-test-list:
    name: "Build E2E Test List"
    runs-on: ubuntu-latest
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - id: set-test-matrix
        run: |
          readarray -d '' test_dirs < <(find ./test/e2e/tests -mindepth 1 -type d -print0)
          json_array="$(printf "%s\n" "${test_dirs[@]}" | jq -R . | jq -cs)"
          echo "e2e-tests=${json_array}" > $GITHUB_OUTPUT
    outputs:
      e2e-tests: ${{ steps.set-test-matrix.outputs.e2e-tests }}
  e2e-test:
    name: "E2E Tests"
    runs-on: ubuntu-latest
    timeout-minutes: 20
    needs:
      - build-e2e-test-list
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        KUBERNETES_VERSION: ["1.27.13", "1.28.9", "1.29.4", "1.30.2"]
        E2E_TEST: ${{ fromJson(needs.build-e2e-test-list.outputs.e2e-tests) }}
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Fetch Build Artifacts
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          pattern: ${{ inputs.bucket-id }}-*
          path: ${{ github.workspace }}/images
          merge-multiple: true
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Set env
        run: |
          ARCHIVE_DIR=${{ github.workspace }}/images
          REMOVER_REPO=remover
          MANAGER_REPO=manager
          COLLECTOR_REPO=collector
          TRIVY_SCANNER_REPO=scanner

          REMOVER_TAG=test
          MANAGER_TAG=test
          COLLECTOR_TAG=test
          TRIVY_SCANNER_TAG=test

          echo REMOVER_REPO=$REMOVER_REPO >> $GITHUB_ENV
          echo MANAGER_REPO=$MANAGER_REPO >> $GITHUB_ENV
          echo COLLECTOR_REPO=$COLLECTOR_REPO >> $GITHUB_ENV
          echo TRIVY_SCANNER_REPO=$TRIVY_SCANNER_REPO >> $GITHUB_ENV

          echo REMOVER_TAG=$REMOVER_TAG >> $GITHUB_ENV
          echo MANAGER_TAG=$MANAGER_TAG >> $GITHUB_ENV
          echo COLLECTOR_TAG=$COLLECTOR_TAG >> $GITHUB_ENV
          echo TRIVY_SCANNER_TAG=$TRIVY_SCANNER_TAG >> $GITHUB_ENV
          echo ARCHIVE_DIR=$ARCHIVE_DIR >> $GITHUB_ENV

          echo REMOVER_TARBALL_PATH=$ARCHIVE_DIR/${REMOVER_REPO}_${REMOVER_TAG}.tar >> $GITHUB_ENV
          echo MANAGER_TARBALL_PATH=$ARCHIVE_DIR/${MANAGER_REPO}_${MANAGER_TAG}.tar >> $GITHUB_ENV
          echo COLLECTOR_TARBALL_PATH=$ARCHIVE_DIR/${COLLECTOR_REPO}_${COLLECTOR_TAG}.tar >> $GITHUB_ENV
          echo SCANNER_TARBALL_PATH=$ARCHIVE_DIR/${TRIVY_SCANNER_REPO}_${TRIVY_SCANNER_TAG}.tar >> $GITHUB_ENV

          if [[ -n "${{ inputs.upgrade-test }}" ]]; then
            echo HELM_UPGRADE_TEST=1 >> $GITHUB_ENV
          fi
      - name: Run e2e test
        run: |
          make e2e-test \
            KUBERNETES_VERSION=${{ matrix.KUBERNETES_VERSION }} \
            E2E_TESTS=${{ matrix.E2E_TEST }}
      - name: Remove slash from E2E_TEST
        run: |
          E2E_TEST=${{ matrix.E2E_TEST }}
          E2E_TEST=${E2E_TEST//\//_}
          echo "E2E_TEST=${E2E_TEST}" >> $GITHUB_ENV
      - name: Upload artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        if: always()
        with:
          name: test_logs_${{ matrix.KUBERNETES_VERSION }}_${{ env.E2E_TEST }}
          path: ${{ github.workspace }}/test_logs/
          retention-days: 1
          overwrite: true


================================================
FILE: .github/workflows/patch-docs.yaml
================================================
name: patch_docs
on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[1-9]+' # run this workflow when a new patch version is published

permissions:
  contents: write
  pull-requests: write

jobs:
  patch-docs:
    runs-on: ubuntu-22.04
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - name: Set release version and target branch for vNext
        if: github.event_name == 'push'
        run: |
          TAG="$(echo "${{ github.ref }}" | tr -d 'refs/tags/v')"
          MAJOR_VERSION="$(echo "${TAG}" | cut -d '.' -f1)"
          echo "MAJOR_VERSION=${MAJOR_VERSION}" >> ${GITHUB_ENV}
          MINOR_VERSION="$(echo "${TAG}" | cut -d '.' -f2)"
          echo "MINOR_VERSION=${MINOR_VERSION}" >> ${GITHUB_ENV}
          PATCH_VERSION="$(echo "${TAG}" | cut -d '.' -f3)"
          echo "PATCH_VERSION=${PATCH_VERSION}" >> ${GITHUB_ENV}
          echo "TAG=${TAG}" >> ${GITHUB_ENV}
      
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
        with:
          fetch-depth: 0

      - name: Create release branch if needed # patched docs are always being merged to the main branch
        run: |
          git checkout main 
      
      - name: Create patch version docs
        run: make patch-version-docs NEWVERSION=v${MAJOR_VERSION}.${MINOR_VERSION}.x TAG=v${TAG} OLDVERSION=v${MAJOR_VERSION}.${MINOR_VERSION}.$((PATCH_VERSION-1))
      
      - name: Create release pull request
        uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
        with:
          commit-message: "chore: Patch docs for ${{ env.TAG }} release"
          title: "chore: Patch docs for ${{ env.TAG }} release"
          branch: "patch-docs-${{ env.TAG }}"
          base: "main"
          signoff: true
          labels: |
            release-pr
            ${{ github.event.inputs.release_version }}
      

================================================
FILE: .github/workflows/release-pr.yaml
================================================
name: create_release_pull_request
on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.0' # run this workflow when a new minor version is published
  workflow_dispatch:
    inputs:
      release_version:
        description: 'Which version are we creating a release pull request for?'
        required: true

permissions:
  contents: write
  pull-requests: write

jobs:
  create-release-pull-request:
    runs-on: ubuntu-latest
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true

      - name: Set release version and target branch for vNext
        if: github.event_name == 'push'
        run: |
          TAG="$(echo "${{ github.ref }}" | tr -d 'refs/tags/v')"
          MAJOR_VERSION="$(echo "${TAG}" | cut -d '.' -f1)"
          echo "MAJOR_VERSION=${MAJOR_VERSION}" >> ${GITHUB_ENV}
          MINOR_VERSION="$(echo "${TAG}" | cut -d '.' -f2)"
          echo "MINOR_VERSION=${MINOR_VERSION}" >> ${GITHUB_ENV}

          # increment the minor version by 1 for vNext
          echo "NEWVERSION=v${MAJOR_VERSION}.$((MINOR_VERSION+1)).0-beta.0" >> ${GITHUB_ENV}
          # pre-release is always being merged to the main branch
          echo "TARGET_BRANCH=main" >> ${GITHUB_ENV}
          echo "TAG=${TAG}" >> ${GITHUB_ENV}

      - name: Set release version and target branch from input
        if: github.event_name == 'workflow_dispatch'
        run: |
          NEWVERSION="${{ github.event.inputs.release_version }}"
          echo "${NEWVERSION}" | grep -E '^v[0-9]+\.[0-9]+\.[0-9](-(beta|rc)\.[0-9]+)?$' || (echo "release_version should be in the format vX.Y.Z, vX.Y.Z-beta.A, or vX.Y.Z-rc.B" && exit 1)

          echo "NEWVERSION=${NEWVERSION}" >> ${GITHUB_ENV}
          echo "TAG=${NEWVERSION}" >> ${GITHUB_ENV}
          MAJOR_VERSION="$(echo "${NEWVERSION}" | cut -d '.' -f1 | tr -d 'v')"
          MINOR_VERSION="$(echo "${NEWVERSION}" | cut -d '.' -f2)"

          # non-beta releases should always be merged to release branches
          echo "TARGET_BRANCH=release-${MAJOR_VERSION}.${MINOR_VERSION}" >> ${GITHUB_ENV}

          # beta releases should always be merged to main
          if [[ "${NEWVERSION}" =~ "beta" ]]; then
            echo "TARGET_BRANCH=main" >> ${GITHUB_ENV}
          fi

      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
        with:
          fetch-depth: 0

      - name: Create release branch if needed
        run: |
          git checkout "${TARGET_BRANCH}" && exit 0

          # Create and push release branch if it doesn't exist
          git checkout -b "${TARGET_BRANCH}"
          git push --set-upstream origin "${TARGET_BRANCH}"

      - run: make release-manifest promote-staging-manifest

      - if: github.event_name == 'push'
        run: make version-docs NEWVERSION=v${MAJOR_VERSION}.${MINOR_VERSION}.x TAG=v${TAG}

      - name: Create release pull request
        uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
        with:
          commit-message: "chore: Prepare ${{ env.NEWVERSION }} release"
          title: "chore: Prepare ${{ env.NEWVERSION }} release"
          branch: "release-${{ env.NEWVERSION }}"
          base: "${{ env.TARGET_BRANCH }}"
          signoff: true


================================================
FILE: .github/workflows/release.yaml
================================================
name: release

on:
  push:
    # Sequence of patterns matched against refs/tags
    tags:
      - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

env:
  REGISTRY: ghcr.io

permissions:
  contents: write
  packages: write

jobs:
  build-publish-release:
    name: "release"
    runs-on: ubuntu-latest
    timeout-minutes: 60
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit

      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0

      - name: Setup buildx instance
        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
        with:
          use: true

      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0

      - name: Get tag
        run: |
          echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

      - name: Log in to the GHCR
        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build eraser-manager
        run: make docker-build-manager \
          CACHE_FROM=type=gha,scope=eraser-manager \
          CACHE_TO=type=gha,scope=eraser-manager,mode=max \
          PLATFORM="linux/amd64,linux/arm64" \
          OUTPUT_TYPE=type=registry \
          GENERATE_ATTESTATIONS=true \
          MANAGER_IMG=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/eraser-manager:${TAG}

      - name: Build remover
        run: make docker-build-remover \
          CACHE_FROM=type=gha,scope=eraser-node \
          CACHE_TO=type=gha,scope=eraser-node,mode=max \
          PLATFORM="linux/amd64,linux/arm64" \
          OUTPUT_TYPE=type=registry \
          GENERATE_ATTESTATIONS=true \
          REMOVER_IMG=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/remover:${TAG}

      - name: Build collector
        run: make docker-build-collector \
          CACHE_FROM=type=gha,scope=collector \
          CACHE_TO=type=gha,scope=collector,mode=max \
          PLATFORM="linux/amd64,linux/arm64" \
          OUTPUT_TYPE=type=registry \
          GENERATE_ATTESTATIONS=true \
          COLLECTOR_IMG=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/collector:${TAG}

      - name: Build Trivy scanner
        run: make docker-build-trivy-scanner \
          CACHE_FROM=type=gha,scope=trivy-scanner \
          CACHE_TO=type=gha,scope=trivy-scanner,mode=max \
          PLATFORM="linux/amd64,linux/arm64" \
          OUTPUT_TYPE=type=registry \
          GENERATE_ATTESTATIONS=true \
          TRIVY_SCANNER_IMG=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/eraser-trivy-scanner:${TAG}

      - name: Create GitHub release
        uses: marvinpinto/action-automatic-releases@919008cf3f741b179569b7a6fb4d8860689ab7f0 # v1.2.1
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN }}"
          prerelease: false

      - name: Publish Helm chart
        uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          charts_dir: charts
          target_dir: charts
          linting: off


================================================
FILE: .github/workflows/scan-images.yaml
================================================
name: Scan Images for Vulnerabilities (Trivy)
run-name: Scan ${{ inputs.version == '' && github.ref_name || inputs.version }} images for vulnerabilities ${{ github.event_name == 'schedule' && '(scheduled)' || '' }}
on:
  schedule:
    - cron: "0 7 * * 1" # Run every Monday at 7:00 AM UTC
  workflow_dispatch:
    inputs:
      version:
        description: "Version of Eraser to run Trivy scans against. Leave empty to scan images built from the branch the action is running against."
        type: string
        required: false
        default: ""
      upload-results:
        description: "Upload results to Github Security?"
        type: boolean
        required: true
        default: false

permissions: read-all

env:
  # Scanning released versions require the project `eraser-dev` as part of the registry name.
  REGISTRY: ghcr.io/${{ github.event.inputs.version == '' && 'eraser-test' || 'eraser-dev' }}
  TAG: ${{ github.event.inputs.version == '' && 'test' || github.event.inputs.version }}

jobs:
  scan_vulnerabilities:
    name: Scan ${{ matrix.data.image }} for vulnerabilities
    runs-on: ubuntu-latest
    timeout-minutes: 15
    strategy:
      matrix:
        data:
          - {image: remover, build_cmd: docker-build-remover, repo_environment_var: REMOVER_REPO}
          - {image: eraser-manager, build_cmd: docker-build-manager, repo_environment_var: MANAGER_REPO}
          - {image: collector, build_cmd: docker-build-collector, repo_environment_var: COLLECTOR_REPO}
          - {image: eraser-trivy-scanner, build_cmd: docker-build-trivy-scanner, repo_environment_var: TRIVY_SCANNER_REPO}
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - name: Check out code
        if: github.event_name == 'schedule' || github.event.inputs.version == ''
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0

      - name: Build image
        if: github.event_name == 'schedule' || github.event.inputs.version == ''
        run: |
          make ${{ matrix.data.build_cmd }} VERSION=${{ env.TAG }} ${{ matrix.data.repo_environment_var }}=${{ env.REGISTRY }}/${{ matrix.data.image }}

      - name: Scan for vulnerabilities
        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
        with:
          image-ref: ${{ env.REGISTRY }}/${{ matrix.data.image }}:${{ env.TAG }}
          vuln-type: 'os,library'
          ignore-unfixed: true
          format: 'sarif'
          output: ${{ matrix.data.image }}-results.sarif

      - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: ${{ matrix.data.image }} Scan Results
          path: ${{ matrix.data.image }}-results.sarif
          overwrite: true

  upload_vulnerabilities:
    name: Upload ${{ matrix.image }} results to GitHub Security
    runs-on: ubuntu-latest
    needs: scan_vulnerabilities
    if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.upload-results == 'true')
    permissions:
      actions: read
      contents: read
      security-events: write
    strategy:
      matrix:
        image: [remover, eraser-manager, collector, eraser-trivy-scanner]
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: ${{ matrix.image }} Scan Results
          path: ${{ matrix.image }}-results.sarif
          merge-multiple: true

      - name: Upload results to GitHub Security
        uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v2.14.4
        with:
          sarif_file: ${{ matrix.image }}-results.sarif


================================================
FILE: .github/workflows/scorecard.yml
================================================
name: Scorecard supply-chain security
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: '0 17 * * 1'
  push:
    branches: [ "main" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write

    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
        with:
          egress-policy: audit

      - name: "Checkout code"
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v3.1.0
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
        with:
          results_file: results.sarif
          results_format: sarif
          # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
          # - you want to enable the Branch-Protection check on a *public* repository, or
          # - you are installing Scorecard on a *private* repository
          # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
          # repo_token: ${{ secrets.SCORECARD_TOKEN }}

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories:
          #   - `publish_results` will always be set to `false`, regardless
          #     of the value entered here.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4  # v5.0.0
        with:
          name: SARIF file
          path: results.sarif
          retention-days: 5
          overwrite: true

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v2.2.4
        with:
          sarif_file: results.sarif


================================================
FILE: .github/workflows/test.yaml
================================================
name: test
on:
  push:
    paths-ignore:
      - "**.md"
      - "hack/**"
      - "docs/**"
  pull_request:
    paths-ignore:
      - "**.md"
      - "hack/**"
      - "docs/**"
env:
  REGISTRY: ghcr.io

permissions: read-all

jobs:
  generate-bucket-id:
    name: "Generate build id for storage"
    uses: ./.github/workflows/build-id.yaml

  build-images:
    name: "Build images for e2e tests"
    uses: ./.github/workflows/e2e-build.yaml
    needs:
      - generate-bucket-id
    with:
      bucket-id: ${{ needs.generate-bucket-id.outputs.bucket-id }}

  e2e-test:
    name: "Run e2e tests"
    uses: ./.github/workflows/e2e-test.yaml
    permissions:
      contents: write
    needs:
      - build-images
      - generate-bucket-id
    with:
      bucket-id: ${{ needs.generate-bucket-id.outputs.bucket-id }}

  lint:
    name: "Lint"
    runs-on: ubuntu-latest
    timeout-minutes: 40
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: lint manager
        uses: golangci/golangci-lint-action@e7fa5ac41e1cf5b7d48e45e42232ce7ada589601 # v9.1.0
        with:
          version: latest
          args: --timeout=10m
      - name: lint remover
        uses: golangci/golangci-lint-action@e7fa5ac41e1cf5b7d48e45e42232ce7ada589601 # v9.1.0
        with:
          version: latest
          working-directory: pkg/remover
          skip-pkg-cache: true
          args: --timeout=10m
      - name: lint collector
        uses: golangci/golangci-lint-action@e7fa5ac41e1cf5b7d48e45e42232ce7ada589601 # v9.1.0
        with:
          version: latest
          working-directory: pkg/collector
          skip-pkg-cache: true
          args: --timeout=10m
      - name: lint trivvy scanner
        uses: golangci/golangci-lint-action@e7fa5ac41e1cf5b7d48e45e42232ce7ada589601 # v9.1.0
        with:
          version: latest
          working-directory: pkg/scanners/trivy
          skip-pkg-cache: true
          args: --timeout=10m

  unit-test:
    name: "Unit Tests"
    runs-on: ubuntu-latest
    timeout-minutes: 40
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          key: ${{ runner.OS }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Unit test
        run: make test
      - name: Codecov upload
        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7
        with:
          flags: unittests
          file: ./cover.out
          fail_ci_if_error: false

  check-manifest:
    name: "Check codegen and manifest"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit
      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Set up Go
        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
        with:
          go-version: "1.25"
          check-latest: true
      - name: Check go.mod and manifests
        run: |
          go mod tidy
          git diff --exit-code
          make generate manifests
          git diff --exit-code

  scan_vulnerabilities:
    name: "[Trivy] Scan for vulnerabilities"
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2
        with:
          egress-policy: audit

      - name: Check out code into the Go module directory
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0

      - name: Get repo
        run: |
          echo "REPO=$(echo $GITHUB_REPOSITORY | awk '{print tolower($0)}')" >> $GITHUB_ENV

      - name: Build eraser-manager
        run: |
          make docker-build-manager MANAGER_REPO=${{ env.REGISTRY }}/${REPO}-manager MANAGER_TAG=test
      - name: Build remover
        run: |
          make docker-build-remover REMOVER_REPO=${{ env.REGISTRY }}/remover REMOVER_TAG=test
      - name: Build collector
        run: |
          make docker-build-collector COLLECTOR_REPO=${{ env.REGISTRY }}/collector COLLECTOR_TAG=test
      - name: Build trivy scanner
        run: |
          make docker-build-trivy-scanner TRIVY_SCANNER_REPO=${{ env.REGISTRY }}/${REPO}-trivy-scanner TRIVY_SCANNER_TAG=test

      - name: Run trivy for remover
        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
        with:
          image-ref: ${{ env.REGISTRY }}/remover:test
          exit-code: "1"
          ignore-unfixed: true
          vuln-type: "os,library"

      - name: Run trivy for eraser-manager
        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.REPO }}-manager:test
          exit-code: "1"
          ignore-unfixed: true
          vuln-type: "os,library"

      - name: Run trivy for collector
        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
        with:
          image-ref: ${{ env.REGISTRY }}/collector:test
          exit-code: "1"
          ignore-unfixed: true
          vuln-type: "os,library"

      - name: Run trivy for trivy-scanner
        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.REPO }}-trivy-scanner:test
          exit-code: "1"
          ignore-unfixed: true
          vuln-type: "os,library"


================================================
FILE: .github/workflows/upgrade.yaml
================================================
name: upgrade
on:
  push:
    paths:
      - "manifest_staging/charts/**"
      - ".github/workflows/upgrade.yaml"

  pull_request:
    paths:
      - "manifest_staging/charts/**"
      - ".github/workflows/upgrade.yaml"

env:
  REGISTRY: ghcr.io

permissions: read-all

jobs:
  generate-bucket-id:
    name: "Generate build id for storage"
    uses: ./.github/workflows/build-id.yaml

  build-images:
    name: "Build images for e2e tests"
    uses: ./.github/workflows/e2e-build.yaml
    needs:
      - generate-bucket-id
    with:
      bucket-id: ${{ needs.generate-bucket-id.outputs.bucket-id }}

  e2e-test:
    name: "Run e2e tests"
    uses: ./.github/workflows/e2e-test.yaml
    permissions:
      contents: write
    needs:
      - build-images
      - generate-bucket-id
    with:
      upgrade-test: "1"
      bucket-id: ${{ needs.generate-bucket-id.outputs.bucket-id }}


================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin
testbin/*
.eraser
./pkg/eraser/eraser
# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Kubernetes Generated files - skip generated files, except for vendored files

!vendor/**/zz_generated.*

# editor and IDE paraphernalia
.idea
*.swp
*.swo
*~

# history files
.history

.vscode/

# macOS
.DS_Store

# docs site
node_modules/
.docusaurus/
/docs/build/

!/build/
/build/*
!/build/tooling/
!/build/version.sh

# e2e test log outputs
test/e2e/tests/eraser_logs/
eraser
remover


================================================
FILE: .golangci.yaml
================================================
version: "2"

run:
  go: "1.25"

linters:
  default: none
  enable:
    - errcheck
    - copyloopvar # replacement for exportloopref
    - forcetypeassert
    - gocritic
    - goconst
    - godot
    - gosec
    - govet
    - ineffassign
    - misspell
    # - revive # replacement for golint
    - staticcheck # includes gosimple and staticcheck
    - unused
    - whitespace
  settings:
    gocritic:
      enabled-tags:
      - performance
    gosec:
      excludes:
      - G108
    lll:
      line-length: 200
    misspell:
      locale: US
  exclusions:
    paths:
      - "docs/build/assets/files/.*\\.go"

formatters:
  enable:
    - gofmt
    - gofumpt
    - goimports


================================================
FILE: .trivyignore
================================================
GHSA-6xv5-86q9-7xr8


================================================
FILE: CODEOWNERS
================================================
# Global approvers
*   @ashnamehrotra @pmengelbert @sozercan


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# CNCF Code of Conduct

This project has adopted the [CNCF Community Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).

Resources:

- [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md)
- [Reporting](https://github.com/cncf/foundation/blob/main/code-of-conduct.md)


================================================
FILE: Dockerfile
================================================
# syntax=docker/dockerfile:1.6

# Default Trivy binary image, overwritten by Makefile
ARG TRIVY_BINARY_IMG="ghcr.io/aquasecurity/trivy:0.67.2"
ARG BUILDKIT_SBOM_SCAN_STAGE=builder,manager-build,collector-build,remover-build,trivy-scanner-build

FROM --platform=$TARGETPLATFORM $TRIVY_BINARY_IMG AS trivy-binary

# Build the manager binary
FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS builder
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
ENV GOCACHE=/root/gocache
ENV CGO_ENABLED=0
RUN \
    --mount=type=cache,target=${GOCACHE} \
    --mount=type=cache,target=/go/pkg/mod \
    go mod download
COPY . .

ARG LDFLAGS
ARG TARGETOS
ARG TARGETARCH

FROM builder AS manager-build
RUN \
    --mount=type=cache,target=${GOCACHE} \
    --mount=type=cache,target=/go/pkg/mod \
    GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build ${LDFLAGS:+-ldflags "$LDFLAGS"} -o out/manager main.go

FROM builder AS collector-build
RUN \
    --mount=type=cache,target=${GOCACHE} \
    --mount=type=cache,target=/go/pkg/mod \
    GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build ${LDFLAGS:+-ldflags "$LDFLAGS"} -o out/collector ./pkg/collector

FROM builder AS remover-build
RUN \
    --mount=type=cache,target=${GOCACHE} \
    --mount=type=cache,target=/go/pkg/mod \
    GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build ${LDFLAGS:+-ldflags "$LDFLAGS"} -o out/remover ./pkg/remover

FROM builder AS trivy-scanner-build
RUN \
    --mount=type=cache,target=${GOCACHE} \
    --mount=type=cache,target=/go/pkg/mod \
    GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build ${LDFLAGS:+-ldflags "$LDFLAGS"} -o out/trivy-scanner ./pkg/scanners/trivy

FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:nonroot AS manager
WORKDIR /
COPY --from=manager-build /workspace/out/manager .
USER 65532:65532
ENTRYPOINT ["/manager"]

FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:latest as collector
COPY --from=collector-build /workspace/out/collector /
ENTRYPOINT ["/collector"]

FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:latest as remover
COPY --from=remover-build /workspace/out/remover /
ENTRYPOINT ["/remover"]

FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:latest as trivy-scanner
COPY --from=trivy-scanner-build /workspace/out/trivy-scanner /
COPY --from=trivy-binary /usr/local/bin/trivy /
WORKDIR /var/lib/trivy
ENTRYPOINT ["/trivy-scanner"]

FROM gcr.io/distroless/static-debian12:nonroot AS non-vulnerable
COPY --from=builder /tmp /tmp


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2023 The Linux Foundation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: MAINTAINERS.md
================================================
# Maintainers

Maintainers:
- Sertaç Özercan (@sozercan)
- Ashna Mehrotra (@ashnamehrotra)
- Peter Engelbert (@pmengelbert)
- Brian Goff (@cpuguy83)


================================================
FILE: Makefile
================================================
VERSION := v1.5.0-beta.0

MANAGER_TAG ?= ${VERSION}
TRIVY_SCANNER_TAG ?= ${VERSION}
COLLECTOR_TAG ?= ${VERSION}
REMOVER_TAG ?= ${VERSION}

# Image URL to use all building/pushing image targets
TRIVY_SCANNER_REPO ?= ghcr.io/eraser-dev/eraser-trivy-scanner
TRIVY_SCANNER_IMG ?= ${TRIVY_SCANNER_REPO}:${TRIVY_SCANNER_TAG}
TRIVY_BINARY_REPO ?= ghcr.io/aquasecurity/trivy
TRIVY_BINARY_TAG ?= 0.67.2
TRIVY_BINARY_IMG ?= ${TRIVY_BINARY_REPO}:${TRIVY_BINARY_TAG}
MANAGER_REPO ?= ghcr.io/eraser-dev/eraser-manager
MANAGER_IMG ?= ${MANAGER_REPO}:${MANAGER_TAG}
REMOVER_REPO ?= ghcr.io/eraser-dev/remover
REMOVER_IMG ?= ${REMOVER_REPO}:${REMOVER_TAG}
COLLECTOR_REPO ?= ghcr.io/eraser-dev/collector
COLLECTOR_IMG ?= ${COLLECTOR_REPO}:${COLLECTOR_TAG}
VULNERABLE_IMG ?= docker.io/library/alpine:3.7.3
EOL_IMG ?= docker.io/library/alpine:3.6
BUSYBOX_BASE_IMG ?= busybox:1.36.0
NON_VULNERABLE_IMG ?= ghcr.io/eraser-dev/non-vulnerable:latest
E2E_TESTS ?= $(shell find ./test/e2e/tests/ -mindepth 1 -type d)
API_VERSIONS ?= ./api/v1alpha1,./api/v1,./api/v1alpha2,./api/v1alpha3

HELM_UPGRADE_TEST ?=
TEST_LOGDIR ?= $(PWD)/test_logs

REMOVER_TARBALL_PATH ?=
MANAGER_TARBALL_PATH ?=
COLLECTOR_TARBALL_PATH ?=
SCANNER_TARBALL_PATH ?=

KUSTOMIZE_VERSION ?= 3.8.9
KUBERNETES_VERSION ?= 1.29.2
NODE_VERSION ?= 20-bullseye-slim
ENVTEST_K8S_VERSION ?= 1.25
GOLANGCI_LINT_VERSION := 1.43.0

PLATFORM ?= linux

# build variables
LDFLAGS ?= $(shell build/version.sh "${VERSION}")
ERASER_LDFLAGS ?= -extldflags=-static $(LDFLAGS) -w
TRIVY_SCANNER_LDFLAGS ?= $(ERASER_LDFLAGS) -X 'main.trivyVersion=v$(TRIVY_BINARY_TAG)'

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

ifdef CACHE_TO
_CACHE_TO := --cache-to $(CACHE_TO)
endif

ifdef CACHE_FROM
_CACHE_FROM := --cache-from $(CACHE_FROM)
endif

ifdef GENERATE_ATTESTATIONS
_ATTESTATIONS := --attest type=sbom --attest type=provenance,mode=max
endif

IDFLAGS=
ifeq (false,$(shell hack/rootless_docker.sh))
IDFLAGS=-u $(shell id -u):$(shell id -g)
endif

OUTPUT_TYPE ?= type=docker
TOOLS_DIR := hack/tools
TOOLS_BIN_DIR := $(abspath $(TOOLS_DIR)/bin)
GO_INSTALL := ./hack/go-install.sh

GOLANGCI_LINT_BIN := golangci-lint
GOLANGCI_LINT := $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-v$(GOLANGCI_LINT_VERSION)

TEST_COUNT ?= 1
TIMEOUT ?= 1800s

$(GOLANGCI_LINT):
	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/cmd/golangci-lint $(GOLANGCI_LINT_BIN) v$(GOLANGCI_LINT_VERSION)

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

all: build

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

help: ## Display this help.
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Linting
.PHONY: lint
lint: $(GOLANGCI_LINT) ## Runs go linting.
	$(GOLANGCI_LINT) run -v

##@ Development

#kustomize_

manifests: __manifest_kustomize __helm_kustomize __controller-gen ## Generates k8s yaml for eraser deployment.
	$(CONTROLLER_GEN) \
		crd \
		rbac:roleName=manager-role \
		webhook \
		paths="./..." \
		output:crd:artifacts:config=config/crd/bases
	rm -rf manifest_staging
	mkdir -p manifest_staging/deploy
	mkdir -p manifest_staging/charts/eraser
	$(MANIFEST_KUSTOMIZE) build /eraser/config/default -o /eraser/manifest_staging/deploy/eraser.yaml
	$(HELM_KUSTOMIZE) build \
		--load_restrictor LoadRestrictionsNone /eraser/third_party/open-policy-agent/gatekeeper/helmify | \
		go run third_party/open-policy-agent/gatekeeper/helmify/*.go

# Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method
# implementations. Also generate conversions between structs of different API versions.
generate: __conversion-gen __controller-gen
	$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..."
	$(CONVERSION_GEN) \
		--output-base=/eraser \
		--input-dirs=$(API_VERSIONS) \
		--go-header-file=./hack/boilerplate.go.txt \
		--output-file-base=zz_generated.conversion

fmt: ## Run go fmt against code.
	go fmt ./...

vet: ## Run go vet against code.
	go vet ./...

test: manifests generate fmt vet envtest ## Run unit tests.
	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out

busybox-img:
	docker build -t busybox-e2e-test:latest \
		-f test/e2e/test-data/Dockerfile.busybox \
		--build-arg IMG=$(BUSYBOX_BASE_IMG) test/e2e/test-data
BUSYBOX_IMG=busybox-e2e-test:latest

collector-dummy-img:
	docker build -t $(COLLECTOR_REPO):dummy \
		-f test/e2e/test-data/Dockerfile.dummyCollector \
		test/e2e/test-data
COLLECTOR_IMAGE_DUMMY=$(COLLECTOR_REPO):dummy

vulnerable-img:
	docker pull $(VULNERABLE_IMG)

eol-img:
	docker pull $(EOL_IMG)

non-vulnerable-img:
	docker buildx build \
		$(_CACHE_FROM) $(_CACHE_TO) \
		--build-arg LDFLAGS="$(LDFLAGS)" \
		--platform="$(PLATFORM)" \
		--output=$(OUTPUT_TYPE) \
		-t ${NON_VULNERABLE_IMG} \
		--target non-vulnerable .

custom-node-v$(KUBERNETES_VERSION):
	docker build -t custom-node:v$(KUBERNETES_VERSION) \
		-f test/e2e/test-data/Dockerfile.customNode \
		--build-arg KUBERNETES_VERSION=${KUBERNETES_VERSION} test/e2e/test-data
MODIFIED_NODE_IMAGE=custom-node:v$(KUBERNETES_VERSION)

e2e-test: vulnerable-img eol-img non-vulnerable-img busybox-img collector-dummy-img custom-node-v$(KUBERNETES_VERSION)
	for test in $(E2E_TESTS); do \
		CGO_ENABLED=0 \
            PROJECT_ABSOLUTE_PATH=$(CURDIR) \
            REMOVER_TARBALL_PATH=${REMOVER_TARBALL_PATH} \
            MANAGER_TARBALL_PATH=${MANAGER_TARBALL_PATH} \
            COLLECTOR_TARBALL_PATH=${COLLECTOR_TARBALL_PATH} \
            SCANNER_TARBALL_PATH=${SCANNER_TARBALL_PATH} \
			HELM_UPGRADE_TEST=${HELM_UPGRADE_TEST} \
			REMOVER_IMAGE=${REMOVER_IMG} \
			MANAGER_IMAGE=${MANAGER_IMG} \
			COLLECTOR_IMAGE=${COLLECTOR_IMG} \
			SCANNER_IMAGE=${TRIVY_SCANNER_IMG} \
			BUSYBOX_IMAGE=${BUSYBOX_IMG} \
			COLLECTOR_IMAGE_DUMMY=${COLLECTOR_IMAGE_DUMMY} \
			VULNERABLE_IMAGE=${VULNERABLE_IMG} \
			NON_VULNERABLE_IMAGE=${NON_VULNERABLE_IMG} \
			EOL_IMAGE=${EOL_IMG} \
			NODE_VERSION=kindest/node:v${KUBERNETES_VERSION} \
			MODIFIED_NODE_IMAGE=${MODIFIED_NODE_IMAGE} \
			TEST_LOGDIR=${TEST_LOGDIR} \
			go test -count=$(TEST_COUNT) -timeout=$(TIMEOUT) $(TESTFLAGS) -tags=e2e -v $$test ; \
	done

##@ Build
build: generate fmt vet ## Build manager binary.
	go build -o bin/manager -ldflags "$(LDFLAGS)" main.go

run: manifests generate fmt vet ## Run a controller from your host.
	go run ./main.go

docker-build-manager: ## Build docker image with the manager.
	docker buildx build \
		$(_CACHE_FROM) $(_CACHE_TO) \
		$(_ATTESTATIONS) \
		--build-arg LDFLAGS="$(LDFLAGS)" \
		--platform="$(PLATFORM)" \
		--output=$(OUTPUT_TYPE) \
		-t ${MANAGER_IMG} \
		--target manager .

docker-build-trivy-scanner: ## Build docker image for trivy-scanner image.
	docker buildx build \
		$(_CACHE_FROM) $(_CACHE_TO) \
		$(_ATTESTATIONS) \
		--build-arg TRIVY_BINARY_IMG="$(TRIVY_BINARY_IMG)" \
		--build-arg LDFLAGS="$(TRIVY_SCANNER_LDFLAGS)" \
		--platform="$(PLATFORM)" \
		--output=$(OUTPUT_TYPE) \
		-t ${TRIVY_SCANNER_IMG} \
		--target trivy-scanner .

docker-build-remover: ## Build docker image for remover image.
	docker buildx build \
		$(_CACHE_FROM) $(_CACHE_TO) \
		$(_ATTESTATIONS) \
		--build-arg LDFLAGS="$(ERASER_LDFLAGS)" \
		--platform="$(PLATFORM)" \
		--output=$(OUTPUT_TYPE) \
		-t ${REMOVER_IMG} \
		--target remover .

docker-build-collector:
	docker buildx build \
		$(_CACHE_FROM) $(_CACHE_TO) \
		$(_ATTESTATIONS) \
		--build-arg LDFLAGS="$(LDFLAGS)" \
		--platform="$(PLATFORM)" \
		--output=$(OUTPUT_TYPE) \
		-t ${COLLECTOR_IMG} \
		--target collector .

##@ Deployment

install: __manifest_kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
	$(MANIFEST_KUSTOMIZE) build /eraser/config/crd | kubectl apply -f -

uninstall: __manifest_kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
	$(MANIFEST_KUSTOMIZE) build /eraser/config/crd | kubectl delete -f -

deploy: __manifest_kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
	$(MANIFEST_KUSTOMIZE) build /eraser/config/default | kubectl apply -f -

undeploy: __manifest_kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
	$(MANIFEST_KUSTOMIZE) build /eraser/config/default | kubectl delete -f -

##@ Release

release-manifest: ## Generates manifests for a release.
	@sed -i -e 's/^VERSION := .*/VERSION := ${NEWVERSION}/' ./Makefile
	@sed -i'' -e 's@image: $(REPOSITORY):.*@image: $(REPOSITORY):'"$(NEWVERSION)"'@' ./config/manager/manager.yaml
	@sed -i "s/appVersion: .*/appVersion: ${NEWVERSION}/" ./third_party/open-policy-agent/gatekeeper/helmify/static/Chart.yaml
	@sed -i "s/version: .*/version: $$(echo ${NEWVERSION} | cut -c2-)/" ./third_party/open-policy-agent/gatekeeper/helmify/static/Chart.yaml
	@sed -Ei 's/(tag:\s*).*/\1"$(NEWVERSION)"/' ./third_party/open-policy-agent/gatekeeper/helmify/static/values.yaml
	@sed -i 's/Current release version: `.*`/Current release version: `'"${NEWVERSION}"'`/' ./third_party/open-policy-agent/gatekeeper/helmify/static/README.md
	@sed -i 's/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/master\/deploy\/eraser\.yaml.*/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/${NEWVERSION}\/deploy\/eraser\.yaml/' ./docs/docs/installation.md
	export
	$(MAKE) manifests

promote-staging-manifest: ## Promotes the k8s deployment yaml files to release.
	@rm -rf deploy
	@cp -r manifest_staging/deploy .
	@rm -rf charts
	@cp -r manifest_staging/charts .

ENVTEST = $(shell pwd)/bin/setup-envtest
.PHONY: envtest
envtest: __tooling-image bin/setup-envtest

bin/setup-envtest:
	docker run --rm -v $(shell pwd)/bin:/go/bin -e GO111MODULE=on eraser-tooling go install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20240320141353-395cfc7486e6

__controller-gen: __tooling-image
CONTROLLER_GEN=docker run --rm -v $(shell pwd):/eraser eraser-tooling controller-gen

__conversion-gen: __tooling-image
CONVERSION_GEN=docker run --rm -v $(shell pwd):/eraser eraser-tooling conversion-gen

__manifest_kustomize: __kustomize-manifest-image
MANIFEST_KUSTOMIZE=docker run --rm -v $(shell pwd)/manifest_staging:/eraser/manifest_staging manifest-kustomize

__helm_kustomize: __kustomize-helm-image
HELM_KUSTOMIZE=docker run --rm -v $(shell pwd)/manifest_staging:/eraser/manifest_staging -v $(shell pwd)/third_party:/eraser/third_party helm-kustomize

__tooling-image:
	docker build . \
		-t eraser-tooling \
		-f build/tooling/Dockerfile

__kustomize-helm-image:
	docker build . \
		-t helm-kustomize \
		--build-arg KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION} \
		-f build/tooling/Dockerfile.helm

__kustomize-manifest-image:
	docker build . \
		-t manifest-kustomize \
		--build-arg KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION} \
		--build-arg TRIVY_SCANNER_REPO=${TRIVY_SCANNER_REPO} \
		--build-arg MANAGER_REPO=${MANAGER_REPO} \
		--build-arg REMOVER_REPO=${REMOVER_REPO} \
		--build-arg COLLECTOR_REPO=${COLLECTOR_REPO} \
		--build-arg MANAGER_TAG=${MANAGER_TAG} \
		--build-arg TRIVY_SCANNER_TAG=${TRIVY_SCANNER_TAG} \
		--build-arg COLLECTOR_TAG=${COLLECTOR_TAG} \
		--build-arg REMOVER_TAG=${REMOVER_TAG} \
		-f build/tooling/Dockerfile.manifest

# Tags a new version for docs
.PHONY: version-docs
version-docs:
	docker run --rm \
		-v $(shell pwd)/docs:/docs \
		-w /docs \
		$(IDFLAGS) \
		node:${NODE_VERSION} \
		sh -c "yarn install --frozen-lockfile && yarn run docusaurus docs:version ${NEWVERSION}"
	@sed -i 's/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/main\/deploy\/eraser\.yaml.*/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/${TAG}\/deploy\/eraser\.yaml/' ./docs/versioned_docs/version-${NEWVERSION}/installation.md

.PHONY: patch-version-docs
patch-version-docs:
	@sed -i 's/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/${OLDVERSION}\/deploy\/eraser\.yaml.*/https:\/\/raw\.githubusercontent\.com\/eraser-dev\/eraser\/${TAG}\/deploy\/eraser\.yaml/' ./docs/versioned_docs/version-${NEWVERSION}/installation.md


================================================
FILE: PROJECT
================================================
domain: eraser-dev.io
layout:
- go.kubebuilder.io/v3
projectName: eraser
repo: github.com/eraser-dev/eraser
resources:
- api:
    crdVersion: v1alpha1
    namespaced: true
  controller: true
  domain: eraser-dev.io
  group: eraser.sh
  kind: ImageList
  path: eraser.io/eraser/api/v1alpha1
  version: v1alpha1
- controller: true
  domain: eraser-dev.io
  group: eraser.sh
  kind: ImageCollector
  version: v1alpha1
- domain: eraser-dev.io
  group: eraser.sh
  kind: ImageList
  version: v1
- api:
    crdVersion: v1
    namespaced: true
  domain: eraser.io
  group: eraser.sh
  kind: EraserConfig
  path: github.com/eraser-dev/eraser/api/v1alpha1
  version: v1alpha1
- domain: eraser.io
  group: eraser.sh
  kind: EraserConfig
  version: v1alpha2
version: "3"


================================================
FILE: README.md
================================================
# Eraser: Cleaning up Images from Kubernetes Nodes

![GitHub](https://img.shields.io/github/license/eraser-dev/eraser)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Feraser-dev%2Feraser.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Feraser-dev%2Feraser?ref=badge_shield)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7622/badge)](https://www.bestpractices.dev/projects/7622)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/eraser-dev/eraser/badge)](https://api.securityscorecards.dev/projects/github.com/eraser-dev/eraser)

<img src="./images/eraser-logo-color-1c.png" alt="Eraser logo" width="100%" />

Eraser helps Kubernetes admins remove a list of non-running images from all Kubernetes nodes in a cluster.

## Getting started

You can find a quick start guide in the Eraser [documentation](https://eraser-dev.github.io/eraser/docs/quick-start).

## Demo

![intro](demo/demo.gif)

## Contributing

There are several ways to get involved:

- Join the [mailing list](https://groups.google.com/u/1/g/eraser-dev) to get notifications for releases, security announcements, etc.
- Join the [biweekly community meetings](https://docs.google.com/document/d/1Sj5u47K3WUGYNPmQHGFpb52auqZb1FxSlWAQnPADhWI/edit) to discuss development, issues, use cases, etc.
- Join the `#eraser` channel on the [Kubernetes Slack](https://kubernetes.slack.com/archives/C03Q8KV8YQ4)
- View the development setup instructions in the [documentation](https://eraser-dev.github.io/eraser/docs/setup)

This project welcomes contributions and suggestions.

This project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).

## Support

### How to file issues and get help

This project uses GitHub Issues to track bugs and feature requests. Please search the [existing issues](https://github.com/eraser-dev/eraser/issues) before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue.

The Eraser maintainers will respond to the best of their abilities.

================================================
FILE: api/group.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apis


================================================
FILE: api/unversioned/config/config.go
================================================
package config

import (
	"fmt"
	"sync"
	"time"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"

	"github.com/eraser-dev/eraser/api/unversioned"
	"github.com/eraser-dev/eraser/version"
)

var defaultScannerConfig = `
cacheDir: /var/lib/trivy
dbRepo: ghcr.io/aquasecurity/trivy-db
deleteFailedImages: true
deleteEOLImages: true
vulnerabilities:
  ignoreUnfixed: false
  types:
    - os
    - library
securityChecks: # need to be documented; determined by trivy, not us
  - vuln
severities:
  - CRITICAL
  - HIGH
  - MEDIUM
  - LOW
ignoredStatuses:
`

type Manager struct {
	mtx sync.Mutex
	cfg *unversioned.EraserConfig
}

func (m *Manager) Read() (unversioned.EraserConfig, error) {
	m.mtx.Lock()
	defer m.mtx.Unlock()

	if m.cfg == nil {
		return unversioned.EraserConfig{}, fmt.Errorf("ConfigManager configuration is nil, aborting")
	}

	cfg := *m.cfg
	return cfg, nil
}

func (m *Manager) Update(newC *unversioned.EraserConfig) error {
	m.mtx.Lock()
	defer m.mtx.Unlock()

	if m.cfg == nil {
		return fmt.Errorf("ConfigManager configuration is nil, aborting")
	}

	if newC == nil {
		return fmt.Errorf("new configuration is nil, aborting")
	}

	*m.cfg = *newC
	return nil
}

func NewManager(cfg *unversioned.EraserConfig) *Manager {
	return &Manager{
		mtx: sync.Mutex{},
		cfg: cfg,
	}
}

const (
	noDelay = unversioned.Duration(0)
	oneDay  = unversioned.Duration(time.Hour * 24)
)

func Default() *unversioned.EraserConfig {
	return &unversioned.EraserConfig{
		Manager: unversioned.ManagerConfig{
			Runtime: unversioned.RuntimeSpec{
				Name:    unversioned.RuntimeContainerd,
				Address: "unix:///run/containerd/containerd.sock",
			},
			OTLPEndpoint: "",
			LogLevel:     "info",
			Scheduling: unversioned.ScheduleConfig{
				RepeatInterval:   unversioned.Duration(oneDay),
				BeginImmediately: true,
			},
			Profile: unversioned.ProfileConfig{
				Enabled: false,
				Port:    6060,
			},
			ImageJob: unversioned.ImageJobConfig{
				SuccessRatio: 1.0,
				Cleanup: unversioned.ImageJobCleanupConfig{
					DelayOnSuccess: noDelay,
					DelayOnFailure: oneDay,
				},
			},
			PullSecrets: []string{},
			NodeFilter: unversioned.NodeFilterConfig{
				Type: "exclude",
				Selectors: []string{
					"eraser.sh/cleanup.filter",
				},
			},
			AdditionalPodLabels: map[string]string{},
		},
		Components: unversioned.Components{
			Collector: unversioned.OptionalContainerConfig{
				Enabled: false,
				ContainerConfig: unversioned.ContainerConfig{
					Image: unversioned.RepoTag{
						Repo: repo("collector"),
						Tag:  version.BuildVersion,
					},
					Request: unversioned.ResourceRequirements{
						Mem: resource.MustParse("25Mi"),
						CPU: resource.MustParse("7m"),
					},
					Limit: unversioned.ResourceRequirements{
						Mem: resource.MustParse("500Mi"),
						CPU: resource.Quantity{},
					},
					Config: nil,
				},
			},
			Scanner: unversioned.OptionalContainerConfig{
				Enabled: false,
				ContainerConfig: unversioned.ContainerConfig{
					Image: unversioned.RepoTag{
						Repo: repo("eraser-trivy-scanner"),
						Tag:  version.BuildVersion,
					},
					Request: unversioned.ResourceRequirements{
						Mem: resource.MustParse("500Mi"),
						CPU: resource.MustParse("1000m"),
					},
					Limit: unversioned.ResourceRequirements{
						Mem: resource.MustParse("2Gi"),
						CPU: resource.MustParse("1500m"),
					},
					Config:  &defaultScannerConfig,
					Volumes: []v1.Volume{},
				},
			},
			Remover: unversioned.ContainerConfig{
				Image: unversioned.RepoTag{
					Repo: repo("remover"),
					Tag:  version.BuildVersion,
				},
				Request: unversioned.ResourceRequirements{
					Mem: resource.MustParse("25Mi"),
					CPU: resource.MustParse("7m"),
				},
				Limit: unversioned.ResourceRequirements{
					Mem: resource.MustParse("30Mi"),
					CPU: resource.Quantity{},
				},
				Config: nil,
			},
		},
	}
}

func repo(basename string) string {
	if version.DefaultRepo == "" {
		return basename
	}

	return fmt.Sprintf("%s/%s", version.DefaultRepo, basename)
}


================================================
FILE: api/unversioned/doc.go
================================================
package unversioned

// +kubebuilder:object:generate=true


================================================
FILE: api/unversioned/eraserconfig_types.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package unversioned

import (
	"encoding/json"
	"fmt"
	"net/url"
	"time"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type (
	Duration time.Duration
	Runtime  string

	RuntimeSpec struct {
		Name    Runtime `json:"name"`
		Address string  `json:"address"`
	}
)

const (
	RuntimeContainerd  Runtime = "containerd"
	RuntimeDockerShim  Runtime = "dockershim"
	RuntimeCrio        Runtime = "crio"
	RuntimeNotProvided Runtime = ""

	ContainerdPath = "/run/containerd/containerd.sock"
	DockerPath     = "/run/dockershim.sock"
	CrioPath       = "/run/crio/crio.sock"
)

func ConvertRuntimeToRuntimeSpec(r Runtime) (RuntimeSpec, error) {
	var rs RuntimeSpec

	switch r {
	case RuntimeContainerd:
		rs = RuntimeSpec{Name: RuntimeContainerd, Address: fmt.Sprintf("unix://%s", ContainerdPath)}
	case RuntimeDockerShim:
		rs = RuntimeSpec{Name: RuntimeDockerShim, Address: fmt.Sprintf("unix://%s", DockerPath)}
	case RuntimeCrio:
		rs = RuntimeSpec{Name: RuntimeCrio, Address: fmt.Sprintf("unix://%s", CrioPath)}
	default:
		return rs, fmt.Errorf("invalid runtime: valid names are %s, %s, %s", RuntimeContainerd, RuntimeDockerShim, RuntimeCrio)
	}

	return rs, nil
}

func (td *Duration) UnmarshalJSON(b []byte) error {
	var str string
	err := json.Unmarshal(b, &str)
	if err != nil {
		return err
	}

	pd, err := time.ParseDuration(str)
	if err != nil {
		return err
	}

	*td = Duration(pd)
	return nil
}

func (td *Duration) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, time.Duration(*td).String())), nil
}

func (r *RuntimeSpec) UnmarshalJSON(b []byte) error {
	// create temp RuntimeSpec to prevent recursive error into this function when using unmarshall to check validity of provided RuntimeSpec
	type TempRuntimeSpec struct {
		Name    string `json:"name"`
		Address string `json:"address"`
	}
	var rs TempRuntimeSpec
	err := json.Unmarshal(b, &rs)
	if err != nil {
		return fmt.Errorf("error unmarshalling into TempRuntimeSpec %v %s", err, string(b))
	}

	switch rt := Runtime(rs.Name); rt {
	// make sure user provided Runtime is valid
	case RuntimeContainerd, RuntimeDockerShim, RuntimeCrio:
		if rs.Address != "" {
			// check that provided RuntimeAddress is valid
			u, err := url.Parse(rs.Address)
			if err != nil {
				return err
			}

			switch u.Scheme {
			case "tcp", "unix":
			default:
				return fmt.Errorf("invalid RuntimeAddress scheme: valid schemes for runtime socket address are `tcp` and `unix`")
			}

			r.Name = Runtime(rs.Name)
			r.Address = rs.Address

			return nil
		}

		// if RuntimeAddress is not provided, get defaults
		converted, err := ConvertRuntimeToRuntimeSpec(rt)
		if err != nil {
			return err
		}

		*r = converted
	case RuntimeNotProvided:
		if rs.Address != "" {
			return fmt.Errorf("runtime name must be provided with address")
		}

		// if empty name and address, use containerd as default
		r.Name = RuntimeContainerd
		r.Address = fmt.Sprintf("unix://%s", ContainerdPath)
	default:
		return fmt.Errorf("invalid runtime: valid names are %s, %s, %s", RuntimeContainerd, RuntimeDockerShim, RuntimeCrio)
	}

	return nil
}

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

type OptionalContainerConfig struct {
	Enabled         bool `json:"enabled,omitempty"`
	ContainerConfig `json:",inline"`
}

type ContainerConfig struct {
	Image   RepoTag              `json:"image,omitempty"`
	Request ResourceRequirements `json:"request,omitempty"`
	Limit   ResourceRequirements `json:"limit,omitempty"`
	Config  *string              `json:"config,omitempty"`
	Volumes []corev1.Volume      `json:"volumes,omitempty"`
}

type ManagerConfig struct {
	Runtime             RuntimeSpec       `json:"runtime,omitempty"`
	OTLPEndpoint        string            `json:"otlpEndpoint,omitempty"`
	LogLevel            string            `json:"logLevel,omitempty"`
	Scheduling          ScheduleConfig    `json:"scheduling,omitempty"`
	Profile             ProfileConfig     `json:"profile,omitempty"`
	ImageJob            ImageJobConfig    `json:"imageJob,omitempty"`
	PullSecrets         []string          `json:"pullSecrets,omitempty"`
	NodeFilter          NodeFilterConfig  `json:"nodeFilter,omitempty"`
	PriorityClassName   string            `json:"priorityClassName,omitempty"`
	AdditionalPodLabels map[string]string `json:"additionalPodLabels,omitempty"`
}

type ScheduleConfig struct {
	RepeatInterval   Duration `json:"repeatInterval,omitempty"`
	BeginImmediately bool     `json:"beginImmediately,omitempty"`
}

type ProfileConfig struct {
	Enabled bool `json:"enabled,omitempty"`
	Port    int  `json:"port,omitempty"`
}

type ImageJobConfig struct {
	SuccessRatio float64               `json:"successRatio,omitempty"`
	Cleanup      ImageJobCleanupConfig `json:"cleanup,omitempty"`
}

type ImageJobCleanupConfig struct {
	DelayOnSuccess Duration `json:"delayOnSuccess,omitempty"`
	DelayOnFailure Duration `json:"delayOnFailure,omitempty"`
}

type NodeFilterConfig struct {
	Type      string   `json:"type,omitempty"`
	Selectors []string `json:"selectors,omitempty"`
}

type ResourceRequirements struct {
	Mem resource.Quantity `json:"mem,omitempty"`
	CPU resource.Quantity `json:"cpu,omitempty"`
}

type RepoTag struct {
	Repo string `json:"repo,omitempty"`
	Tag  string `json:"tag,omitempty"`
}

type Components struct {
	Collector OptionalContainerConfig `json:"collector,omitempty"`
	Scanner   OptionalContainerConfig `json:"scanner,omitempty"`
	Remover   ContainerConfig         `json:"remover,omitempty"`
}

//+kubebuilder:object:root=true

// EraserConfig is the Schema for the eraserconfigs API.
type EraserConfig struct {
	metav1.TypeMeta `json:",inline"`
	Manager         ManagerConfig `json:"manager"`
	Components      Components    `json:"components"`
}

func init() {
	SchemeBuilder.Register(&EraserConfig{})
}


================================================
FILE: api/unversioned/groupversion_info.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1 contains API Schema definitions for the eraser.sh v1 API group
// +kubebuilder:object:generate=true
// +groupName=eraser.sh
package unversioned

import (
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
	// GroupVersion is group version used to register these objects.
	GroupVersion = schema.GroupVersion{Group: "eraser.sh", Version: "unversioned"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)


================================================
FILE: api/unversioned/imagejob_types.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// +kubebuilder:skip
package unversioned

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Image struct {
	ImageID string   `json:"image_id"`
	Names   []string `json:"names,omitempty"`
	Digests []string `json:"digests,omitempty"`
}

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// JobPhase defines the phase of an ImageJob status.
type JobPhase string

const (
	PhaseRunning   JobPhase = "Running"
	PhaseCompleted JobPhase = "Completed"
	PhaseFailed    JobPhase = "Failed"
)

// ImageJobStatus defines the observed state of ImageJob.
type ImageJobStatus struct {
	// number of pods that failed
	Failed int `json:"failed"`

	// number of pods that completed successfully
	Succeeded int `json:"succeeded"`

	// desired number of pods
	Desired int `json:"desired"`

	// number of nodes that were skipped e.g. because they are not a linux node
	Skipped int `json:"skipped"`

	// job running, successfully completed, or failed
	Phase JobPhase `json:"phase"`

	// Time to delay deletion until
	DeleteAfter *metav1.Time `json:"deleteAfter,omitempty"`
}

// ImageJob is the Schema for the imagejobs API.
type ImageJob struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Status ImageJobStatus `json:"status,omitempty"`
}

// ImageJobList contains a list of ImageJob.
type ImageJobList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageJob `json:"items"`
}


================================================
FILE: api/unversioned/imagelist_types.go
================================================
/*
Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// +kubebuilder:skip
package unversioned

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ImageListSpec defines the desired state of ImageList.
type ImageListSpec struct {
	// The list of non-compliant images to delete if non-running.
	Images []string `json:"images"`
}

// ImageListStatus defines the observed state of ImageList.
type ImageListStatus struct {
	// Information when the job was completed.
	Timestamp *metav1.Time `json:"timestamp"`
	// Number of nodes that successfully ran the job
	Success int64 `json:"success"`
	// Number of nodes that failed to run the job
	Failed int64 `json:"failed"`
	// Number of nodes that were skipped due to a skip selector
	Skipped int64 `json:"skipped"`
}

// ImageList is the Schema for the imagelists API.
type ImageList struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   ImageListSpec   `json:"spec,omitempty"`
	Status ImageListStatus `json:"status,omitempty"`
}

// ImageListList contains a list of ImageList.
type ImageListList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageList `json:"items"`
}


================================================
FILE: api/unversioned/zz_generated.deepcopy.go
================================================
//go:build !ignore_autogenerated

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Code generated by controller-gen. DO NOT EDIT.

package unversioned

import (
	"k8s.io/api/core/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
)

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Components) DeepCopyInto(out *Components) {
	*out = *in
	in.Collector.DeepCopyInto(&out.Collector)
	in.Scanner.DeepCopyInto(&out.Scanner)
	in.Remover.DeepCopyInto(&out.Remover)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Components.
func (in *Components) DeepCopy() *Components {
	if in == nil {
		return nil
	}
	out := new(Components)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
	*out = *in
	out.Image = in.Image
	in.Request.DeepCopyInto(&out.Request)
	in.Limit.DeepCopyInto(&out.Limit)
	if in.Config != nil {
		in, out := &in.Config, &out.Config
		*out = new(string)
		**out = **in
	}
	if in.Volumes != nil {
		in, out := &in.Volumes, &out.Volumes
		*out = make([]v1.Volume, len(*in))
		for i := range *in {
			(*in)[i].DeepCopyInto(&(*out)[i])
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig.
func (in *ContainerConfig) DeepCopy() *ContainerConfig {
	if in == nil {
		return nil
	}
	out := new(ContainerConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EraserConfig) DeepCopyInto(out *EraserConfig) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.Manager.DeepCopyInto(&out.Manager)
	in.Components.DeepCopyInto(&out.Components)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EraserConfig.
func (in *EraserConfig) DeepCopy() *EraserConfig {
	if in == nil {
		return nil
	}
	out := new(EraserConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *EraserConfig) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Image) DeepCopyInto(out *Image) {
	*out = *in
	if in.Names != nil {
		in, out := &in.Names, &out.Names
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
	if in.Digests != nil {
		in, out := &in.Digests, &out.Digests
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image.
func (in *Image) DeepCopy() *Image {
	if in == nil {
		return nil
	}
	out := new(Image)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJob) DeepCopyInto(out *ImageJob) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
	in.Status.DeepCopyInto(&out.Status)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJob.
func (in *ImageJob) DeepCopy() *ImageJob {
	if in == nil {
		return nil
	}
	out := new(ImageJob)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobCleanupConfig) DeepCopyInto(out *ImageJobCleanupConfig) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobCleanupConfig.
func (in *ImageJobCleanupConfig) DeepCopy() *ImageJobCleanupConfig {
	if in == nil {
		return nil
	}
	out := new(ImageJobCleanupConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobConfig) DeepCopyInto(out *ImageJobConfig) {
	*out = *in
	out.Cleanup = in.Cleanup
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobConfig.
func (in *ImageJobConfig) DeepCopy() *ImageJobConfig {
	if in == nil {
		return nil
	}
	out := new(ImageJobConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobList) DeepCopyInto(out *ImageJobList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ListMeta.DeepCopyInto(&out.ListMeta)
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]ImageJob, len(*in))
		for i := range *in {
			(*in)[i].DeepCopyInto(&(*out)[i])
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobList.
func (in *ImageJobList) DeepCopy() *ImageJobList {
	if in == nil {
		return nil
	}
	out := new(ImageJobList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobStatus) DeepCopyInto(out *ImageJobStatus) {
	*out = *in
	if in.DeleteAfter != nil {
		in, out := &in.DeleteAfter, &out.DeleteAfter
		*out = (*in).DeepCopy()
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobStatus.
func (in *ImageJobStatus) DeepCopy() *ImageJobStatus {
	if in == nil {
		return nil
	}
	out := new(ImageJobStatus)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageList) DeepCopyInto(out *ImageList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
	in.Spec.DeepCopyInto(&out.Spec)
	in.Status.DeepCopyInto(&out.Status)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageList.
func (in *ImageList) DeepCopy() *ImageList {
	if in == nil {
		return nil
	}
	out := new(ImageList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListList) DeepCopyInto(out *ImageListList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ListMeta.DeepCopyInto(&out.ListMeta)
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]ImageList, len(*in))
		for i := range *in {
			(*in)[i].DeepCopyInto(&(*out)[i])
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListList.
func (in *ImageListList) DeepCopy() *ImageListList {
	if in == nil {
		return nil
	}
	out := new(ImageListList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListSpec) DeepCopyInto(out *ImageListSpec) {
	*out = *in
	if in.Images != nil {
		in, out := &in.Images, &out.Images
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListSpec.
func (in *ImageListSpec) DeepCopy() *ImageListSpec {
	if in == nil {
		return nil
	}
	out := new(ImageListSpec)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListStatus) DeepCopyInto(out *ImageListStatus) {
	*out = *in
	if in.Timestamp != nil {
		in, out := &in.Timestamp, &out.Timestamp
		*out = (*in).DeepCopy()
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListStatus.
func (in *ImageListStatus) DeepCopy() *ImageListStatus {
	if in == nil {
		return nil
	}
	out := new(ImageListStatus)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ManagerConfig) DeepCopyInto(out *ManagerConfig) {
	*out = *in
	out.Runtime = in.Runtime
	out.Scheduling = in.Scheduling
	out.Profile = in.Profile
	out.ImageJob = in.ImageJob
	if in.PullSecrets != nil {
		in, out := &in.PullSecrets, &out.PullSecrets
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
	in.NodeFilter.DeepCopyInto(&out.NodeFilter)
	if in.AdditionalPodLabels != nil {
		in, out := &in.AdditionalPodLabels, &out.AdditionalPodLabels
		*out = make(map[string]string, len(*in))
		for key, val := range *in {
			(*out)[key] = val
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagerConfig.
func (in *ManagerConfig) DeepCopy() *ManagerConfig {
	if in == nil {
		return nil
	}
	out := new(ManagerConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeFilterConfig) DeepCopyInto(out *NodeFilterConfig) {
	*out = *in
	if in.Selectors != nil {
		in, out := &in.Selectors, &out.Selectors
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFilterConfig.
func (in *NodeFilterConfig) DeepCopy() *NodeFilterConfig {
	if in == nil {
		return nil
	}
	out := new(NodeFilterConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OptionalContainerConfig) DeepCopyInto(out *OptionalContainerConfig) {
	*out = *in
	in.ContainerConfig.DeepCopyInto(&out.ContainerConfig)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OptionalContainerConfig.
func (in *OptionalContainerConfig) DeepCopy() *OptionalContainerConfig {
	if in == nil {
		return nil
	}
	out := new(OptionalContainerConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProfileConfig) DeepCopyInto(out *ProfileConfig) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileConfig.
func (in *ProfileConfig) DeepCopy() *ProfileConfig {
	if in == nil {
		return nil
	}
	out := new(ProfileConfig)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RepoTag) DeepCopyInto(out *RepoTag) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoTag.
func (in *RepoTag) DeepCopy() *RepoTag {
	if in == nil {
		return nil
	}
	out := new(RepoTag)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) {
	*out = *in
	out.Mem = in.Mem.DeepCopy()
	out.CPU = in.CPU.DeepCopy()
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRequirements.
func (in *ResourceRequirements) DeepCopy() *ResourceRequirements {
	if in == nil {
		return nil
	}
	out := new(ResourceRequirements)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RuntimeSpec) DeepCopyInto(out *RuntimeSpec) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeSpec.
func (in *RuntimeSpec) DeepCopy() *RuntimeSpec {
	if in == nil {
		return nil
	}
	out := new(RuntimeSpec)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScheduleConfig) DeepCopyInto(out *ScheduleConfig) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScheduleConfig.
func (in *ScheduleConfig) DeepCopy() *ScheduleConfig {
	if in == nil {
		return nil
	}
	out := new(ScheduleConfig)
	in.DeepCopyInto(out)
	return out
}


================================================
FILE: api/v1/doc.go
================================================
// +k8s:conversion-gen=github.com/eraser-dev/eraser/api/unversioned
package v1


================================================
FILE: api/v1/groupversion_info.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1 contains API Schema definitions for the eraser.sh v1 API group
// +kubebuilder:object:generate=true
// +groupName=eraser.sh
package v1

import (
	runtime "k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
	// GroupVersion is group version used to register these objects.
	GroupVersion = schema.GroupVersion{Group: "eraser.sh", Version: "v1"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	localSchemeBuilder = runtime.NewSchemeBuilder(SchemeBuilder.AddToScheme)

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)


================================================
FILE: api/v1/imagejob_types.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Image struct {
	ImageID string   `json:"image_id"`
	Names   []string `json:"names,omitempty"`
	Digests []string `json:"digests,omitempty"`
}

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// JobPhase defines the phase of an ImageJob status.
type JobPhase string

const (
	PhaseRunning   JobPhase = "Running"
	PhaseCompleted JobPhase = "Completed"
	PhaseFailed    JobPhase = "Failed"
)

// ImageJobStatus defines the observed state of ImageJob.
type ImageJobStatus struct {
	// number of pods that failed
	Failed int `json:"failed"`

	// number of pods that completed successfully
	Succeeded int `json:"succeeded"`

	// desired number of pods
	Desired int `json:"desired"`

	// number of nodes that were skipped e.g. because they are not a linux node
	Skipped int `json:"skipped"`

	// job running, successfully completed, or failed
	Phase JobPhase `json:"phase"`

	// Time to delay deletion until
	DeleteAfter *metav1.Time `json:"deleteAfter,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:storageversion
// ImageJob is the Schema for the imagejobs API.
type ImageJob struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Status ImageJobStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// ImageJobList contains a list of ImageJob.
type ImageJobList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageJob `json:"items"`
}

func init() {
	SchemeBuilder.Register(&ImageJob{}, &ImageJobList{})
}


================================================
FILE: api/v1/imagelist_types.go
================================================
/*
Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ImageListSpec defines the desired state of ImageList.
type ImageListSpec struct {
	// The list of non-compliant images to delete if non-running.
	Images []string `json:"images"`
}

// ImageListStatus defines the observed state of ImageList.
type ImageListStatus struct {
	// Information when the job was completed.
	Timestamp *metav1.Time `json:"timestamp"`
	// Number of nodes that successfully ran the job
	Success int64 `json:"success"`
	// Number of nodes that failed to run the job
	Failed int64 `json:"failed"`
	// Number of nodes that were skipped due to a skip selector
	Skipped int64 `json:"skipped"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:storageversion
// ImageList is the Schema for the imagelists API.
type ImageList struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   ImageListSpec   `json:"spec,omitempty"`
	Status ImageListStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// ImageListList contains a list of ImageList.
type ImageListList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageList `json:"items"`
}

func init() {
	SchemeBuilder.Register(&ImageList{}, &ImageListList{})
}


================================================
FILE: api/v1/zz_generated.conversion.go
================================================
//go:build !ignore_autogenerated
// +build !ignore_autogenerated

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by conversion-gen. DO NOT EDIT.

package v1

import (
	unsafe "unsafe"

	unversioned "github.com/eraser-dev/eraser/api/unversioned"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	conversion "k8s.io/apimachinery/pkg/conversion"
	runtime "k8s.io/apimachinery/pkg/runtime"
)

func init() {
	localSchemeBuilder.Register(RegisterConversions)
}

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
	if err := s.AddGeneratedConversionFunc((*Image)(nil), (*unversioned.Image)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_Image_To_unversioned_Image(a.(*Image), b.(*unversioned.Image), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.Image)(nil), (*Image)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_Image_To_v1_Image(a.(*unversioned.Image), b.(*Image), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJob)(nil), (*unversioned.ImageJob)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageJob_To_unversioned_ImageJob(a.(*ImageJob), b.(*unversioned.ImageJob), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJob)(nil), (*ImageJob)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJob_To_v1_ImageJob(a.(*unversioned.ImageJob), b.(*ImageJob), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobList)(nil), (*unversioned.ImageJobList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageJobList_To_unversioned_ImageJobList(a.(*ImageJobList), b.(*unversioned.ImageJobList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobList)(nil), (*ImageJobList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobList_To_v1_ImageJobList(a.(*unversioned.ImageJobList), b.(*ImageJobList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobStatus)(nil), (*unversioned.ImageJobStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(a.(*ImageJobStatus), b.(*unversioned.ImageJobStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobStatus)(nil), (*ImageJobStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(a.(*unversioned.ImageJobStatus), b.(*ImageJobStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageList)(nil), (*unversioned.ImageList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageList_To_unversioned_ImageList(a.(*ImageList), b.(*unversioned.ImageList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageList)(nil), (*ImageList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageList_To_v1_ImageList(a.(*unversioned.ImageList), b.(*ImageList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListList)(nil), (*unversioned.ImageListList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageListList_To_unversioned_ImageListList(a.(*ImageListList), b.(*unversioned.ImageListList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListList)(nil), (*ImageListList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListList_To_v1_ImageListList(a.(*unversioned.ImageListList), b.(*ImageListList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListSpec)(nil), (*unversioned.ImageListSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageListSpec_To_unversioned_ImageListSpec(a.(*ImageListSpec), b.(*unversioned.ImageListSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListSpec)(nil), (*ImageListSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListSpec_To_v1_ImageListSpec(a.(*unversioned.ImageListSpec), b.(*ImageListSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListStatus)(nil), (*unversioned.ImageListStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ImageListStatus_To_unversioned_ImageListStatus(a.(*ImageListStatus), b.(*unversioned.ImageListStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListStatus)(nil), (*ImageListStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListStatus_To_v1_ImageListStatus(a.(*unversioned.ImageListStatus), b.(*ImageListStatus), scope)
	}); err != nil {
		return err
	}
	return nil
}

func autoConvert_v1_Image_To_unversioned_Image(in *Image, out *unversioned.Image, s conversion.Scope) error {
	out.ImageID = in.ImageID
	out.Names = *(*[]string)(unsafe.Pointer(&in.Names))
	out.Digests = *(*[]string)(unsafe.Pointer(&in.Digests))
	return nil
}

// Convert_v1_Image_To_unversioned_Image is an autogenerated conversion function.
func Convert_v1_Image_To_unversioned_Image(in *Image, out *unversioned.Image, s conversion.Scope) error {
	return autoConvert_v1_Image_To_unversioned_Image(in, out, s)
}

func autoConvert_unversioned_Image_To_v1_Image(in *unversioned.Image, out *Image, s conversion.Scope) error {
	out.ImageID = in.ImageID
	out.Names = *(*[]string)(unsafe.Pointer(&in.Names))
	out.Digests = *(*[]string)(unsafe.Pointer(&in.Digests))
	return nil
}

// Convert_unversioned_Image_To_v1_Image is an autogenerated conversion function.
func Convert_unversioned_Image_To_v1_Image(in *unversioned.Image, out *Image, s conversion.Scope) error {
	return autoConvert_unversioned_Image_To_v1_Image(in, out, s)
}

func autoConvert_v1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *unversioned.ImageJob, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1_ImageJob_To_unversioned_ImageJob is an autogenerated conversion function.
func Convert_v1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *unversioned.ImageJob, s conversion.Scope) error {
	return autoConvert_v1_ImageJob_To_unversioned_ImageJob(in, out, s)
}

func autoConvert_unversioned_ImageJob_To_v1_ImageJob(in *unversioned.ImageJob, out *ImageJob, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_ImageJob_To_v1_ImageJob is an autogenerated conversion function.
func Convert_unversioned_ImageJob_To_v1_ImageJob(in *unversioned.ImageJob, out *ImageJob, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJob_To_v1_ImageJob(in, out, s)
}

func autoConvert_v1_ImageJobList_To_unversioned_ImageJobList(in *ImageJobList, out *unversioned.ImageJobList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]unversioned.ImageJob)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_v1_ImageJobList_To_unversioned_ImageJobList is an autogenerated conversion function.
func Convert_v1_ImageJobList_To_unversioned_ImageJobList(in *ImageJobList, out *unversioned.ImageJobList, s conversion.Scope) error {
	return autoConvert_v1_ImageJobList_To_unversioned_ImageJobList(in, out, s)
}

func autoConvert_unversioned_ImageJobList_To_v1_ImageJobList(in *unversioned.ImageJobList, out *ImageJobList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]ImageJob)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_unversioned_ImageJobList_To_v1_ImageJobList is an autogenerated conversion function.
func Convert_unversioned_ImageJobList_To_v1_ImageJobList(in *unversioned.ImageJobList, out *ImageJobList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobList_To_v1_ImageJobList(in, out, s)
}

func autoConvert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(in *ImageJobStatus, out *unversioned.ImageJobStatus, s conversion.Scope) error {
	out.Failed = in.Failed
	out.Succeeded = in.Succeeded
	out.Desired = in.Desired
	out.Skipped = in.Skipped
	out.Phase = unversioned.JobPhase(in.Phase)
	out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter))
	return nil
}

// Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus is an autogenerated conversion function.
func Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(in *ImageJobStatus, out *unversioned.ImageJobStatus, s conversion.Scope) error {
	return autoConvert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(in, out, s)
}

func autoConvert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(in *unversioned.ImageJobStatus, out *ImageJobStatus, s conversion.Scope) error {
	out.Failed = in.Failed
	out.Succeeded = in.Succeeded
	out.Desired = in.Desired
	out.Skipped = in.Skipped
	out.Phase = JobPhase(in.Phase)
	out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter))
	return nil
}

// Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus is an autogenerated conversion function.
func Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(in *unversioned.ImageJobStatus, out *ImageJobStatus, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(in, out, s)
}

func autoConvert_v1_ImageList_To_unversioned_ImageList(in *ImageList, out *unversioned.ImageList, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_v1_ImageListSpec_To_unversioned_ImageListSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_v1_ImageListStatus_To_unversioned_ImageListStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1_ImageList_To_unversioned_ImageList is an autogenerated conversion function.
func Convert_v1_ImageList_To_unversioned_ImageList(in *ImageList, out *unversioned.ImageList, s conversion.Scope) error {
	return autoConvert_v1_ImageList_To_unversioned_ImageList(in, out, s)
}

func autoConvert_unversioned_ImageList_To_v1_ImageList(in *unversioned.ImageList, out *ImageList, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_unversioned_ImageListSpec_To_v1_ImageListSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ImageListStatus_To_v1_ImageListStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_ImageList_To_v1_ImageList is an autogenerated conversion function.
func Convert_unversioned_ImageList_To_v1_ImageList(in *unversioned.ImageList, out *ImageList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageList_To_v1_ImageList(in, out, s)
}

func autoConvert_v1_ImageListList_To_unversioned_ImageListList(in *ImageListList, out *unversioned.ImageListList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]unversioned.ImageList)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_v1_ImageListList_To_unversioned_ImageListList is an autogenerated conversion function.
func Convert_v1_ImageListList_To_unversioned_ImageListList(in *ImageListList, out *unversioned.ImageListList, s conversion.Scope) error {
	return autoConvert_v1_ImageListList_To_unversioned_ImageListList(in, out, s)
}

func autoConvert_unversioned_ImageListList_To_v1_ImageListList(in *unversioned.ImageListList, out *ImageListList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]ImageList)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_unversioned_ImageListList_To_v1_ImageListList is an autogenerated conversion function.
func Convert_unversioned_ImageListList_To_v1_ImageListList(in *unversioned.ImageListList, out *ImageListList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListList_To_v1_ImageListList(in, out, s)
}

func autoConvert_v1_ImageListSpec_To_unversioned_ImageListSpec(in *ImageListSpec, out *unversioned.ImageListSpec, s conversion.Scope) error {
	out.Images = *(*[]string)(unsafe.Pointer(&in.Images))
	return nil
}

// Convert_v1_ImageListSpec_To_unversioned_ImageListSpec is an autogenerated conversion function.
func Convert_v1_ImageListSpec_To_unversioned_ImageListSpec(in *ImageListSpec, out *unversioned.ImageListSpec, s conversion.Scope) error {
	return autoConvert_v1_ImageListSpec_To_unversioned_ImageListSpec(in, out, s)
}

func autoConvert_unversioned_ImageListSpec_To_v1_ImageListSpec(in *unversioned.ImageListSpec, out *ImageListSpec, s conversion.Scope) error {
	out.Images = *(*[]string)(unsafe.Pointer(&in.Images))
	return nil
}

// Convert_unversioned_ImageListSpec_To_v1_ImageListSpec is an autogenerated conversion function.
func Convert_unversioned_ImageListSpec_To_v1_ImageListSpec(in *unversioned.ImageListSpec, out *ImageListSpec, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListSpec_To_v1_ImageListSpec(in, out, s)
}

func autoConvert_v1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageListStatus, out *unversioned.ImageListStatus, s conversion.Scope) error {
	out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp))
	out.Success = in.Success
	out.Failed = in.Failed
	out.Skipped = in.Skipped
	return nil
}

// Convert_v1_ImageListStatus_To_unversioned_ImageListStatus is an autogenerated conversion function.
func Convert_v1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageListStatus, out *unversioned.ImageListStatus, s conversion.Scope) error {
	return autoConvert_v1_ImageListStatus_To_unversioned_ImageListStatus(in, out, s)
}

func autoConvert_unversioned_ImageListStatus_To_v1_ImageListStatus(in *unversioned.ImageListStatus, out *ImageListStatus, s conversion.Scope) error {
	out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp))
	out.Success = in.Success
	out.Failed = in.Failed
	out.Skipped = in.Skipped
	return nil
}

// Convert_unversioned_ImageListStatus_To_v1_ImageListStatus is an autogenerated conversion function.
func Convert_unversioned_ImageListStatus_To_v1_ImageListStatus(in *unversioned.ImageListStatus, out *ImageListStatus, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListStatus_To_v1_ImageListStatus(in, out, s)
}


================================================
FILE: api/v1/zz_generated.deepcopy.go
================================================
//go:build !ignore_autogenerated

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Code generated by controller-gen. DO NOT EDIT.

package v1

import (
	"k8s.io/apimachinery/pkg/runtime"
)

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Image) DeepCopyInto(out *Image) {
	*out = *in
	if in.Names != nil {
		in, out := &in.Names, &out.Names
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
	if in.Digests != nil {
		in, out := &in.Digests, &out.Digests
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image.
func (in *Image) DeepCopy() *Image {
	if in == nil {
		return nil
	}
	out := new(Image)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJob) DeepCopyInto(out *ImageJob) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
	in.Status.DeepCopyInto(&out.Status)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJob.
func (in *ImageJob) DeepCopy() *ImageJob {
	if in == nil {
		return nil
	}
	out := new(ImageJob)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ImageJob) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobList) DeepCopyInto(out *ImageJobList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ListMeta.DeepCopyInto(&out.ListMeta)
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]ImageJob, len(*in))
		for i := range *in {
			(*in)[i].DeepCopyInto(&(*out)[i])
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobList.
func (in *ImageJobList) DeepCopy() *ImageJobList {
	if in == nil {
		return nil
	}
	out := new(ImageJobList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ImageJobList) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageJobStatus) DeepCopyInto(out *ImageJobStatus) {
	*out = *in
	if in.DeleteAfter != nil {
		in, out := &in.DeleteAfter, &out.DeleteAfter
		*out = (*in).DeepCopy()
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageJobStatus.
func (in *ImageJobStatus) DeepCopy() *ImageJobStatus {
	if in == nil {
		return nil
	}
	out := new(ImageJobStatus)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageList) DeepCopyInto(out *ImageList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
	in.Spec.DeepCopyInto(&out.Spec)
	in.Status.DeepCopyInto(&out.Status)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageList.
func (in *ImageList) DeepCopy() *ImageList {
	if in == nil {
		return nil
	}
	out := new(ImageList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ImageList) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListList) DeepCopyInto(out *ImageListList) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ListMeta.DeepCopyInto(&out.ListMeta)
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]ImageList, len(*in))
		for i := range *in {
			(*in)[i].DeepCopyInto(&(*out)[i])
		}
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListList.
func (in *ImageListList) DeepCopy() *ImageListList {
	if in == nil {
		return nil
	}
	out := new(ImageListList)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ImageListList) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListSpec) DeepCopyInto(out *ImageListSpec) {
	*out = *in
	if in.Images != nil {
		in, out := &in.Images, &out.Images
		*out = make([]string, len(*in))
		copy(*out, *in)
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListSpec.
func (in *ImageListSpec) DeepCopy() *ImageListSpec {
	if in == nil {
		return nil
	}
	out := new(ImageListSpec)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageListStatus) DeepCopyInto(out *ImageListStatus) {
	*out = *in
	if in.Timestamp != nil {
		in, out := &in.Timestamp, &out.Timestamp
		*out = (*in).DeepCopy()
	}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageListStatus.
func (in *ImageListStatus) DeepCopy() *ImageListStatus {
	if in == nil {
		return nil
	}
	out := new(ImageListStatus)
	in.DeepCopyInto(out)
	return out
}


================================================
FILE: api/v1alpha1/config/config.go
================================================
package config

import (
	"fmt"
	"time"

	v1alpha1 "github.com/eraser-dev/eraser/api/v1alpha1"
	"github.com/eraser-dev/eraser/version"
	"k8s.io/apimachinery/pkg/api/resource"
)

var defaultScannerConfig = `
cacheDir: /var/lib/trivy
dbRepo: ghcr.io/aquasecurity/trivy-db
deleteFailedImages: true
deleteEOLImages: true
vulnerabilities:
  ignoreUnfixed: false
  types:
    - os
    - library
securityChecks: # need to be documented; determined by trivy, not us
  - vuln
severities:
  - CRITICAL
  - HIGH
  - MEDIUM
  - LOW
`

const (
	noDelay = v1alpha1.Duration(0)
	oneDay  = v1alpha1.Duration(time.Hour * 24)
)

func Default() *v1alpha1.EraserConfig {
	return &v1alpha1.EraserConfig{
		Manager: v1alpha1.ManagerConfig{
			Runtime:      "containerd",
			OTLPEndpoint: "",
			LogLevel:     "info",
			Scheduling: v1alpha1.ScheduleConfig{
				RepeatInterval:   v1alpha1.Duration(oneDay),
				BeginImmediately: true,
			},
			Profile: v1alpha1.ProfileConfig{
				Enabled: false,
				Port:    6060,
			},
			ImageJob: v1alpha1.ImageJobConfig{
				SuccessRatio: 1.0,
				Cleanup: v1alpha1.ImageJobCleanupConfig{
					DelayOnSuccess: noDelay,
					DelayOnFailure: oneDay,
				},
			},
			PullSecrets: []string{},
			NodeFilter: v1alpha1.NodeFilterConfig{
				Type: "exclude",
				Selectors: []string{
					"eraser.sh/cleanup.filter",
				},
			},
		},
		Components: v1alpha1.Components{
			Collector: v1alpha1.OptionalContainerConfig{
				Enabled: false,
				ContainerConfig: v1alpha1.ContainerConfig{
					Image: v1alpha1.RepoTag{
						Repo: repo("collector"),
						Tag:  version.BuildVersion,
					},
					Request: v1alpha1.ResourceRequirements{
						Mem: resource.MustParse("25Mi"),
						CPU: resource.MustParse("7m"),
					},
					Limit: v1alpha1.ResourceRequirements{
						Mem: resource.MustParse("500Mi"),
						CPU: resource.Quantity{},
					},
					Config: nil,
				},
			},
			Scanner: v1alpha1.OptionalContainerConfig{
				Enabled: false,
				ContainerConfig: v1alpha1.ContainerConfig{
					Image: v1alpha1.RepoTag{
						Repo: repo("eraser-trivy-scanner"),
						Tag:  version.BuildVersion,
					},
					Request: v1alpha1.ResourceRequirements{
						Mem: resource.MustParse("500Mi"),
						CPU: resource.MustParse("1000m"),
					},
					Limit: v1alpha1.ResourceRequirements{
						Mem: resource.MustParse("2Gi"),
						CPU: resource.MustParse("1500m"),
					},
					Config: &defaultScannerConfig,
				},
			},
			Eraser: v1alpha1.ContainerConfig{
				Image: v1alpha1.RepoTag{
					Repo: repo("eraser"),
					Tag:  version.BuildVersion,
				},
				Request: v1alpha1.ResourceRequirements{
					Mem: resource.MustParse("25Mi"),
					CPU: resource.MustParse("7m"),
				},
				Limit: v1alpha1.ResourceRequirements{
					Mem: resource.MustParse("30Mi"),
					CPU: resource.Quantity{},
				},
				Config: nil,
			},
		},
	}
}

func repo(basename string) string {
	if version.DefaultRepo == "" {
		return basename
	}

	return fmt.Sprintf("%s/%s", version.DefaultRepo, basename)
}


================================================
FILE: api/v1alpha1/custom_conversions.go
================================================
package v1alpha1

import (
	unversioned "github.com/eraser-dev/eraser/api/unversioned"
	conversion "k8s.io/apimachinery/pkg/conversion"
)

//nolint:revive
func Convert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(in *ManagerConfig, out *unversioned.ManagerConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(in, out, s)
}

//nolint:revive
func manualConvert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(in *Runtime, out *unversioned.RuntimeSpec, _ conversion.Scope) error {
	out.Name = unversioned.Runtime(string(*in))

	rs, err := unversioned.ConvertRuntimeToRuntimeSpec(out.Name)
	if err != nil {
		return err
	}
	out.Address = rs.Address

	return nil
}

//nolint:revive
func Convert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(in *Runtime, out *unversioned.RuntimeSpec, s conversion.Scope) error {
	return manualConvert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(in, out, s)
}

//nolint:revive
func Convert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(in *unversioned.ManagerConfig, out *ManagerConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(in, out, s)
}

//nolint:revive
func manualConvert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(in *unversioned.RuntimeSpec, out *Runtime, _ conversion.Scope) error {
	*out = Runtime(in.Name)
	return nil
}

//nolint:revive
func Convert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(in *unversioned.RuntimeSpec, out *Runtime, s conversion.Scope) error {
	return manualConvert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(in, out, s)
}


================================================
FILE: api/v1alpha1/doc.go
================================================
// Package v1alpha1 contains API Schema definitions for the eraser v1alpha1 API version.
// +k8s:conversion-gen=github.com/eraser-dev/eraser/api/unversioned
package v1alpha1


================================================
FILE: api/v1alpha1/eraserconfig_types.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/eraser-dev/eraser/api/unversioned"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/conversion"
)

type (
	Duration time.Duration
	Runtime  string
)

const (
	RuntimeContainerd Runtime = "containerd"
	RuntimeDockerShim Runtime = "dockershim"
	RuntimeCrio       Runtime = "crio"
)

func (td *Duration) UnmarshalJSON(b []byte) error {
	var str string
	err := json.Unmarshal(b, &str)
	if err != nil {
		return err
	}

	pd, err := time.ParseDuration(str)
	if err != nil {
		return err
	}

	*td = Duration(pd)
	return nil
}

func (td *Duration) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, time.Duration(*td).String())), nil
}

func (r *Runtime) UnmarshalJSON(b []byte) error {
	var str string
	err := json.Unmarshal(b, &str)
	if err != nil {
		return err
	}

	switch rt := Runtime(str); rt {
	case RuntimeContainerd, RuntimeDockerShim, RuntimeCrio:
		*r = rt
	default:
		return fmt.Errorf("cannot determine runtime type: %s. valid values are containerd, dockershim, or crio", str)
	}

	return nil
}

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

type OptionalContainerConfig struct {
	Enabled         bool `json:"enabled,omitempty"`
	ContainerConfig `json:",inline"`
}

type ContainerConfig struct {
	Image   RepoTag              `json:"image,omitempty"`
	Request ResourceRequirements `json:"request,omitempty"`
	Limit   ResourceRequirements `json:"limit,omitempty"`
	Config  *string              `json:"config,omitempty"`
	Volumes []corev1.Volume      `json:"volumes,omitempty"`
}

type ManagerConfig struct {
	Runtime           Runtime          `json:"runtime,omitempty"`
	OTLPEndpoint      string           `json:"otlpEndpoint,omitempty"`
	LogLevel          string           `json:"logLevel,omitempty"`
	Scheduling        ScheduleConfig   `json:"scheduling,omitempty"`
	Profile           ProfileConfig    `json:"profile,omitempty"`
	ImageJob          ImageJobConfig   `json:"imageJob,omitempty"`
	PullSecrets       []string         `json:"pullSecrets,omitempty"`
	NodeFilter        NodeFilterConfig `json:"nodeFilter,omitempty"`
	PriorityClassName string           `json:"priorityClassName,omitempty"`
}

type ScheduleConfig struct {
	RepeatInterval   Duration `json:"repeatInterval,omitempty"`
	BeginImmediately bool     `json:"beginImmediately,omitempty"`
}

type ProfileConfig struct {
	Enabled bool `json:"enabled,omitempty"`
	Port    int  `json:"port,omitempty"`
}

type ImageJobConfig struct {
	SuccessRatio float64               `json:"successRatio,omitempty"`
	Cleanup      ImageJobCleanupConfig `json:"cleanup,omitempty"`
}

type ImageJobCleanupConfig struct {
	DelayOnSuccess Duration `json:"delayOnSuccess,omitempty"`
	DelayOnFailure Duration `json:"delayOnFailure,omitempty"`
}

type NodeFilterConfig struct {
	Type      string   `json:"type,omitempty"`
	Selectors []string `json:"selectors,omitempty"`
}

type ResourceRequirements struct {
	Mem resource.Quantity `json:"mem,omitempty"`
	CPU resource.Quantity `json:"cpu,omitempty"`
}

type RepoTag struct {
	Repo string `json:"repo,omitempty"`
	Tag  string `json:"tag,omitempty"`
}

type Components struct {
	Collector OptionalContainerConfig `json:"collector,omitempty"`
	Scanner   OptionalContainerConfig `json:"scanner,omitempty"`
	Eraser    ContainerConfig         `json:"eraser,omitempty"`
}

//+kubebuilder:object:root=true

// EraserConfig is the Schema for the eraserconfigs API.
type EraserConfig struct {
	metav1.TypeMeta `json:",inline"`
	Manager         ManagerConfig `json:"manager"`
	Components      Components    `json:"components"`
}

func init() {
	SchemeBuilder.Register(&EraserConfig{})
}

// In future versions of EraserConfig (for example, v1alpha2), the
// .Components.Eraser field has been renamed to .Components.Remover
// conversion-gen is unable to make the conversion automatically,
// and provides stubs for these functions, with a warning that they
// will not work properly. Because they are called by other generated
// functions, the names of these functions cannot change.
func Convert_v1alpha1_Components_To_unversioned_Components(in *Components, out *unversioned.Components, s conversion.Scope) error { //nolint:revive
	if err := Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(&in.Collector, &out.Collector, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(&in.Scanner, &out.Scanner, s); err != nil {
		return err
	}
	return Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(&in.Eraser, &out.Remover, s)
}

func Convert_unversioned_Components_To_v1alpha1_Components(in *unversioned.Components, out *Components, s conversion.Scope) error { //nolint:revive
	if err := Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(&in.Collector, &out.Collector, s); err != nil {
		return err
	}
	if err := Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(&in.Scanner, &out.Scanner, s); err != nil {
		return err
	}
	return Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(&in.Remover, &out.Eraser, s)
}


================================================
FILE: api/v1alpha1/groupversion_info.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1 contains API Schema definitions for the eraser.sh v1 API group
// +kubebuilder:object:generate=true
// +groupName=eraser.sh
package v1alpha1

import (
	runtime "k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
	// GroupVersion is group version used to register these objects.
	GroupVersion = schema.GroupVersion{Group: "eraser.sh", Version: "v1alpha1"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	localSchemeBuilder = runtime.NewSchemeBuilder(SchemeBuilder.AddToScheme)

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)


================================================
FILE: api/v1alpha1/imagejob_types.go
================================================
/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Image struct {
	ImageID string   `json:"image_id"`
	Names   []string `json:"names,omitempty"`
	Digests []string `json:"digests,omitempty"`
}

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// JobPhase defines the phase of an ImageJob status.
type JobPhase string

const (
	PhaseRunning   JobPhase = "Running"
	PhaseCompleted JobPhase = "Completed"
	PhaseFailed    JobPhase = "Failed"
)

// ImageJobStatus defines the observed state of ImageJob.
type ImageJobStatus struct {
	// number of pods that failed
	Failed int `json:"failed"`

	// number of pods that completed successfully
	Succeeded int `json:"succeeded"`

	// desired number of pods
	Desired int `json:"desired"`

	// number of nodes that were skipped e.g. because they are not a linux node
	Skipped int `json:"skipped"`

	// job running, successfully completed, or failed
	Phase JobPhase `json:"phase"`

	// Time to delay deletion until
	DeleteAfter *metav1.Time `json:"deleteAfter,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:deprecatedversion:warning="v1alpha1 of the eraser API has been deprecated. Please migrate to v1."
// ImageJob is the Schema for the imagejobs API.
type ImageJob struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Status ImageJobStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ImageJobList contains a list of ImageJob.
type ImageJobList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageJob `json:"items"`
}

func init() {
	SchemeBuilder.Register(&ImageJob{}, &ImageJobList{})
}


================================================
FILE: api/v1alpha1/imagelist_types.go
================================================
/*
Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ImageListSpec defines the desired state of ImageList.
type ImageListSpec struct {
	// The list of non-compliant images to delete if non-running.
	Images []string `json:"images"`
}

// ImageListStatus defines the observed state of ImageList.
type ImageListStatus struct {
	// Information when the job was completed.
	Timestamp *metav1.Time `json:"timestamp"`
	// Number of nodes that successfully ran the job
	Success int64 `json:"success"`
	// Number of nodes that failed to run the job
	Failed int64 `json:"failed"`
	// Number of nodes that were skipped due to a skip selector
	Skipped int64 `json:"skipped"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:deprecatedversion:warning="v1alpha1 of the eraser API has been deprecated. Please migrate to v1."
// ImageList is the Schema for the imagelists API.
type ImageList struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   ImageListSpec   `json:"spec,omitempty"`
	Status ImageListStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ImageListList contains a list of ImageList.
type ImageListList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ImageList `json:"items"`
}

func init() {
	SchemeBuilder.Register(&ImageList{}, &ImageListList{})
}


================================================
FILE: api/v1alpha1/zz_generated.conversion.go
================================================
//go:build !ignore_autogenerated
// +build !ignore_autogenerated

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by conversion-gen. DO NOT EDIT.

package v1alpha1

import (
	unsafe "unsafe"

	unversioned "github.com/eraser-dev/eraser/api/unversioned"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	conversion "k8s.io/apimachinery/pkg/conversion"
	runtime "k8s.io/apimachinery/pkg/runtime"
)

func init() {
	localSchemeBuilder.Register(RegisterConversions)
}

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
	if err := s.AddGeneratedConversionFunc((*ContainerConfig)(nil), (*unversioned.ContainerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(a.(*ContainerConfig), b.(*unversioned.ContainerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ContainerConfig)(nil), (*ContainerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(a.(*unversioned.ContainerConfig), b.(*ContainerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*EraserConfig)(nil), (*unversioned.EraserConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(a.(*EraserConfig), b.(*unversioned.EraserConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.EraserConfig)(nil), (*EraserConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(a.(*unversioned.EraserConfig), b.(*EraserConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*Image)(nil), (*unversioned.Image)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_Image_To_unversioned_Image(a.(*Image), b.(*unversioned.Image), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.Image)(nil), (*Image)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_Image_To_v1alpha1_Image(a.(*unversioned.Image), b.(*Image), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJob)(nil), (*unversioned.ImageJob)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageJob_To_unversioned_ImageJob(a.(*ImageJob), b.(*unversioned.ImageJob), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJob)(nil), (*ImageJob)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJob_To_v1alpha1_ImageJob(a.(*unversioned.ImageJob), b.(*ImageJob), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobCleanupConfig)(nil), (*unversioned.ImageJobCleanupConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig(a.(*ImageJobCleanupConfig), b.(*unversioned.ImageJobCleanupConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobCleanupConfig)(nil), (*ImageJobCleanupConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig(a.(*unversioned.ImageJobCleanupConfig), b.(*ImageJobCleanupConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobConfig)(nil), (*unversioned.ImageJobConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(a.(*ImageJobConfig), b.(*unversioned.ImageJobConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobConfig)(nil), (*ImageJobConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(a.(*unversioned.ImageJobConfig), b.(*ImageJobConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobList)(nil), (*unversioned.ImageJobList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(a.(*ImageJobList), b.(*unversioned.ImageJobList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobList)(nil), (*ImageJobList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(a.(*unversioned.ImageJobList), b.(*ImageJobList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageJobStatus)(nil), (*unversioned.ImageJobStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(a.(*ImageJobStatus), b.(*unversioned.ImageJobStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageJobStatus)(nil), (*ImageJobStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(a.(*unversioned.ImageJobStatus), b.(*ImageJobStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageList)(nil), (*unversioned.ImageList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageList_To_unversioned_ImageList(a.(*ImageList), b.(*unversioned.ImageList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageList)(nil), (*ImageList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageList_To_v1alpha1_ImageList(a.(*unversioned.ImageList), b.(*ImageList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListList)(nil), (*unversioned.ImageListList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageListList_To_unversioned_ImageListList(a.(*ImageListList), b.(*unversioned.ImageListList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListList)(nil), (*ImageListList)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListList_To_v1alpha1_ImageListList(a.(*unversioned.ImageListList), b.(*ImageListList), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListSpec)(nil), (*unversioned.ImageListSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(a.(*ImageListSpec), b.(*unversioned.ImageListSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListSpec)(nil), (*ImageListSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(a.(*unversioned.ImageListSpec), b.(*ImageListSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ImageListStatus)(nil), (*unversioned.ImageListStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(a.(*ImageListStatus), b.(*unversioned.ImageListStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ImageListStatus)(nil), (*ImageListStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(a.(*unversioned.ImageListStatus), b.(*ImageListStatus), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*NodeFilterConfig)(nil), (*unversioned.NodeFilterConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(a.(*NodeFilterConfig), b.(*unversioned.NodeFilterConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.NodeFilterConfig)(nil), (*NodeFilterConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(a.(*unversioned.NodeFilterConfig), b.(*NodeFilterConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*OptionalContainerConfig)(nil), (*unversioned.OptionalContainerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(a.(*OptionalContainerConfig), b.(*unversioned.OptionalContainerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.OptionalContainerConfig)(nil), (*OptionalContainerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(a.(*unversioned.OptionalContainerConfig), b.(*OptionalContainerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ProfileConfig)(nil), (*unversioned.ProfileConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(a.(*ProfileConfig), b.(*unversioned.ProfileConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ProfileConfig)(nil), (*ProfileConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(a.(*unversioned.ProfileConfig), b.(*ProfileConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*RepoTag)(nil), (*unversioned.RepoTag)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_RepoTag_To_unversioned_RepoTag(a.(*RepoTag), b.(*unversioned.RepoTag), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.RepoTag)(nil), (*RepoTag)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_RepoTag_To_v1alpha1_RepoTag(a.(*unversioned.RepoTag), b.(*RepoTag), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ResourceRequirements)(nil), (*unversioned.ResourceRequirements)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(a.(*ResourceRequirements), b.(*unversioned.ResourceRequirements), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ResourceRequirements)(nil), (*ResourceRequirements)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(a.(*unversioned.ResourceRequirements), b.(*ResourceRequirements), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*ScheduleConfig)(nil), (*unversioned.ScheduleConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(a.(*ScheduleConfig), b.(*unversioned.ScheduleConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*unversioned.ScheduleConfig)(nil), (*ScheduleConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(a.(*unversioned.ScheduleConfig), b.(*ScheduleConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*unversioned.Components)(nil), (*Components)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_Components_To_v1alpha1_Components(a.(*unversioned.Components), b.(*Components), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*unversioned.ManagerConfig)(nil), (*ManagerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(a.(*unversioned.ManagerConfig), b.(*ManagerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*unversioned.RuntimeSpec)(nil), (*Runtime)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(a.(*unversioned.RuntimeSpec), b.(*Runtime), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*Components)(nil), (*unversioned.Components)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_Components_To_unversioned_Components(a.(*Components), b.(*unversioned.Components), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*ManagerConfig)(nil), (*unversioned.ManagerConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(a.(*ManagerConfig), b.(*unversioned.ManagerConfig), scope)
	}); err != nil {
		return err
	}
	if err := s.AddConversionFunc((*Runtime)(nil), (*unversioned.RuntimeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(a.(*Runtime), b.(*unversioned.RuntimeSpec), scope)
	}); err != nil {
		return err
	}
	return nil
}

func autoConvert_v1alpha1_Components_To_unversioned_Components(in *Components, out *unversioned.Components, s conversion.Scope) error {
	if err := Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(&in.Collector, &out.Collector, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(&in.Scanner, &out.Scanner, s); err != nil {
		return err
	}
	// WARNING: in.Eraser requires manual conversion: does not exist in peer-type
	return nil
}

func autoConvert_unversioned_Components_To_v1alpha1_Components(in *unversioned.Components, out *Components, s conversion.Scope) error {
	if err := Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(&in.Collector, &out.Collector, s); err != nil {
		return err
	}
	if err := Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(&in.Scanner, &out.Scanner, s); err != nil {
		return err
	}
	// WARNING: in.Remover requires manual conversion: does not exist in peer-type
	return nil
}

func autoConvert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(in *ContainerConfig, out *unversioned.ContainerConfig, s conversion.Scope) error {
	if err := Convert_v1alpha1_RepoTag_To_unversioned_RepoTag(&in.Image, &out.Image, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(&in.Request, &out.Request, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(&in.Limit, &out.Limit, s); err != nil {
		return err
	}
	out.Config = (*string)(unsafe.Pointer(in.Config))
	out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes))
	return nil
}

// Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig is an autogenerated conversion function.
func Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(in *ContainerConfig, out *unversioned.ContainerConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(in, out, s)
}

func autoConvert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(in *unversioned.ContainerConfig, out *ContainerConfig, s conversion.Scope) error {
	if err := Convert_unversioned_RepoTag_To_v1alpha1_RepoTag(&in.Image, &out.Image, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(&in.Request, &out.Request, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(&in.Limit, &out.Limit, s); err != nil {
		return err
	}
	out.Config = (*string)(unsafe.Pointer(in.Config))
	out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes))
	return nil
}

// Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig is an autogenerated conversion function.
func Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(in *unversioned.ContainerConfig, out *ContainerConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(in, out, s)
}

func autoConvert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(in *EraserConfig, out *unversioned.EraserConfig, s conversion.Scope) error {
	if err := Convert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(&in.Manager, &out.Manager, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_Components_To_unversioned_Components(&in.Components, &out.Components, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1alpha1_EraserConfig_To_unversioned_EraserConfig is an autogenerated conversion function.
func Convert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(in *EraserConfig, out *unversioned.EraserConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(in, out, s)
}

func autoConvert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(in *unversioned.EraserConfig, out *EraserConfig, s conversion.Scope) error {
	if err := Convert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(&in.Manager, &out.Manager, s); err != nil {
		return err
	}
	if err := Convert_unversioned_Components_To_v1alpha1_Components(&in.Components, &out.Components, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_EraserConfig_To_v1alpha1_EraserConfig is an autogenerated conversion function.
func Convert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(in *unversioned.EraserConfig, out *EraserConfig, s conversion.Scope) error {
	return autoConvert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(in, out, s)
}

func autoConvert_v1alpha1_Image_To_unversioned_Image(in *Image, out *unversioned.Image, s conversion.Scope) error {
	out.ImageID = in.ImageID
	out.Names = *(*[]string)(unsafe.Pointer(&in.Names))
	out.Digests = *(*[]string)(unsafe.Pointer(&in.Digests))
	return nil
}

// Convert_v1alpha1_Image_To_unversioned_Image is an autogenerated conversion function.
func Convert_v1alpha1_Image_To_unversioned_Image(in *Image, out *unversioned.Image, s conversion.Scope) error {
	return autoConvert_v1alpha1_Image_To_unversioned_Image(in, out, s)
}

func autoConvert_unversioned_Image_To_v1alpha1_Image(in *unversioned.Image, out *Image, s conversion.Scope) error {
	out.ImageID = in.ImageID
	out.Names = *(*[]string)(unsafe.Pointer(&in.Names))
	out.Digests = *(*[]string)(unsafe.Pointer(&in.Digests))
	return nil
}

// Convert_unversioned_Image_To_v1alpha1_Image is an autogenerated conversion function.
func Convert_unversioned_Image_To_v1alpha1_Image(in *unversioned.Image, out *Image, s conversion.Scope) error {
	return autoConvert_unversioned_Image_To_v1alpha1_Image(in, out, s)
}

func autoConvert_v1alpha1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *unversioned.ImageJob, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1alpha1_ImageJob_To_unversioned_ImageJob is an autogenerated conversion function.
func Convert_v1alpha1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *unversioned.ImageJob, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageJob_To_unversioned_ImageJob(in, out, s)
}

func autoConvert_unversioned_ImageJob_To_v1alpha1_ImageJob(in *unversioned.ImageJob, out *ImageJob, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_ImageJob_To_v1alpha1_ImageJob is an autogenerated conversion function.
func Convert_unversioned_ImageJob_To_v1alpha1_ImageJob(in *unversioned.ImageJob, out *ImageJob, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJob_To_v1alpha1_ImageJob(in, out, s)
}

func autoConvert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig(in *ImageJobCleanupConfig, out *unversioned.ImageJobCleanupConfig, s conversion.Scope) error {
	out.DelayOnSuccess = unversioned.Duration(in.DelayOnSuccess)
	out.DelayOnFailure = unversioned.Duration(in.DelayOnFailure)
	return nil
}

// Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig is an autogenerated conversion function.
func Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig(in *ImageJobCleanupConfig, out *unversioned.ImageJobCleanupConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig(in, out, s)
}

func autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig(in *unversioned.ImageJobCleanupConfig, out *ImageJobCleanupConfig, s conversion.Scope) error {
	out.DelayOnSuccess = Duration(in.DelayOnSuccess)
	out.DelayOnFailure = Duration(in.DelayOnFailure)
	return nil
}

// Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig is an autogenerated conversion function.
func Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig(in *unversioned.ImageJobCleanupConfig, out *ImageJobCleanupConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig(in, out, s)
}

func autoConvert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(in *ImageJobConfig, out *unversioned.ImageJobConfig, s conversion.Scope) error {
	out.SuccessRatio = in.SuccessRatio
	if err := Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig(&in.Cleanup, &out.Cleanup, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig is an autogenerated conversion function.
func Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(in *ImageJobConfig, out *unversioned.ImageJobConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(in, out, s)
}

func autoConvert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(in *unversioned.ImageJobConfig, out *ImageJobConfig, s conversion.Scope) error {
	out.SuccessRatio = in.SuccessRatio
	if err := Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig(&in.Cleanup, &out.Cleanup, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig is an autogenerated conversion function.
func Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(in *unversioned.ImageJobConfig, out *ImageJobConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(in, out, s)
}

func autoConvert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(in *ImageJobList, out *unversioned.ImageJobList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]unversioned.ImageJob)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_v1alpha1_ImageJobList_To_unversioned_ImageJobList is an autogenerated conversion function.
func Convert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(in *ImageJobList, out *unversioned.ImageJobList, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(in, out, s)
}

func autoConvert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(in *unversioned.ImageJobList, out *ImageJobList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]ImageJob)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_unversioned_ImageJobList_To_v1alpha1_ImageJobList is an autogenerated conversion function.
func Convert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(in *unversioned.ImageJobList, out *ImageJobList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(in, out, s)
}

func autoConvert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(in *ImageJobStatus, out *unversioned.ImageJobStatus, s conversion.Scope) error {
	out.Failed = in.Failed
	out.Succeeded = in.Succeeded
	out.Desired = in.Desired
	out.Skipped = in.Skipped
	out.Phase = unversioned.JobPhase(in.Phase)
	out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter))
	return nil
}

// Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus is an autogenerated conversion function.
func Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(in *ImageJobStatus, out *unversioned.ImageJobStatus, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(in, out, s)
}

func autoConvert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(in *unversioned.ImageJobStatus, out *ImageJobStatus, s conversion.Scope) error {
	out.Failed = in.Failed
	out.Succeeded = in.Succeeded
	out.Desired = in.Desired
	out.Skipped = in.Skipped
	out.Phase = JobPhase(in.Phase)
	out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter))
	return nil
}

// Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus is an autogenerated conversion function.
func Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(in *unversioned.ImageJobStatus, out *ImageJobStatus, s conversion.Scope) error {
	return autoConvert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(in, out, s)
}

func autoConvert_v1alpha1_ImageList_To_unversioned_ImageList(in *ImageList, out *unversioned.ImageList, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1alpha1_ImageList_To_unversioned_ImageList is an autogenerated conversion function.
func Convert_v1alpha1_ImageList_To_unversioned_ImageList(in *ImageList, out *unversioned.ImageList, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageList_To_unversioned_ImageList(in, out, s)
}

func autoConvert_unversioned_ImageList_To_v1alpha1_ImageList(in *unversioned.ImageList, out *ImageList, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	if err := Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_ImageList_To_v1alpha1_ImageList is an autogenerated conversion function.
func Convert_unversioned_ImageList_To_v1alpha1_ImageList(in *unversioned.ImageList, out *ImageList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageList_To_v1alpha1_ImageList(in, out, s)
}

func autoConvert_v1alpha1_ImageListList_To_unversioned_ImageListList(in *ImageListList, out *unversioned.ImageListList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]unversioned.ImageList)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_v1alpha1_ImageListList_To_unversioned_ImageListList is an autogenerated conversion function.
func Convert_v1alpha1_ImageListList_To_unversioned_ImageListList(in *ImageListList, out *unversioned.ImageListList, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageListList_To_unversioned_ImageListList(in, out, s)
}

func autoConvert_unversioned_ImageListList_To_v1alpha1_ImageListList(in *unversioned.ImageListList, out *ImageListList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	out.Items = *(*[]ImageList)(unsafe.Pointer(&in.Items))
	return nil
}

// Convert_unversioned_ImageListList_To_v1alpha1_ImageListList is an autogenerated conversion function.
func Convert_unversioned_ImageListList_To_v1alpha1_ImageListList(in *unversioned.ImageListList, out *ImageListList, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListList_To_v1alpha1_ImageListList(in, out, s)
}

func autoConvert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(in *ImageListSpec, out *unversioned.ImageListSpec, s conversion.Scope) error {
	out.Images = *(*[]string)(unsafe.Pointer(&in.Images))
	return nil
}

// Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec is an autogenerated conversion function.
func Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(in *ImageListSpec, out *unversioned.ImageListSpec, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(in, out, s)
}

func autoConvert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in *unversioned.ImageListSpec, out *ImageListSpec, s conversion.Scope) error {
	out.Images = *(*[]string)(unsafe.Pointer(&in.Images))
	return nil
}

// Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec is an autogenerated conversion function.
func Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in *unversioned.ImageListSpec, out *ImageListSpec, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in, out, s)
}

func autoConvert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageListStatus, out *unversioned.ImageListStatus, s conversion.Scope) error {
	out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp))
	out.Success = in.Success
	out.Failed = in.Failed
	out.Skipped = in.Skipped
	return nil
}

// Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus is an autogenerated conversion function.
func Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageListStatus, out *unversioned.ImageListStatus, s conversion.Scope) error {
	return autoConvert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in, out, s)
}

func autoConvert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(in *unversioned.ImageListStatus, out *ImageListStatus, s conversion.Scope) error {
	out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp))
	out.Success = in.Success
	out.Failed = in.Failed
	out.Skipped = in.Skipped
	return nil
}

// Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus is an autogenerated conversion function.
func Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(in *unversioned.ImageListStatus, out *ImageListStatus, s conversion.Scope) error {
	return autoConvert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(in, out, s)
}

func autoConvert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(in *ManagerConfig, out *unversioned.ManagerConfig, s conversion.Scope) error {
	if err := Convert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(&in.Runtime, &out.Runtime, s); err != nil {
		return err
	}
	out.OTLPEndpoint = in.OTLPEndpoint
	out.LogLevel = in.LogLevel
	if err := Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(&in.Scheduling, &out.Scheduling, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(&in.Profile, &out.Profile, s); err != nil {
		return err
	}
	if err := Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(&in.ImageJob, &out.ImageJob, s); err != nil {
		return err
	}
	out.PullSecrets = *(*[]string)(unsafe.Pointer(&in.PullSecrets))
	if err := Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(&in.NodeFilter, &out.NodeFilter, s); err != nil {
		return err
	}
	out.PriorityClassName = in.PriorityClassName
	return nil
}

func autoConvert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(in *unversioned.ManagerConfig, out *ManagerConfig, s conversion.Scope) error {
	if err := Convert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(&in.Runtime, &out.Runtime, s); err != nil {
		return err
	}
	out.OTLPEndpoint = in.OTLPEndpoint
	out.LogLevel = in.LogLevel
	if err := Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(&in.Scheduling, &out.Scheduling, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(&in.Profile, &out.Profile, s); err != nil {
		return err
	}
	if err := Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(&in.ImageJob, &out.ImageJob, s); err != nil {
		return err
	}
	out.PullSecrets = *(*[]string)(unsafe.Pointer(&in.PullSecrets))
	if err := Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(&in.NodeFilter, &out.NodeFilter, s); err != nil {
		return err
	}
	out.PriorityClassName = in.PriorityClassName
	// WARNING: in.AdditionalPodLabels requires manual conversion: does not exist in peer-type
	return nil
}

func autoConvert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(in *NodeFilterConfig, out *unversioned.NodeFilterConfig, s conversion.Scope) error {
	out.Type = in.Type
	out.Selectors = *(*[]string)(unsafe.Pointer(&in.Selectors))
	return nil
}

// Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig is an autogenerated conversion function.
func Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(in *NodeFilterConfig, out *unversioned.NodeFilterConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(in, out, s)
}

func autoConvert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(in *unversioned.NodeFilterConfig, out *NodeFilterConfig, s conversion.Scope) error {
	out.Type = in.Type
	out.Selectors = *(*[]string)(unsafe.Pointer(&in.Selectors))
	return nil
}

// Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig is an autogenerated conversion function.
func Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(in *unversioned.NodeFilterConfig, out *NodeFilterConfig, s conversion.Scope) error {
	return autoConvert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(in, out, s)
}

func autoConvert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(in *OptionalContainerConfig, out *unversioned.OptionalContainerConfig, s conversion.Scope) error {
	out.Enabled = in.Enabled
	if err := Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(&in.ContainerConfig, &out.ContainerConfig, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig is an autogenerated conversion function.
func Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(in *OptionalContainerConfig, out *unversioned.OptionalContainerConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig(in, out, s)
}

func autoConvert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(in *unversioned.OptionalContainerConfig, out *OptionalContainerConfig, s conversion.Scope) error {
	out.Enabled = in.Enabled
	if err := Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(&in.ContainerConfig, &out.ContainerConfig, s); err != nil {
		return err
	}
	return nil
}

// Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig is an autogenerated conversion function.
func Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(in *unversioned.OptionalContainerConfig, out *OptionalContainerConfig, s conversion.Scope) error {
	return autoConvert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig(in, out, s)
}

func autoConvert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(in *ProfileConfig, out *unversioned.ProfileConfig, s conversion.Scope) error {
	out.Enabled = in.Enabled
	out.Port = in.Port
	return nil
}

// Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig is an autogenerated conversion function.
func Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(in *ProfileConfig, out *unversioned.ProfileConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(in, out, s)
}

func autoConvert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(in *unversioned.ProfileConfig, out *ProfileConfig, s conversion.Scope) error {
	out.Enabled = in.Enabled
	out.Port = in.Port
	return nil
}

// Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig is an autogenerated conversion function.
func Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(in *unversioned.ProfileConfig, out *ProfileConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(in, out, s)
}

func autoConvert_v1alpha1_RepoTag_To_unversioned_RepoTag(in *RepoTag, out *unversioned.RepoTag, s conversion.Scope) error {
	out.Repo = in.Repo
	out.Tag = in.Tag
	return nil
}

// Convert_v1alpha1_RepoTag_To_unversioned_RepoTag is an autogenerated conversion function.
func Convert_v1alpha1_RepoTag_To_unversioned_RepoTag(in *RepoTag, out *unversioned.RepoTag, s conversion.Scope) error {
	return autoConvert_v1alpha1_RepoTag_To_unversioned_RepoTag(in, out, s)
}

func autoConvert_unversioned_RepoTag_To_v1alpha1_RepoTag(in *unversioned.RepoTag, out *RepoTag, s conversion.Scope) error {
	out.Repo = in.Repo
	out.Tag = in.Tag
	return nil
}

// Convert_unversioned_RepoTag_To_v1alpha1_RepoTag is an autogenerated conversion function.
func Convert_unversioned_RepoTag_To_v1alpha1_RepoTag(in *unversioned.RepoTag, out *RepoTag, s conversion.Scope) error {
	return autoConvert_unversioned_RepoTag_To_v1alpha1_RepoTag(in, out, s)
}

func autoConvert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(in *ResourceRequirements, out *unversioned.ResourceRequirements, s conversion.Scope) error {
	out.Mem = in.Mem
	out.CPU = in.CPU
	return nil
}

// Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements is an autogenerated conversion function.
func Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(in *ResourceRequirements, out *unversioned.ResourceRequirements, s conversion.Scope) error {
	return autoConvert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements(in, out, s)
}

func autoConvert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(in *unversioned.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error {
	out.Mem = in.Mem
	out.CPU = in.CPU
	return nil
}

// Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements is an autogenerated conversion function.
func Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(in *unversioned.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error {
	return autoConvert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements(in, out, s)
}

func autoConvert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(in *ScheduleConfig, out *unversioned.ScheduleConfig, s conversion.Scope) error {
	out.RepeatInterval = unversioned.Duration(in.RepeatInterval)
	out.BeginImmediately = in.BeginImmediately
	return nil
}

// Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig is an autogenerated conversion function.
func Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(in *ScheduleConfig, out *unversioned.ScheduleConfig, s conversion.Scope) error {
	return autoConvert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(in, out, s)
}

func autoConvert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(in *unversioned.ScheduleConfig, out *ScheduleConfig, s conversion.Scope) error {
	out.RepeatInterval = Duration(in.RepeatInterval)
	out.BeginImmediately = in.BeginImmediately
	return nil
}

// Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig is an autogenerated conversion function.
func Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(in *unversioned.ScheduleConfig, out *ScheduleConfig, s conversion.Scope) error {
	return autoConvert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(in, out, s)
}


================================================
FILE: api/v1alpha1/zz_generated.deepcopy.go
================================================
//go:build !ignore_autogenerated

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Code generated by controller-gen. DO NOT EDIT.

package v1alpha1

import (
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
)

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Components) DeepCopyInto(out *Components) {
	*out = *in
	in.Collector.DeepCopyInto(&out.Collector)
	in.Scanner.DeepCopyInto(&out.Scanner)
	in.Eraser.DeepCopyInto(&out.Eraser)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Components.
func (in *Components) DeepCopy() *Components {
	if in == nil {
		return nil
	}
	out := new(Components)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
	*out = *in
	out.Image = in.Image
	in.Request.DeepCopyInto(&out.Request)
	in.Limit.DeepCopyInto(&out.Limit)
	if in.Config != nil {
		in, out := &in.Config, &out.Config
		*out = new(string)
		**out = **in
	}
	if in.Volumes != nil {
		in, out := &in.Volumes, &out.Volumes
		
Download .txt
gitextract_ygu3dx5m/

├── .dockerignore
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   └── feature-request.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── dependabot.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── README.md
│       ├── build-id.yaml
│       ├── codeql.yaml
│       ├── dep-review.yaml
│       ├── deploy_docs.yaml
│       ├── e2e-build.yaml
│       ├── e2e-test.yaml
│       ├── patch-docs.yaml
│       ├── release-pr.yaml
│       ├── release.yaml
│       ├── scan-images.yaml
│       ├── scorecard.yml
│       ├── test.yaml
│       └── upgrade.yaml
├── .gitignore
├── .golangci.yaml
├── .trivyignore
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── Dockerfile
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── PROJECT
├── README.md
├── api/
│   ├── group.go
│   ├── unversioned/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1/
│   │   ├── doc.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1alpha1/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── custom_conversions.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── imagejob_types.go
│   │   ├── imagelist_types.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   ├── v1alpha2/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── custom_conversions.go
│   │   ├── doc.go
│   │   ├── eraserconfig_types.go
│   │   ├── groupversion_info.go
│   │   ├── zz_generated.conversion.go
│   │   └── zz_generated.deepcopy.go
│   └── v1alpha3/
│       ├── config/
│       │   └── config.go
│       ├── doc.go
│       ├── eraserconfig_types.go
│       ├── groupversion_info.go
│       ├── runtime_spec_test.go
│       ├── zz_generated.conversion.go
│       └── zz_generated.deepcopy.go
├── build/
│   └── version.sh
├── config/
│   ├── crd/
│   │   ├── bases/
│   │   │   ├── _.yaml
│   │   │   ├── eraser.sh_imagejobs.yaml
│   │   │   └── eraser.sh_imagelists.yaml
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches/
│   │       ├── cainjection_in_eraserconfigs.yaml
│   │       ├── cainjection_in_imagelists.yaml
│   │       ├── webhook_in_eraserconfigs.yaml
│   │       └── webhook_in_imagelists.yaml
│   ├── default/
│   │   ├── kustomization.yaml
│   │   └── manager_auth_proxy_patch.yaml
│   ├── manager/
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   ├── manager.yaml
│   │   └── patch.yaml
│   ├── prometheus/
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   └── rbac/
│       ├── auth_proxy_client_clusterrole.yaml
│       ├── auth_proxy_role.yaml
│       ├── auth_proxy_role_binding.yaml
│       ├── auth_proxy_service.yaml
│       ├── cluster_role_binding.yaml
│       ├── imagejob_pods_service.yaml
│       ├── imagelist_editor_role.yaml
│       ├── imagelist_viewer_role.yaml
│       ├── kustomization.yaml
│       ├── leader_election_role.yaml
│       ├── leader_election_role_binding.yaml
│       ├── role.yaml
│       ├── role_binding.yaml
│       └── service_account.yaml
├── controllers/
│   ├── configmap/
│   │   └── configmap.go
│   ├── controller.go
│   ├── imagecollector/
│   │   └── imagecollector_controller.go
│   ├── imagejob/
│   │   └── imagejob_controller.go
│   ├── imagelist/
│   │   └── imagelist_controller.go
│   ├── suite_test.go
│   └── util/
│       └── util.go
├── demo/
│   ├── README.md
│   ├── demo-magic.sh
│   ├── demo.sh
│   └── ds.yaml
├── deploy/
│   └── eraser.yaml
├── docs/
│   ├── README.md
│   ├── babel.config.js
│   ├── design/
│   │   └── README.md
│   ├── docs/
│   │   ├── architecture.md
│   │   ├── code-of-conduct.md
│   │   ├── contributing.md
│   │   ├── custom-scanner.md
│   │   ├── customization.md
│   │   ├── exclusion.md
│   │   ├── faq.md
│   │   ├── installation.md
│   │   ├── introduction.md
│   │   ├── manual-removal.md
│   │   ├── metrics.md
│   │   ├── quick-start.md
│   │   ├── release-management.md
│   │   ├── releasing.md
│   │   ├── setup.md
│   │   └── trivy.md
│   ├── docusaurus.config.js
│   ├── package.json
│   ├── sidebars.js
│   ├── src/
│   │   └── css/
│   │       └── custom.css
│   ├── static/
│   │   └── .nojekyll
│   ├── versioned_docs/
│   │   ├── version-v0.4.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v0.5.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.0.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.1.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.2.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   ├── version-v1.3.x/
│   │   │   ├── architecture.md
│   │   │   ├── code-of-conduct.md
│   │   │   ├── contributing.md
│   │   │   ├── custom-scanner.md
│   │   │   ├── customization.md
│   │   │   ├── exclusion.md
│   │   │   ├── faq.md
│   │   │   ├── installation.md
│   │   │   ├── introduction.md
│   │   │   ├── manual-removal.md
│   │   │   ├── metrics.md
│   │   │   ├── quick-start.md
│   │   │   ├── release-management.md
│   │   │   ├── releasing.md
│   │   │   ├── setup.md
│   │   │   └── trivy.md
│   │   └── version-v1.4.x/
│   │       ├── architecture.md
│   │       ├── code-of-conduct.md
│   │       ├── contributing.md
│   │       ├── custom-scanner.md
│   │       ├── customization.md
│   │       ├── exclusion.md
│   │       ├── faq.md
│   │       ├── installation.md
│   │       ├── introduction.md
│   │       ├── manual-removal.md
│   │       ├── metrics.md
│   │       ├── quick-start.md
│   │       ├── release-management.md
│   │       ├── releasing.md
│   │       ├── setup.md
│   │       └── trivy.md
│   ├── versioned_sidebars/
│   │   ├── version-v0.4.x-sidebars.json
│   │   ├── version-v0.5.x-sidebars.json
│   │   ├── version-v1.0.x-sidebars.json
│   │   ├── version-v1.1.x-sidebars.json
│   │   ├── version-v1.2.x-sidebars.json
│   │   ├── version-v1.3.x-sidebars.json
│   │   └── version-v1.4.x-sidebars.json
│   └── versions.json
├── go.mod
├── go.sum
├── hack/
│   ├── boilerplate.go.txt
│   ├── go-install.sh
│   └── rootless_docker.sh
├── main.go
├── manifest_staging/
│   └── deploy/
│       └── eraser.yaml
├── pkg/
│   ├── collector/
│   │   ├── collector.go
│   │   └── helpers.go
│   ├── cri/
│   │   ├── client.go
│   │   ├── client_v1.go
│   │   ├── client_v1alpha2.go
│   │   └── util.go
│   ├── logger/
│   │   └── zap.go
│   ├── metrics/
│   │   ├── metrics.go
│   │   └── metrics_test.go
│   ├── scanners/
│   │   ├── template/
│   │   │   └── scanner_template.go
│   │   └── trivy/
│   │       ├── helpers.go
│   │       ├── trivy.go
│   │       ├── trivy_test.go
│   │       ├── types.go
│   │       └── types_test.go
│   └── utils/
│       ├── flag.go
│       ├── pod_info.go
│       ├── security_context.go
│       ├── utils.go
│       └── utils_test.go
├── test/
│   └── e2e/
│       ├── kind-config-custom-runtime.yaml
│       ├── kind-config.yaml
│       ├── test-data/
│       │   ├── Dockerfile.busybox
│       │   ├── Dockerfile.customNode
│       │   ├── Dockerfile.dummyCollector
│       │   ├── eraser_v1_imagelist.yaml
│       │   ├── eraser_v1alpha1_imagelist.yaml
│       │   ├── eraser_v1alpha1_imagelist_updated.yaml
│       │   ├── helm-empty-values.yaml
│       │   ├── helm-test-config.yaml
│       │   ├── imagelist_alpine.yaml
│       │   └── otelcollector.yaml
│       ├── tests/
│       │   ├── collector_delete_deployment/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_delete_manager/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_disable_scan/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_ensure_scan/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_pipeline/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_runtime_config/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── collector_skip_excluded/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── configmap_update/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── helm_pull_secret/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── helm_pull_secret_imagelist/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_alias/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_change/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_exclusion_list/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_include_nodes/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_prune_images/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_rm_images/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── imagelist_skip_nodes/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── metrics_test_disable_scanner/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   ├── metrics_test_eraser/
│       │   │   ├── eraser_test.go
│       │   │   └── main_test.go
│       │   └── metrics_test_scanner/
│       │       ├── eraser_test.go
│       │       └── main_test.go
│       └── util/
│           ├── kubectl.go
│           ├── utils.go
│           └── utils_test.go
├── third_party/
│   └── open-policy-agent/
│       └── gatekeeper/
│           └── helmify/
│               ├── LICENSE
│               ├── README.md
│               ├── kustomization.yaml
│               ├── kustomize-for-helm.yaml
│               ├── main.go
│               ├── replacements.go
│               └── static/
│                   ├── .helmignore
│                   ├── Chart.yaml
│                   ├── README.md
│                   ├── templates/
│                   │   ├── _helpers.tpl
│                   │   └── configmap.yaml
│                   └── values.yaml
└── version/
    ├── version.go
    └── version_test.go
Download .txt
SYMBOL INDEX (930 symbols across 98 files)

FILE: api/unversioned/config/config.go
  type Manager (line 35) | type Manager struct
    method Read (line 40) | func (m *Manager) Read() (unversioned.EraserConfig, error) {
    method Update (line 52) | func (m *Manager) Update(newC *unversioned.EraserConfig) error {
  function NewManager (line 68) | func NewManager(cfg *unversioned.EraserConfig) *Manager {
  constant noDelay (line 76) | noDelay = unversioned.Duration(0)
  constant oneDay (line 77) | oneDay  = unversioned.Duration(time.Hour * 24)
  function Default (line 80) | func Default() *unversioned.EraserConfig {
  function repo (line 170) | func repo(basename string) string {

FILE: api/unversioned/eraserconfig_types.go
  type Duration (line 31) | type Duration
    method UnmarshalJSON (line 68) | func (td *Duration) UnmarshalJSON(b []byte) error {
    method MarshalJSON (line 84) | func (td *Duration) MarshalJSON() ([]byte, error) {
  type Runtime (line 32) | type Runtime
  type RuntimeSpec (line 34) | type RuntimeSpec struct
    method UnmarshalJSON (line 88) | func (r *RuntimeSpec) UnmarshalJSON(b []byte) error {
  constant RuntimeContainerd (line 41) | RuntimeContainerd  Runtime = "containerd"
  constant RuntimeDockerShim (line 42) | RuntimeDockerShim  Runtime = "dockershim"
  constant RuntimeCrio (line 43) | RuntimeCrio        Runtime = "crio"
  constant RuntimeNotProvided (line 44) | RuntimeNotProvided Runtime = ""
  constant ContainerdPath (line 46) | ContainerdPath = "/run/containerd/containerd.sock"
  constant DockerPath (line 47) | DockerPath     = "/run/dockershim.sock"
  constant CrioPath (line 48) | CrioPath       = "/run/crio/crio.sock"
  function ConvertRuntimeToRuntimeSpec (line 51) | func ConvertRuntimeToRuntimeSpec(r Runtime) (RuntimeSpec, error) {
  type OptionalContainerConfig (line 147) | type OptionalContainerConfig struct
  type ContainerConfig (line 152) | type ContainerConfig struct
  type ManagerConfig (line 160) | type ManagerConfig struct
  type ScheduleConfig (line 173) | type ScheduleConfig struct
  type ProfileConfig (line 178) | type ProfileConfig struct
  type ImageJobConfig (line 183) | type ImageJobConfig struct
  type ImageJobCleanupConfig (line 188) | type ImageJobCleanupConfig struct
  type NodeFilterConfig (line 193) | type NodeFilterConfig struct
  type ResourceRequirements (line 198) | type ResourceRequirements struct
  type RepoTag (line 203) | type RepoTag struct
  type Components (line 208) | type Components struct
  type EraserConfig (line 217) | type EraserConfig struct
  function init (line 223) | func init() {

FILE: api/unversioned/imagejob_types.go
  type Image (line 24) | type Image struct
  type JobPhase (line 34) | type JobPhase
  constant PhaseRunning (line 37) | PhaseRunning   JobPhase = "Running"
  constant PhaseCompleted (line 38) | PhaseCompleted JobPhase = "Completed"
  constant PhaseFailed (line 39) | PhaseFailed    JobPhase = "Failed"
  type ImageJobStatus (line 43) | type ImageJobStatus struct
  type ImageJob (line 64) | type ImageJob struct
  type ImageJobList (line 72) | type ImageJobList struct

FILE: api/unversioned/imagelist_types.go
  type ImageListSpec (line 22) | type ImageListSpec struct
  type ImageListStatus (line 28) | type ImageListStatus struct
  type ImageList (line 40) | type ImageList struct
  type ImageListList (line 49) | type ImageListList struct

FILE: api/unversioned/zz_generated.deepcopy.go
  method DeepCopyInto (line 29) | func (in *Components) DeepCopyInto(out *Components) {
  method DeepCopy (line 37) | func (in *Components) DeepCopy() *Components {
  method DeepCopyInto (line 47) | func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
  method DeepCopy (line 67) | func (in *ContainerConfig) DeepCopy() *ContainerConfig {
  method DeepCopyInto (line 77) | func (in *EraserConfig) DeepCopyInto(out *EraserConfig) {
  method DeepCopy (line 85) | func (in *EraserConfig) DeepCopy() *EraserConfig {
  method DeepCopyObject (line 95) | func (in *EraserConfig) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 103) | func (in *Image) DeepCopyInto(out *Image) {
  method DeepCopy (line 118) | func (in *Image) DeepCopy() *Image {
  method DeepCopyInto (line 128) | func (in *ImageJob) DeepCopyInto(out *ImageJob) {
  method DeepCopy (line 136) | func (in *ImageJob) DeepCopy() *ImageJob {
  method DeepCopyInto (line 146) | func (in *ImageJobCleanupConfig) DeepCopyInto(out *ImageJobCleanupConfig) {
  method DeepCopy (line 151) | func (in *ImageJobCleanupConfig) DeepCopy() *ImageJobCleanupConfig {
  method DeepCopyInto (line 161) | func (in *ImageJobConfig) DeepCopyInto(out *ImageJobConfig) {
  method DeepCopy (line 167) | func (in *ImageJobConfig) DeepCopy() *ImageJobConfig {
  method DeepCopyInto (line 177) | func (in *ImageJobList) DeepCopyInto(out *ImageJobList) {
  method DeepCopy (line 191) | func (in *ImageJobList) DeepCopy() *ImageJobList {
  method DeepCopyInto (line 201) | func (in *ImageJobStatus) DeepCopyInto(out *ImageJobStatus) {
  method DeepCopy (line 210) | func (in *ImageJobStatus) DeepCopy() *ImageJobStatus {
  method DeepCopyInto (line 220) | func (in *ImageList) DeepCopyInto(out *ImageList) {
  method DeepCopy (line 229) | func (in *ImageList) DeepCopy() *ImageList {
  method DeepCopyInto (line 239) | func (in *ImageListList) DeepCopyInto(out *ImageListList) {
  method DeepCopy (line 253) | func (in *ImageListList) DeepCopy() *ImageListList {
  method DeepCopyInto (line 263) | func (in *ImageListSpec) DeepCopyInto(out *ImageListSpec) {
  method DeepCopy (line 273) | func (in *ImageListSpec) DeepCopy() *ImageListSpec {
  method DeepCopyInto (line 283) | func (in *ImageListStatus) DeepCopyInto(out *ImageListStatus) {
  method DeepCopy (line 292) | func (in *ImageListStatus) DeepCopy() *ImageListStatus {
  method DeepCopyInto (line 302) | func (in *ManagerConfig) DeepCopyInto(out *ManagerConfig) {
  method DeepCopy (line 324) | func (in *ManagerConfig) DeepCopy() *ManagerConfig {
  method DeepCopyInto (line 334) | func (in *NodeFilterConfig) DeepCopyInto(out *NodeFilterConfig) {
  method DeepCopy (line 344) | func (in *NodeFilterConfig) DeepCopy() *NodeFilterConfig {
  method DeepCopyInto (line 354) | func (in *OptionalContainerConfig) DeepCopyInto(out *OptionalContainerCo...
  method DeepCopy (line 360) | func (in *OptionalContainerConfig) DeepCopy() *OptionalContainerConfig {
  method DeepCopyInto (line 370) | func (in *ProfileConfig) DeepCopyInto(out *ProfileConfig) {
  method DeepCopy (line 375) | func (in *ProfileConfig) DeepCopy() *ProfileConfig {
  method DeepCopyInto (line 385) | func (in *RepoTag) DeepCopyInto(out *RepoTag) {
  method DeepCopy (line 390) | func (in *RepoTag) DeepCopy() *RepoTag {
  method DeepCopyInto (line 400) | func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) {
  method DeepCopy (line 407) | func (in *ResourceRequirements) DeepCopy() *ResourceRequirements {
  method DeepCopyInto (line 417) | func (in *RuntimeSpec) DeepCopyInto(out *RuntimeSpec) {
  method DeepCopy (line 422) | func (in *RuntimeSpec) DeepCopy() *RuntimeSpec {
  method DeepCopyInto (line 432) | func (in *ScheduleConfig) DeepCopyInto(out *ScheduleConfig) {
  method DeepCopy (line 437) | func (in *ScheduleConfig) DeepCopy() *ScheduleConfig {

FILE: api/v1/imagejob_types.go
  type Image (line 23) | type Image struct
  type JobPhase (line 33) | type JobPhase
  constant PhaseRunning (line 36) | PhaseRunning   JobPhase = "Running"
  constant PhaseCompleted (line 37) | PhaseCompleted JobPhase = "Completed"
  constant PhaseFailed (line 38) | PhaseFailed    JobPhase = "Failed"
  type ImageJobStatus (line 42) | type ImageJobStatus struct
  type ImageJob (line 67) | type ImageJob struct
  type ImageJobList (line 77) | type ImageJobList struct
  function init (line 83) | func init() {

FILE: api/v1/imagelist_types.go
  type ImageListSpec (line 21) | type ImageListSpec struct
  type ImageListStatus (line 27) | type ImageListStatus struct
  type ImageList (line 43) | type ImageList struct
  type ImageListList (line 54) | type ImageListList struct
  function init (line 60) | func init() {

FILE: api/v1/zz_generated.conversion.go
  function init (line 32) | func init() {
  function RegisterConversions (line 38) | func RegisterConversions(s *runtime.Scheme) error {
  function autoConvert_v1_Image_To_unversioned_Image (line 122) | func autoConvert_v1_Image_To_unversioned_Image(in *Image, out *unversion...
  function Convert_v1_Image_To_unversioned_Image (line 130) | func Convert_v1_Image_To_unversioned_Image(in *Image, out *unversioned.I...
  function autoConvert_unversioned_Image_To_v1_Image (line 134) | func autoConvert_unversioned_Image_To_v1_Image(in *unversioned.Image, ou...
  function Convert_unversioned_Image_To_v1_Image (line 142) | func Convert_unversioned_Image_To_v1_Image(in *unversioned.Image, out *I...
  function autoConvert_v1_ImageJob_To_unversioned_ImageJob (line 146) | func autoConvert_v1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *...
  function Convert_v1_ImageJob_To_unversioned_ImageJob (line 155) | func Convert_v1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out *unve...
  function autoConvert_unversioned_ImageJob_To_v1_ImageJob (line 159) | func autoConvert_unversioned_ImageJob_To_v1_ImageJob(in *unversioned.Ima...
  function Convert_unversioned_ImageJob_To_v1_ImageJob (line 168) | func Convert_unversioned_ImageJob_To_v1_ImageJob(in *unversioned.ImageJo...
  function autoConvert_v1_ImageJobList_To_unversioned_ImageJobList (line 172) | func autoConvert_v1_ImageJobList_To_unversioned_ImageJobList(in *ImageJo...
  function Convert_v1_ImageJobList_To_unversioned_ImageJobList (line 179) | func Convert_v1_ImageJobList_To_unversioned_ImageJobList(in *ImageJobLis...
  function autoConvert_unversioned_ImageJobList_To_v1_ImageJobList (line 183) | func autoConvert_unversioned_ImageJobList_To_v1_ImageJobList(in *unversi...
  function Convert_unversioned_ImageJobList_To_v1_ImageJobList (line 190) | func Convert_unversioned_ImageJobList_To_v1_ImageJobList(in *unversioned...
  function autoConvert_v1_ImageJobStatus_To_unversioned_ImageJobStatus (line 194) | func autoConvert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(in *Ima...
  function Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus (line 205) | func Convert_v1_ImageJobStatus_To_unversioned_ImageJobStatus(in *ImageJo...
  function autoConvert_unversioned_ImageJobStatus_To_v1_ImageJobStatus (line 209) | func autoConvert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(in *unv...
  function Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus (line 220) | func Convert_unversioned_ImageJobStatus_To_v1_ImageJobStatus(in *unversi...
  function autoConvert_v1_ImageList_To_unversioned_ImageList (line 224) | func autoConvert_v1_ImageList_To_unversioned_ImageList(in *ImageList, ou...
  function Convert_v1_ImageList_To_unversioned_ImageList (line 236) | func Convert_v1_ImageList_To_unversioned_ImageList(in *ImageList, out *u...
  function autoConvert_unversioned_ImageList_To_v1_ImageList (line 240) | func autoConvert_unversioned_ImageList_To_v1_ImageList(in *unversioned.I...
  function Convert_unversioned_ImageList_To_v1_ImageList (line 252) | func Convert_unversioned_ImageList_To_v1_ImageList(in *unversioned.Image...
  function autoConvert_v1_ImageListList_To_unversioned_ImageListList (line 256) | func autoConvert_v1_ImageListList_To_unversioned_ImageListList(in *Image...
  function Convert_v1_ImageListList_To_unversioned_ImageListList (line 263) | func Convert_v1_ImageListList_To_unversioned_ImageListList(in *ImageList...
  function autoConvert_unversioned_ImageListList_To_v1_ImageListList (line 267) | func autoConvert_unversioned_ImageListList_To_v1_ImageListList(in *unver...
  function Convert_unversioned_ImageListList_To_v1_ImageListList (line 274) | func Convert_unversioned_ImageListList_To_v1_ImageListList(in *unversion...
  function autoConvert_v1_ImageListSpec_To_unversioned_ImageListSpec (line 278) | func autoConvert_v1_ImageListSpec_To_unversioned_ImageListSpec(in *Image...
  function Convert_v1_ImageListSpec_To_unversioned_ImageListSpec (line 284) | func Convert_v1_ImageListSpec_To_unversioned_ImageListSpec(in *ImageList...
  function autoConvert_unversioned_ImageListSpec_To_v1_ImageListSpec (line 288) | func autoConvert_unversioned_ImageListSpec_To_v1_ImageListSpec(in *unver...
  function Convert_unversioned_ImageListSpec_To_v1_ImageListSpec (line 294) | func Convert_unversioned_ImageListSpec_To_v1_ImageListSpec(in *unversion...
  function autoConvert_v1_ImageListStatus_To_unversioned_ImageListStatus (line 298) | func autoConvert_v1_ImageListStatus_To_unversioned_ImageListStatus(in *I...
  function Convert_v1_ImageListStatus_To_unversioned_ImageListStatus (line 307) | func Convert_v1_ImageListStatus_To_unversioned_ImageListStatus(in *Image...
  function autoConvert_unversioned_ImageListStatus_To_v1_ImageListStatus (line 311) | func autoConvert_unversioned_ImageListStatus_To_v1_ImageListStatus(in *u...
  function Convert_unversioned_ImageListStatus_To_v1_ImageListStatus (line 320) | func Convert_unversioned_ImageListStatus_To_v1_ImageListStatus(in *unver...

FILE: api/v1/zz_generated.deepcopy.go
  method DeepCopyInto (line 28) | func (in *Image) DeepCopyInto(out *Image) {
  method DeepCopy (line 43) | func (in *Image) DeepCopy() *Image {
  method DeepCopyInto (line 53) | func (in *ImageJob) DeepCopyInto(out *ImageJob) {
  method DeepCopy (line 61) | func (in *ImageJob) DeepCopy() *ImageJob {
  method DeepCopyObject (line 71) | func (in *ImageJob) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 79) | func (in *ImageJobList) DeepCopyInto(out *ImageJobList) {
  method DeepCopy (line 93) | func (in *ImageJobList) DeepCopy() *ImageJobList {
  method DeepCopyObject (line 103) | func (in *ImageJobList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 111) | func (in *ImageJobStatus) DeepCopyInto(out *ImageJobStatus) {
  method DeepCopy (line 120) | func (in *ImageJobStatus) DeepCopy() *ImageJobStatus {
  method DeepCopyInto (line 130) | func (in *ImageList) DeepCopyInto(out *ImageList) {
  method DeepCopy (line 139) | func (in *ImageList) DeepCopy() *ImageList {
  method DeepCopyObject (line 149) | func (in *ImageList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 157) | func (in *ImageListList) DeepCopyInto(out *ImageListList) {
  method DeepCopy (line 171) | func (in *ImageListList) DeepCopy() *ImageListList {
  method DeepCopyObject (line 181) | func (in *ImageListList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 189) | func (in *ImageListSpec) DeepCopyInto(out *ImageListSpec) {
  method DeepCopy (line 199) | func (in *ImageListSpec) DeepCopy() *ImageListSpec {
  method DeepCopyInto (line 209) | func (in *ImageListStatus) DeepCopyInto(out *ImageListStatus) {
  method DeepCopy (line 218) | func (in *ImageListStatus) DeepCopy() *ImageListStatus {

FILE: api/v1alpha1/config/config.go
  constant noDelay (line 32) | noDelay = v1alpha1.Duration(0)
  constant oneDay (line 33) | oneDay  = v1alpha1.Duration(time.Hour * 24)
  function Default (line 36) | func Default() *v1alpha1.EraserConfig {
  function repo (line 121) | func repo(basename string) string {

FILE: api/v1alpha1/custom_conversions.go
  function Convert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig (line 9) | func Convert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(in *Man...
  function manualConvert_v1alpha1_Runtime_To_unversioned_RuntimeSpec (line 14) | func manualConvert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(in *Runti...
  function Convert_v1alpha1_Runtime_To_unversioned_RuntimeSpec (line 27) | func Convert_v1alpha1_Runtime_To_unversioned_RuntimeSpec(in *Runtime, ou...
  function Convert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig (line 32) | func Convert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(in *unv...
  function manualConvert_unversioned_RuntimeSpec_To_v1alpha1_Runtime (line 37) | func manualConvert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(in *unver...
  function Convert_unversioned_RuntimeSpec_To_v1alpha1_Runtime (line 43) | func Convert_unversioned_RuntimeSpec_To_v1alpha1_Runtime(in *unversioned...

FILE: api/v1alpha1/eraserconfig_types.go
  type Duration (line 32) | type Duration
    method UnmarshalJSON (line 42) | func (td *Duration) UnmarshalJSON(b []byte) error {
    method MarshalJSON (line 58) | func (td *Duration) MarshalJSON() ([]byte, error) {
  type Runtime (line 33) | type Runtime
    method UnmarshalJSON (line 62) | func (r *Runtime) UnmarshalJSON(b []byte) error {
  constant RuntimeContainerd (line 37) | RuntimeContainerd Runtime = "containerd"
  constant RuntimeDockerShim (line 38) | RuntimeDockerShim Runtime = "dockershim"
  constant RuntimeCrio (line 39) | RuntimeCrio       Runtime = "crio"
  type OptionalContainerConfig (line 82) | type OptionalContainerConfig struct
  type ContainerConfig (line 87) | type ContainerConfig struct
  type ManagerConfig (line 95) | type ManagerConfig struct
  type ScheduleConfig (line 107) | type ScheduleConfig struct
  type ProfileConfig (line 112) | type ProfileConfig struct
  type ImageJobConfig (line 117) | type ImageJobConfig struct
  type ImageJobCleanupConfig (line 122) | type ImageJobCleanupConfig struct
  type NodeFilterConfig (line 127) | type NodeFilterConfig struct
  type ResourceRequirements (line 132) | type ResourceRequirements struct
  type RepoTag (line 137) | type RepoTag struct
  type Components (line 142) | type Components struct
  type EraserConfig (line 151) | type EraserConfig struct
  function init (line 157) | func init() {
  function Convert_v1alpha1_Components_To_unversioned_Components (line 167) | func Convert_v1alpha1_Components_To_unversioned_Components(in *Component...
  function Convert_unversioned_Components_To_v1alpha1_Components (line 177) | func Convert_unversioned_Components_To_v1alpha1_Components(in *unversion...

FILE: api/v1alpha1/imagejob_types.go
  type Image (line 23) | type Image struct
  type JobPhase (line 33) | type JobPhase
  constant PhaseRunning (line 36) | PhaseRunning   JobPhase = "Running"
  constant PhaseCompleted (line 37) | PhaseCompleted JobPhase = "Completed"
  constant PhaseFailed (line 38) | PhaseFailed    JobPhase = "Failed"
  type ImageJobStatus (line 42) | type ImageJobStatus struct
  type ImageJob (line 67) | type ImageJob struct
  type ImageJobList (line 77) | type ImageJobList struct
  function init (line 83) | func init() {

FILE: api/v1alpha1/imagelist_types.go
  type ImageListSpec (line 21) | type ImageListSpec struct
  type ImageListStatus (line 27) | type ImageListStatus struct
  type ImageList (line 43) | type ImageList struct
  type ImageListList (line 54) | type ImageListList struct
  function init (line 60) | func init() {

FILE: api/v1alpha1/zz_generated.conversion.go
  function init (line 33) | func init() {
  function RegisterConversions (line 39) | func RegisterConversions(s *runtime.Scheme) error {
  function autoConvert_v1alpha1_Components_To_unversioned_Components (line 253) | func autoConvert_v1alpha1_Components_To_unversioned_Components(in *Compo...
  function autoConvert_unversioned_Components_To_v1alpha1_Components (line 264) | func autoConvert_unversioned_Components_To_v1alpha1_Components(in *unver...
  function autoConvert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig (line 275) | func autoConvert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig...
  function Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig (line 291) | func Convert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(in ...
  function autoConvert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig (line 295) | func autoConvert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig...
  function Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig (line 311) | func Convert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(in ...
  function autoConvert_v1alpha1_EraserConfig_To_unversioned_EraserConfig (line 315) | func autoConvert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(in *E...
  function Convert_v1alpha1_EraserConfig_To_unversioned_EraserConfig (line 326) | func Convert_v1alpha1_EraserConfig_To_unversioned_EraserConfig(in *Erase...
  function autoConvert_unversioned_EraserConfig_To_v1alpha1_EraserConfig (line 330) | func autoConvert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(in *u...
  function Convert_unversioned_EraserConfig_To_v1alpha1_EraserConfig (line 341) | func Convert_unversioned_EraserConfig_To_v1alpha1_EraserConfig(in *unver...
  function autoConvert_v1alpha1_Image_To_unversioned_Image (line 345) | func autoConvert_v1alpha1_Image_To_unversioned_Image(in *Image, out *unv...
  function Convert_v1alpha1_Image_To_unversioned_Image (line 353) | func Convert_v1alpha1_Image_To_unversioned_Image(in *Image, out *unversi...
  function autoConvert_unversioned_Image_To_v1alpha1_Image (line 357) | func autoConvert_unversioned_Image_To_v1alpha1_Image(in *unversioned.Ima...
  function Convert_unversioned_Image_To_v1alpha1_Image (line 365) | func Convert_unversioned_Image_To_v1alpha1_Image(in *unversioned.Image, ...
  function autoConvert_v1alpha1_ImageJob_To_unversioned_ImageJob (line 369) | func autoConvert_v1alpha1_ImageJob_To_unversioned_ImageJob(in *ImageJob,...
  function Convert_v1alpha1_ImageJob_To_unversioned_ImageJob (line 378) | func Convert_v1alpha1_ImageJob_To_unversioned_ImageJob(in *ImageJob, out...
  function autoConvert_unversioned_ImageJob_To_v1alpha1_ImageJob (line 382) | func autoConvert_unversioned_ImageJob_To_v1alpha1_ImageJob(in *unversion...
  function Convert_unversioned_ImageJob_To_v1alpha1_ImageJob (line 391) | func Convert_unversioned_ImageJob_To_v1alpha1_ImageJob(in *unversioned.I...
  function autoConvert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 395) | func autoConvert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobC...
  function Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 402) | func Convert_v1alpha1_ImageJobCleanupConfig_To_unversioned_ImageJobClean...
  function autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig (line 406) | func autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobC...
  function Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobCleanupConfig (line 413) | func Convert_unversioned_ImageJobCleanupConfig_To_v1alpha1_ImageJobClean...
  function autoConvert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig (line 417) | func autoConvert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(i...
  function Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig (line 426) | func Convert_v1alpha1_ImageJobConfig_To_unversioned_ImageJobConfig(in *I...
  function autoConvert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig (line 430) | func autoConvert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(i...
  function Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig (line 439) | func Convert_unversioned_ImageJobConfig_To_v1alpha1_ImageJobConfig(in *u...
  function autoConvert_v1alpha1_ImageJobList_To_unversioned_ImageJobList (line 443) | func autoConvert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(in *I...
  function Convert_v1alpha1_ImageJobList_To_unversioned_ImageJobList (line 450) | func Convert_v1alpha1_ImageJobList_To_unversioned_ImageJobList(in *Image...
  function autoConvert_unversioned_ImageJobList_To_v1alpha1_ImageJobList (line 454) | func autoConvert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(in *u...
  function Convert_unversioned_ImageJobList_To_v1alpha1_ImageJobList (line 461) | func Convert_unversioned_ImageJobList_To_v1alpha1_ImageJobList(in *unver...
  function autoConvert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus (line 465) | func autoConvert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(i...
  function Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus (line 476) | func Convert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(in *I...
  function autoConvert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus (line 480) | func autoConvert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(i...
  function Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus (line 491) | func Convert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(in *u...
  function autoConvert_v1alpha1_ImageList_To_unversioned_ImageList (line 495) | func autoConvert_v1alpha1_ImageList_To_unversioned_ImageList(in *ImageLi...
  function Convert_v1alpha1_ImageList_To_unversioned_ImageList (line 507) | func Convert_v1alpha1_ImageList_To_unversioned_ImageList(in *ImageList, ...
  function autoConvert_unversioned_ImageList_To_v1alpha1_ImageList (line 511) | func autoConvert_unversioned_ImageList_To_v1alpha1_ImageList(in *unversi...
  function Convert_unversioned_ImageList_To_v1alpha1_ImageList (line 523) | func Convert_unversioned_ImageList_To_v1alpha1_ImageList(in *unversioned...
  function autoConvert_v1alpha1_ImageListList_To_unversioned_ImageListList (line 527) | func autoConvert_v1alpha1_ImageListList_To_unversioned_ImageListList(in ...
  function Convert_v1alpha1_ImageListList_To_unversioned_ImageListList (line 534) | func Convert_v1alpha1_ImageListList_To_unversioned_ImageListList(in *Ima...
  function autoConvert_unversioned_ImageListList_To_v1alpha1_ImageListList (line 538) | func autoConvert_unversioned_ImageListList_To_v1alpha1_ImageListList(in ...
  function Convert_unversioned_ImageListList_To_v1alpha1_ImageListList (line 545) | func Convert_unversioned_ImageListList_To_v1alpha1_ImageListList(in *unv...
  function autoConvert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec (line 549) | func autoConvert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(in ...
  function Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec (line 555) | func Convert_v1alpha1_ImageListSpec_To_unversioned_ImageListSpec(in *Ima...
  function autoConvert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec (line 559) | func autoConvert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in ...
  function Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec (line 565) | func Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in *unv...
  function autoConvert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus (line 569) | func autoConvert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus...
  function Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus (line 578) | func Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in ...
  function autoConvert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus (line 582) | func autoConvert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus...
  function Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus (line 591) | func Convert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(in ...
  function autoConvert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig (line 595) | func autoConvert_v1alpha1_ManagerConfig_To_unversioned_ManagerConfig(in ...
  function autoConvert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig (line 618) | func autoConvert_unversioned_ManagerConfig_To_v1alpha1_ManagerConfig(in ...
  function autoConvert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 642) | func autoConvert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConf...
  function Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 649) | func Convert_v1alpha1_NodeFilterConfig_To_unversioned_NodeFilterConfig(i...
  function autoConvert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig (line 653) | func autoConvert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConf...
  function Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig (line 660) | func Convert_unversioned_NodeFilterConfig_To_v1alpha1_NodeFilterConfig(i...
  function autoConvert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 664) | func autoConvert_v1alpha1_OptionalContainerConfig_To_unversioned_Optiona...
  function Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 673) | func Convert_v1alpha1_OptionalContainerConfig_To_unversioned_OptionalCon...
  function autoConvert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig (line 677) | func autoConvert_unversioned_OptionalContainerConfig_To_v1alpha1_Optiona...
  function Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalContainerConfig (line 686) | func Convert_unversioned_OptionalContainerConfig_To_v1alpha1_OptionalCon...
  function autoConvert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig (line 690) | func autoConvert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(in ...
  function Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig (line 697) | func Convert_v1alpha1_ProfileConfig_To_unversioned_ProfileConfig(in *Pro...
  function autoConvert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig (line 701) | func autoConvert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(in ...
  function Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig (line 708) | func Convert_unversioned_ProfileConfig_To_v1alpha1_ProfileConfig(in *unv...
  function autoConvert_v1alpha1_RepoTag_To_unversioned_RepoTag (line 712) | func autoConvert_v1alpha1_RepoTag_To_unversioned_RepoTag(in *RepoTag, ou...
  function Convert_v1alpha1_RepoTag_To_unversioned_RepoTag (line 719) | func Convert_v1alpha1_RepoTag_To_unversioned_RepoTag(in *RepoTag, out *u...
  function autoConvert_unversioned_RepoTag_To_v1alpha1_RepoTag (line 723) | func autoConvert_unversioned_RepoTag_To_v1alpha1_RepoTag(in *unversioned...
  function Convert_unversioned_RepoTag_To_v1alpha1_RepoTag (line 730) | func Convert_unversioned_RepoTag_To_v1alpha1_RepoTag(in *unversioned.Rep...
  function autoConvert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements (line 734) | func autoConvert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRe...
  function Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequirements (line 741) | func Convert_v1alpha1_ResourceRequirements_To_unversioned_ResourceRequir...
  function autoConvert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements (line 745) | func autoConvert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRe...
  function Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequirements (line 752) | func Convert_unversioned_ResourceRequirements_To_v1alpha1_ResourceRequir...
  function autoConvert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig (line 756) | func autoConvert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(i...
  function Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig (line 763) | func Convert_v1alpha1_ScheduleConfig_To_unversioned_ScheduleConfig(in *S...
  function autoConvert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig (line 767) | func autoConvert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(i...
  function Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig (line 774) | func Convert_unversioned_ScheduleConfig_To_v1alpha1_ScheduleConfig(in *u...

FILE: api/v1alpha1/zz_generated.deepcopy.go
  method DeepCopyInto (line 29) | func (in *Components) DeepCopyInto(out *Components) {
  method DeepCopy (line 37) | func (in *Components) DeepCopy() *Components {
  method DeepCopyInto (line 47) | func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
  method DeepCopy (line 67) | func (in *ContainerConfig) DeepCopy() *ContainerConfig {
  method DeepCopyInto (line 77) | func (in *EraserConfig) DeepCopyInto(out *EraserConfig) {
  method DeepCopy (line 85) | func (in *EraserConfig) DeepCopy() *EraserConfig {
  method DeepCopyObject (line 95) | func (in *EraserConfig) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 103) | func (in *Image) DeepCopyInto(out *Image) {
  method DeepCopy (line 118) | func (in *Image) DeepCopy() *Image {
  method DeepCopyInto (line 128) | func (in *ImageJob) DeepCopyInto(out *ImageJob) {
  method DeepCopy (line 136) | func (in *ImageJob) DeepCopy() *ImageJob {
  method DeepCopyObject (line 146) | func (in *ImageJob) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 154) | func (in *ImageJobCleanupConfig) DeepCopyInto(out *ImageJobCleanupConfig) {
  method DeepCopy (line 159) | func (in *ImageJobCleanupConfig) DeepCopy() *ImageJobCleanupConfig {
  method DeepCopyInto (line 169) | func (in *ImageJobConfig) DeepCopyInto(out *ImageJobConfig) {
  method DeepCopy (line 175) | func (in *ImageJobConfig) DeepCopy() *ImageJobConfig {
  method DeepCopyInto (line 185) | func (in *ImageJobList) DeepCopyInto(out *ImageJobList) {
  method DeepCopy (line 199) | func (in *ImageJobList) DeepCopy() *ImageJobList {
  method DeepCopyObject (line 209) | func (in *ImageJobList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 217) | func (in *ImageJobStatus) DeepCopyInto(out *ImageJobStatus) {
  method DeepCopy (line 226) | func (in *ImageJobStatus) DeepCopy() *ImageJobStatus {
  method DeepCopyInto (line 236) | func (in *ImageList) DeepCopyInto(out *ImageList) {
  method DeepCopy (line 245) | func (in *ImageList) DeepCopy() *ImageList {
  method DeepCopyObject (line 255) | func (in *ImageList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 263) | func (in *ImageListList) DeepCopyInto(out *ImageListList) {
  method DeepCopy (line 277) | func (in *ImageListList) DeepCopy() *ImageListList {
  method DeepCopyObject (line 287) | func (in *ImageListList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 295) | func (in *ImageListSpec) DeepCopyInto(out *ImageListSpec) {
  method DeepCopy (line 305) | func (in *ImageListSpec) DeepCopy() *ImageListSpec {
  method DeepCopyInto (line 315) | func (in *ImageListStatus) DeepCopyInto(out *ImageListStatus) {
  method DeepCopy (line 324) | func (in *ImageListStatus) DeepCopy() *ImageListStatus {
  method DeepCopyInto (line 334) | func (in *ManagerConfig) DeepCopyInto(out *ManagerConfig) {
  method DeepCopy (line 348) | func (in *ManagerConfig) DeepCopy() *ManagerConfig {
  method DeepCopyInto (line 358) | func (in *NodeFilterConfig) DeepCopyInto(out *NodeFilterConfig) {
  method DeepCopy (line 368) | func (in *NodeFilterConfig) DeepCopy() *NodeFilterConfig {
  method DeepCopyInto (line 378) | func (in *OptionalContainerConfig) DeepCopyInto(out *OptionalContainerCo...
  method DeepCopy (line 384) | func (in *OptionalContainerConfig) DeepCopy() *OptionalContainerConfig {
  method DeepCopyInto (line 394) | func (in *ProfileConfig) DeepCopyInto(out *ProfileConfig) {
  method DeepCopy (line 399) | func (in *ProfileConfig) DeepCopy() *ProfileConfig {
  method DeepCopyInto (line 409) | func (in *RepoTag) DeepCopyInto(out *RepoTag) {
  method DeepCopy (line 414) | func (in *RepoTag) DeepCopy() *RepoTag {
  method DeepCopyInto (line 424) | func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) {
  method DeepCopy (line 431) | func (in *ResourceRequirements) DeepCopy() *ResourceRequirements {
  method DeepCopyInto (line 441) | func (in *ScheduleConfig) DeepCopyInto(out *ScheduleConfig) {
  method DeepCopy (line 446) | func (in *ScheduleConfig) DeepCopy() *ScheduleConfig {

FILE: api/v1alpha2/config/config.go
  constant noDelay (line 32) | noDelay = v1alpha2.Duration(0)
  constant oneDay (line 33) | oneDay  = v1alpha2.Duration(time.Hour * 24)
  function Default (line 36) | func Default() *v1alpha2.EraserConfig {
  function repo (line 121) | func repo(basename string) string {

FILE: api/v1alpha2/custom_conversions.go
  function Convert_v1alpha2_ManagerConfig_To_unversioned_ManagerConfig (line 9) | func Convert_v1alpha2_ManagerConfig_To_unversioned_ManagerConfig(in *Man...
  function manualConvert_v1alpha2_Runtime_To_unversioned_RuntimeSpec (line 14) | func manualConvert_v1alpha2_Runtime_To_unversioned_RuntimeSpec(in *Runti...
  function Convert_v1alpha2_Runtime_To_unversioned_RuntimeSpec (line 27) | func Convert_v1alpha2_Runtime_To_unversioned_RuntimeSpec(in *Runtime, ou...
  function Convert_unversioned_ManagerConfig_To_v1alpha2_ManagerConfig (line 32) | func Convert_unversioned_ManagerConfig_To_v1alpha2_ManagerConfig(in *unv...
  function manualConvert_unversioned_RuntimeSpec_To_v1alpha2_Runtime (line 37) | func manualConvert_unversioned_RuntimeSpec_To_v1alpha2_Runtime(in *unver...
  function Convert_unversioned_RuntimeSpec_To_v1alpha2_Runtime (line 43) | func Convert_unversioned_RuntimeSpec_To_v1alpha2_Runtime(in *unversioned...

FILE: api/v1alpha2/eraserconfig_types.go
  type Duration (line 30) | type Duration
    method UnmarshalJSON (line 40) | func (td *Duration) UnmarshalJSON(b []byte) error {
    method MarshalJSON (line 73) | func (td *Duration) MarshalJSON() ([]byte, error) {
  type Runtime (line 31) | type Runtime
    method UnmarshalJSON (line 56) | func (r *Runtime) UnmarshalJSON(b []byte) error {
  constant RuntimeContainerd (line 35) | RuntimeContainerd Runtime = "containerd"
  constant RuntimeDockerShim (line 36) | RuntimeDockerShim Runtime = "dockershim"
  constant RuntimeCrio (line 37) | RuntimeCrio       Runtime = "crio"
  type OptionalContainerConfig (line 80) | type OptionalContainerConfig struct
  type ContainerConfig (line 85) | type ContainerConfig struct
  type ManagerConfig (line 93) | type ManagerConfig struct
  type ScheduleConfig (line 105) | type ScheduleConfig struct
  type ProfileConfig (line 110) | type ProfileConfig struct
  type ImageJobConfig (line 115) | type ImageJobConfig struct
  type ImageJobCleanupConfig (line 120) | type ImageJobCleanupConfig struct
  type NodeFilterConfig (line 125) | type NodeFilterConfig struct
  type ResourceRequirements (line 130) | type ResourceRequirements struct
  type RepoTag (line 135) | type RepoTag struct
  type Components (line 140) | type Components struct
  type EraserConfig (line 149) | type EraserConfig struct
  function init (line 155) | func init() {

FILE: api/v1alpha2/zz_generated.conversion.go
  function init (line 32) | func init() {
  function RegisterConversions (line 38) | func RegisterConversions(s *runtime.Scheme) error {
  function autoConvert_v1alpha2_Components_To_unversioned_Components (line 172) | func autoConvert_v1alpha2_Components_To_unversioned_Components(in *Compo...
  function Convert_v1alpha2_Components_To_unversioned_Components (line 186) | func Convert_v1alpha2_Components_To_unversioned_Components(in *Component...
  function autoConvert_unversioned_Components_To_v1alpha2_Components (line 190) | func autoConvert_unversioned_Components_To_v1alpha2_Components(in *unver...
  function Convert_unversioned_Components_To_v1alpha2_Components (line 204) | func Convert_unversioned_Components_To_v1alpha2_Components(in *unversion...
  function autoConvert_v1alpha2_ContainerConfig_To_unversioned_ContainerConfig (line 208) | func autoConvert_v1alpha2_ContainerConfig_To_unversioned_ContainerConfig...
  function Convert_v1alpha2_ContainerConfig_To_unversioned_ContainerConfig (line 224) | func Convert_v1alpha2_ContainerConfig_To_unversioned_ContainerConfig(in ...
  function autoConvert_unversioned_ContainerConfig_To_v1alpha2_ContainerConfig (line 228) | func autoConvert_unversioned_ContainerConfig_To_v1alpha2_ContainerConfig...
  function Convert_unversioned_ContainerConfig_To_v1alpha2_ContainerConfig (line 244) | func Convert_unversioned_ContainerConfig_To_v1alpha2_ContainerConfig(in ...
  function autoConvert_v1alpha2_EraserConfig_To_unversioned_EraserConfig (line 248) | func autoConvert_v1alpha2_EraserConfig_To_unversioned_EraserConfig(in *E...
  function Convert_v1alpha2_EraserConfig_To_unversioned_EraserConfig (line 259) | func Convert_v1alpha2_EraserConfig_To_unversioned_EraserConfig(in *Erase...
  function autoConvert_unversioned_EraserConfig_To_v1alpha2_EraserConfig (line 263) | func autoConvert_unversioned_EraserConfig_To_v1alpha2_EraserConfig(in *u...
  function Convert_unversioned_EraserConfig_To_v1alpha2_EraserConfig (line 274) | func Convert_unversioned_EraserConfig_To_v1alpha2_EraserConfig(in *unver...
  function autoConvert_v1alpha2_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 278) | func autoConvert_v1alpha2_ImageJobCleanupConfig_To_unversioned_ImageJobC...
  function Convert_v1alpha2_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 285) | func Convert_v1alpha2_ImageJobCleanupConfig_To_unversioned_ImageJobClean...
  function autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha2_ImageJobCleanupConfig (line 289) | func autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha2_ImageJobC...
  function Convert_unversioned_ImageJobCleanupConfig_To_v1alpha2_ImageJobCleanupConfig (line 296) | func Convert_unversioned_ImageJobCleanupConfig_To_v1alpha2_ImageJobClean...
  function autoConvert_v1alpha2_ImageJobConfig_To_unversioned_ImageJobConfig (line 300) | func autoConvert_v1alpha2_ImageJobConfig_To_unversioned_ImageJobConfig(i...
  function Convert_v1alpha2_ImageJobConfig_To_unversioned_ImageJobConfig (line 309) | func Convert_v1alpha2_ImageJobConfig_To_unversioned_ImageJobConfig(in *I...
  function autoConvert_unversioned_ImageJobConfig_To_v1alpha2_ImageJobConfig (line 313) | func autoConvert_unversioned_ImageJobConfig_To_v1alpha2_ImageJobConfig(i...
  function Convert_unversioned_ImageJobConfig_To_v1alpha2_ImageJobConfig (line 322) | func Convert_unversioned_ImageJobConfig_To_v1alpha2_ImageJobConfig(in *u...
  function autoConvert_v1alpha2_ManagerConfig_To_unversioned_ManagerConfig (line 326) | func autoConvert_v1alpha2_ManagerConfig_To_unversioned_ManagerConfig(in ...
  function autoConvert_unversioned_ManagerConfig_To_v1alpha2_ManagerConfig (line 349) | func autoConvert_unversioned_ManagerConfig_To_v1alpha2_ManagerConfig(in ...
  function autoConvert_v1alpha2_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 373) | func autoConvert_v1alpha2_NodeFilterConfig_To_unversioned_NodeFilterConf...
  function Convert_v1alpha2_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 380) | func Convert_v1alpha2_NodeFilterConfig_To_unversioned_NodeFilterConfig(i...
  function autoConvert_unversioned_NodeFilterConfig_To_v1alpha2_NodeFilterConfig (line 384) | func autoConvert_unversioned_NodeFilterConfig_To_v1alpha2_NodeFilterConf...
  function Convert_unversioned_NodeFilterConfig_To_v1alpha2_NodeFilterConfig (line 391) | func Convert_unversioned_NodeFilterConfig_To_v1alpha2_NodeFilterConfig(i...
  function autoConvert_v1alpha2_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 395) | func autoConvert_v1alpha2_OptionalContainerConfig_To_unversioned_Optiona...
  function Convert_v1alpha2_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 404) | func Convert_v1alpha2_OptionalContainerConfig_To_unversioned_OptionalCon...
  function autoConvert_unversioned_OptionalContainerConfig_To_v1alpha2_OptionalContainerConfig (line 408) | func autoConvert_unversioned_OptionalContainerConfig_To_v1alpha2_Optiona...
  function Convert_unversioned_OptionalContainerConfig_To_v1alpha2_OptionalContainerConfig (line 417) | func Convert_unversioned_OptionalContainerConfig_To_v1alpha2_OptionalCon...
  function autoConvert_v1alpha2_ProfileConfig_To_unversioned_ProfileConfig (line 421) | func autoConvert_v1alpha2_ProfileConfig_To_unversioned_ProfileConfig(in ...
  function Convert_v1alpha2_ProfileConfig_To_unversioned_ProfileConfig (line 428) | func Convert_v1alpha2_ProfileConfig_To_unversioned_ProfileConfig(in *Pro...
  function autoConvert_unversioned_ProfileConfig_To_v1alpha2_ProfileConfig (line 432) | func autoConvert_unversioned_ProfileConfig_To_v1alpha2_ProfileConfig(in ...
  function Convert_unversioned_ProfileConfig_To_v1alpha2_ProfileConfig (line 439) | func Convert_unversioned_ProfileConfig_To_v1alpha2_ProfileConfig(in *unv...
  function autoConvert_v1alpha2_RepoTag_To_unversioned_RepoTag (line 443) | func autoConvert_v1alpha2_RepoTag_To_unversioned_RepoTag(in *RepoTag, ou...
  function Convert_v1alpha2_RepoTag_To_unversioned_RepoTag (line 450) | func Convert_v1alpha2_RepoTag_To_unversioned_RepoTag(in *RepoTag, out *u...
  function autoConvert_unversioned_RepoTag_To_v1alpha2_RepoTag (line 454) | func autoConvert_unversioned_RepoTag_To_v1alpha2_RepoTag(in *unversioned...
  function Convert_unversioned_RepoTag_To_v1alpha2_RepoTag (line 461) | func Convert_unversioned_RepoTag_To_v1alpha2_RepoTag(in *unversioned.Rep...
  function autoConvert_v1alpha2_ResourceRequirements_To_unversioned_ResourceRequirements (line 465) | func autoConvert_v1alpha2_ResourceRequirements_To_unversioned_ResourceRe...
  function Convert_v1alpha2_ResourceRequirements_To_unversioned_ResourceRequirements (line 472) | func Convert_v1alpha2_ResourceRequirements_To_unversioned_ResourceRequir...
  function autoConvert_unversioned_ResourceRequirements_To_v1alpha2_ResourceRequirements (line 476) | func autoConvert_unversioned_ResourceRequirements_To_v1alpha2_ResourceRe...
  function Convert_unversioned_ResourceRequirements_To_v1alpha2_ResourceRequirements (line 483) | func Convert_unversioned_ResourceRequirements_To_v1alpha2_ResourceRequir...
  function autoConvert_v1alpha2_ScheduleConfig_To_unversioned_ScheduleConfig (line 487) | func autoConvert_v1alpha2_ScheduleConfig_To_unversioned_ScheduleConfig(i...
  function Convert_v1alpha2_ScheduleConfig_To_unversioned_ScheduleConfig (line 494) | func Convert_v1alpha2_ScheduleConfig_To_unversioned_ScheduleConfig(in *S...
  function autoConvert_unversioned_ScheduleConfig_To_v1alpha2_ScheduleConfig (line 498) | func autoConvert_unversioned_ScheduleConfig_To_v1alpha2_ScheduleConfig(i...
  function Convert_unversioned_ScheduleConfig_To_v1alpha2_ScheduleConfig (line 505) | func Convert_unversioned_ScheduleConfig_To_v1alpha2_ScheduleConfig(in *u...

FILE: api/v1alpha2/zz_generated.deepcopy.go
  method DeepCopyInto (line 29) | func (in *Components) DeepCopyInto(out *Components) {
  method DeepCopy (line 37) | func (in *Components) DeepCopy() *Components {
  method DeepCopyInto (line 47) | func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
  method DeepCopy (line 67) | func (in *ContainerConfig) DeepCopy() *ContainerConfig {
  method DeepCopyInto (line 77) | func (in *EraserConfig) DeepCopyInto(out *EraserConfig) {
  method DeepCopy (line 85) | func (in *EraserConfig) DeepCopy() *EraserConfig {
  method DeepCopyObject (line 95) | func (in *EraserConfig) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 103) | func (in *ImageJobCleanupConfig) DeepCopyInto(out *ImageJobCleanupConfig) {
  method DeepCopy (line 108) | func (in *ImageJobCleanupConfig) DeepCopy() *ImageJobCleanupConfig {
  method DeepCopyInto (line 118) | func (in *ImageJobConfig) DeepCopyInto(out *ImageJobConfig) {
  method DeepCopy (line 124) | func (in *ImageJobConfig) DeepCopy() *ImageJobConfig {
  method DeepCopyInto (line 134) | func (in *ManagerConfig) DeepCopyInto(out *ManagerConfig) {
  method DeepCopy (line 148) | func (in *ManagerConfig) DeepCopy() *ManagerConfig {
  method DeepCopyInto (line 158) | func (in *NodeFilterConfig) DeepCopyInto(out *NodeFilterConfig) {
  method DeepCopy (line 168) | func (in *NodeFilterConfig) DeepCopy() *NodeFilterConfig {
  method DeepCopyInto (line 178) | func (in *OptionalContainerConfig) DeepCopyInto(out *OptionalContainerCo...
  method DeepCopy (line 184) | func (in *OptionalContainerConfig) DeepCopy() *OptionalContainerConfig {
  method DeepCopyInto (line 194) | func (in *ProfileConfig) DeepCopyInto(out *ProfileConfig) {
  method DeepCopy (line 199) | func (in *ProfileConfig) DeepCopy() *ProfileConfig {
  method DeepCopyInto (line 209) | func (in *RepoTag) DeepCopyInto(out *RepoTag) {
  method DeepCopy (line 214) | func (in *RepoTag) DeepCopy() *RepoTag {
  method DeepCopyInto (line 224) | func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) {
  method DeepCopy (line 231) | func (in *ResourceRequirements) DeepCopy() *ResourceRequirements {
  method DeepCopyInto (line 241) | func (in *ScheduleConfig) DeepCopyInto(out *ScheduleConfig) {
  method DeepCopy (line 246) | func (in *ScheduleConfig) DeepCopy() *ScheduleConfig {

FILE: api/v1alpha3/config/config.go
  constant noDelay (line 32) | noDelay = v1alpha3.Duration(0)
  constant oneDay (line 33) | oneDay  = v1alpha3.Duration(time.Hour * 24)
  function Default (line 36) | func Default() *v1alpha3.EraserConfig {
  function repo (line 125) | func repo(basename string) string {

FILE: api/v1alpha3/eraserconfig_types.go
  type Duration (line 31) | type Duration
    method UnmarshalJSON (line 68) | func (td *Duration) UnmarshalJSON(b []byte) error {
    method MarshalJSON (line 84) | func (td *Duration) MarshalJSON() ([]byte, error) {
  type Runtime (line 32) | type Runtime
  type RuntimeSpec (line 34) | type RuntimeSpec struct
    method UnmarshalJSON (line 88) | func (r *RuntimeSpec) UnmarshalJSON(b []byte) error {
  constant RuntimeContainerd (line 41) | RuntimeContainerd  Runtime = "containerd"
  constant RuntimeDockerShim (line 42) | RuntimeDockerShim  Runtime = "dockershim"
  constant RuntimeCrio (line 43) | RuntimeCrio        Runtime = "crio"
  constant RuntimeNotProvided (line 44) | RuntimeNotProvided Runtime = ""
  constant ContainerdPath (line 46) | ContainerdPath = "/run/containerd/containerd.sock"
  constant DockerPath (line 47) | DockerPath     = "/run/dockershim.sock"
  constant CrioPath (line 48) | CrioPath       = "/run/crio/crio.sock"
  function ConvertRuntimeToRuntimeSpec (line 51) | func ConvertRuntimeToRuntimeSpec(r Runtime) (RuntimeSpec, error) {
  type OptionalContainerConfig (line 147) | type OptionalContainerConfig struct
  type ContainerConfig (line 152) | type ContainerConfig struct
  type ManagerConfig (line 160) | type ManagerConfig struct
  type ScheduleConfig (line 173) | type ScheduleConfig struct
  type ProfileConfig (line 178) | type ProfileConfig struct
  type ImageJobConfig (line 183) | type ImageJobConfig struct
  type ImageJobCleanupConfig (line 188) | type ImageJobCleanupConfig struct
  type NodeFilterConfig (line 193) | type NodeFilterConfig struct
  type ResourceRequirements (line 198) | type ResourceRequirements struct
  type RepoTag (line 203) | type RepoTag struct
  type Components (line 208) | type Components struct
  type EraserConfig (line 217) | type EraserConfig struct
  function init (line 223) | func init() {

FILE: api/v1alpha3/runtime_spec_test.go
  function TestConvertRuntimeToRuntimeSpec (line 9) | func TestConvertRuntimeToRuntimeSpec(t *testing.T) {
  function TestUnmarshalJSON (line 58) | func TestUnmarshalJSON(t *testing.T) {

FILE: api/v1alpha3/zz_generated.conversion.go
  function init (line 32) | func init() {
  function RegisterConversions (line 38) | func RegisterConversions(s *runtime.Scheme) error {
  function autoConvert_v1alpha3_Components_To_unversioned_Components (line 172) | func autoConvert_v1alpha3_Components_To_unversioned_Components(in *Compo...
  function Convert_v1alpha3_Components_To_unversioned_Components (line 186) | func Convert_v1alpha3_Components_To_unversioned_Components(in *Component...
  function autoConvert_unversioned_Components_To_v1alpha3_Components (line 190) | func autoConvert_unversioned_Components_To_v1alpha3_Components(in *unver...
  function Convert_unversioned_Components_To_v1alpha3_Components (line 204) | func Convert_unversioned_Components_To_v1alpha3_Components(in *unversion...
  function autoConvert_v1alpha3_ContainerConfig_To_unversioned_ContainerConfig (line 208) | func autoConvert_v1alpha3_ContainerConfig_To_unversioned_ContainerConfig...
  function Convert_v1alpha3_ContainerConfig_To_unversioned_ContainerConfig (line 224) | func Convert_v1alpha3_ContainerConfig_To_unversioned_ContainerConfig(in ...
  function autoConvert_unversioned_ContainerConfig_To_v1alpha3_ContainerConfig (line 228) | func autoConvert_unversioned_ContainerConfig_To_v1alpha3_ContainerConfig...
  function Convert_unversioned_ContainerConfig_To_v1alpha3_ContainerConfig (line 244) | func Convert_unversioned_ContainerConfig_To_v1alpha3_ContainerConfig(in ...
  function autoConvert_v1alpha3_EraserConfig_To_unversioned_EraserConfig (line 248) | func autoConvert_v1alpha3_EraserConfig_To_unversioned_EraserConfig(in *E...
  function Convert_v1alpha3_EraserConfig_To_unversioned_EraserConfig (line 259) | func Convert_v1alpha3_EraserConfig_To_unversioned_EraserConfig(in *Erase...
  function autoConvert_unversioned_EraserConfig_To_v1alpha3_EraserConfig (line 263) | func autoConvert_unversioned_EraserConfig_To_v1alpha3_EraserConfig(in *u...
  function Convert_unversioned_EraserConfig_To_v1alpha3_EraserConfig (line 274) | func Convert_unversioned_EraserConfig_To_v1alpha3_EraserConfig(in *unver...
  function autoConvert_v1alpha3_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 278) | func autoConvert_v1alpha3_ImageJobCleanupConfig_To_unversioned_ImageJobC...
  function Convert_v1alpha3_ImageJobCleanupConfig_To_unversioned_ImageJobCleanupConfig (line 285) | func Convert_v1alpha3_ImageJobCleanupConfig_To_unversioned_ImageJobClean...
  function autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha3_ImageJobCleanupConfig (line 289) | func autoConvert_unversioned_ImageJobCleanupConfig_To_v1alpha3_ImageJobC...
  function Convert_unversioned_ImageJobCleanupConfig_To_v1alpha3_ImageJobCleanupConfig (line 296) | func Convert_unversioned_ImageJobCleanupConfig_To_v1alpha3_ImageJobClean...
  function autoConvert_v1alpha3_ImageJobConfig_To_unversioned_ImageJobConfig (line 300) | func autoConvert_v1alpha3_ImageJobConfig_To_unversioned_ImageJobConfig(i...
  function Convert_v1alpha3_ImageJobConfig_To_unversioned_ImageJobConfig (line 309) | func Convert_v1alpha3_ImageJobConfig_To_unversioned_ImageJobConfig(in *I...
  function autoConvert_unversioned_ImageJobConfig_To_v1alpha3_ImageJobConfig (line 313) | func autoConvert_unversioned_ImageJobConfig_To_v1alpha3_ImageJobConfig(i...
  function Convert_unversioned_ImageJobConfig_To_v1alpha3_ImageJobConfig (line 322) | func Convert_unversioned_ImageJobConfig_To_v1alpha3_ImageJobConfig(in *u...
  function autoConvert_v1alpha3_ManagerConfig_To_unversioned_ManagerConfig (line 326) | func autoConvert_v1alpha3_ManagerConfig_To_unversioned_ManagerConfig(in ...
  function Convert_v1alpha3_ManagerConfig_To_unversioned_ManagerConfig (line 351) | func Convert_v1alpha3_ManagerConfig_To_unversioned_ManagerConfig(in *Man...
  function autoConvert_unversioned_ManagerConfig_To_v1alpha3_ManagerConfig (line 355) | func autoConvert_unversioned_ManagerConfig_To_v1alpha3_ManagerConfig(in ...
  function Convert_unversioned_ManagerConfig_To_v1alpha3_ManagerConfig (line 380) | func Convert_unversioned_ManagerConfig_To_v1alpha3_ManagerConfig(in *unv...
  function autoConvert_v1alpha3_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 384) | func autoConvert_v1alpha3_NodeFilterConfig_To_unversioned_NodeFilterConf...
  function Convert_v1alpha3_NodeFilterConfig_To_unversioned_NodeFilterConfig (line 391) | func Convert_v1alpha3_NodeFilterConfig_To_unversioned_NodeFilterConfig(i...
  function autoConvert_unversioned_NodeFilterConfig_To_v1alpha3_NodeFilterConfig (line 395) | func autoConvert_unversioned_NodeFilterConfig_To_v1alpha3_NodeFilterConf...
  function Convert_unversioned_NodeFilterConfig_To_v1alpha3_NodeFilterConfig (line 402) | func Convert_unversioned_NodeFilterConfig_To_v1alpha3_NodeFilterConfig(i...
  function autoConvert_v1alpha3_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 406) | func autoConvert_v1alpha3_OptionalContainerConfig_To_unversioned_Optiona...
  function Convert_v1alpha3_OptionalContainerConfig_To_unversioned_OptionalContainerConfig (line 415) | func Convert_v1alpha3_OptionalContainerConfig_To_unversioned_OptionalCon...
  function autoConvert_unversioned_OptionalContainerConfig_To_v1alpha3_OptionalContainerConfig (line 419) | func autoConvert_unversioned_OptionalContainerConfig_To_v1alpha3_Optiona...
  function Convert_unversioned_OptionalContainerConfig_To_v1alpha3_OptionalContainerConfig (line 428) | func Convert_unversioned_OptionalContainerConfig_To_v1alpha3_OptionalCon...
  function autoConvert_v1alpha3_ProfileConfig_To_unversioned_ProfileConfig (line 432) | func autoConvert_v1alpha3_ProfileConfig_To_unversioned_ProfileConfig(in ...
  function Convert_v1alpha3_ProfileConfig_To_unversioned_ProfileConfig (line 439) | func Convert_v1alpha3_ProfileConfig_To_unversioned_ProfileConfig(in *Pro...
  function autoConvert_unversioned_ProfileConfig_To_v1alpha3_ProfileConfig (line 443) | func autoConvert_unversioned_ProfileConfig_To_v1alpha3_ProfileConfig(in ...
  function Convert_unversioned_ProfileConfig_To_v1alpha3_ProfileConfig (line 450) | func Convert_unversioned_ProfileConfig_To_v1alpha3_ProfileConfig(in *unv...
  function autoConvert_v1alpha3_RepoTag_To_unversioned_RepoTag (line 454) | func autoConvert_v1alpha3_RepoTag_To_unversioned_RepoTag(in *RepoTag, ou...
  function Convert_v1alpha3_RepoTag_To_unversioned_RepoTag (line 461) | func Convert_v1alpha3_RepoTag_To_unversioned_RepoTag(in *RepoTag, out *u...
  function autoConvert_unversioned_RepoTag_To_v1alpha3_RepoTag (line 465) | func autoConvert_unversioned_RepoTag_To_v1alpha3_RepoTag(in *unversioned...
  function Convert_unversioned_RepoTag_To_v1alpha3_RepoTag (line 472) | func Convert_unversioned_RepoTag_To_v1alpha3_RepoTag(in *unversioned.Rep...
  function autoConvert_v1alpha3_ResourceRequirements_To_unversioned_ResourceRequirements (line 476) | func autoConvert_v1alpha3_ResourceRequirements_To_unversioned_ResourceRe...
  function Convert_v1alpha3_ResourceRequirements_To_unversioned_ResourceRequirements (line 483) | func Convert_v1alpha3_ResourceRequirements_To_unversioned_ResourceRequir...
  function autoConvert_unversioned_ResourceRequirements_To_v1alpha3_ResourceRequirements (line 487) | func autoConvert_unversioned_ResourceRequirements_To_v1alpha3_ResourceRe...
  function Convert_unversioned_ResourceRequirements_To_v1alpha3_ResourceRequirements (line 494) | func Convert_unversioned_ResourceRequirements_To_v1alpha3_ResourceRequir...
  function autoConvert_v1alpha3_RuntimeSpec_To_unversioned_RuntimeSpec (line 498) | func autoConvert_v1alpha3_RuntimeSpec_To_unversioned_RuntimeSpec(in *Run...
  function Convert_v1alpha3_RuntimeSpec_To_unversioned_RuntimeSpec (line 505) | func Convert_v1alpha3_RuntimeSpec_To_unversioned_RuntimeSpec(in *Runtime...
  function autoConvert_unversioned_RuntimeSpec_To_v1alpha3_RuntimeSpec (line 509) | func autoConvert_unversioned_RuntimeSpec_To_v1alpha3_RuntimeSpec(in *unv...
  function Convert_unversioned_RuntimeSpec_To_v1alpha3_RuntimeSpec (line 516) | func Convert_unversioned_RuntimeSpec_To_v1alpha3_RuntimeSpec(in *unversi...
  function autoConvert_v1alpha3_ScheduleConfig_To_unversioned_ScheduleConfig (line 520) | func autoConvert_v1alpha3_ScheduleConfig_To_unversioned_ScheduleConfig(i...
  function Convert_v1alpha3_ScheduleConfig_To_unversioned_ScheduleConfig (line 527) | func Convert_v1alpha3_ScheduleConfig_To_unversioned_ScheduleConfig(in *S...
  function autoConvert_unversioned_ScheduleConfig_To_v1alpha3_ScheduleConfig (line 531) | func autoConvert_unversioned_ScheduleConfig_To_v1alpha3_ScheduleConfig(i...
  function Convert_unversioned_ScheduleConfig_To_v1alpha3_ScheduleConfig (line 538) | func Convert_unversioned_ScheduleConfig_To_v1alpha3_ScheduleConfig(in *u...

FILE: api/v1alpha3/zz_generated.deepcopy.go
  method DeepCopyInto (line 29) | func (in *Components) DeepCopyInto(out *Components) {
  method DeepCopy (line 37) | func (in *Components) DeepCopy() *Components {
  method DeepCopyInto (line 47) | func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) {
  method DeepCopy (line 67) | func (in *ContainerConfig) DeepCopy() *ContainerConfig {
  method DeepCopyInto (line 77) | func (in *EraserConfig) DeepCopyInto(out *EraserConfig) {
  method DeepCopy (line 85) | func (in *EraserConfig) DeepCopy() *EraserConfig {
  method DeepCopyObject (line 95) | func (in *EraserConfig) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 103) | func (in *ImageJobCleanupConfig) DeepCopyInto(out *ImageJobCleanupConfig) {
  method DeepCopy (line 108) | func (in *ImageJobCleanupConfig) DeepCopy() *ImageJobCleanupConfig {
  method DeepCopyInto (line 118) | func (in *ImageJobConfig) DeepCopyInto(out *ImageJobConfig) {
  method DeepCopy (line 124) | func (in *ImageJobConfig) DeepCopy() *ImageJobConfig {
  method DeepCopyInto (line 134) | func (in *ManagerConfig) DeepCopyInto(out *ManagerConfig) {
  method DeepCopy (line 156) | func (in *ManagerConfig) DeepCopy() *ManagerConfig {
  method DeepCopyInto (line 166) | func (in *NodeFilterConfig) DeepCopyInto(out *NodeFilterConfig) {
  method DeepCopy (line 176) | func (in *NodeFilterConfig) DeepCopy() *NodeFilterConfig {
  method DeepCopyInto (line 186) | func (in *OptionalContainerConfig) DeepCopyInto(out *OptionalContainerCo...
  method DeepCopy (line 192) | func (in *OptionalContainerConfig) DeepCopy() *OptionalContainerConfig {
  method DeepCopyInto (line 202) | func (in *ProfileConfig) DeepCopyInto(out *ProfileConfig) {
  method DeepCopy (line 207) | func (in *ProfileConfig) DeepCopy() *ProfileConfig {
  method DeepCopyInto (line 217) | func (in *RepoTag) DeepCopyInto(out *RepoTag) {
  method DeepCopy (line 222) | func (in *RepoTag) DeepCopy() *RepoTag {
  method DeepCopyInto (line 232) | func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) {
  method DeepCopy (line 239) | func (in *ResourceRequirements) DeepCopy() *ResourceRequirements {
  method DeepCopyInto (line 249) | func (in *RuntimeSpec) DeepCopyInto(out *RuntimeSpec) {
  method DeepCopy (line 254) | func (in *RuntimeSpec) DeepCopy() *RuntimeSpec {
  method DeepCopyInto (line 264) | func (in *ScheduleConfig) DeepCopyInto(out *ScheduleConfig) {
  method DeepCopy (line 269) | func (in *ScheduleConfig) DeepCopy() *ScheduleConfig {

FILE: controllers/configmap/configmap.go
  type Reconciler (line 46) | type Reconciler struct
    method Reconcile (line 120) | func (r *Reconciler) Reconcile(ctx context.Context, _ ctrl.Request) (c...
  function Add (line 52) | func Add(mgr manager.Manager, cfg *config.Manager) error {
  function newReconciler (line 94) | func newReconciler(mgr manager.Manager, cfg *config.Manager) (reconcile....

FILE: controllers/controller.go
  type controllerSetupFunc (line 17) | type controllerSetupFunc
  function SetupWithManager (line 30) | func SetupWithManager(m manager.Manager, cfg *config.Manager) error {

FILE: controllers/imagecollector/imagecollector_controller.go
  constant ownerLabelValue (line 60) | ownerLabelValue  = "imagecollector"
  constant configVolumeName (line 61) | configVolumeName = "eraser-config"
  function init (line 73) | func init() {
  type Reconciler (line 84) | type Reconciler struct
    method Reconcile (line 216) | func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) ...
    method handleJobDeletion (line 249) | func (r *Reconciler) handleJobDeletion(ctx context.Context, job *erase...
    method createImageJob (line 282) | func (r *Reconciler) createImageJob(ctx context.Context) (ctrl.Result,...
    method handleCompletedImageJob (line 531) | func (r *Reconciler) handleCompletedImageJob(ctx context.Context, chil...
  function Add (line 90) | func Add(mgr manager.Manager, cfg *config.Manager) error {
  function newReconciler (line 111) | func newReconciler(mgr manager.Manager, cfg *config.Manager) (*Reconcile...
  function add (line 135) | func add(mgr manager.Manager, r *Reconciler) error {

FILE: controllers/imagejob/imagejob_controller.go
  constant defaultFilterLabel (line 51) | defaultFilterLabel   = "eraser.sh/cleanup.filter"
  constant windowsFilterLabel (line 52) | windowsFilterLabel   = "kubernetes.io/os=windows"
  constant imageJobTypeLabelKey (line 53) | imageJobTypeLabelKey = "eraser.sh/type"
  constant collectorJobType (line 54) | collectorJobType     = "collector"
  constant manualJobType (line 55) | manualJobType        = "manual"
  constant removerContainer (line 56) | removerContainer     = "remover"
  constant managerLabelValue (line 57) | managerLabelValue    = "controller-manager"
  constant managerLabelKey (line 58) | managerLabelKey      = "control-plane"
  function Add (line 69) | func Add(mgr manager.Manager, cfg *config.Manager) error {
  function newReconciler (line 74) | func newReconciler(mgr manager.Manager, cfg *config.Manager) reconcile.R...
  type Reconciler (line 85) | type Reconciler struct
    method Reconcile (line 178) | func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) ...
    method handleRunningJob (line 221) | func (r *Reconciler) handleRunningJob(ctx context.Context, imageJob *e...
    method handleNewJob (line 294) | func (r *Reconciler) handleNewJob(ctx context.Context, imageJob *erase...
    method isPodReady (line 416) | func (r *Reconciler) isPodReady(ctx context.Context, namespacedName ty...
    method SetupWithManager (line 429) | func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
    method updateJobStatus (line 455) | func (r *Reconciler) updateJobStatus(ctx context.Context, imageJob *er...
  function add (line 92) | func add(mgr manager.Manager, r reconcile.Reconciler) error {
  function podListOptions (line 206) | func podListOptions(jobTemplate *corev1.PodTemplate) client.ListOptions {
  function podsComplete (line 436) | func podsComplete(podList []corev1.Pod) bool {
  function containersFailed (line 445) | func containersFailed(pod *corev1.Pod) bool {
  function selectIncludedNodes (line 464) | func selectIncludedNodes(nodes *corev1.NodeList, includeNodesSelectors [...
  function filterOutSkippedNodes (line 498) | func filterOutSkippedNodes(nodes *corev1.NodeList, skipNodesSelectors []...
  function copyAndFillTemplateSpec (line 533) | func copyAndFillTemplateSpec(templateSpecTemplate *corev1.PodSpec, env [...

FILE: controllers/imagelist/imagelist_controller.go
  constant imgListPath (line 55) | imgListPath     = "/run/eraser.sh/imagelist"
  constant ownerLabelValue (line 56) | ownerLabelValue = "imagelist-controller"
  function init (line 69) | func init() {
  function Add (line 78) | func Add(mgr manager.Manager, cfg *config.Manager) error {
  function newReconciler (line 88) | func newReconciler(mgr manager.Manager, cfg *config.Manager) (reconcile....
  type ImageJobReconciler (line 113) | type ImageJobReconciler struct
  type Reconciler (line 118) | type Reconciler struct
    method Reconcile (line 139) | func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) ...
    method handleJobListEvent (line 179) | func (r *Reconciler) handleJobListEvent(ctx context.Context, imageList...
    method handleJobDeletion (line 225) | func (r *Reconciler) handleJobDeletion(ctx context.Context, job *erase...
    method handleImageListEvent (line 257) | func (r *Reconciler) handleImageListEvent(ctx context.Context, imageLi...
    method handleJobCompletion (line 420) | func (r *Reconciler) handleJobCompletion(ctx context.Context, imageLis...
  function add (line 436) | func add(mgr manager.Manager, r reconcile.Reconciler) error {

FILE: controllers/suite_test.go
  function TestAPIs (line 43) | func TestAPIs(t *testing.T) {

FILE: controllers/util/util.go
  function init (line 22) | func init() {
  constant ImageJobOwnerLabelKey (line 29) | ImageJobOwnerLabelKey = "eraser.sh/job-owner"
  constant exclusionLabel (line 31) | exclusionLabel = "eraser.sh/exclude.list=true"
  constant EnvVarContainerdNamespaceKey (line 33) | EnvVarContainerdNamespaceKey   = "CONTAINERD_NAMESPACE"
  constant EnvVarContainerdNamespaceValue (line 34) | EnvVarContainerdNamespaceValue = "k8s.io"
  constant CRIPath (line 35) | CRIPath                        = "/run/cri/cri.sock"
  function NeverOnCreate (line 38) | func NeverOnCreate(_ event.CreateEvent) bool {
  function NeverOnDelete (line 42) | func NeverOnDelete(_ event.DeleteEvent) bool {
  function NeverOnGeneric (line 46) | func NeverOnGeneric(_ event.GenericEvent) bool {
  function NeverOnUpdate (line 50) | func NeverOnUpdate(_ event.UpdateEvent) bool {
  function AlwaysOnCreate (line 54) | func AlwaysOnCreate(_ event.CreateEvent) bool {
  function AlwaysOnDelete (line 58) | func AlwaysOnDelete(_ event.DeleteEvent) bool {
  function AlwaysOnGeneric (line 62) | func AlwaysOnGeneric(_ event.GenericEvent) bool {
  function AlwaysOnUpdate (line 66) | func AlwaysOnUpdate(_ event.UpdateEvent) bool {
  function IsCompletedOrFailed (line 70) | func IsCompletedOrFailed(p eraserv1.JobPhase) bool {
  function FilterJobListByOwner (line 74) | func FilterJobListByOwner(jobs []eraserv1.ImageJob, owner *metav1.OwnerR...
  function FilterBatchJobListByOwner (line 93) | func FilterBatchJobListByOwner(jobs []batchv1.Job, owner *metav1.OwnerRe...
  function After (line 112) | func After(t time.Time, seconds int64) *metav1.Time {
  function GetExclusionVolume (line 117) | func GetExclusionVolume(configmapList *corev1.ConfigMapList) ([]corev1.V...

FILE: main.go
  function init (line 73) | func init() {
  type apiVersion (line 81) | type apiVersion struct
  type convertFunc (line 85) | type convertFunc
  function main (line 87) | func main() {
  function getConfig (line 211) | func getConfig(configFile string) (*unversioned.EraserConfig, error) {
  function getUnversioned (line 238) | func getUnversioned[T any](b []byte, defaults *T, convert convertFunc[T]...
  function setupWatcher (line 259) | func setupWatcher(configFile string) (*inotify.Watcher, error) {
  function startConfigWatch (line 272) | func startConfigWatch(cancel context.CancelFunc, watcher *inotify.Watche...
  function needsRestart (line 331) | func needsRestart(oldConfig, newConfig *unversioned.EraserConfig) bool {

FILE: pkg/collector/collector.go
  function main (line 32) | func main() {

FILE: pkg/collector/helpers.go
  function getImages (line 11) | func getImages(c cri.Collector) ([]unversioned.Image, error) {

FILE: pkg/cri/client.go
  constant RuntimeV1 (line 14) | RuntimeV1       runtimeVersion = "v1"
  constant RuntimeV1Alpha2 (line 15) | RuntimeV1Alpha2 runtimeVersion = "v1alpha2"
  type Collector (line 19) | type Collector interface
  type Remover (line 24) | type Remover interface
  type runtimeTryFunc (line 29) | type runtimeTryFunc
  function NewCollectorClient (line 32) | func NewCollectorClient(socketPath string) (Collector, error) {
  function NewRemoverClient (line 36) | func NewRemoverClient(socketPath string) (Remover, error) {
  function newClientWithFallback (line 47) | func newClientWithFallback(ctx context.Context, conn *grpc.ClientConn) (...
  function tryV1Alpha2 (line 70) | func tryV1Alpha2(ctx context.Context, conn *grpc.ClientConn) (string, er...
  function tryV1 (line 82) | func tryV1(ctx context.Context, conn *grpc.ClientConn) (string, error) {
  function getClientFromRuntimeVersion (line 94) | func getClientFromRuntimeVersion(conn *grpc.ClientConn, runtimeAPIVersio...

FILE: pkg/cri/client_v1.go
  type v1Client (line 12) | type v1Client struct
    method ListContainers (line 18) | func (c *v1Client) ListContainers(ctx context.Context) (list []*v1.Con...
    method ListImages (line 26) | func (c *v1Client) ListImages(ctx context.Context) (list []*v1.Image, ...
    method DeleteImage (line 37) | func (c *v1Client) DeleteImage(ctx context.Context, image string) (err...

FILE: pkg/cri/client_v1alpha2.go
  type v1alpha2Client (line 13) | type v1alpha2Client struct
    method ListContainers (line 19) | func (c *v1alpha2Client) ListContainers(ctx context.Context) (list []*...
    method ListImages (line 27) | func (c *v1alpha2Client) ListImages(ctx context.Context) (list []*v1.I...
    method DeleteImage (line 38) | func (c *v1alpha2Client) DeleteImage(ctx context.Context, image string...
  function convertContainers (line 56) | func convertContainers(list []*v1alpha2.Container) []*v1.Container {
  function convertImages (line 66) | func convertImages(list []*v1alpha2.Image) []*v1.Image {
  function convertContainer (line 76) | func convertContainer(c *v1alpha2.Container) *v1.Container {
  function convertImage (line 108) | func convertImage(i *v1alpha2.Image) *v1.Image {

FILE: pkg/cri/util.go
  type runtimeVersion (line 8) | type runtimeVersion
  type errors (line 10) | type errors
    method Error (line 13) | func (errs errors) Error() string {
    method Append (line 22) | func (errs *errors) Append(err error) {

FILE: pkg/logger/zap.go
  function GetLevel (line 23) | func GetLevel() string {
  function Configure (line 28) | func Configure() error {

FILE: pkg/metrics/metrics.go
  constant ImagesRemovedCounter (line 17) | ImagesRemovedCounter     = "images_removed_run_total"
  constant ImagesRemovedDescription (line 18) | ImagesRemovedDescription = "total images removed"
  function ConfigureMetrics (line 21) | func ConfigureMetrics(ctx context.Context, log logr.Logger, endpoint str...
  function ExportMetrics (line 50) | func ExportMetrics(log logr.Logger, exporter sdkmetric.Exporter, reader ...
  function RecordMetricsRemover (line 64) | func RecordMetricsRemover(ctx context.Context, p metric.MeterProvider, t...
  function RecordMetricsScanner (line 74) | func RecordMetricsScanner(ctx context.Context, p metric.MeterProvider, t...
  function RecordMetricsController (line 84) | func RecordMetricsController(ctx context.Context, p metric.MeterProvider...

FILE: pkg/metrics/metrics_test.go
  function TestConfigureMetrics (line 16) | func TestConfigureMetrics(t *testing.T) {
  function TestRecordMetrics (line 31) | func TestRecordMetrics(t *testing.T) {
  function TestMeterCreatesInstrument (line 45) | func TestMeterCreatesInstrument(t *testing.T) {

FILE: pkg/scanners/template/scanner_template.go
  type ImageProvider (line 21) | type ImageProvider interface
  type config (line 32) | type config struct
    method ReceiveImages (line 59) | func (cfg *config) ReceiveImages() ([]unversioned.Image, error) {
    method SendImages (line 82) | func (cfg *config) SendImages(nonCompliantImages, failedImages []unver...
    method Finish (line 109) | func (cfg *config) Finish() error {
  type ConfigFunc (line 40) | type ConfigFunc
  function NewImageProvider (line 42) | func NewImageProvider(funcs ...ConfigFunc) ImageProvider {
  function WithContext (line 137) | func WithContext(ctx context.Context) ConfigFunc {
  function WithDeleteScanFailedImages (line 144) | func WithDeleteScanFailedImages(deleteScanFailedImages bool) ConfigFunc {
  function WithDeleteEOLImages (line 151) | func WithDeleteEOLImages(deleteEOLImages bool) ConfigFunc {
  function WithLogger (line 158) | func WithLogger(log logr.Logger) ConfigFunc {
  function WithMetrics (line 165) | func WithMetrics(reportMetrics bool) ConfigFunc {

FILE: pkg/scanners/trivy/helpers.go
  function loadConfig (line 10) | func loadConfig(filename string) (Config, error) {

FILE: pkg/scanners/trivy/trivy.go
  constant generalErr (line 24) | generalErr = 1
  constant severityCritical (line 26) | severityCritical = "CRITICAL"
  constant severityHigh (line 27) | severityHigh     = "HIGH"
  constant severityMedium (line 28) | severityMedium   = "MEDIUM"
  constant severityLow (line 29) | severityLow      = "LOW"
  constant severityUnknown (line 30) | severityUnknown  = "UNKNOWN"
  constant vulnTypeOs (line 32) | vulnTypeOs      = "os"
  constant vulnTypeLibrary (line 33) | vulnTypeLibrary = "library"
  constant securityCheckVuln (line 35) | securityCheckVuln   = "vuln"
  constant securityCheckConfig (line 36) | securityCheckConfig = "config"
  constant securityCheckSecret (line 37) | securityCheckSecret = "secret"
  constant statusUnknown (line 39) | statusUnknown            = "unknown"
  constant statusAffected (line 40) | statusAffected           = "affected"
  constant statusFixed (line 41) | statusFixed              = "fixed"
  constant statusUnderInvestigation (line 42) | statusUnderInvestigation = "under_investigation"
  constant statusWillNotFix (line 43) | statusWillNotFix         = "will_not_fix"
  constant statusFixDeferred (line 44) | statusFixDeferred        = "fix_deferred"
  constant statusEndOfLife (line 45) | statusEndOfLife          = "end_of_life"
  function main (line 59) | func main() {
  function runProfileServer (line 137) | func runProfileServer() {
  function initScanner (line 146) | func initScanner(userConfig *Config) (Scanner, error) {
  function scan (line 168) | func scan(s Scanner, allImages []unversioned.Image) ([]unversioned.Image...

FILE: pkg/scanners/trivy/types.go
  constant StatusFailed (line 18) | StatusFailed ScanStatus = iota
  constant StatusNonCompliant (line 19) | StatusNonCompliant
  constant StatusOK (line 20) | StatusOK
  constant ImgSrcPodman (line 21) | ImgSrcPodman     = "podman"
  constant ImgSrcDocker (line 22) | ImgSrcDocker     = "docker"
  constant ImgSrcContainerd (line 23) | ImgSrcContainerd = "containerd"
  constant trivyCommandName (line 27) | trivyCommandName        = "/trivy"
  constant trivyImageArg (line 28) | trivyImageArg           = "image"
  constant trivyJSONFormatFlag (line 29) | trivyJSONFormatFlag     = "--format=json"
  constant trivyCacheDirFlag (line 30) | trivyCacheDirFlag       = "--cache-dir"
  constant trivyTimeoutFlag (line 31) | trivyTimeoutFlag        = "--timeout"
  constant trivyDBRepoFlag (line 32) | trivyDBRepoFlag         = "--db-repository"
  constant trivyIgnoreUnfixedFlag (line 33) | trivyIgnoreUnfixedFlag  = "--ignore-unfixed"
  constant trivyVulnTypesFlag (line 34) | trivyVulnTypesFlag      = "--vuln-type"
  constant trivySecurityChecksFlag (line 35) | trivySecurityChecksFlag = "--scanners"
  constant trivySeveritiesFlag (line 36) | trivySeveritiesFlag     = "--severity"
  constant trivyRuntimeFlag (line 37) | trivyRuntimeFlag        = "--image-src"
  constant trivyIgnoreStatusFlag (line 38) | trivyIgnoreStatusFlag   = "--ignore-status"
  type Config (line 42) | type Config struct
    method cliArgs (line 100) | func (c *Config) cliArgs(ref string) []string {
    method getRuntimeVar (line 154) | func (c *Config) getRuntimeVar() (string, error) {
  type VulnConfig (line 52) | type VulnConfig struct
  type TimeoutConfig (line 60) | type TimeoutConfig struct
  type ScanStatus (line 65) | type ScanStatus
  type Scanner (line 67) | type Scanner interface
  function DefaultConfig (line 73) | func DefaultConfig() *Config {
  type ImageScanner (line 170) | type ImageScanner struct
    method Scan (line 175) | func (s *ImageScanner) Scan(img unversioned.Image) (ScanStatus, error) {
    method Timer (line 269) | func (s *ImageScanner) Timer() *time.Timer {
  function setRuntimeSocketEnvVars (line 233) | func setRuntimeSocketEnvVars(cmd *exec.Cmd, runtime unversioned.RuntimeS...

FILE: pkg/scanners/trivy/types_test.go
  constant ref (line 10) | ref = "image:tag"
  function init (line 14) | func init() {
  function TestCLIArgs (line 17) | func TestCLIArgs(t *testing.T) {

FILE: pkg/utils/flag.go
  type MultiFlag (line 7) | type MultiFlag
    method String (line 9) | func (nss *MultiFlag) String() string {
    method Set (line 13) | func (nss *MultiFlag) Set(s string) error {

FILE: pkg/utils/pod_info.go
  function GetNamespace (line 5) | func GetNamespace() string {

FILE: pkg/utils/utils.go
  constant unixProtocol (line 25) | unixProtocol             = "unix"
  constant PipeMode (line 26) | PipeMode                 = 0o644
  constant ScanErasePath (line 27) | ScanErasePath            = "/run/eraser.sh/shared-data/scanErase"
  constant CollectScanPath (line 28) | CollectScanPath          = "/run/eraser.sh/shared-data/collectScan"
  constant EraseCompleteCollectPath (line 29) | EraseCompleteCollectPath = "/run/eraser.sh/shared-data/eraseCompleteColl...
  constant EraseCompleteMessage (line 30) | EraseCompleteMessage     = "complete"
  constant EraseCompleteScanPath (line 31) | EraseCompleteScanPath    = "/run/eraser.sh/shared-data/eraseCompleteScan"
  constant CRIPath (line 33) | CRIPath = "/run/cri/cri.sock"
  constant EnvEraserRuntimeName (line 35) | EnvEraserRuntimeName = "ERASER_RUNTIME_NAME"
  type ExclusionList (line 38) | type ExclusionList struct
  function GetConn (line 48) | func GetConn(ctx context.Context, socketPath string) (conn *grpc.ClientC...
  function getAddressAndDialer (line 65) | func getAddressAndDialer(endpoint string) (string, func(ctx context.Cont...
  function dial (line 77) | func dial(ctx context.Context, addr string) (net.Conn, error) {
  function ParseEndpointWithFallbackProtocol (line 81) | func ParseEndpointWithFallbackProtocol(endpoint string, fallbackProtocol...
  function ParseEndpoint (line 92) | func ParseEndpoint(endpoint string) (string, string, error) {
  function ListImages (line 110) | func ListImages(ctx context.Context, images v1.ImageServiceClient) (list...
  function ListContainers (line 121) | func ListContainers(ctx context.Context, runtime v1.RuntimeServiceClient...
  function GetRunningImages (line 129) | func GetRunningImages(containers []*v1.Container, idToImageMap map[strin...
  function GetNonRunningImages (line 149) | func GetNonRunningImages(runningImages map[string]string, allImages []un...
  function IsExcluded (line 172) | func IsExcluded(excluded map[string]struct{}, img string, idToImageMap m...
  function ParseImageList (line 248) | func ParseImageList(path string) ([]string, error) {
  function ParseExcluded (line 263) | func ParseExcluded() (map[string]struct{}, error) {
  function BoolPtr (line 289) | func BoolPtr(b bool) *bool {
  function readConfigMap (line 293) | func readConfigMap(path string) ([]string, error) {
  function ReadCollectScanPipe (line 328) | func ReadCollectScanPipe(ctx context.Context) ([]unversioned.Image, erro...
  function WriteScanErasePipe (line 370) | func WriteScanErasePipe(vulnerableImages []unversioned.Image) error {
  function ProcessRepoDigests (line 392) | func ProcessRepoDigests(repoDigests []string) ([]string, []error) {

FILE: pkg/utils/utils_test.go
  function TestParseEndpointWithFallBackProtocol (line 10) | func TestParseEndpointWithFallBackProtocol(t *testing.T) {
  function TestParseEndpoint (line 76) | func TestParseEndpoint(t *testing.T) {
  function TestGetAddressAndDialer (line 136) | func TestGetAddressAndDialer(t *testing.T) {

FILE: test/e2e/tests/collector_delete_deployment/eraser_test.go
  function TestDeleteDeployment (line 21) | func TestDeleteDeployment(t *testing.T) {

FILE: test/e2e/tests/collector_delete_deployment/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_delete_manager/eraser_test.go
  function TestDeleteManager (line 23) | func TestDeleteManager(t *testing.T) {

FILE: test/e2e/tests/collector_delete_manager/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_disable_scan/eraser_test.go
  function TestDisableScanner (line 16) | func TestDisableScanner(t *testing.T) {

FILE: test/e2e/tests/collector_disable_scan/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_ensure_scan/eraser_test.go
  function TestEnsureScannerFunctions (line 16) | func TestEnsureScannerFunctions(t *testing.T) {

FILE: test/e2e/tests/collector_ensure_scan/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_pipeline/eraser_test.go
  function TestCollectScanErasePipeline (line 21) | func TestCollectScanErasePipeline(t *testing.T) {

FILE: test/e2e/tests/collector_pipeline/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_runtime_config/eraser_test.go
  function TestCustomRuntimeAddress (line 16) | func TestCustomRuntimeAddress(t *testing.T) {

FILE: test/e2e/tests/collector_runtime_config/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/collector_skip_excluded/eraser_test.go
  function TestCollectorExcluded (line 22) | func TestCollectorExcluded(t *testing.T) {

FILE: test/e2e/tests/collector_skip_excluded/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/configmap_update/eraser_test.go
  constant numPods (line 24) | numPods       = 3
  constant configKey (line 25) | configKey     = "controller_manager_config.yaml"
  constant configmapName (line 26) | configmapName = "eraser-manager-config"
  function TestConfigmapUpdate (line 31) | func TestConfigmapUpdate(t *testing.T) {

FILE: test/e2e/tests/configmap_update/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/helm_pull_secret/eraser_test.go
  constant expectedPods (line 22) | expectedPods = 4
  function TestHelmPullSecret (line 25) | func TestHelmPullSecret(t *testing.T) {

FILE: test/e2e/tests/helm_pull_secret/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/helm_pull_secret_imagelist/eraser_test.go
  constant expectedPods (line 23) | expectedPods = 4
  function TestHelmPullSecretImagelist (line 26) | func TestHelmPullSecretImagelist(t *testing.T) {

FILE: test/e2e/tests/helm_pull_secret_imagelist/main_test.go
  function TestMain (line 20) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_alias/eraser_test.go
  type nodeString (line 21) | type nodeString
  constant nginxOneName (line 24) | nginxOneName            = "nginxone"
  constant nginxTwoName (line 25) | nginxTwoName            = "nginxtwo"
  constant nodeNameKey (line 26) | nodeNameKey  nodeString = "nodeName"
  function TestEnsureAliasedImageRemoved (line 29) | func TestEnsureAliasedImageRemoved(t *testing.T) {

FILE: test/e2e/tests/imagelist_alias/main_test.go
  function TestMain (line 20) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_change/eraser_test.go
  function TestUpdateImageList (line 23) | func TestUpdateImageList(t *testing.T) {

FILE: test/e2e/tests/imagelist_change/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_exclusion_list/eraser_test.go
  function TestExclusionList (line 22) | func TestExclusionList(t *testing.T) {

FILE: test/e2e/tests/imagelist_exclusion_list/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_include_nodes/eraser_test.go
  function TestIncludeNodes (line 23) | func TestIncludeNodes(t *testing.T) {

FILE: test/e2e/tests/imagelist_include_nodes/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_prune_images/eraser_test.go
  function TestPrune (line 23) | func TestPrune(t *testing.T) {

FILE: test/e2e/tests/imagelist_prune_images/main_test.go
  function TestMain (line 20) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_rm_images/eraser_test.go
  constant restartTimeout (line 25) | restartTimeout = time.Minute
  function TestImageListTriggersRemoverImageJob (line 28) | func TestImageListTriggersRemoverImageJob(t *testing.T) {

FILE: test/e2e/tests/imagelist_rm_images/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/imagelist_skip_nodes/eraser_test.go
  function TestSkipNodes (line 23) | func TestSkipNodes(t *testing.T) {

FILE: test/e2e/tests/imagelist_skip_nodes/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/metrics_test_disable_scanner/eraser_test.go
  constant expectedImagesRemoved (line 19) | expectedImagesRemoved = 3
  function TestMetricsWithScannerDisabled (line 22) | func TestMetricsWithScannerDisabled(t *testing.T) {

FILE: test/e2e/tests/metrics_test_disable_scanner/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/metrics_test_eraser/eraser_test.go
  constant expectedImagesRemoved (line 19) | expectedImagesRemoved = 3
  function TestMetricsEraserOnly (line 22) | func TestMetricsEraserOnly(t *testing.T) {

FILE: test/e2e/tests/metrics_test_eraser/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/tests/metrics_test_scanner/eraser_test.go
  constant expectedVulnerableImages (line 19) | expectedVulnerableImages = 3
  function TestMetricsWithScanner (line 22) | func TestMetricsWithScanner(t *testing.T) {

FILE: test/e2e/tests/metrics_test_scanner/main_test.go
  function TestMain (line 19) | func TestMain(m *testing.M) {

FILE: test/e2e/util/kubectl.go
  function KubectlApply (line 13) | func KubectlApply(kubeconfigPath, namespace string, args []string) error {
  function HelmInstall (line 25) | func HelmInstall(kubeconfigPath, namespace string, args []string) error {
  function HelmUpgrade (line 41) | func HelmUpgrade(kubeconfigPath, namespace string, args []string) error {
  function HelmUninstall (line 56) | func HelmUninstall(kubeconfigPath, namespace string, args []string) error {
  function KubectlDelete (line 69) | func KubectlDelete(kubeconfigPath, namespace string, args []string) error {
  function KubectlExecCurl (line 80) | func KubectlExecCurl(kubeconfigPath, podName string, endpoint, namespace...
  function KubectlWait (line 97) | func KubectlWait(kubeconfigPath, podName, namespace string) (string, err...
  function KubectlLogs (line 113) | func KubectlLogs(kubeconfigPath, podName, containerName, namespace strin...
  function KubectlDescribe (line 131) | func KubectlDescribe(kubeconfigPath, podName, namespace string) (string,...
  function KubectlCurlPod (line 143) | func KubectlCurlPod(kubeconfigPath, namespace string) (string, error) {
  function KubectlGet (line 162) | func KubectlGet(kubeconfigPath string, otherArgs ...string) (string, err...
  function Kubectl (line 172) | func Kubectl(args []string) (string, error) {
  function KubectlBackground (line 186) | func KubectlBackground(args []string) error {
  function Helm (line 198) | func Helm(args []string) (string, error) {

FILE: test/e2e/util/utils.go
  constant providerResourceChartDir (line 35) | providerResourceChartDir  = "manifest_staging/charts"
  constant providerResourceDeployDir (line 36) | providerResourceDeployDir = "manifest_staging/deploy"
  constant publishedHelmRepo (line 37) | publishedHelmRepo         = "https://eraser-dev.github.io/eraser/charts"
  constant KindClusterName (line 39) | KindClusterName  = "eraser-e2e-test"
  constant ProviderResource (line 40) | ProviderResource = "eraser.yaml"
  constant Alpine (line 42) | Alpine        = "alpine"
  constant Nginx (line 43) | Nginx         = "nginx"
  constant NginxLatest (line 44) | NginxLatest   = "ghcr.io/eraser-dev/eraser/e2e-test/nginx:latest"
  constant NginxAliasOne (line 45) | NginxAliasOne = "ghcr.io/eraser-dev/eraser/e2e-test/nginx:one"
  constant NginxAliasTwo (line 46) | NginxAliasTwo = "ghcr.io/eraser-dev/eraser/e2e-test/nginx:two"
  constant Redis (line 47) | Redis         = "redis"
  constant Caddy (line 48) | Caddy         = "caddy"
  constant ImageCollectorShared (line 50) | ImageCollectorShared = "imagecollector-shared"
  constant Prune (line 51) | Prune                = "imagelist"
  constant ImagePullSecret (line 52) | ImagePullSecret      = "testsecret"
  constant FilterNodeName (line 53) | FilterNodeName       = "eraser-e2e-test-worker"
  constant FilterNodeSelector (line 54) | FilterNodeSelector   = "kubernetes.io/hostname=eraser-e2e-test-worker"
  constant FilterLabelKey (line 55) | FilterLabelKey       = "eraser.sh/cleanup.filter"
  constant FilterLabelValue (line 56) | FilterLabelValue     = "true"
  constant CollectorEnable (line 60) | CollectorEnable    = HelmPath("runtimeConfig.components.collector.enabled")
  constant CollectorImageRepo (line 61) | CollectorImageRepo = HelmPath("runtimeConfig.components.collector.image....
  constant CollectorImageTag (line 62) | CollectorImageTag  = HelmPath("runtimeConfig.components.collector.image....
  constant ScannerConfig (line 64) | ScannerConfig    = HelmPath("runtimeConfig.components.scanner.config")
  constant ScannerEnable (line 65) | ScannerEnable    = HelmPath("runtimeConfig.components.scanner.enabled")
  constant ScannerImageRepo (line 66) | ScannerImageRepo = HelmPath("runtimeConfig.components.scanner.image.repo")
  constant ScannerImageTag (line 67) | ScannerImageTag  = HelmPath("runtimeConfig.components.scanner.image.tag")
  constant RemoverImageRepo (line 69) | RemoverImageRepo = HelmPath("runtimeConfig.components.remover.image.repo")
  constant RemoverImageTag (line 70) | RemoverImageTag  = HelmPath("runtimeConfig.components.remover.image.tag")
  constant ManagerImageRepo (line 72) | ManagerImageRepo = HelmPath("deploy.image.repo")
  constant ManagerImageTag (line 73) | ManagerImageTag  = HelmPath("deploy.image.tag")
  constant ImagePullSecrets (line 75) | ImagePullSecrets = HelmPath("runtimeConfig.manager.pullSecrets")
  constant OTLPEndpoint (line 76) | OTLPEndpoint     = HelmPath("runtimeConfig.manager.otlpEndpoint")
  constant CleanupOnSuccessDelay (line 78) | CleanupOnSuccessDelay = HelmPath("runtimeConfig.manager.imageJob.cleanup...
  constant FilterNodesType (line 79) | FilterNodesType       = HelmPath("runtimeConfig.manager.nodeFilter.type")
  constant ScheduleImmediate (line 80) | ScheduleImmediate     = HelmPath("runtimeConfig.manager.scheduling.begin...
  constant CustomRuntimeAddress (line 82) | CustomRuntimeAddress = HelmPath("runtimeConfig.manager.runtime.address")
  constant CustomRuntimeName (line 83) | CustomRuntimeName    = HelmPath("runtimeConfig.manager.runtime.name")
  constant CollectorLabel (line 85) | CollectorLabel       = "collector"
  constant ManualLabel (line 86) | ManualLabel          = "manual"
  constant ImageJobTypeLabelKey (line 87) | ImageJobTypeLabelKey = "eraser.sh/type"
  constant ManagerLabelKey (line 88) | ManagerLabelKey      = "control-plane"
  constant ManagerLabelValue (line 89) | ManagerLabelValue    = "controller-manager"
  type RepoTag (line 142) | type RepoTag struct
  type Images (line 147) | type Images struct
  type HelmPath (line 154) | type HelmPath
    method Set (line 162) | func (hp HelmPath) Set(val string) string {
  type HelmSet (line 156) | type HelmSet struct
    method Set (line 166) | func (hs *HelmSet) Set(val ...string) *HelmSet {
    method String (line 171) | func (hs *HelmSet) String() string {
  function init (line 175) | func init() {
  function toRepoTag (line 184) | func toRepoTag(ref registry.Reference) RepoTag {
  function parsedImages (line 196) | func parsedImages(removerImage, managerImage, collectorImage, scannerIma...
  function parseRepoTag (line 225) | func parseRepoTag(img string) (RepoTag, error) {
  function LoadImageToCluster (line 252) | func LoadImageToCluster(clusterName, imageRef, tarballPath string) env.F...
  function HelmDeployLatestEraserRelease (line 260) | func HelmDeployLatestEraserRelease(namespace string, extraArgs ...string...
  function IsNotFound (line 309) | func IsNotFound(err error) bool {
  function NewDeployment (line 313) | func NewDeployment(namespace, name string, replicas int32, labels map[st...
  function NewPod (line 351) | func NewPod(namespace, image, name, nodeName string) *corev1.Pod {
  function DeployEraserConfig (line 370) | func DeployEraserConfig(kubeConfig, namespace, fileName string) error {
  function NumPodsPresentForLabel (line 379) | func NumPodsPresentForLabel(ctx context.Context, client klient.Client, n...
  function ContainerNotPresentOnNode (line 391) | func ContainerNotPresentOnNode(nodeName, containerName string) func() (b...
  function ImagejobNotInCluster (line 402) | func ImagejobNotInCluster(kubeconfigPath string) func() (bool, error) {
  function GetImageJob (line 413) | func GetImageJob(ctx context.Context, cfg *envconf.Config) (eraserv1.Ima...
  function ListNodeContainers (line 432) | func ListNodeContainers(nodeName string) (string, error) {
  function ListNodeImages (line 454) | func ListNodeImages(nodeName string) (string, error) {
  function GetClusterNodes (line 477) | func GetClusterNodes(t *testing.T) []string {
  function CheckImagesExist (line 496) | func CheckImagesExist(t *testing.T, nodes []string, images ...string) {
  function CheckDeploymentCleanedUp (line 514) | func CheckDeploymentCleanedUp(ctx context.Context, t *testing.T, client ...
  function CheckImageRemoved (line 537) | func CheckImageRemoved(ctx context.Context, t *testing.T, nodes []string...
  function DockerPullImage (line 578) | func DockerPullImage(image string) (string, error) {
  function DockerTagImage (line 592) | func DockerTagImage(image, tag string) (string, error) {
  function DeleteImageListsAndJobs (line 606) | func DeleteImageListsAndJobs(kubeConfig string) error {
  function DeleteStringFromSlice (line 613) | func DeleteStringFromSlice(strings []string, s string) []string {
  function DeployEraserHelm (line 631) | func DeployEraserHelm(namespace string, args ...string) env.Func {
  function UpgradeEraserHelm (line 664) | func UpgradeEraserHelm(namespace string, args ...string) env.Func {
  function DeployOtelCollector (line 701) | func DeployOtelCollector(namespace string) env.Func {
  function GetPodLogs (line 731) | func GetPodLogs(t *testing.T) error {
  function MakeDeploy (line 760) | func MakeDeploy(env map[string]string) env.Func {
  function DeployEraserManifest (line 782) | func DeployEraserManifest(namespace, fileName string) env.Func {
  function CreateExclusionList (line 792) | func CreateExclusionList(namespace string, list string) env.Func {

FILE: test/e2e/util/utils_test.go
  function TestParseRepoTag (line 9) | func TestParseRepoTag(t *testing.T) {

FILE: third_party/open-policy-agent/gatekeeper/helmify/main.go
  function extractKind (line 21) | func extractKind(s string) (string, error) {
  function extractName (line 29) | func extractName(s string) (string, error) {
  type kindSet (line 37) | type kindSet struct
    method Add (line 41) | func (ks *kindSet) Add(obj string) error {
    method Write (line 56) | func (ks *kindSet) Write() error {
  function doReplacements (line 82) | func doReplacements(obj string) string {
  function copyStaticFiles (line 89) | func copyStaticFiles(root string, subdirs ...string) error {
  function main (line 121) | func main() {

FILE: version/version.go
  function GetUserAgent (line 21) | func GetUserAgent(component string) string {

FILE: version/version_test.go
  function TestGetUserAgent (line 10) | func TestGetUserAgent(t *testing.T) {
Condensed preview — 345 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,144K chars).
[
  {
    "path": ".dockerignore",
    "chars": 151,
    "preview": "# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file\n# Ignore all files which are not go typ"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "chars": 1688,
    "preview": "name: Bug Report\ndescription: Report a bug in Eraser\ntitle: \"[BUG] <title>\"\nlabels:\n  - \"bug\"\nbody:\n  - type: markdown\n "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "chars": 1456,
    "preview": "name: Request\ndescription: Request a new feature or propose an enhancement to Eraser\ntitle: \"[REQ] <title>\"\nlabels:\n  - "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 251,
    "preview": "**What this PR does / why we need it**:\n\n**Which issue(s) this PR fixes** *(optional, using `fixes #<issue number>(, fix"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 997,
    "preview": "version: 2\n\nupdates:\n  - package-ecosystem: \"npm\"\n    directory: \"/docs\"\n    schedule:\n      interval: \"weekly\"\n    comm"
  },
  {
    "path": ".github/semantic.yml",
    "chars": 128,
    "preview": "titleOnly: true\ntypes:\n  - build\n  - chore\n  - ci\n  - docs\n  - feat\n  - fix\n  - perf\n  - refactor\n  - revert\n  - style\n "
  },
  {
    "path": ".github/workflows/README.md",
    "chars": 1282,
    "preview": "# GitHub Workflows\n\nThis directory contains all of our workflows used in our GitHub CI/CD pipeline.\n\n## Descriptions\n\n##"
  },
  {
    "path": ".github/workflows/build-id.yaml",
    "chars": 979,
    "preview": "name: Image build definitions for e2e tests\n\non:\n  workflow_call:\n    outputs:\n      build-id:\n        description: \"ran"
  },
  {
    "path": ".github/workflows/codeql.yaml",
    "chars": 1012,
    "preview": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ main ]\n  schedule:\n    - cron: '0 7 * * 1' # Monday at 7:00 AM\n\npermissions:"
  },
  {
    "path": ".github/workflows/dep-review.yaml",
    "chars": 530,
    "preview": "name: 'Dependency Review'\non: [pull_request]\n\npermissions:\n  contents: read\n\njobs:\n  dependency-review:\n    runs-on: ubu"
  },
  {
    "path": ".github/workflows/deploy_docs.yaml",
    "chars": 1775,
    "preview": "name: Generate docs website to GitHub Pages\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - '.github/workflow"
  },
  {
    "path": ".github/workflows/e2e-build.yaml",
    "chars": 7063,
    "preview": "name: Image build definitions for e2e tests\n\non:\n  workflow_call:\n    inputs:\n      bucket-id:\n        required: true\n  "
  },
  {
    "path": ".github/workflows/e2e-test.yaml",
    "chars": 4194,
    "preview": "name: Run E2E tests\n\non:\n  workflow_call:\n    inputs:\n      upgrade-test:\n        required: false\n        type: string\n "
  },
  {
    "path": ".github/workflows/patch-docs.yaml",
    "chars": 1983,
    "preview": "name: patch_docs\non:\n  push:\n    tags:\n      - 'v[0-9]+.[0-9]+.[1-9]+' # run this workflow when a new patch version is p"
  },
  {
    "path": ".github/workflows/release-pr.yaml",
    "chars": 3506,
    "preview": "name: create_release_pull_request\non:\n  push:\n    tags:\n      - 'v[0-9]+.[0-9]+.0' # run this workflow when a new minor "
  },
  {
    "path": ".github/workflows/release.yaml",
    "chars": 3647,
    "preview": "name: release\n\non:\n  push:\n    # Sequence of patterns matched against refs/tags\n    tags:\n      - 'v*' # Push events to "
  },
  {
    "path": ".github/workflows/scan-images.yaml",
    "chars": 3978,
    "preview": "name: Scan Images for Vulnerabilities (Trivy)\nrun-name: Scan ${{ inputs.version == '' && github.ref_name || inputs.versi"
  },
  {
    "path": ".github/workflows/scorecard.yml",
    "chars": 2854,
    "preview": "name: Scorecard supply-chain security\non:\n  # For Branch-Protection check. Only the default branch is supported. See\n  #"
  },
  {
    "path": ".github/workflows/test.yaml",
    "chars": 6567,
    "preview": "name: test\non:\n  push:\n    paths-ignore:\n      - \"**.md\"\n      - \"hack/**\"\n      - \"docs/**\"\n  pull_request:\n    paths-i"
  },
  {
    "path": ".github/workflows/upgrade.yaml",
    "chars": 883,
    "preview": "name: upgrade\non:\n  push:\n    paths:\n      - \"manifest_staging/charts/**\"\n      - \".github/workflows/upgrade.yaml\"\n\n  pu"
  },
  {
    "path": ".gitignore",
    "chars": 623,
    "preview": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\nbin\ntestbin/*\n.eraser\n./pkg/eraser/eraser\n# Test bin"
  },
  {
    "path": ".golangci.yaml",
    "chars": 678,
    "preview": "version: \"2\"\n\nrun:\n  go: \"1.25\"\n\nlinters:\n  default: none\n  enable:\n    - errcheck\n    - copyloopvar # replacement for e"
  },
  {
    "path": ".trivyignore",
    "chars": 20,
    "preview": "GHSA-6xv5-86q9-7xr8\n"
  },
  {
    "path": "CODEOWNERS",
    "chars": 61,
    "preview": "# Global approvers\n*   @ashnamehrotra @pmengelbert @sozercan\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 334,
    "preview": "# CNCF Code of Conduct\n\nThis project has adopted the [CNCF Community Code of Conduct](https://github.com/cncf/foundation"
  },
  {
    "path": "Dockerfile",
    "chars": 2652,
    "preview": "# syntax=docker/dockerfile:1.6\n\n# Default Trivy binary image, overwritten by Makefile\nARG TRIVY_BINARY_IMG=\"ghcr.io/aqua"
  },
  {
    "path": "LICENSE",
    "chars": 11350,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "MAINTAINERS.md",
    "chars": 149,
    "preview": "# Maintainers\n\nMaintainers:\n- Sertaç Özercan (@sozercan)\n- Ashna Mehrotra (@ashnamehrotra)\n- Peter Engelbert (@pmengelbe"
  },
  {
    "path": "Makefile",
    "chars": 13130,
    "preview": "VERSION := v1.5.0-beta.0\n\nMANAGER_TAG ?= ${VERSION}\nTRIVY_SCANNER_TAG ?= ${VERSION}\nCOLLECTOR_TAG ?= ${VERSION}\nREMOVER_"
  },
  {
    "path": "PROJECT",
    "chars": 760,
    "preview": "domain: eraser-dev.io\nlayout:\n- go.kubebuilder.io/v3\nprojectName: eraser\nrepo: github.com/eraser-dev/eraser\nresources:\n-"
  },
  {
    "path": "README.md",
    "chars": 2134,
    "preview": "# Eraser: Cleaning up Images from Kubernetes Nodes\n\n![GitHub](https://img.shields.io/github/license/eraser-dev/eraser)\n["
  },
  {
    "path": "api/group.go",
    "chars": 557,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/unversioned/config/config.go",
    "chars": 4034,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\tv1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/api/resource\"\n\n\t\"git"
  },
  {
    "path": "api/unversioned/doc.go",
    "chars": 58,
    "preview": "package unversioned\n\n// +kubebuilder:object:generate=true\n"
  },
  {
    "path": "api/unversioned/eraserconfig_types.go",
    "chars": 6510,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/unversioned/groupversion_info.go",
    "chars": 1212,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/unversioned/imagejob_types.go",
    "chars": 2136,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/unversioned/imagelist_types.go",
    "chars": 1722,
    "preview": "/*\nCopyright 2021.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in c"
  },
  {
    "path": "api/unversioned/zz_generated.deepcopy.go",
    "chars": 12878,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "api/v1/doc.go",
    "chars": 79,
    "preview": "// +k8s:conversion-gen=github.com/eraser-dev/eraser/api/unversioned\npackage v1\n"
  },
  {
    "path": "api/v1/groupversion_info.go",
    "chars": 1312,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1/imagejob_types.go",
    "chars": 2381,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1/imagelist_types.go",
    "chars": 1969,
    "preview": "/*\nCopyright 2021.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in c"
  },
  {
    "path": "api/v1/zz_generated.conversion.go",
    "chars": 15449,
    "preview": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License,"
  },
  {
    "path": "api/v1/zz_generated.deepcopy.go",
    "chars": 6318,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "api/v1alpha1/config/config.go",
    "chars": 2980,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\tv1alpha1 \"github.com/eraser-dev/eraser/api/v1alpha1\"\n\t\"github.com/eraser-dev/e"
  },
  {
    "path": "api/v1alpha1/custom_conversions.go",
    "chars": 1605,
    "preview": "package v1alpha1\n\nimport (\n\tunversioned \"github.com/eraser-dev/eraser/api/unversioned\"\n\tconversion \"k8s.io/apimachinery/"
  },
  {
    "path": "api/v1alpha1/doc.go",
    "chars": 174,
    "preview": "// Package v1alpha1 contains API Schema definitions for the eraser v1alpha1 API version.\n// +k8s:conversion-gen=github.c"
  },
  {
    "path": "api/v1alpha1/eraserconfig_types.go",
    "chars": 5939,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha1/groupversion_info.go",
    "chars": 1324,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha1/imagejob_types.go",
    "chars": 2440,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha1/imagelist_types.go",
    "chars": 2028,
    "preview": "/*\nCopyright 2021.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in c"
  },
  {
    "path": "api/v1alpha1/zz_generated.conversion.go",
    "chars": 41185,
    "preview": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License,"
  },
  {
    "path": "api/v1alpha1/zz_generated.deepcopy.go",
    "chars": 13131,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "api/v1alpha2/config/config.go",
    "chars": 2973,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/eraser-dev/eraser/api/v1alpha2\"\n\t\"github.com/eraser-dev/eraser/ver"
  },
  {
    "path": "api/v1alpha2/custom_conversions.go",
    "chars": 1605,
    "preview": "package v1alpha2\n\nimport (\n\tunversioned \"github.com/eraser-dev/eraser/api/unversioned\"\n\tconversion \"k8s.io/apimachinery/"
  },
  {
    "path": "api/v1alpha2/doc.go",
    "chars": 174,
    "preview": "// Package v1alpha2 contains API Schema definitions for the eraser v1alpha2 API version.\n// +k8s:conversion-gen=github.c"
  },
  {
    "path": "api/v1alpha2/eraserconfig_types.go",
    "chars": 4342,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha2/groupversion_info.go",
    "chars": 1336,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha2/zz_generated.conversion.go",
    "chars": 27079,
    "preview": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License,"
  },
  {
    "path": "api/v1alpha2/zz_generated.deepcopy.go",
    "chars": 7506,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "api/v1alpha3/config/config.go",
    "chars": 3123,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/eraser-dev/eraser/api/v1alpha3\"\n\t\"github.com/eraser-dev/eraser/ver"
  },
  {
    "path": "api/v1alpha3/doc.go",
    "chars": 85,
    "preview": "// +k8s:conversion-gen=github.com/eraser-dev/eraser/api/unversioned\npackage v1alpha3\n"
  },
  {
    "path": "api/v1alpha3/eraserconfig_types.go",
    "chars": 6507,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha3/groupversion_info.go",
    "chars": 1336,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "api/v1alpha3/runtime_spec_test.go",
    "chars": 2870,
    "preview": "package v1alpha3\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestConvertRuntimeToRuntimeSpec(t *testing.T) {\n\tt"
  },
  {
    "path": "api/v1alpha3/zz_generated.conversion.go",
    "chars": 28975,
    "preview": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License,"
  },
  {
    "path": "api/v1alpha3/zz_generated.deepcopy.go",
    "chars": 8162,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "build/version.sh",
    "chars": 3759,
    "preview": "#!/bin/bash\n# borrowed from sigs.k8s.io/cluster-api-provider-azure/hack/version.sh and modified\n\nset -o errexit\nset -o p"
  },
  {
    "path": "config/crd/bases/_.yaml",
    "chars": 256,
    "preview": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubeb"
  },
  {
    "path": "config/crd/bases/eraser.sh_imagejobs.yaml",
    "chars": 4831,
    "preview": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubeb"
  },
  {
    "path": "config/crd/bases/eraser.sh_imagelists.yaml",
    "chars": 5264,
    "preview": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubeb"
  },
  {
    "path": "config/crd/kustomization.yaml",
    "chars": 1031,
    "preview": "# This kustomization.yaml is not intended to be run by itself,\n# since it depends on service name and namespace that are"
  },
  {
    "path": "config/crd/kustomizeconfig.yaml",
    "chars": 512,
    "preview": "# This file is for teaching kustomize how to substitute name and namespace reference in CRD\nnameReference:\n- kind: Servi"
  },
  {
    "path": "config/crd/patches/cainjection_in_eraserconfigs.yaml",
    "chars": 286,
    "preview": "# The following patch adds a directive for certmanager to inject CA into the CRD\napiVersion: apiextensions.k8s.io/v1\nkin"
  },
  {
    "path": "config/crd/patches/cainjection_in_imagelists.yaml",
    "chars": 289,
    "preview": "# The following patch adds a directive for certmanager to inject CA into the CRD\napiVersion: apiextensions.k8s.io/v1alph"
  },
  {
    "path": "config/crd/patches/webhook_in_eraserconfigs.yaml",
    "chars": 392,
    "preview": "# The following patch enables a conversion webhook for the CRD\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceD"
  },
  {
    "path": "config/crd/patches/webhook_in_imagelists.yaml",
    "chars": 412,
    "preview": "# The following patch enables a conversion webhook for the CRD\napiVersion: apiextensions.k8s.io/v1alpha1\nkind: CustomRes"
  },
  {
    "path": "config/default/kustomization.yaml",
    "chars": 2537,
    "preview": "# Adds namespace to all resources.\nnamespace: eraser-system\n\n# Value of this field is prepended to the\n# names of all re"
  },
  {
    "path": "config/default/manager_auth_proxy_patch.yaml",
    "chars": 790,
    "preview": "# This patch inject a sidecar container which is a HTTP proxy for the\n# controller manager, it performs RBAC authorizati"
  },
  {
    "path": "config/manager/controller_manager_config.yaml",
    "chars": 2451,
    "preview": "apiVersion: eraser.sh/v1alpha3\nkind: EraserConfig\nmanager:\n  runtime:\n    name: containerd\n    address: unix:///run/cont"
  },
  {
    "path": "config/manager/kustomization.yaml",
    "chars": 622,
    "preview": "resources:\n- manager.yaml\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\n\napiVersion: kustomize.config.k8s.io/v1beta1"
  },
  {
    "path": "config/manager/manager.yaml",
    "chars": 1666,
    "preview": "apiVersion: v1\nkind: Namespace\nmetadata:\n  labels:\n    control-plane: controller-manager\n  name: system\n---\napiVersion: "
  },
  {
    "path": "config/manager/patch.yaml",
    "chars": 508,
    "preview": "- op: add\n  path: /spec/template/spec/containers/0/volumeMounts\n  value: []\n- op: add\n  path: /spec/template/spec/contai"
  },
  {
    "path": "config/prometheus/kustomization.yaml",
    "chars": 26,
    "preview": "resources:\n- monitor.yaml\n"
  },
  {
    "path": "config/prometheus/monitor.yaml",
    "chars": 497,
    "preview": "\n# Prometheus Monitor Service (Metrics)\napiVersion: monitoring.coreos.com/v1alpha1\nkind: ServiceMonitor\nmetadata:\n  labe"
  },
  {
    "path": "config/rbac/auth_proxy_client_clusterrole.yaml",
    "chars": 150,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: metrics-reader\nrules:\n- nonResourceURLs:\n  "
  },
  {
    "path": "config/rbac/auth_proxy_role.yaml",
    "chars": 280,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: proxy-role\nrules:\n- apiGroups:\n  - authenti"
  },
  {
    "path": "config/rbac/auth_proxy_role_binding.yaml",
    "chars": 268,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: proxy-rolebinding\nroleRef:\n  apiGrou"
  },
  {
    "path": "config/rbac/auth_proxy_service.yaml",
    "chars": 268,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    control-plane: controller-manager\n  name: controller-manager-metric"
  },
  {
    "path": "config/rbac/cluster_role_binding.yaml",
    "chars": 272,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: manager-rolebinding\nroleRef:\n  apiGr"
  },
  {
    "path": "config/rbac/imagejob_pods_service.yaml",
    "chars": 88,
    "preview": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: imagejob-pods\n  namespace: system\n"
  },
  {
    "path": "config/rbac/imagelist_editor_role.yaml",
    "chars": 367,
    "preview": "# permissions for end users to edit imagelists.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  n"
  },
  {
    "path": "config/rbac/imagelist_viewer_role.yaml",
    "chars": 324,
    "preview": "# permissions for end users to view imagelists.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  n"
  },
  {
    "path": "config/rbac/kustomization.yaml",
    "chars": 826,
    "preview": "resources:\n# All RBAC will be applied under this service account in\n# the deployment namespace. You may comment out this"
  },
  {
    "path": "config/rbac/leader_election_role.yaml",
    "chars": 476,
    "preview": "# permissions to do leader election.\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: leader-electi"
  },
  {
    "path": "config/rbac/leader_election_role_binding.yaml",
    "chars": 274,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: leader-election-rolebinding\nroleRef:\n  apiG"
  },
  {
    "path": "config/rbac/role.yaml",
    "chars": 1063,
    "preview": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: manager-role\nrules:\n- apiGroups:\n  - \"\""
  },
  {
    "path": "config/rbac/role_binding.yaml",
    "chars": 278,
    "preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: manager-rolebinding\n  namespace: system\nrol"
  },
  {
    "path": "config/rbac/service_account.yaml",
    "chars": 93,
    "preview": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: controller-manager\n  namespace: system\n"
  },
  {
    "path": "controllers/configmap/configmap.go",
    "chars": 4737,
    "preview": "package configmap\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\t"
  },
  {
    "path": "controllers/controller.go",
    "chars": 1179,
    "preview": "// Package controllers implements Kubernetes controllers for eraser resources.\npackage controllers\n\nimport (\n\t\"errors\"\n\n"
  },
  {
    "path": "controllers/imagecollector/imagecollector_controller.go",
    "chars": 17852,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "controllers/imagejob/imagejob_controller.go",
    "chars": 17436,
    "preview": "/*\nCopyright 2021.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in c"
  },
  {
    "path": "controllers/imagelist/imagelist_controller.go",
    "chars": 14324,
    "preview": "/*\nCopyright 2021.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in c"
  },
  {
    "path": "controllers/suite_test.go",
    "chars": 2220,
    "preview": "/*\nCopyright 2021.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in "
  },
  {
    "path": "controllers/util/util.go",
    "chars": 3164,
    "preview": "// Package util provides utility functions and constants for eraser controllers.\npackage util\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\""
  },
  {
    "path": "demo/README.md",
    "chars": 508,
    "preview": "# Eraser Demo\nThis demo is using [demo magic](https://github.com/paxtonhare/demo-magic) to execute. \n\n## Prerequisites\nT"
  },
  {
    "path": "demo/demo-magic.sh",
    "chars": 4284,
    "preview": "#!/usr/bin/env bash\n\n###############################################################################\n#\n# demo-magic.sh\n#"
  },
  {
    "path": "demo/demo.sh",
    "chars": 733,
    "preview": "#!/bin/bash\n\n########################\n# include the magic\n########################\n. demo-magic.sh\n\n# boostrap environme"
  },
  {
    "path": "demo/ds.yaml",
    "chars": 269,
    "preview": "apiVersion: apps/v1\nkind: DaemonSet\nmetadata:\n  name: alpine\nspec:\n  selector:\n    matchLabels:\n      app: alpine\n  temp"
  },
  {
    "path": "deploy/eraser.yaml",
    "chars": 16943,
    "preview": "apiVersion: v1\nkind: Namespace\nmetadata:\n  labels:\n    control-plane: controller-manager\n  name: eraser-system\n---\napiVe"
  },
  {
    "path": "docs/README.md",
    "chars": 1380,
    "preview": "# Website\n\nThis website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.\n\n### I"
  },
  {
    "path": "docs/babel.config.js",
    "chars": 89,
    "preview": "module.exports = {\n  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],\n};\n"
  },
  {
    "path": "docs/design/README.md",
    "chars": 289,
    "preview": "# Design Docs\n\n## Implemented\n* [ImageList and Collector/Scanner Design](https://docs.google.com/document/d/1Rz1bkZKZSLV"
  },
  {
    "path": "docs/docs/architecture.md",
    "chars": 830,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/docs/code-of-conduct.md",
    "chars": 348,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/docs/contributing.md",
    "chars": 748,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/docs/custom-scanner.md",
    "chars": 858,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, use the"
  },
  {
    "path": "docs/docs/customization.md",
    "chars": 11115,
    "preview": "---\ntitle: Customization\n---\n\n## Overview\n\nEraser uses a configmap to configure its behavior. The configmap is part of t"
  },
  {
    "path": "docs/docs/exclusion.md",
    "chars": 1171,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  },
  {
    "path": "docs/docs/faq.md",
    "chars": 1329,
    "preview": "---\ntitle: FAQ\n---\n## Why am I still seeing vulnerable images?\nEraser currently targets **non-running** images, so any v"
  },
  {
    "path": "docs/docs/installation.md",
    "chars": 392,
    "preview": "---\ntitle: Installation\n---\n\n## Manifest\n\nTo install Eraser with the manifest file, run the following command:\n\n```bash\n"
  },
  {
    "path": "docs/docs/introduction.md",
    "chars": 603,
    "preview": "---\ntitle: Introduction\nslug: /\n---\n\n# Introduction\n\nWhen deploying to Kubernetes, it's common for pipelines to build an"
  },
  {
    "path": "docs/docs/manual-removal.md",
    "chars": 2163,
    "preview": "---\ntitle: Manual Removal\n---\n\nCreate an `ImageList` and specify the images you would like to remove. In this case, the "
  },
  {
    "path": "docs/docs/metrics.md",
    "chars": 1302,
    "preview": "---\ntitle: Metrics\n---\n\nTo view Eraser metrics, you will need to deploy an Open Telemetry collector in the 'eraser-syste"
  },
  {
    "path": "docs/docs/quick-start.md",
    "chars": 5099,
    "preview": "---\ntitle: Quick Start\n---\n\nThis tutorial demonstrates the functionality of Eraser and validates that non-running images"
  },
  {
    "path": "docs/docs/release-management.md",
    "chars": 4297,
    "preview": "# Release Management\n\n## Overview\n\nThis document describes Eraser project release management, which includes release ver"
  },
  {
    "path": "docs/docs/releasing.md",
    "chars": 1314,
    "preview": "---\ntitle: Releasing\n---\n\n## Create Release Pull Request\n\n1. Go to `create_release_pull_request` workflow under actions."
  },
  {
    "path": "docs/docs/setup.md",
    "chars": 13953,
    "preview": "---\ntitle: Setup\n---\n\n# Development Setup\n\nThis document describes the steps to get started with development.\nYou can ei"
  },
  {
    "path": "docs/docs/trivy.md",
    "chars": 272,
    "preview": "---\ntitle: Trivy\n---\n\n## Trivy Provider Options\nThe Trivy provider is used in Eraser for image scanning and detecting vu"
  },
  {
    "path": "docs/docusaurus.config.js",
    "chars": 2766,
    "preview": "// @ts-check\n// Note: type annotations allow type checking and IDEs autocompletion\n\nconst lightCodeTheme = require('pris"
  },
  {
    "path": "docs/package.json",
    "chars": 1377,
    "preview": "{\n  \"name\": \"website\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"docusaurus\": \"docusaurus\",\n    \"star"
  },
  {
    "path": "docs/sidebars.js",
    "chars": 1145,
    "preview": "/**\n * Creating a sidebar enables you to:\n - create an ordered group of docs\n - render a sidebar for each doc of that gr"
  },
  {
    "path": "docs/src/css/custom.css",
    "chars": 2968,
    "preview": "/**\n * Any CSS included here will be global. The classic template\n * bundles Infima by default. Infima is a CSS framewor"
  },
  {
    "path": "docs/static/.nojekyll",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/architecture.md",
    "chars": 941,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/code-of-conduct.md",
    "chars": 348,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/contributing.md",
    "chars": 749,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/custom-scanner.md",
    "chars": 532,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, provide"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/customization.md",
    "chars": 660,
    "preview": "---\ntitle: Customization\n---\n\nBy default, successful jobs will be deleted after a period of time. You can change this be"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/exclusion.md",
    "chars": 1882,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/faq.md",
    "chars": 401,
    "preview": "---\ntitle: FAQ\n---\n## Why am I still seeing vulnerable images?\nEraser currently targets **non-running** images, so any v"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/installation.md",
    "chars": 394,
    "preview": "---\ntitle: Installation\n---\n\n## Manifest\n\nTo install Eraser with the manifest file, run the following command:\n\n```bash\n"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/introduction.md",
    "chars": 603,
    "preview": "---\ntitle: Introduction\nslug: /\n---\n\n# Introduction\n\nWhen deploying to Kubernetes, it's common for pipelines to build an"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/manual-removal.md",
    "chars": 2163,
    "preview": "---\ntitle: Manual Removal\n---\n\nCreate an `ImageList` and specify the images you would like to remove. In this case, the "
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/quick-start.md",
    "chars": 5020,
    "preview": "---\ntitle: Quick Start\n---\n\nThis tutorial demonstrates the functionality of Eraser and validates that non-running images"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/releasing.md",
    "chars": 2566,
    "preview": "---\ntitle: Releasing\n---\n\n## Overview\n\nThe release process consists of three phases: versioning, building, and publishin"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/setup.md",
    "chars": 13946,
    "preview": "---\ntitle: Setup\n---\n\n# Development Setup\n\nThis document describes the steps to get started with development.\nYou can ei"
  },
  {
    "path": "docs/versioned_docs/version-v0.4.x/trivy.md",
    "chars": 631,
    "preview": "---\ntitle: Trivy\n---\n\n## Trivy Provider Options\nThe trivy provider is used in Eraser for image scanning and detecting vu"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/architecture.md",
    "chars": 941,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/code-of-conduct.md",
    "chars": 348,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/contributing.md",
    "chars": 748,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/custom-scanner.md",
    "chars": 861,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, use the"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/customization.md",
    "chars": 660,
    "preview": "---\ntitle: Customization\n---\n\nBy default, successful jobs will be deleted after a period of time. You can change this be"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/exclusion.md",
    "chars": 1873,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/faq.md",
    "chars": 401,
    "preview": "---\ntitle: FAQ\n---\n## Why am I still seeing vulnerable images?\nEraser currently targets **non-running** images, so any v"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/installation.md",
    "chars": 394,
    "preview": "---\ntitle: Installation\n---\n\n## Manifest\n\nTo install Eraser with the manifest file, run the following command:\n\n```bash\n"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/introduction.md",
    "chars": 603,
    "preview": "---\ntitle: Introduction\nslug: /\n---\n\n# Introduction\n\nWhen deploying to Kubernetes, it's common for pipelines to build an"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/manual-removal.md",
    "chars": 2163,
    "preview": "---\ntitle: Manual Removal\n---\n\nCreate an `ImageList` and specify the images you would like to remove. In this case, the "
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/quick-start.md",
    "chars": 5020,
    "preview": "---\ntitle: Quick Start\n---\n\nThis tutorial demonstrates the functionality of Eraser and validates that non-running images"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/releasing.md",
    "chars": 2566,
    "preview": "---\ntitle: Releasing\n---\n\n## Overview\n\nThe release process consists of three phases: versioning, building, and publishin"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/setup.md",
    "chars": 13946,
    "preview": "---\ntitle: Setup\n---\n\n# Development Setup\n\nThis document describes the steps to get started with development.\nYou can ei"
  },
  {
    "path": "docs/versioned_docs/version-v0.5.x/trivy.md",
    "chars": 631,
    "preview": "---\ntitle: Trivy\n---\n\n## Trivy Provider Options\nThe trivy provider is used in Eraser for image scanning and detecting vu"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/architecture.md",
    "chars": 830,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/code-of-conduct.md",
    "chars": 347,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/contributing.md",
    "chars": 748,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/custom-scanner.md",
    "chars": 861,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, use the"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/customization.md",
    "chars": 10296,
    "preview": "---\ntitle: Customization\n---\n\n## Overview\n\nEraser uses a configmap to configure its behavior. The configmap is part of t"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/exclusion.md",
    "chars": 1171,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/faq.md",
    "chars": 469,
    "preview": "---\ntitle: FAQ\n---\n## Why am I still seeing vulnerable images?\nEraser currently targets **non-running** images, so any v"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/installation.md",
    "chars": 394,
    "preview": "---\ntitle: Installation\n---\n\n## Manifest\n\nTo install Eraser with the manifest file, run the following command:\n\n```bash\n"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/introduction.md",
    "chars": 603,
    "preview": "---\ntitle: Introduction\nslug: /\n---\n\n# Introduction\n\nWhen deploying to Kubernetes, it's common for pipelines to build an"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/manual-removal.md",
    "chars": 2157,
    "preview": "---\ntitle: Manual Removal\n---\n\nCreate an `ImageList` and specify the images you would like to remove. In this case, the "
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/metrics.md",
    "chars": 1302,
    "preview": "---\ntitle: Metrics\n---\n\nTo view Eraser metrics, you will need to deploy an Open Telemetry collector in the 'eraser-syste"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/quick-start.md",
    "chars": 5117,
    "preview": "---\ntitle: Quick Start\n---\n\nThis tutorial demonstrates the functionality of Eraser and validates that non-running images"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/releasing.md",
    "chars": 1040,
    "preview": "---\ntitle: Releasing\n---\n\n## Create Release Pull Request\n\n1. Go to `create_release_pull_request` workflow under actions."
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/setup.md",
    "chars": 13946,
    "preview": "---\ntitle: Setup\n---\n\n# Development Setup\n\nThis document describes the steps to get started with development.\nYou can ei"
  },
  {
    "path": "docs/versioned_docs/version-v1.0.x/trivy.md",
    "chars": 272,
    "preview": "---\ntitle: Trivy\n---\n\n## Trivy Provider Options\nThe trivy provider is used in Eraser for image scanning and detecting vu"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/architecture.md",
    "chars": 830,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/code-of-conduct.md",
    "chars": 348,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/contributing.md",
    "chars": 748,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/custom-scanner.md",
    "chars": 861,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, use the"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/customization.md",
    "chars": 10403,
    "preview": "---\ntitle: Customization\n---\n\n## Overview\n\nEraser uses a configmap to configure its behavior. The configmap is part of t"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/exclusion.md",
    "chars": 1171,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/faq.md",
    "chars": 1329,
    "preview": "---\ntitle: FAQ\n---\n## Why am I still seeing vulnerable images?\nEraser currently targets **non-running** images, so any v"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/installation.md",
    "chars": 394,
    "preview": "---\ntitle: Installation\n---\n\n## Manifest\n\nTo install Eraser with the manifest file, run the following command:\n\n```bash\n"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/introduction.md",
    "chars": 603,
    "preview": "---\ntitle: Introduction\nslug: /\n---\n\n# Introduction\n\nWhen deploying to Kubernetes, it's common for pipelines to build an"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/manual-removal.md",
    "chars": 2163,
    "preview": "---\ntitle: Manual Removal\n---\n\nCreate an `ImageList` and specify the images you would like to remove. In this case, the "
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/metrics.md",
    "chars": 1302,
    "preview": "---\ntitle: Metrics\n---\n\nTo view Eraser metrics, you will need to deploy an Open Telemetry collector in the 'eraser-syste"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/quick-start.md",
    "chars": 5099,
    "preview": "---\ntitle: Quick Start\n---\n\nThis tutorial demonstrates the functionality of Eraser and validates that non-running images"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/releasing.md",
    "chars": 1041,
    "preview": "---\ntitle: Releasing\n---\n\n## Create Release Pull Request\n\n1. Go to `create_release_pull_request` workflow under actions."
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/setup.md",
    "chars": 13953,
    "preview": "---\ntitle: Setup\n---\n\n# Development Setup\n\nThis document describes the steps to get started with development.\nYou can ei"
  },
  {
    "path": "docs/versioned_docs/version-v1.1.x/trivy.md",
    "chars": 272,
    "preview": "---\ntitle: Trivy\n---\n\n## Trivy Provider Options\nThe trivy provider is used in Eraser for image scanning and detecting vu"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/architecture.md",
    "chars": 830,
    "preview": "---\ntitle: Architecture\n---\nAt a high level, Eraser has two main modes of operation: manual and automated.\n\nManual image"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/code-of-conduct.md",
    "chars": 348,
    "preview": "---\ntitle: Code of Conduct\n---\n\nThis project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/b"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/contributing.md",
    "chars": 748,
    "preview": "---\ntitle: Contributing\n---\n\nThere are several ways to get involved with Eraser\n\n- Join the [mailing list](https://group"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/custom-scanner.md",
    "chars": 861,
    "preview": "---\ntitle: Custom Scanner\n---\n\n## Creating a Custom Scanner\nTo create a custom scanner for non-compliant images, use the"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/customization.md",
    "chars": 10403,
    "preview": "---\ntitle: Customization\n---\n\n## Overview\n\nEraser uses a configmap to configure its behavior. The configmap is part of t"
  },
  {
    "path": "docs/versioned_docs/version-v1.2.x/exclusion.md",
    "chars": 1171,
    "preview": "---\ntitle: Exclusion\n---\n\n## Excluding registries, repositories, and images\nEraser can exclude registries (example, `doc"
  }
]

// ... and 145 more files (download for full content)

About this extraction

This page contains the full source code of the Azure/eraser GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 345 files (1.0 MB), approximately 290.3k tokens, and a symbol index with 930 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!