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

feat(lxdprofiles): add DDL and state layer for adding and retrieving LXD profiles #18140

Merged
merged 4 commits into from
Sep 27, 2024

Conversation

nvinuesa
Copy link
Member

@nvinuesa nvinuesa commented Sep 25, 2024

This small patch adds the DDL (creation of the new lxd_profile table) and the state layer to add and retrieve all lxd profiles for a given machine.

Note: the new methods use the internal/errors new convention but I haven't updated the rest of the methods, this will be done little by little or on a following PR since the machines domain will continue to evolve.

Checklist

  • Code style: imports ordered, good names, simple structure, etc
  • Comments saying why design decisions were made
  • Go unit tests, with comments saying what you're testing
  • Integration tests, with comments saying what you're testing
  • doc.go added or updated in changed packages

QA steps

Only state layer changed, so unit tests must pass.

Links

Jira card: JUJU-6808

profiles

This small patch adds the DDL (creation of the new lxd_profile table)
and the state layer to add and retrieve all lxd profiles for a given
machine.
setLXDProfileStmt, err := st.Prepare(`
INSERT INTO lxd_profile (*)
VALUES ($lxdProfile.*)
ON CONFLICT DO NOTHING`, lxdProfile{})
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 better approach is to ask which profiles haven't been inserted, and then insert the ones that are missing. This would work in our favor if there are profiles that have already been applied. You'd do nothing. Also, the number of inserts will be less.

Always prefer a read over a write. The fewer writes we have, the less contention we have, which means we're more likely to go brrrrrrrrrrrrr!

Copy link
Contributor

@gfouillet gfouillet left a comment

Choose a reason for hiding this comment

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

Mostly LGTM, I have request on TU.

domain/machine/state/state_test.go Show resolved Hide resolved
domain/machine/state/state_test.go Show resolved Hide resolved
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

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

Couple of changes please.

domain/machine/state/state.go Show resolved Hide resolved
domain/schema/model/sql/0017-machine.sql Outdated Show resolved Hide resolved
Copy link
Contributor

@gfouillet gfouillet left a comment

Choose a reason for hiding this comment

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

Few more suggestion ;)

domain/machine/state/state.go Outdated Show resolved Hide resolved
c.Assert(err, jc.ErrorIsNil)
profiles = append(profiles, profile)
}
c.Check(profiles, gc.HasLen, 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

todo: remove hasLen check, I think it is redundant with the SameContent check (which already do it)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 82a3a30.


profiles, err := s.state.LXDProfiles(context.Background(), "deadbeef")
c.Assert(err, jc.ErrorIsNil)
c.Check(profiles, gc.HasLen, 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

todo: remove hasLen check, I think it is redundant with the SameContent check (which already do it)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 82a3a30.

Comment on lines 161 to 163
machine_uuid TEXT NOT NULL,
name TEXT NOT NULL,
PRIMARY KEY (machine_uuid, name),
Copy link
Member

Choose a reason for hiding this comment

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

There is a potential pitfall here. The order in which lxd profiles are applied is important, as each successive profile over writes items defined prior profiles. The order should not change.

When a new profile is applied, it's to the end of the list. This is problematic with upgrading charms as the name of the profile includes the charm revision.

A caveat is that we always start the list of profiles for a machine with the default profile and juju-<model> profile. This never changes.

Copy link
Member

Choose a reason for hiding this comment

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

You could cheat here and when you get the machine_lxd_profile you sort by the magic rowid column.

But in reality, you need to add an index and just use the slice index when adding, and ordering it when it comes out.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice! yeah we were just discussing this with @hmlanigan and I was even thinking about adding a new column just for sorting. Because the worst case scenario was to switch back to having one row per machine and profile names would be an array somehow.

Copy link
Member

Choose a reason for hiding this comment

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

There is precedence of this:

array_index INT NOT NULL,

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines 871 to 873
SELECT &lxdProfile.name
FROM machine_lxd_profile
WHERE machine_uuid = $machineUUID.uuid`
Copy link
Member

Choose a reason for hiding this comment

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

Ensure you order by index on the way out.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, see 82a3a30.

return internalerrors.Errorf("checking if machine %q exists: %w", mUUID, err)
}

// Make sure to clean up any existing profiles on the given machine.
Copy link
Member

@SimonRichardson SimonRichardson Sep 27, 2024

Choose a reason for hiding this comment

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

Before deleting the profiles, can we check that the profiles in the rows don't already match the ones that already exist. It's very common for the SetLXDProfiles to be triggered with the same content. This comes back to only do a write query if you really need to do one.

When we do wire up lxd profiles, we'll need to insert a logical row into the change stream at the end of this to fire the worker. Hence we need that select check to ensure we're not firing additional changes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, see 6189295.

I'm interested in yours and @manadart 's thoughts on what I did, because this includes now some (small amount of) logic in the state layer. This case sits on the edge of where I'd start using RunAtomic, but IMO it can still live in the state layer.

Copy link
Member

Choose a reason for hiding this comment

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

Keep it here for now.

}

return db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error {
queryMachineUUID := machineUUID{UUID: mUUID}
Copy link
Member

Choose a reason for hiding this comment

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

Make this at the top, and pass it to the Prepare calls.

@nvinuesa
Copy link
Member Author

/merge

@jujubot jujubot merged commit bcc06c7 into juju:main Sep 27, 2024
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants