Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4f25ab8
chore: update package-spec to pre-release version
teresaromero Mar 3, 2026
adf728b
feat: extend manifest types for required input packages
teresaromero Mar 3, 2026
3ecf9d6
feat: implement input package template bundling
teresaromero Mar 3, 2026
eba23df
feat: wire registry client and requires overrides into build and test…
teresaromero Mar 3, 2026
b43bf5b
docs: document composable integrations and local registry usage
teresaromero Mar 4, 2026
5da820b
chore: update with latests package-spec. this commit should be revert…
teresaromero Mar 4, 2026
09fdab8
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 4, 2026
7468026
use profile epr url on install command. update readme
teresaromero Mar 10, 2026
50c3b2b
Revert "update readme"
teresaromero Mar 10, 2026
a690ef0
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 10, 2026
d76ffad
Update dependency management documentation to clarify package depende…
teresaromero Mar 11, 2026
ad98db8
Add TLS support to registry client
teresaromero Mar 11, 2026
5d69e4b
Add bundle policy templates input package handling and tests
teresaromero Mar 12, 2026
1d8e4dd
Add bundle data stream templates handling and tests
teresaromero Mar 12, 2026
11fe9df
Add YAML utility functions for mapping and formatting
teresaromero Mar 12, 2026
22047e8
Add function to read and unpack data stream manifest bytes
teresaromero Mar 12, 2026
2cd96e7
refactor bundle templates for builder
teresaromero Mar 12, 2026
9f6ade8
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 12, 2026
e490bb3
remove overrides implementation
teresaromero Mar 12, 2026
c91a537
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 12, 2026
d9a438d
Update manifest.yml to replace sql_input with test_input_pkg and adju…
teresaromero Mar 13, 2026
39c787c
refactor and fixing injection into installer and builder. naming refa…
teresaromero Mar 13, 2026
6d40f8e
remove default empty template option
teresaromero Mar 13, 2026
85990e2
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 13, 2026
0ba7f63
Remove FindPackageInRepo function from packages.go
teresaromero Mar 13, 2026
dbe671b
rename PackageRef
teresaromero Mar 13, 2026
8337f12
Refactor YAML utility functions to use slices.IndexFunc for improved …
teresaromero Mar 13, 2026
9c3301f
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 18, 2026
cabe0a3
feat: gate data stream template bundling on explicit data_streams ass…
teresaromero Mar 18, 2026
3dc281d
chore: update package-spec dependency to v3.5.8 in go.mod and go.sum
teresaromero Mar 19, 2026
df6a557
revert: remove data_streams gating for template bundling
teresaromero Mar 19, 2026
42ad433
docs: update howto guide
teresaromero Mar 19, 2026
1366c46
fix: prevent nil panic and Windows path failures in required inputs r…
teresaromero Mar 19, 2026
f4d026b
test: ensure proper resource cleanup in policy templates and streams …
teresaromero Mar 19, 2026
86557d8
tests: update test script to include test package into stack registry
teresaromero Mar 19, 2026
0f962e7
Move required_inputs fixtures to test/manual_packages
teresaromero Mar 23, 2026
32c11ae
Revert "tests: update test script to include test package into stack …
teresaromero Mar 23, 2026
32a2ff5
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 23, 2026
6cf85da
requiredinputs: open directory packages with os.Root for fs.FS
teresaromero Mar 25, 2026
3e850ca
Improve requiredinputs error messages with consistent wording
teresaromero Mar 25, 2026
4c381ed
docs: fix standalone package registry Docker image in HOWTO
teresaromero Mar 25, 2026
f0eebb2
Align docs with package-registry and elastic-package
teresaromero Mar 26, 2026
7ce8e8f
Export requiredinputs.Resolver and remove duplicate interfaces
teresaromero Mar 26, 2026
95c83df
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Mar 26, 2026
07c2995
Merge branch 'main' of github.com:elastic/elastic-package into 3278-b…
teresaromero Apr 13, 2026
e1245f4
Remove unused download.go file from the internal registry package
teresaromero Apr 13, 2026
4de860d
Use profile-aware package registry URL for test, benchmark, script
teresaromero Apr 13, 2026
2e52d58
Nil-safe required inputs resolver and simplify NewRequiredInputsResolver
teresaromero Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ Built packages are served up by the Elastic Package Registry running locally (se

Built packages can also be published to the global package registry service.

When the package declares required input packages ("requires.input" in manifest.yml), the build downloads those input packages from the configured package registry (see "package_registry.base_url" in ~/.elastic-package/config.yml). For details on using a local or custom registry during development, see the [HOWTO guide](./docs/howto/local_package_registry.md).

For details on how to enable dependency management, see the [HOWTO guide](https://github.com/elastic/elastic-package/blob/main/docs/howto/dependency_management.md).

### `elastic-package changelog`
Expand Down
6 changes: 6 additions & 0 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/elastic/elastic-package/internal/install"
"github.com/elastic/elastic-package/internal/logger"
"github.com/elastic/elastic-package/internal/packages"
"github.com/elastic/elastic-package/internal/registry"
)

const buildLongDescription = `Use this command to build a package.
Expand All @@ -26,6 +27,8 @@ Built packages are served up by the Elastic Package Registry running locally (se

Built packages can also be published to the global package registry service.

When the package declares required input packages ("requires.input" in manifest.yml), the build downloads those input packages from the configured package registry (see "package_registry.base_url" in ~/.elastic-package/config.yml). For details on using a local or custom registry during development, see the [HOWTO guide](./docs/howto/local_package_registry.md).

For details on how to enable dependency management, see the [HOWTO guide](https://github.com/elastic/elastic-package/blob/main/docs/howto/dependency_management.md).`

func setupBuildCommand() *cobraext.Command {
Expand Down Expand Up @@ -84,6 +87,8 @@ func buildCommandAction(cmd *cobra.Command, args []string) error {
return fmt.Errorf("can't load configuration: %w", err)
}

eprClient := registry.NewClient(appConfig.PackageRegistryBaseURL())

target, err := builder.BuildPackage(builder.BuildOptions{
PackageRoot: packageRoot,
BuildDir: buildDir,
Expand All @@ -93,6 +98,7 @@ func buildCommandAction(cmd *cobra.Command, args []string) error {
RepositoryRoot: repositoryRoot,
UpdateReadmes: true,
SchemaURLs: appConfig.SchemaURLs(),
RegistryClient: eprClient,
})
if err != nil {
return fmt.Errorf("building package failed: %w", err)
Expand Down
4 changes: 4 additions & 0 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/elastic/elastic-package/internal/kibana"
"github.com/elastic/elastic-package/internal/packages"
"github.com/elastic/elastic-package/internal/packages/installer"
"github.com/elastic/elastic-package/internal/registry"
"github.com/elastic/elastic-package/internal/stack"
)

Expand Down Expand Up @@ -92,13 +93,16 @@ func installCommandAction(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("can't load configuration: %w", err)
}

eprClient := registry.NewClient(stack.PackageRegistryBaseURL(profile, appConfig))

installer, err := installer.NewForPackage(installer.Options{
Kibana: kibanaClient,
PackageRoot: packageRoot,
SkipValidation: skipValidation,
ZipPath: zipPathFile,
RepositoryRoot: repositoryRoot,
SchemaURLs: appConfig.SchemaURLs(),
RegistryClient: eprClient,
})
if err != nil {
return fmt.Errorf("package installation failed: %w", err)
Expand Down
6 changes: 6 additions & 0 deletions cmd/testrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,12 @@ func testRunnerScriptCommandAction(cmd *cobra.Command, args []string) error {

opts.Package = manifest.Name

globalTestConfig, err := testrunner.ReadGlobalTestConfig(pkgRoot)
if err != nil {
return fmt.Errorf("failed to read global config: %w", err)
}
opts.RequiresOverrides = globalTestConfig.RequiresOverrides("script")

var results []testrunner.TestResult
err = script.Run(&results, cmd.OutOrStderr(), opts)
if err != nil {
Expand Down
42 changes: 39 additions & 3 deletions docs/howto/dependency_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,21 @@ which field definition was correct, maintenance and typo correction process was
The described situation brought us to a point in time when a simple dependency management was a requirement to maintain
all used fields, especially ones imported from external sources.

Elastic Packages support two kinds of build-time dependency:

- **Field dependencies** — import field definitions from external schemas (e.g. ECS) using
`_dev/build/build.yml`. Resolved from Git references and cached locally.
- **Package dependencies** — composable (integration) packages can depend on **input packages**
declared under `requires.input` in `manifest.yml`. Resolved at build time by downloading from
the package registry.

Both are described in the sections below.

## Principles of operation

Currently Elastic Packages support build-time dependencies that can be used as external field sources. They use a flat
dependency model represented with an additional build manifest, stored in an optional YAML file - `_dev/build/build.yml`:
Currently Elastic Packages support build-time field dependencies that can be used as external
field sources. They use a flat dependency model represented with an additional build manifest,
stored in an optional YAML file - `_dev/build/build.yml`:

```yaml
dependencies:
Expand Down Expand Up @@ -83,4 +94,29 @@ and use a following field definition:
```yaml
- name: event.category
external: ecs
```
```

## Composable packages and the package registry

Composable (integration) packages can also depend on other packages — specifically **input
packages** — by declaring them under `requires.input` in `manifest.yml`:
Comment thread
teresaromero marked this conversation as resolved.
Outdated

```yaml
requires:
input:
- package: sql_input
version: "0.2.0"
```

This type of dependency is resolved at **build time** by downloading the required input package
from the **package registry**. During `elastic-package build`, agent templates from the
required input packages are fetched and bundled into the built integration so that Fleet can
merge them at policy creation time.

Unlike field-level dependencies (which are resolved from Git references and cached locally),
package dependencies are fetched from the configured package registry URL
(`package_registry.base_url` in `~/.elastic-package/config.yml`, defaulting to
`https://epr.elastic.co`).

For details on using a local or custom registry when the required input packages are still
under development, see [HOWTO: Use a local or custom package registry](./local_package_registry.md).
145 changes: 145 additions & 0 deletions docs/howto/local_package_registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# HOWTO: Use a local or custom package registry for composable integrations

## Overview

Composable (integration) packages can declare required input packages in their `manifest.yml`
under `requires.input`. When you run `elastic-package build` or `elastic-package install`,
elastic-package resolves those dependencies by downloading them from the **package registry**.
By default it uses the production registry at `https://epr.elastic.co`.

This guide explains how to point elastic-package at a local or custom registry, which is
useful when the required input packages are still under development and not yet published to
the production registry.
Comment on lines +10 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elastic-package stack up with the compose provider (the default), starts a local package registry, that serves the packages under build/packages. This can be used to serve local packages. You only need to remember building the ones you need.

This mechanism would even be improved after your change in elastic/package-registry#1482, what would allow reloading the packages without needing to restart the registry.

In the documentation here we are adding another method to serve local packages. We should probably converge both methods in a single one.


For field-level build-time dependencies (ECS, `_dev/build/build.yml`), see
[HOWTO: Enable dependency management](./dependency_management.md).

## Prerequisites

- An integration package that declares `requires.input` in its `manifest.yml`, for example:

```yaml
requires:
input:
- package: sql_input
version: "0.2.0"
```

- Optionally, a running local package registry that serves the required input packages.

## Option 1: Configure the registry URL globally

Edit `~/.elastic-package/config.yml` and set `package_registry.base_url` to your registry URL:

```yaml
package_registry:
base_url: http://localhost:8080
```

This setting is read by `elastic-package build`, `elastic-package install`, and
`elastic-package status` when they need to contact the registry. It defaults to
`https://epr.elastic.co` when not set.

> **Note:** This setting does not change the package registry container that the Elastic Stack
> itself uses (served by `elastic-package stack`). To also redirect the stack, see
> [Option 2](#option-2-configure-the-registry-url-per-profile) below.

### Running a local package registry

To serve local packages, you can use the
[Elastic Package Registry](https://github.com/elastic/package-registry) with the
`--packages-path` flag pointing at a directory containing your built packages:

```shell
# Build your input package first
cd /path/to/sql_input
elastic-package build

# Start a local registry serving the build/ directory
docker run --rm -p 8080:8080 \
Comment thread
teresaromero marked this conversation as resolved.
Outdated
-v /path/to/build/packages:/packages/package \
docker.elastic.co/package-registry/distribution:latest \
Comment thread
teresaromero marked this conversation as resolved.
Outdated
/package-registry serve --packages-path /packages
```

With a registry running at `http://localhost:8080`, set `package_registry.base_url` as shown
above and run `elastic-package build` from your integration package directory.

## Option 2: Configure the registry URL per profile

If you run `elastic-package stack` and want both the **build tools** and the **stack's Fleet**
to use the same custom registry, configure the active profile
(e.g. `~/.elastic-package/profiles/default/config.yml`):

```yaml
# URL for the stack's package registry container to proxy requests to
stack.epr.proxy_to: http://host.docker.internal:8080

# URL for the stack's package registry base endpoint
stack.epr.base_url: http://localhost:8080
```

Profile settings take precedence over the global `package_registry.base_url` for
stack-related behavior. The priority order is:

1. `stack.epr.proxy_to` (profile) — used as the proxy target for the local registry container
2. `stack.epr.base_url` (profile) — used as the registry base URL
3. `package_registry.base_url` (global `~/.elastic-package/config.yml`)
4. `https://epr.elastic.co` (production fallback)

For more details on profiles, see the
[Elastic Package profiles section of the README](../../README.md#elastic-package-profiles).

## Option 3: Use local source directories during tests (no registry required)

For **testing** only, you can bypass the registry entirely for specific required packages by
declaring **requires overrides** in `_dev/test/config.yml` with a `source` path pointing at a
local package directory:

```yaml
requires:
- package: sql_input
source: ../../sql_input
```

The `source` path can be absolute or relative to the package root. When the test runner builds
the package, it passes these overrides to the builder, which uses the local directory instead
of downloading from the registry.

You can also pin a version from the registry instead of using a local source:

```yaml
requires:
- package: sql_input
version: "0.1.0"
```

Overrides in `_dev/test/config.yml` apply to all test types. You can also scope them to a
specific test type:

```yaml
requires:
- package: sql_input
source: ../../sql_input

system:
requires:
- package: sql_input
version: "0.2.0"
```

In this example, system tests use version `0.2.0` from the registry while all other test types
use the local source.

> **Note:** Requires overrides in `_dev/test/config.yml` only affect the **test runner's
> internal build step**. Running `elastic-package build` manually still uses the registry URL
> from the global config. Use Options 1 or 2 for the manual build workflow.

## Summary

| Goal | Configuration |
|------|--------------|
| Override registry for `build` / `install` | `package_registry.base_url` in `~/.elastic-package/config.yml` |
| Override registry for `stack` (Fleet) | `stack.epr.base_url` / `stack.epr.proxy_to` in the active profile `config.yml` |
| Use local package dir during tests | `requires[].source` in `_dev/test/config.yml` |
| Pin a specific version during tests | `requires[].version` in `_dev/test/config.yml` |
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ require (
github.com/elastic/go-elasticsearch/v7 v7.17.10
github.com/elastic/go-licenser v0.4.2
github.com/elastic/go-resource v0.2.0
github.com/elastic/package-spec/v3 v3.0.0-20260303155217-5f23052266aa
github.com/elastic/go-ucfg v0.9.1
github.com/elastic/package-spec/v3 v3.5.7
github.com/fatih/color v1.18.0
github.com/go-viper/mapstructure/v2 v2.5.0
github.com/gobwas/glob v0.2.3
Expand Down Expand Up @@ -51,6 +51,10 @@ require (
k8s.io/client-go v0.35.2
)

// TODO: Remove this before merging.
// Replace with the latest version of the package spec when available.
replace github.com/elastic/package-spec/v3 => github.com/elastic/package-spec/v3 v3.0.0-20260303155217-5f23052266aa

require (
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ github.com/elastic/gojsonschema v1.2.1 h1:cUMbgsz0wyEB4x7xf3zUEvUVDl6WCz2RKcQPul
github.com/elastic/gojsonschema v1.2.1/go.mod h1:biw5eBS2Z4T02wjATMRSfecfjCmwaDPvuaqf844gLrg=
github.com/elastic/kbncontent v0.1.4 h1:GoUkJkqkn2H6iJTnOHcxEqYVVYyjvcebLQVaSR1aSvU=
github.com/elastic/kbncontent v0.1.4/go.mod h1:kOPREITK9gSJsiw/WKe7QWSO+PRiZMyEFQCw+CMLAHI=
github.com/elastic/package-spec/v3 v3.5.7 h1:0Ep0+S4mEJIzlBeBJfVL/0j6MYvqe87AdM3SsUpKQWc=
github.com/elastic/package-spec/v3 v3.5.7/go.mod h1:6b+9mtcaDJvKAb1sHXNLBPSemG+8Llv+Pup/j1yPYMc=
github.com/elastic/package-spec/v3 v3.0.0-20260303155217-5f23052266aa h1:rbMqr/EbXKbQgCRi8enM0M4kAwP3wTmjSJmFL8FdNA0=
github.com/elastic/package-spec/v3 v3.0.0-20260303155217-5f23052266aa/go.mod h1:iFshXIUVyYuPVatkeXtQ6o14MGw8XvJPJXyWNRmtstc=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
Expand Down
Loading