Skip to content

Conversation

@psaintlaurent
Copy link
Contributor

@psaintlaurent psaintlaurent commented Jun 11, 2024

- What I did
Add OOMScoreAdj to the moby API

- How I did it
I modified the executor, convertor and API to accept OOMScoreAdj

- How to test it
Using the swarmkit PR
moby/swarmkit#3177

Start moby using make BIND_DIR=. DOCKER_DEBUG=1 DELVE_PORT=127.0.0.1:2345:2345 shell
make install
./hack/make.sh run

Use curl to query agains the API to verify the changes or you can use the docker CLI from

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Thanks! I left some comments; can you also add a bullet under the v1.46 changes in the API "version history"? https://github.com/moby/moby/blob/master/docs/api/version-history.md

As this affects the swarm API endpoints, it would be changing multiple endpoints (at least "create" and "update". You can find some prior examples of such changes, e.g. like;

POST /services/create and POST /services/{id}/update now accept Seccomp and AppArmor fields in the ContainerSpec.Privileges object. This allows some configuration of Seccomp and AppArmor in Swarm services.

api/common.go Outdated
const (
// DefaultVersion of the current REST API.
DefaultVersion = "1.46"
DefaultVersion = "1.47"
Copy link
Member

Choose a reason for hiding this comment

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

APi 1.46 has not yet been released (but will be with docker v27.0.0) so you can keep it at the current version.

"context"
"encoding/json"
"fmt"
"github.com/opencontainers/go-digest"
Copy link
Member

Choose a reason for hiding this comment

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

looks like an accidental change

Comment on lines 401 to 403
Sysctls: c.spec().Sysctls,
CapAdd: c.spec().CapabilityAdd,
CapDrop: c.spec().CapabilityDrop,
Copy link
Member

Choose a reason for hiding this comment

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

Not for this PR, but looking at this list, I'm wondering if there's other properties that are actually wired up, but that were forgotten to be included in the swagger.

If that's the case, we should fix that 🤔

Copy link
Member

Choose a reason for hiding this comment

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

See my other comment; we can include these changes in v1.46 (which didn't ship yet); we'll create the v1.46.yaml short before release.

@thaJeztah
Copy link
Member

This probably also needs to be gated by API version (both for create and update ; similar to

version := httputils.VersionFromContext(ctx)
if versions.LessThan(version, "1.44") {
if service.TaskTemplate.ContainerSpec != nil && service.TaskTemplate.ContainerSpec.Healthcheck != nil {
// StartInterval was added in API 1.44
service.TaskTemplate.ContainerSpec.Healthcheck.StartInterval = 0
}
}

@thaJeztah
Copy link
Member

I see you made some updates, but at least one commit is missing a DCO sign-off.

It's probably fine for all commits to be in a single commit; can you squash the commits and add the sign-off? (otherwise CI won't run 😅)

`--sysctl` settings for `eth0` will be migrated to `DriverOpts` when possible.
This automatic migration will be removed for API versions 1.47 and greater.

* `POST /services/create` now supports OomScoreAdj
Copy link
Member

Choose a reason for hiding this comment

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

Can you mention the update endpoint as well?

Copy link
Contributor Author

@psaintlaurent psaintlaurent Jun 13, 2024

Choose a reason for hiding this comment

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

I only made modifications for create not update.

Copy link
Member

Choose a reason for hiding this comment

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

I think the same type is used for updating services as well; or at least, I think any property that can be set when creating a service must also be able to be changed (updateable) for the service (and swarmkit will reconcile)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think @thaJeztah has a point. Look at the most recent PR to extend the POST /services/create endpoint prior to this one: #46386. It affects both create and update. IIRC, when a Swarm service is updated, the Swarm scheduler reconciles by replacing all running tasks with new tasks that follow the updated task template in the service spec.

@psaintlaurent psaintlaurent force-pushed the ENGINE-903 branch 2 times, most recently from c559d59 to c9897ea Compare June 13, 2024 20:02
CapabilityAdd []string `json:",omitempty"`
CapabilityDrop []string `json:",omitempty"`
Ulimits []*units.Ulimit `json:",omitempty"`
OomScoreAdj int64 `json:",omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm torn. On the one hand, coding style dictates that this field should be spelled OOMScoreAdj on account of "OOM" being an initialism for "out of memory." On the other hand, we have existing precedent in the API for this spelling, with (container.HostConfig).OomScoreAdj.

OomScoreAdj int // Container preference for OOM-killing

I am okay with either spelling. Anyone have a strong opinion one way or the other?

Copy link
Contributor

Choose a reason for hiding this comment

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

Match the existing API field name. No reason to make Swarmkit any more different than it already is.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I hate the Oom, but agree if it's matching the engine API, it's fine.

@psaintlaurent psaintlaurent force-pushed the ENGINE-903 branch 4 times, most recently from ca7d893 to 9f989d6 Compare June 13, 2024 21:02
@corhere corhere marked this pull request as draft June 13, 2024 21:58
@psaintlaurent psaintlaurent marked this pull request as ready for review June 14, 2024 17:04
@psaintlaurent psaintlaurent marked this pull request as draft June 14, 2024 17:05
api/swagger.yaml Outdated
Shared: true
Size: 0
CreatedAt: "2021-06-28T13:31:01.474619385Z"
CreatedAt: "2021-06-28T13:31:01.464619385Z"
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did this line change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a typo, I'l be more careful about proofreading.

Comment on lines 235 to 240
if versions.LessThan(version, "1.46") {
if service.TaskTemplate.ContainerSpec != nil && service.TaskTemplate.ContainerSpec.OomScoreAdj != 0 {
// OomScoreAdj was added in API 1.46
service.TaskTemplate.ContainerSpec.OomScoreAdj = 0
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this function the right place for this code? In #46386 the equivalent change was made in func adjustForAPIVersion, which is called by both func createService and func updateService. (I think above code block for Healthcheck.StartInterval is also misplaced.)

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'm not certain, I'm following the pattern that already exists in that function. I haven't read the entire codebase yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

I asked @dperny: unfortunately, the pattern you copied was buggy code. I have opened a PR to address that deficiency. #47991

You will need to move the gating of OomScoreAdj by API version into func adjustForAPIVersion so that it applies to both create and update operations. And you will have to update version-history.md to mention that support was added to both the create and update API endpoints.

Copy link
Contributor Author

@psaintlaurent psaintlaurent Jun 16, 2024

Choose a reason for hiding this comment

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

I read through that code and debugged it manually earlier. It works as intended but I have to infer the intended behavior through existing code patterns as there is no documentation to work off with intended behavior.

Will changing the location make a difference other than for update operations as I only worked on create.

@psaintlaurent psaintlaurent force-pushed the ENGINE-903 branch 2 times, most recently from 6f976c7 to 5ff48d0 Compare June 17, 2024 12:45
CapabilityAdd []string `json:",omitempty"`
CapabilityDrop []string `json:",omitempty"`
Ulimits []*units.Ulimit `json:",omitempty"`
OomScoreAdj int64 `json:",omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Match the existing API field name. No reason to make Swarmkit any more different than it already is.

CapabilityAdd: c.CapabilityAdd,
CapabilityDrop: c.CapabilityDrop,
Ulimits: ulimitsToGRPC(c.Ulimits),
OomScoreAdj: c.OomScoreAdj,
Copy link
Contributor

Choose a reason for hiding this comment

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

This covers containerToGRPC, but you need a matching back-conversion in containerSpecFromGRPC. Without the back-conversion, the client cannot correctly read out the ServiceSpec.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, this was an IDE issue. Goland just removed code without notice, I have to turn off a few options.

Signed-off-by: plaurent <[email protected]>
@psaintlaurent psaintlaurent marked this pull request as ready for review June 17, 2024 18:49
@corhere corhere requested a review from thaJeztah June 17, 2024 20:21
// Ulimits defines the list of ulimits to set in the container. This option
// is equivalent to passing --ulimit to docker run.
Ulimits []*ContainerSpec_Ulimit `protobuf:"bytes,29,rep,name=ulimits,proto3" json:"ulimits,omitempty"`
// OOmScoreAdj defines the relative value used for destroying a container during an OOM
Copy link
Member

Choose a reason for hiding this comment

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

Looks like the comment here doesn't match the casing of the actual field.

This is vendored code, so needs to be fixed in SwarmKit (and definitely not a blocker 😅)

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'll fix that in the morning, thanks!

// to the container OS's default - generally 60, or the value predefined in
// the image; set to -1 to unset a previously set value
google.protobuf.Int64Value memory_swappiness = 4;

Copy link
Member

Choose a reason for hiding this comment

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

Wondering where the empty lines here originated from, or is this some change in the code generating these? (just curious where the changes came from)

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@thaJeztah thaJeztah merged commit 4ea464d into moby:master Jun 17, 2024
@thaJeztah thaJeztah added this to the 27.0.0 milestone Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api API area/swarm impact/api impact/changelog kind/enhancement Enhancements are not bugs or new features but can improve usability or performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants