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

validate: optimize capabilites check #220

Merged

Conversation

Mashimiao
Copy link

@Mashimiao Mashimiao commented Sep 23, 2016

Signed-off-by: Ma Shimiao mashimiao.fnst@cn.fujitsu.com

By now, if we generate with option --priviliged, the validation of bundle will fail.
capabilities need to be more than original defaultCap has.

if !capValid(capability) {
msgs = append(msgs, fmt.Sprintf("capability %q is not valid, man capabilities(7)", process.Capabilities[index]))
if !capValid(capability, hostCheck) {
msgs = append(msgs, fmt.Sprintf("capability %q is not valid, man capabilities(7)", capability))
Copy link
Contributor

Choose a reason for hiding this comment

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

Complaining by capability (and not by index) makes sense to me. But now that we're doing that, I think we should replace the current for loop with:

for _, capability := range process.Capabilities {

Copy link
Author

Choose a reason for hiding this comment

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

fixed, thanks.


for _, cap := range capability.List() {
if cp == fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())) {
if hostSpecific && cap > lastCap() {
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 not sure List is the right logic for host-agnostic checks. The docs say:

List returns list of all supported capabilities

What we want here is a list of all possible capabilities. But maybe I'm just misreading the docs. Does someone have an old kernel around to test this on?

return false
}

func lastCap() capability.Cap {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like duplicating code between the generate and validate libraries. Validation seems more fundamental to me, so can we make a public LastCap function here and import that into the generate library?

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like your new capValid code is also coming over from generate. Can we move all of that to a public validate function and import that into the generate library as well?

Copy link
Author

Choose a reason for hiding this comment

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

I also don't like duplicating code. @liangchenye is working on a new validate module at #188 .
Maybe we can made a cleanup after that merged or wait until it merged?

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 #188 is ready to land, so I'd rather idle here.

@Mashimiao
Copy link
Author

@wking @mrunalp @liangchenye rebased.

@@ -679,12 +679,12 @@ func lastCap() capability.Cap {
return last
}

func checkCap(c string, hostSpecific bool) error {
func ValidCap(c string, hostSpecific bool) error {
isValid := false
cp := strings.ToUpper(c)
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 we can drop this. The spec says nothing about case-insensitivity, and the values listed in the referenced man page are uppercase.

@@ -694,7 +694,7 @@ func checkCap(c string, hostSpecific bool) error {
}

if !isValid {
return fmt.Errorf("Invalid value passed for adding capability")
return fmt.Errorf("Invalid capability value: %s", cp)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need “value”? I'd rather have Invalid capability: %q.

Copy link
Author

Choose a reason for hiding this comment

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

fixed.

@@ -709,12 +709,11 @@ func (g *Generator) ClearProcessCapabilities() {

// AddProcessCapability adds a process capability into g.spec.Process.Capabilities.
func (g *Generator) AddProcessCapability(c string) error {
if err := checkCap(c, g.HostSpecific); err != nil {
cp := fmt.Sprintf("CAP_%s", strings.ToUpper(c))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we adding the CAP_ prefix here? I'd rather require AddProcessCapability callers give us a valid string without massaging it internally.

Copy link
Author

Choose a reason for hiding this comment

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

removed

@@ -679,12 +679,12 @@ func lastCap() capability.Cap {
return last
}

func checkCap(c string, hostSpecific bool) error {
func ValidCap(c string, hostSpecific bool) error {
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 ValidCap should live in validate/ and generate.go should import the validate package.

Copy link
Author

Choose a reason for hiding this comment

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

Fine, fixed.

if process.Rlimits[index].Hard < process.Rlimits[index].Soft {
msgs = append(msgs, fmt.Sprintf("hard limit of rlimit %s should not be less than soft limit.", process.Rlimits[index].Type))
if rlimit.Hard < rlimit.Soft {
msgs = append(msgs, fmt.Sprintf("hard limit of rlimit %s should not be less than soft limit.", rlimit.Type))
Copy link
Contributor

Choose a reason for hiding this comment

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

rlimitValid is an overly-generic name if it only validates the type. I'd recommend renaming it to validRlimitType or moving the hard/soft limit checks inside validRlimit.

Copy link
Author

Choose a reason for hiding this comment

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

move hard/soft limit check into rlimitValid

@Mashimiao Mashimiao force-pushed the validate-optimize-cap-check branch 2 times, most recently from dd8124d to d2b72fc Compare October 20, 2016 09:10
Copy link
Contributor

@wking wking left a comment

Choose a reason for hiding this comment

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

Looking pretty good, just a few remaining nits.

@@ -123,6 +129,8 @@ func (v *Validator) CheckRootfsPath() (msgs []string) {
return

}

// CheckSemVer checks v.sepc.Version
Copy link
Contributor

Choose a reason for hiding this comment

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

“sepc” → “spec”

@@ -203,6 +213,7 @@ func checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (ms
return
}

// CheckProcess checks v.spec.process
Copy link
Contributor

Choose a reason for hiding this comment

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

“process” → “Process”.

if val == rlimit.Type {
if rlimit.Hard < rlimit.Soft {
return fmt.Errorf("hard limit of rlimit %s should not be less than soft limit", rlimit.Type)
}
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 rather not bury the hard/soft comparison inside the type check. I'm fine checking this before the type, because “hard < soft” is always wrong, but “type not in defaultRlimits” could be “runtime-tools maintainers haven't taught runtime-tools about the new rlimit”. If you really want the type check first, you could do something like:

found := false
for … {
  if val == rlimit.Type {
    found = true
    break
  }
}
if !found {
  return fmt.Errorf("rlimit type %q is invalid", rlimit.Type)
}

@Mashimiao
Copy link
Author

On 10/22/2016 03:23 PM, W. Trevor King wrote:

I'd rather not bury the hard/soft comparison inside the type check. I'm fine checking this before the type, because “hard < soft” is /always/ wrong, but “type not in |defaultRlimits|” could be “runtime-tools maintainers haven't taught runtime-tools about the new rlimit”. If you really want the type check first, you could do something like:

I'd like do type check first.
I think if type was invalid, hard/soft check doesn't make any sense.

|found := false for … { if val == rlimit.Type { found = true break } } if !found { return fmt.Errorf("rlimit type %q is invalid", rlimit.Type) } |

Maybe I didn't understand your means.
I think the above code has no difference with current code except lack of hard/soft check.

@wking
Copy link
Contributor

wking commented Oct 25, 2016

On Tue, Oct 25, 2016 at 11:21:28AM -0700, Ma Shimiao wrote:

I'd like do type check first. I think if type was invalid,
hard/soft check doesn't make any sense.

But runtime-tools may think the type is invalid when it really isn't
1.

I think the above code has no difference with current code except
lack of hard/soft check.

Exactly. That lets you handle the hard/soft check independently after
passing through the type-checking loop. Separating the checks inside
rlimitValid makes it more clear that the type and hard/soft checks
are completely orthogonal.

@Mashimiao
Copy link
Author

Fixed. @wking PTAL

@wking
Copy link
Contributor

wking commented Oct 26, 2016 via email

@Mashimiao
Copy link
Author

ping @opencontainers/runtime-tools-maintainers

@liangchenye
Copy link
Member

liangchenye commented Jan 3, 2017

LGTM

Approved with PullApprove

@Mashimiao
Copy link
Author

@mrunalp @hqhq PTAL

Ma Shimiao added 2 commits February 14, 2017 09:51
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
@Mashimiao
Copy link
Author

Rebased. @opencontainers/runtime-tools-maintainers PTAL

@Mashimiao
Copy link
Author

@hqhq @mrunalp @liangchenye PTAL

@hqhq
Copy link
Contributor

hqhq commented Mar 6, 2017

LGTM

Approved with PullApprove

@hqhq
Copy link
Contributor

hqhq commented Mar 6, 2017

ping @liangchenye needs re-LGTM.

@liangchenye
Copy link
Member

liangchenye commented Mar 6, 2017

LGTM

Approved with PullApprove

@Mashimiao Mashimiao merged commit 9539bef into opencontainers:master Mar 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants