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

Log impilict constraints to log if level=trace #25233

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .changelog/25233.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
server: add the log output of the implicit constraints that are considered in the scheduling decision when the log level is `trace`.
```
4 changes: 2 additions & 2 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ def configureLinuxProvisioners(vmCfg)

vmCfg.vm.provision "shell",
privileged: true,
path: './scripts/linux-priv-go.sh'
path: './scripts/linux-priv-config.sh'

vmCfg.vm.provision "shell",
privileged: true,
path: './scripts/linux-priv-config.sh'
path: './scripts/linux-priv-go.sh'

vmCfg.vm.provision "shell",
privileged: true,
Expand Down
8 changes: 7 additions & 1 deletion contributing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ A development environment is supplied via Vagrant to make getting started easier
```sh
$ vagrant ssh
```

1. Previous command opens a shell. Execute the tests in that shell:
```sh
cd /opt/gopath/src/github.com/hashicorp/nomad
sudo su
make bootstrap
PATH=/root/go/bin:$PATH make test
```
Developing without Vagrant
---
1. Install [Go 1.23.6+](https://golang.org/) *(Note: `gcc-go` is not supported)*
Expand Down
6 changes: 6 additions & 0 deletions nomad/job_endpoint_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ func (j *Job) admissionMutators(job *structs.Job) (_ *structs.Job, warnings []er
}
warnings = append(warnings, w...)
}
//if trace is enabled, print out all constraints
if j.logger.IsTrace() {
for _, constraint := range job.CollectConstraints() {
j.logger.Trace("constraint of job", "constraint", constraint, "ID", job.ID)
}
}
return job, warnings, err
}

Expand Down
72 changes: 72 additions & 0 deletions nomad/job_endpoint_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,90 @@
package nomad

import (
"errors"
"slices"
"strings"
"testing"
"time"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/ci"
"github.com/hashicorp/nomad/helper/pointer"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/nomad/structs/config"
"github.com/hashicorp/nomad/testutil"
"github.com/shoenig/test/must"
)

type traceLevelConstraintAttributeCollector struct {
constraints []string
}

// Accept implements hclog.SinkAdapter.
func (l *traceLevelConstraintAttributeCollector) Accept(name string, level hclog.Level, msg string, args ...interface{}) {
if level == hclog.Trace {
if len(args)%2 != 0 {
panic(errors.New("args must contains an even number of elements"))
}
//idx is the index of the log argument `constraint`.
idx := slices.IndexFunc(args, func(a interface{}) bool {
v, ok := a.(string)
if !ok {
return false
}
return v == "constraint"
})
if idx != -1 {
if len(args) < idx+1 {
panic(errors.New("in logging args, after the arg constraint must follow another arg"))
}
constraintInNextArg := args[idx+1]
l.constraints = append(l.constraints, constraintInNextArg.(string))
}
}
}

var _ hclog.SinkAdapter = &traceLevelConstraintAttributeCollector{}

func TestConstrainsAreWrittenToLogIfLoglevelIsTrace(t *testing.T) {
ci.Parallel(t)
collector := &traceLevelConstraintAttributeCollector{}
srv, cleanup := TestServer(t, func(c *Config) {
c.NumSchedulers = 0
})
srv.logger.RegisterSink(collector)

t.Cleanup(cleanup)
testutil.WaitForLeader(t, srv.RPC)

jobEndpoint := NewJobEndpoints(srv, nil)

j := mock.ConnectJob()
j.TaskGroups[0].Services[0].Name = "${JOB}-api"
j, warnings, err := jobEndpoint.admissionMutators(j)
must.NoError(t, err)
must.Nil(t, warnings)

constraints := j.CollectConstraints()
//all Constraints found in structs.Job are printed to logger with level trace
must.Eq(t, 10, len(constraints))
expected := []string{
"${attr.kernel.name} = linux",
"${attr.consul.version} semver >= 1.8.0",
"${attr.plugins.cni.version.bridge} semver >= 0.4.0",
"${attr.plugins.cni.version.firewall} semver >= 0.4.0",
"${attr.plugins.cni.version.host-local} semver >= 0.4.0",
"${attr.plugins.cni.version.loopback} semver >= 0.4.0",
"${attr.plugins.cni.version.portmap} semver >= 0.4.0",
"${attr.consul.version} semver >= 1.8.0",
"${attr.consul.version} semver >= 1.8.0",
"${attr.consul.grpc} > 0",
}
must.SliceEqOp(t, constraints, collector.constraints)
must.SliceEqOp(t, expected, collector.constraints)
}

func Test_jobValidate_Validate_consul_service(t *testing.T) {
ci.Parallel(t)

Expand Down
23 changes: 23 additions & 0 deletions nomad/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6522,6 +6522,29 @@ func (j *Job) UsesDeployments() bool {
}
}

type constraintCollectors struct {
constraints []string
}

func (cc *constraintCollectors) append(constraints []*Constraint) {
for _, c := range constraints {
cc.constraints = append(cc.constraints, c.String())
}

}

func (j *Job) CollectConstraints() []string {
cc := constraintCollectors{}
cc.append(j.Constraints)
for _, tg := range j.TaskGroups {
cc.append(tg.GetConstraints())
for _, t := range tg.Tasks {
cc.append(t.GetConstraints())
}
}
return cc.constraints
}

// ScalingPolicyListStub is used to return a subset of scaling policy information
// for the scaling policy list
type ScalingPolicyListStub struct {
Expand Down
Loading