Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 24, 2020. It is now read-only.

Conversation

@s-urbaniak
Copy link
Contributor

This cleans up the code a bit and provides the necessary uid/gid functionality for implementing user/groups for rkt fly, see #2439

@s-urbaniak s-urbaniak self-assigned this Apr 26, 2016
@s-urbaniak s-urbaniak added this to the v1.5.0 milestone Apr 26, 2016
@s-urbaniak s-urbaniak changed the title [WIP] uid/gid generators Implement composable uid/gid generators Apr 26, 2016
@s-urbaniak
Copy link
Contributor Author

@alban @tmrts PTAL

@s-urbaniak
Copy link
Contributor Author

I just recognized ... now that I factored that jazz out I really should introduce unit tests ;-)


// FromEtc is the struct that generates a uid/gid by parsing etc/passwd,
// and etc/group relative from the given Root path looking for the given Name.
type FromEtc struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

You missed a NewFromEtc for this one.

Further, since all of your constructors return the interface, there's no need to export any of these structs - and indeed, to me it's preferable not to, since it minimises the exposed interface to the package. However, obviously if you don't export them, you will need to test them within the same package (hi @tmrts).

And personally I think all the generators should be in a single file - it's a relatively trivial amount of code, and now uid_range.go is an odd exception in the package.

buuut - I want to leave the bulk of this review to @tmrts ;-)

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 missed NewFromEtc to make the invariant of a non-nil Etc based uid/gid generator explicit but I see this confuses more than it helps, I'll introduce it then.

Why not exposing the structs? Just because they implement the interface doesn't mean they are unusable without that fact. But I have no strong opinion on that so I'll gladly make it all private.

Let's see @tmrts's opinion :-)

Copy link
Contributor

@tmrts tmrts Apr 27, 2016

Choose a reason for hiding this comment

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

@jonboulle I now have a better idea of your position in "_test". Here is how everything should be tested without exporting everything:

package uid

type Generator interface{
  ....
}

type fromEtc struct {...}

var _ Generator = &fromEtc{}

func FromEtc(....) Generator {
  ...
  return &fromEtc{...}
}

and the tests should be like:

package uid_test

func TestCreatesIDGeneratorFromEtc(t *testing.T) {
  g := uid.FromEtc(...)

  if g.UID() != expected {
  ...
  }

  if g.GID() != expected {
  ...
  }

and this function should be repeated for all exported constructors or a table-driven test should be used.

This way you test everything and you only export the interface and constructors.

Copy link
Contributor

@tmrts tmrts Apr 27, 2016

Choose a reason for hiding this comment

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

@s-urbaniak if you can avoid exported structs, it's much better to export interfaces and let the clients depend on interfaces/behavior. This way we can easily test a function that uses a generator from this package by mocking the interface. Otherwise you would have to create mocks for each exported struct.

Copy link
Contributor Author

@s-urbaniak s-urbaniak Apr 27, 2016

Choose a reason for hiding this comment

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

Agree with all that have been said above, and the existing implementation did not contradict with mocking though since all New.. functions already return the Generator interface. Nevertheless I'll make all of them private and in one source file.

Copy link
Contributor

Choose a reason for hiding this comment

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

This way you test everything and you only export the interface and constructors.

It actually works in this particular case, but only because i) the implementation is particularly simple, so you can be fairly confident that all code paths are covered; and ii) the interface happens to expose a path override, which is ideal for testing. But such customisations are not always desirable in interfaces and it's unclean to add them to external interfaces only for testing purposes. It's quite plausible, for example, that the package could instead expose NewFromEtcdPasswd() Generator, pinned to using /etc/passwd, in which case you would internally have a way to customise and test with an alternative path (newFromSpecificFile), but never expose this to package consumers.

Copy link
Contributor

Choose a reason for hiding this comment

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

Anyway, how do you plan to do any code coverage? Last time I checked go wasn't able to do it cross-package.

@tmrts tmrts assigned tmrts and unassigned s-urbaniak Apr 27, 2016
// For how the uidshift and uidcount are generated please check:
// http://cgit.freedesktop.org/systemd/systemd/commit/?id=03cfe0d51499e86b1573d1

package uid
Copy link
Contributor

@tmrts tmrts Apr 27, 2016

Choose a reason for hiding this comment

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

uid is not a very descriptive name since it is about extracting uid & gid.
A better name would be nss or nssid since passwd, shadow, etc. are all members of Name Service Switch name resolution mechanism.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nss is an implementation detail, as suggested below I'd call this user.

@tmrts
Copy link
Contributor

tmrts commented Apr 27, 2016

After the modifications I commented plus the tests, LGTM

)

if uid_, err = uidGen.UID(); err != nil {
if uid_, _, err = uidGen.IDs(); err != nil {
Copy link
Contributor

@jellonek jellonek Apr 27, 2016

Choose a reason for hiding this comment

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

uid_ could be now renamed to uid. same with gid_ below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah good catch, thanks!

@s-urbaniak
Copy link
Contributor Author

blocked by #2515 for providing functional tests for fly, this is too short notice, rescheduling for the next release.

@s-urbaniak s-urbaniak modified the milestones: v1.6.0, v1.5.0 Apr 28, 2016
if gid, err = group.LookupGidFromFile(
e.group,
filepath.Join(e.rootPath, "etc/group"),
); e.group != "" && err != nil {
Copy link
Contributor

@tmrts tmrts Apr 29, 2016

Choose a reason for hiding this comment

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

Please don't use multiple line statements in if initializations.

gid, err = .....
if e.group != "" && err != nil {
  ...
}

return

would be much better since you are using named return values.

@s-urbaniak s-urbaniak force-pushed the uid-gid-generators branch 7 times, most recently from fb32b3b to 645156b Compare May 3, 2016 06:56
@s-urbaniak
Copy link
Contributor Author

s-urbaniak commented May 3, 2016

TODO: backport fix from #2508 (done)

@s-urbaniak s-urbaniak force-pushed the uid-gid-generators branch from 645156b to 1568129 Compare May 3, 2016 10:18
@s-urbaniak
Copy link
Contributor Author

@tmrts @alban @iaguis PTAL

@s-urbaniak s-urbaniak force-pushed the uid-gid-generators branch 2 times, most recently from 94316e9 to a601390 Compare May 3, 2016 10:51
return idsFromStat{filepath.Join(rootPath, file), r}
}

return nil
Copy link
Contributor

@tmrts tmrts May 3, 2016

Choose a reason for hiding this comment

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

Don't do this please. User has to start checking for nil values, which is tedious and error-prone and if it receives a nil he won't know the reason, worse it won't be traceable without a proper error.

Instead modify the signature to (Generator, error) from Generator

Same goes for other constructors.

PickGenerator is used to get a valid generator by checking nil, but you can also check the errors and log them and pick a working one. I want to avoid introducing nil checks unless it's an absolute must.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed, what's your suggestion to set up a generator chain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I'll leave chaining up to the user

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd agree with leaving it up to user unless you have a specific case in mind.

@tmrts
Copy link
Contributor

tmrts commented May 3, 2016

LGTM

@iaguis
Copy link
Member

iaguis commented May 3, 2016

Do you wanna squash the commits?

Currently resolving UIDs/GIDs is implemented in a single
private method in stage1/init/common/pod.go.

For future reuse/compositionality this is not the best solution. This
refactors resolving UIDs/GIDs in a new user package. It introduces
uid/gid resolvers capable of resolving those values from stat()ing a
file, looking up etc/passwd, or etc/group, or simply assigning static
uid/gid values.

Fixes rkt#2439
Backports rkt#2508
@s-urbaniak s-urbaniak force-pushed the uid-gid-generators branch from d3c0c9e to 748c626 Compare May 3, 2016 12:33
@s-urbaniak
Copy link
Contributor Author

@iaguis squashed

@iaguis
Copy link
Member

iaguis commented May 3, 2016

I didn't go very deep reviewing this but LGTM on the surface.

@tmrts tmrts merged commit 981c1fb into rkt:master May 3, 2016
@s-urbaniak s-urbaniak deleted the uid-gid-generators branch November 7, 2016 13:00
@lucab lucab unassigned tmrts Apr 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants