Skip to content

Add elastic-agent-service container to packaging#5349

Merged
blakerouse merged 17 commits intoelastic:mainfrom
blakerouse:agent-service-docker
Sep 30, 2024
Merged

Add elastic-agent-service container to packaging#5349
blakerouse merged 17 commits intoelastic:mainfrom
blakerouse:agent-service-docker

Conversation

@blakerouse
Copy link
Contributor

@blakerouse blakerouse commented Aug 23, 2024

What does this PR do?

Adds a new docker variant of elastic-agent-service that includes the python connectors.

Currently this PR includes the following PR until that PR is merged - #5338

Why is it important?

Used by the Elastic Agent service.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [ ] I have made corresponding change to the default configuration files
  • [ ] I have added tests that prove my fix is effective or that my feature works
  • [ ] I have added an entry in ./changelog/fragments using the changelog tool (not really user facing at this level)
  • [ ] I have added an integration test or an E2E test

Disruptive User Impact

None.

How to test this PR locally

$ PLATFORMS="linux/arm64" PACKAGES="docker" SNAPSHOT="true" EXTERNAL="true" DOCKER_VARIANTS="service" mage package
$ docker run -it --rm docker.elastic.co/beats-ci/elastic-agent-service:8.16.0-SNAPSHOT

@blakerouse blakerouse added Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team backport-skip labels Aug 23, 2024
@blakerouse blakerouse self-assigned this Aug 23, 2024
Copy link
Member

@seanstory seanstory left a comment

Choose a reason for hiding this comment

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

Few nits but this is super exciting. Thank you so much for your help, it would have taken us ages to figure out how to stitch into this system. 🙏

source: '{{.AgentDropPath}}/archives/{{.GOOS}}-{{.AgentArchName}}.tar.gz/connectors-{{ beat_version }}{{if .Snapshot}}-SNAPSHOT{{end}}.zip'
mode: 0755
'data/{{.BeatName}}-{{ commit_short }}/components/connectors':
source: '{{ elastic_beats_dir }}/dev-tools/packaging/files/linux/connectors.py'
Copy link
Member

Choose a reason for hiding this comment

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

I expect this will end up being a bash script rather than python, but I don't think that really matters right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it doesn't matter. Just need to know what the contents should be.


{{- if (and (contains .image_name "-complete") (contains .from "ubuntu")) }}
{{- if eq .Variant "service" }}
RUN apk add --no-cache python-3.12 py3.12-pip && \
Copy link
Member

Choose a reason for hiding this comment

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

We don't support python 3.12 yet :( It's on our roadmap, but 3.11 is probably better for now. See elastic/connectors#2734 for details

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can lower the version, once we know whats in the execution script. By the time its ready you might support 3.12 :-)

Copy link
Member

Choose a reason for hiding this comment

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

I don't expect 3.12 support to make it that fast. :) We were on 3.10 for about 2 years before we just added 3.11 a few weeks ago. Urgency is not there.

{{- if (and (contains .image_name "-complete") (contains .from "ubuntu")) }}
{{- if eq .Variant "service" }}
RUN apk add --no-cache python-3.12 py3.12-pip && \
pip install {{ $beatHome }}/data/service_downloads/connectors-*.zip && \
Copy link
Member

Choose a reason for hiding this comment

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

Would be safer to unzip and make install, as that'll also give it a python virtual environment, and keep it resileint to any other system python deps that might end up in this image one day.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can do that, seems a little un-needed being this is the only python used in the image. The simple pip install without requiring unzip to be installed in the image seems better to me.

Copy link
Member

Choose a reason for hiding this comment

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

it's best practice (AFAIU) to not use system python if you can help it. Also by using a make target, it allows us to hook into other setup bits. For example, our make isntall insures that bin/pip install --upgrade pip and bin/pip install --upgrade setuptools are both run, and also ensure that the right requirements/$ARCH.txt is selected, depending upon the OS that it's being run on.

@blakerouse
Copy link
Contributor Author

Just note I am blocked on making any more progress on this PR, under we know what the contents of the bash script should be and I believe we are waiting for the python version of the elastic-agent-client to be included in the DRA or possibly in a pypi dist (some way of getting it).

@seanstory
Copy link
Member

I am blocked on making any more progress on this PR, under we know what the contents of the bash script should be

Can we not merge it as is, and follow up later with edits to make the binary more "real"? Is there some sort of testing bar that happens for each included binary that we need to to be able to meet?

I believe we are waiting for the python version of the elastic-agent-client to be included in the DRA

@artem-shelkovnikov is currently working on that, but is needing to do some repo restructuring so that the private-repo py-elastic-agent-client lib can be installed in this docker image, but won't prevent community members from cloning and building self-managed connectors from source.

@mergify
Copy link
Contributor

mergify bot commented Aug 28, 2024

This pull request is now in conflicts. Could you fix it? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

git fetch upstream
git checkout -b agent-service-docker upstream/agent-service-docker
git merge upstream/main
git push upstream agent-service-docker

@artem-shelkovnikov
Copy link
Member

👋 We should be unblocked on making progress on this PR.

We've recently merged elastic/connectors#2787 that has a component ready to be ran.

To run the component you'd need:

  1. Pull the repo
  2. Run make install-agent in the root of the repo
  3. Use python from the virtual environment to run the component: .venv/bin/python connectors/agent/cli.py

I tested this code locally by having an agent downloaded and adding component and component spec into the components with following code (would need to be adapted to run in the docker image):

artemshelkovnikov-m2@Work-M2 components % cat connectors-agent
#!/bin/bash
FOLDER=/Users/artemshelkovnikov-m2/git_tree/connectors-py/.venv/bin

$FOLDER/elastic-agent-connectors $FOLDER/elastic-agent-connectors

artemshelkovnikov-m2@Work-M2 components % cat connectors-agent.spec.yml
version: 2
inputs:
  - name: connectors-py
    description: "Connectors Py component input"
    platforms: &platforms
      - linux/amd64
      - linux/arm64
      - darwin/amd64
      - darwin/arm64
      - windows/amd64
      - container/amd64
      - container/arm64
    outputs: &outputs
      - elasticsearch
    shippers: &shippers
      - shipper
    command: &command
      restart_monitoring_period: 5s
      maximum_restarts_per_period: 1
      timeouts:
        restart: 1s
      args: []

@seanstory
Copy link
Member

Woo!! Thanks, Artem!
@blakerouse , we were also talking in a call today with @cmacknz , who suggested that we should make sure that this PR also includes some basic smoke tests that validate that Agent can start the connector binary, and do some basic communication. This will be really valuable for us since we're using a new python agent client, so anything that can catch basic problems earlier in the build/test pipeline is good. :)

@blakerouse
Copy link
Contributor Author

@artem-shelkovnikov I am unable to get this to actually build, I am getting the following error calling make install-agent. I also had to change it to also install git and make in the container to even get make install-agent to run, which is why I preferred the pip install .zip method.

Let me know how to solve this issue:

28.90 Due to the length of these fields, this option is best paired with --format=json.
28.91 .venv/bin/pip install -r requirements/agent.txt
29.04 Collecting elastic-agent-client@ git+https://github.com/elastic/python-elastic-agent-client@main (from -r requirements/agent.txt (line 1))
29.04   Cloning https://github.com/elastic/python-elastic-agent-client (to revision main) to /tmp/pip-install-aqhch75y/elastic-agent-client_7cbc275ad90345f7ac781fecfb1014d3
29.04   Running command git clone --filter=blob:none --quiet https://github.com/elastic/python-elastic-agent-client /tmp/pip-install-aqhch75y/elastic-agent-client_7cbc275ad90345f7ac781fecfb1014d3
29.22   fatal: could not read Username for 'https://github.com': No such device or address
29.22   error: subprocess-exited-with-error
29.22   
29.22   × git clone --filter=blob:none --quiet https://github.com/elastic/python-elastic-agent-client /tmp/pip-install-aqhch75y/elastic-agent-client_7cbc275ad90345f7ac781fecfb1014d3 did not run successfully.
29.22   │ exit code: 128
29.22   ╰─> See above for output.
29.22   
29.22   note: This error originates from a subprocess, and is likely not a problem with pip.
29.23 error: subprocess-exited-with-error
29.23 
29.23 × git clone --filter=blob:none --quiet https://github.com/elastic/python-elastic-agent-client /tmp/pip-install-aqhch75y/elastic-agent-client_7cbc275ad90345f7ac781fecfb1014d3 did not run successfully.
29.23 │ exit code: 128
29.23 ╰─> See above for output.
29.23 
29.23 note: This error originates from a subprocess, and is likely not a problem with pip.
29.25 make: Leaving directory '/usr/share/elastic-agent/data/service/elasticsearch_connectors-8.16.0'
29.25 make: *** [Makefile:28: install-agent] Error 1
------
Dockerfile:136
--------------------
 135 |         chown elastic-agent:elastic-agent /app
 136 | >>> RUN apk add --no-cache git make python-3.11 py3.11-pip && \
 137 | >>>     unzip /usr/share/elastic-agent/data/service/connectors-*.zip -d /usr/share/elastic-agent/data/service && \
 138 | >>>     make -C /usr/share/elastic-agent/data/service/elasticsearch_connectors-* install-agent && \
 139 | >>>     chmod 0755 /usr/share/elastic-agent/data/elastic-agent-*/components/connectors
 140 |     
--------------------

@blakerouse
Copy link
Contributor Author

@seanstory I can add an integration test using this container, once I have it building and working.

@artem-shelkovnikov
Copy link
Member

@blakerouse the problem comes from the fact that connectors dependency is a private Elastic repository.

We had to work around this with this change: https://github.com/elastic/ci/pull/3327

Additionally, we're gonna be opening the private repo ASAP.

I don't think it would work even if we provided a zip or any other artifact, as the problem is with access to the dependency?

@blakerouse
Copy link
Contributor Author

@artem-shelkovnikov Opening it to be public would make this much easier and allow developers to build this locally with our simple mage package target in the Elastic Agent repository. ETA on public access?

@artem-shelkovnikov
Copy link
Member

ETA unknown - I've submitted a request to #open-source here: https://github.com/elastic/open-source/issues/443

Open source team will look at it today and best case will allow to open it up, I'll follow up here after I get a response

@seanstory
Copy link
Member

We just got the approval, and https://github.com/elastic/python-elastic-agent-client now has public/open visibility 🎉
@blakerouse can you try again?

@blakerouse
Copy link
Contributor Author

@seanstory @artem-shelkovnikov Nice! I did get it to build. With it built I ran the container and tried to execute the elastic-agent-connectors binary and I am getting the following error (this should be using the venv for python):

bash-5.2$ data/service/elasticsearch_connectors-8.16.0/.venv/bin/elastic-agent-connectors 
Traceback (most recent call last):
  File "/usr/share/elastic-agent/data/service/elasticsearch_connectors-8.16.0/.venv/bin/elastic-agent-connectors", line 33, in <module>
    sys.exit(load_entry_point('elasticsearch-connectors', 'console_scripts', 'elastic-agent-connectors')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/elastic-agent/data/service/elasticsearch_connectors-8.16.0/.venv/bin/elastic-agent-connectors", line 25, in importlib_load_entry_point
    return next(matches).load()
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/metadata/__init__.py", line 202, in load
    module = import_module(match.group('module'))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'connectors.agent'

Check its using python from venv:

bash-5.2$ head data/service/elasticsearch_connectors-8.16.0/.venv/bin/elastic-agent-connectors
#!/usr/share/elastic-agent/data/service/elasticsearch_connectors-8.16.0/.venv/bin/python

@seanstory
Copy link
Member

Fixed by elastic/connectors#2811. Sorry about that. New DRAs should be available momentarily. 🤞

@blakerouse
Copy link
Contributor Author

@seanstory

I don't think the DRA has that change or even the change that was merged last week, or something is wrong

The contents of the DRA only show the following

bash-5.2$ ls
VERSION                __pycache__            config.py              content_extraction.py  filtering              logger.py              protocol               services               sync_job_runner.py
__init__.py            access_control.py      connectors_cli.py      es                     kibana.py              preflight_check.py     service_cli.py         source.py              utils.py

which doesn't have the agent or cli directory at all

@seanstory
Copy link
Member

seanstory commented Sep 10, 2024

For those watching, we solved the missing dir issue with a three-part combo of:

and now we're discussing further hiccups in this slack thread.

@mergify
Copy link
Contributor

mergify bot commented Sep 10, 2024

backport-v8.x has been added to help with the transition to the new branch 8.x.

@mergify
Copy link
Contributor

mergify bot commented Sep 11, 2024

backport-v8.x has been added to help with the transition to the new branch 8.x.

@mergify mergify bot added the backport-8.x Automated backport to the 8.x branch with mergify label Sep 11, 2024
@mergify
Copy link
Contributor

mergify bot commented Sep 11, 2024

This pull request is now in conflicts. Could you fix it? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

git fetch upstream
git checkout -b agent-service-docker upstream/agent-service-docker
git merge upstream/main
git push upstream agent-service-docker

@elasticmachine
Copy link
Contributor

Pinging @elastic/elastic-agent-control-plane (Team:Elastic-Agent-Control-Plane)

@blakerouse
Copy link
Contributor Author

@seanstory I finally have a passing integration test for this new container. Its all working now. Just need a review and it can be merged.

@blakerouse blakerouse requested review from pkoutsovasilis and removed request for andrzej-stencel September 20, 2024 20:31
@pkoutsovasilis
Copy link
Contributor

pkoutsovasilis commented Sep 20, 2024

hey @blakerouse 👋 I left only a minor comment that I think you need to address. However, may I join forces with you here and push a Helm-chart based integration test? I was looking for a reason to add a custom integration/input test for the agent Helm chart and this one seems like ideal. Or maybe it can be a follow up pull request, no prob with that either I have thought about it I am gonna open a follow up PR when this one is merged 😉

@blakerouse
Copy link
Contributor Author

@pkoutsovasilis Fixed

Copy link
Contributor

@pkoutsovasilis pkoutsovasilis left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines +1162 to +1164
// never flatten any python wheels, the packages.yml and docker should handle
// those specifically so that the python wheels are installed into the container
matches = removePythonWheels(matches, packageVersion)
Copy link
Member

Choose a reason for hiding this comment

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

Is there an alternative to adding the PythonWheel binary specs to the ExpectedBinaries just to remove them from the flattened directory? The connectors are added to ExpectedBinaries just to download the archive ?
If the handling of connectors is different from the other components' binaries we package with agent maybe we can separate the handling with a collectAdditionalDependencies target after flattening or something similar ?
My understanding is also that these dependencies are not needed to create an agent archive but get installed when we run docker build, maybe we can move the processing at that stage ?

@blakerouse
Copy link
Contributor Author

buildkite test this

1 similar comment
@blakerouse
Copy link
Contributor Author

buildkite test this

@blakerouse blakerouse enabled auto-merge (squash) September 26, 2024 20:47
@elastic-sonarqube
Copy link

@blakerouse blakerouse merged commit 701f8b9 into elastic:main Sep 30, 2024
mergify bot pushed a commit that referenced this pull request Sep 30, 2024
Adds the elastic-agent-service container with the py-connectors component enabled.

(cherry picked from commit 701f8b9)

# Conflicts:
#	dev-tools/mage/manifest/manifest.go
pierrehilbert pushed a commit that referenced this pull request Oct 14, 2024
#5634)

* Add elastic-agent-service container to packaging (#5349)

Adds the elastic-agent-service container with the py-connectors component enabled.

(cherry picked from commit 701f8b9)

# Conflicts:
#	dev-tools/mage/manifest/manifest.go

* Update manifest.go

Fix conflicts caused by mergify

* Include python wheel packages when moving downloaded dependencies archives (#5647)

This commit modifies movePackagesToArchive() function to include python
wheel packages introduced with commit 701f8b9 .
This solves an issue when packaging docker images using a DROP_PATH env
var: prior to this change, the python wheel archives present in
DROP_PATH were not moved to `<DROP PATH>/archive/<platform>` failing to
create an image for which the Dockerfile expects to install the python
wheel package

* Fix docker image build when multiple platforms are specified (#5658)

Force merging to unblock the unified release process

---------

Co-authored-by: Blake Rouse <blake.rouse@elastic.co>
Co-authored-by: Julien Lind <julien.lind@elastic.co>
Co-authored-by: Paolo Chilà <paolo.chila@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-8.x Automated backport to the 8.x branch with mergify skip-changelog Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants