-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Implement readUser on Windows #3518
Conversation
9f84471
to
508b7fb
Compare
508b7fb
to
cf6e4af
Compare
0355063
to
aca323e
Compare
With the dependency merged, this PR is now ready for review. This is the last PR in this series. It enables useful definitions to be built natively on Windows. |
solver/llbsolver/file/backend.go
Outdated
@@ -251,6 +212,7 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * | |||
} | |||
|
|||
type Backend struct { | |||
Executor executor.Executor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wdyt if we put separate type definitions here for UNIX and windows? Logically the executor dependency really does not belong here, so would like to avoid it for UNIX case.
Another option would be to leave this type as-is and in solve()
optionally pass in some option that does the user conversion. This would then only be passed in case of windows and linux can use the default implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logically the executor dependency really does not belong here
It felt a bit yucky to add the executor there. I changed it and added a new function NewFileOpBackend()
that sets a readUserFn
in the Backend{}
. For Windows it wraps the readUser()
function which uses the executor. For everything else we just return the usual readUser()
function. This way we don't set an exported Executor
field in the Backend{}
struct.
Does that sound acceptable?
solver/llbsolver/file/backend.go
Outdated
@@ -250,7 +211,16 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * | |||
return nil | |||
} | |||
|
|||
// NewFileOpBackend returns a new file operation backend. The executor is currently only used for Windows, | |||
// and it is used to construct the readUserFn field set in the returned Backend. | |||
func NewFileOpBackend(exec executor.Executor) *Backend { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid passing this Executor
in here (and import on buildkit/executor). And instead pass a function/interface only for readuser (ideally only on windows, in linux you can just pass nil).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will mean having code that reads the user defined in more than one place (this package and somewhere else). Also, if we only pass in that function/interface for one OS, it creates a special case that will add cognitive burden for future readers of this code (one more thing to keep track of). I can do that if you wish, but it might be better to pass in that function/interface for all OSs, just to keep things consistent and in one place.
If we decide to go that route, we can define a new interface in solver/llbsolver/file
, implement it in solver/llbsolver/ops
package (the Windows version will call into the executor which is already imported in exec.go
), and pass that implementation into Backend{}`.
How does that sound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that if you wish, but it might be better to pass in that function/interface for all OSs, just to keep things consistent and in one place.
Fine by me if you prefer that. I thought about it from the mindset that file can do its job without special configuration but if user wants to pass in custom readUser they can do this. This doesn't necessarily need to be just OS-based in the future but using /etc/passwd
from some other snapshot or some other user database.
we can define a new interface
If it is just one function it can just be a callback as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the readUser()
code and defined a callback type. Have a look and let me know if you would prefer it done differently.
solver/llbsolver/file/backend.go
Outdated
@@ -266,7 +237,8 @@ func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, | |||
} | |||
defer lm.Unmount() | |||
|
|||
u, err := readUser(action.Owner, user, group) | |||
// u, err := readUser(action.Owner, user, group, fb.Executor) | |||
u, err := fb.readUserFn(action.Owner, user, group) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not panic on nil
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think if we unexport Backend{}
and have NewFileOpBackend()
return an error if we pass in a nil callback. I think we should always pass in a callback even if it's a noop. This way we can avoid having to check if the read user function is nill whenever we want to use it, and simply check once in the "constructor".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nil check should do I think. Or defaulting to noop function.
solver/llbsolver/file/backend.go
Outdated
@@ -250,7 +210,18 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * | |||
return nil | |||
} | |||
|
|||
// NewFileOpBackend returns a new file operation backend. The executor is currently only used for Windows, | |||
// and it is used to construct the readUserFn field set in the returned Backend. | |||
func NewFileOpBackend(readUserFn ReadUserCallback) *Backend { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe makes sense to put this into opt stuct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like some comments are marked as resolved but I think you forgot to push your updates.
0d782c2
to
8ddc21f
Compare
Changes made. Apologies for the delay. I've been sidetracked for the past couple of weeks, and may be sparse for the next 2 weeks as well. I changed the The |
failures seem to be due to rate limits(?) |
Uh? https://github.com/moby/buildkit/actions/runs/6428415521/job/17455566735?pr=3518#step:4:446
|
Will fix later today. Apologies for the noise. |
@slonopotamus I had a quick look at one of the tests and stumbled across: https://github.com/moby/buildkit/actions/runs/6428415520/job/17455724114?pr=3518#step:8:1798 Which led me to believe it was a rate limit issue. I stopped there. As for the linting issue, fixing that now. |
8836e0f
to
3339003
Compare
3339003
to
120f330
Compare
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
120f330
to
2585dd9
Compare
The failing test seems to be due to vagrant failing. @tonistiigi if you have a few minutes, let me know if the changes here are fine. |
func (fb *Backend) readUserWrapper(owner *pb.ChownOpt, user, group fileoptypes.Mount) (*copy.User, error) { | ||
var userMountable, groupMountable snapshot.Mountable | ||
if user != nil { | ||
usr, ok := user.(*Mount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still something iffy about these type casts but looks like the previous code had a similar problem, so no update is needed with this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. There are a few architectural boundaries being broken here which could do with some refactor, but it will require touching a lot of code. This pattern is present in a number of places and should probably be tackled at some point as part of a broader cleanup.
Thanks for the review and the merge!
This change adds the ability to resolve usernames to SIDs in the FileOpSolver. This enables
WORKDIR
,ADD
andCOPY
to properly set permissions on Windows.Depends on:
Signed-off-by: Gabriel Adrian Samfira gsamfira@cloudbasesolutions.com