Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix permissions for config files used in tests #42914

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

AndersonQ
Copy link
Member

@AndersonQ AndersonQ commented Feb 26, 2025

Proposed commit message

relax permissions checks for config files on test

set `strict.perms` flag to false on test that load config files committed to the
repo.

By default, beats require the config files to be writable only by the file 
owner, so tests reading config files committed do the repo might fail depending 
on how the host system is configured. For those tests the permission check is 
relaxed.

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.next.asciidoc or CHANGELOG-developer.next.asciidoc.

Disruptive User Impact

  • N/A

How to test this PR locally

tl;dr: no unit/system test should fail due to a configuration file with the wrong permissions.

  • set the system umask to 002
  • run the tests with the new test framework:
cd filebeat/testing/integration
go test -v -tags integration -run TestFilebeat
  • it should succeed, before it'd fail with:
[...]
        Exiting: error loading config file: config file ("/tmp/TestFilebeatFilebeat_starts_and_ingests_filesplain_text_files1677938519/002/filebeat.yml") can only be writable by the owner but the permissions are "-rwxrwxr-x" (to fix the permissions use: 'chmod go-w /tmp/TestFilebeatFilebeat_starts_and_ingests_filesplain_text_files1677938519/002/filebeat.yml')
[...]
  • try some of the other unit tests, but first ensure the configuration files have the wrong permissions
cd metricbeat/mb/testdata
chmod -R go+w ./
go test -run TestProcessorsForMetricSet_FromSource ./
  • it should succeed. Before it's fail with:
❯ go test -run TestProcessorsForMetricSet_FromSource ./              
--- FAIL: TestProcessorsForMetricSet_FromSource (0.00s)
    registry_test.go:245: 
        	Error Trace:	/home/ainsoph/devel/github.com/elastic/beats/metricbeat/mb/registry_test.go:245
        	Error:      	Received unexpected error:
        	            	reading processors for metricset 'withprocessors' in module 'unpack': loading light module 'unpack' definition: loading module configuration from 'testdata/lightmodules/unpack/module.yml': config file ("testdata/lightmodules/unpack/module.yml") can only be writable by the owner but the permissions are "-rw-rw-r--" (to fix the permissions use: 'chmod go-w /home/ainsoph/devel/github.com/elastic/beats/metricbeat/mb/testdata/lightmodules/unpack/module.yml')
        	Test:       	TestProcessorsForMetricSet_FromSource
FAIL
FAIL	github.com/elastic/beats/v7/metricbeat/mb	0.082s
FAIL

Related issues

@AndersonQ AndersonQ self-assigned this Feb 26, 2025
@botelastic botelastic bot added the needs_team Indicates that the issue/PR needs a Team:* label label Feb 26, 2025
Copy link
Contributor

mergify bot commented Feb 26, 2025

This pull request does not have a backport label.
If this is a bug or security fix, could you label this PR @AndersonQ? 🙏.
For such, you'll need to label your PR with:

  • The upcoming major version of the Elastic Stack
  • The upcoming minor version of the Elastic Stack (if you're not pushing a breaking change)

To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-8./d is the label to automatically backport to the 8./d branch. /d is the digit
  • backport-active-all is the label that automatically backports to all active branches.
  • backport-active-8 is the label that automatically backports to all active minor branches for the 8 major.
  • backport-active-9 is the label that automatically backports to all active minor branches for the 9 major.

@AndersonQ AndersonQ added Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team backport-8.x Automated backport to the 8.x branch with mergify labels Feb 27, 2025
@botelastic botelastic bot removed the needs_team Indicates that the issue/PR needs a Team:* label label Feb 27, 2025
The tests which rely on reading config from disk did not correctly set the 
permissions. The beats require the config files must be writable only by the 
owner, now the tests explicitly set the permissions accordingly.

A new `testcfg` package provides `NewFileWith644Perm` and
`CopyDirectoryWithOwnerWriteOnly` as helper functions for tests to create 
a temporary copy of the files committed to the repo to use in the test.

The test framework was also adjusted to save the config file with the correct 
permission.
@AndersonQ AndersonQ force-pushed the 42779-fix-test-config-creation branch from 0151d2e to dc61260 Compare February 27, 2025 08:03
@AndersonQ AndersonQ marked this pull request as ready for review February 27, 2025 08:03
@AndersonQ AndersonQ requested a review from a team as a code owner February 27, 2025 08:03
@elasticmachine
Copy link
Collaborator

Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane)

@AndersonQ AndersonQ changed the title [WIP] Fix permissions for config files used in tests Fix permissions for config files used in tests Feb 27, 2025
Copy link
Member

@rdner rdner left a comment

Choose a reason for hiding this comment

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

I'm not convinced we need an entire package with helpers. Especially copying files just to change permissions does not seem justified.

Instead I think we should fix permissions on the existing files use for testing. Or assert permissions as a part of the tests.

If we create files we have full control over permissions, so we just need to fix these occurrences.

@@ -41,17 +42,24 @@ func makeTestInfo(version string) beat.Info {
}
}

func getModuleForTesting(t *testing.T, module, fileset string) *Fileset {
func getModuleForTesting(t *testing.T, module, fileset string, filesetCfg *FilesetConfig) *Fileset {
Copy link
Member

Choose a reason for hiding this comment

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

Why filesetCfg *FilesetConfig was introduced if it's always nil in all usages? Can't we just always pass nil to the New function?

Copy link
Member Author

Choose a reason for hiding this comment

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

it's not always nil:

that's why it was introduced as a parameter. getModuleForTesting ensures the configuration files will have the correct permissions, thus I changed TestEvaluateVarsNginxOverride and TestGetInputConfigNginxOverrides to call it instead of calling New directly

Comment on lines 85 to 86
fixedModulesPath := testcfg.CopyDirectoryWithOwnerWriteOnly(t, modulesPath, "")
reg, err := newModuleRegistry(fixedModulesPath, configs, nil, beat.Info{Version: "5.2.0"}, FilesetOverrides{})
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need copy? Why can't we assert permissions and change them on the existing files?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think tests should be doing permanent changes on the repo, that's why I took this approach of copying the files as it isn't possible to commit the full file permission to git.

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 think tests should be doing permanent changes on the repo, that's why I took this approach of copying the files as it isn't possible to commit the full file permission to git.

This is not entirely true, git stores permissions but only 2 possible values 644 and 755 which you can set/switch with git update-index --chmod=+x.

So, unless you switch the executable flag, git would not detect permission changes and for git the repository remains untouched.

I still don't think that copying files is a good idea, it increases the load on CI for no reason and complicates our tests.

We should create files with right permissions and assert files to be with right permissions without copying files. The only exception is when the test data is supposed to be changed by the test.

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 think tests should be doing permanent changes on the repo, that's why I took this approach of copying the files as it isn't possible to commit the full file permission to git.

I don't see it as a permanent change, it's a part of the test setup to make sure that the permissions on the test files are correct. We would not commit these changes to the repository, so I'm confused about "permanent" here.

Copy link
Member Author

Choose a reason for hiding this comment

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

"permanent" as in after the test run the original state of the files won't be restored.

it increases the load on CI for no reason and complicates our tests.

I don't think there is concrete evidence this overhead will be significant. We probably have other things that can be improved if we want to make CI performance better.

I still don't think that copying files is a good idea

I don't see why it's a problem, given as I said above I don't believe the overhead is any issue. Much more problematic is the unit tests making permanent changes to files. That's why I don't see as a good solution a "single function Ensure644 that walks the directory, and sets 644 permission to every file".

Copy link
Member

Choose a reason for hiding this comment

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

Rather than writing a bunch of code to solve this, my thought would be to just relax the permissions checks in the beats during these tests.

It turns out we have had this problem before and there is already a flag that does this, --strict-perms. It is also available as the BEAT_STRICT_PERMS environment variable:

// IsStrictPerms returns true if strict permission checking on config files is
// enabled.
func IsStrictPerms() bool {
if !*flagStrictPerms || os.Getenv("BEAT_STRICT_PERMS") == "false" {
return false
}
return true
}

It turns off exactly the error we are seeing:

func LoadFile(path string) (*config.C, error) {
if IsStrictPerms() {
if err := OwnerHasExclusiveWritePerms(path); err != nil {
return nil, err
}
}

Pretty much every metricbeat module test already sets this. It is very widely used in our other tests. https://github.com/search?q=repo%3Aelastic%2Fbeats%20BEAT_STRICT_PERMS&type=code

Can we make this problem go away by using --strict.perms=false or BEAT_STRICT_PERMS=false in the new framework instead?

Copy link
Member

Choose a reason for hiding this comment

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

@AndersonQ FYI: we already set permissions to a Filebeat configuration file in another test

const configPath = "../test/filebeat_test.yml"
// Ensure that the config has owner-exclusive write permissions.
// This is necessary on some systems which have a default umask
// of 0o002, meaning that files are checked out by git with mode
// 0o664. This would cause cfgfile.Load to fail.
err = os.Chmod(configPath, 0o644)
to make it work. What I describe is not new.

Copy link
Member Author

Choose a reason for hiding this comment

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

It turns out we have had this problem before and there is already a flag that does this, --strict-perms. It is also available as the BEAT_STRICT_PERMS environment variable:

that's interesting. I'll set it them

I confess I wonder why we have this strict permission requirement in place.

@AndersonQ
Copy link
Member Author

Instead I think we should fix permissions on the existing files use for testing.

Git does not save the full set of permissions, it only saves if the file is executable or not. So we can't just fix the permissions on the git repo.

Also having the test permanently changing the files does not seems a good approach.

If we create files we have full control over permissions, so we just need to fix these occurrences.

If we do it in runtime, yes, I just believe the current approach is better than changing all the affected tests to create the files in runtime.

I'm not convinced we need an entire package with helpers. Especially copying files just to change permissions does not seem justified.

as I said above, the alternative would be to make all the tests to create the files in runtime. It's an option, but I think the current approach is less intrusive.

@AndersonQ AndersonQ requested a review from rdner March 5, 2025 13:35
@rdner
Copy link
Member

rdner commented Mar 6, 2025

@AndersonQ can we just create a single function Ensure644 that walks the directory, and sets 644 permission to every file?

As I explained #42914 (comment) git should not detect changes unless the executable flag is flipped.

@pierrehilbert
Copy link
Collaborator

Considering this is only fixing tests, shouldn't we backport this to all active branches?

@AndersonQ AndersonQ added backport-active-all Automated backport with mergify to all the active branches and removed backport-8.x Automated backport to the 8.x branch with mergify labels Mar 7, 2025
set `strict.perms` flag to false on test that load config files committed to the repo.

By default beats require the config files to be writable only by the file owner, so tests reading config files committed do the repo might fail depending on how the host system is configured. For those tests the permission check is relaxed.
@AndersonQ
Copy link
Member Author

Considering this is only fixing tests, shouldn't we backport this to all active branches?

done

@AndersonQ
Copy link
Member Author

@AndersonQ can we just create a single function Ensure644 that walks the directory, and sets 644 permission to every file?

As I explained #42914 (comment) git should not detect changes unless the executable flag is flipped.

I followed Craig's suggestion and relaxed the permission check instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-active-all Automated backport with mergify to all the active branches Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test framework incorrectly creates beat config file
5 participants