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

refactor: make spec created more reasonable #1154

Merged
merged 1 commit into from
Apr 25, 2018
Merged

refactor: make spec created more reasonable #1154

merged 1 commit into from
Apr 25, 2018

Conversation

Ace-Tang
Copy link
Contributor

Old spec related code is splited messed, lots of fields in spec
have relationship with each other, simple make them as general
funtion is wrong, I try to make spec files splited from runtime
spec struct, make it more reasonable and remove redundancy code.

Signed-off-by: Ace-Tang [email protected]

Ⅰ. Describe what this PR did

Ⅱ. Does this pull request fix one issue?

Ⅲ. Describe how you did it

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@allencloud
Copy link
Collaborator

I like the spirit this pull request figures out. 👍

@codecov-io
Copy link

codecov-io commented Apr 18, 2018

Codecov Report

Merging #1154 into master will increase coverage by 0.05%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1154      +/-   ##
==========================================
+ Coverage   15.57%   15.62%   +0.05%     
==========================================
  Files         178      171       -7     
  Lines       10454    10420      -34     
==========================================
  Hits         1628     1628              
+ Misses       8706     8672      -34     
  Partials      120      120
Impacted Files Coverage Δ
daemon/mgr/spec_process.go 0% <0%> (ø) ⬆️
daemon/mgr/container.go 0% <0%> (ø) ⬆️
daemon/mgr/spec.go 0% <0%> (ø) ⬆️
daemon/mgr/spec_annotations.go 0% <0%> (ø) ⬆️
daemon/mgr/spec_linux.go 0% <0%> (ø) ⬆️
daemon/mgr/spec_mount.go 0% <0%> (ø)
daemon/mgr/spec_hook.go 0% <0%> (ø) ⬆️

@Ace-Tang
Copy link
Contributor Author

Please help to review the code, @allencloud , @rudyfly , @YaoZengzeng

func createSpec(ctx context.Context, c *ContainerMeta, specWrapper *SpecWrapper) error {
// new a default spec from containerd.
s, err := ctrd.NewDefaultSpec(ctx, c.ID)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think it is a right way to modify, it decreases the scalability of these code. When I write a part of spec, I just focus on it, don't care others. I agree to merge some similar functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

First I want to say, fields in specs have related with each other, you can not focus on just one but not care about other.
For eg. When you set namespace, you must be careful about you are use other container ns or use host , or just make a new ns . Because in different case, lots of spec field should be changed. If you set uts ns to host, you need modify hostname, if you set user ns, you should get correct values for s.Linux.UIDMappings and s.Linux.GIDMappings.
How can you say you can just care one part. Or you can say it can be fixed by set setup functions to a good order, but I think it bad. When we read code at first time, we just think they
are general functions, these functions do not care about order since they are independent from each other. Unfortunately, they do have order, and if they execute in the wrong order, things will go wrong way.

On the other hand, spec code is splited into different parts by specs.Spec.

type Spec struct {
    // Version of the Open Container Runtime Specification with which the bundle complies.
    Version string `json:"ociVersion"`
    // Platform specifies the configuration's target platform.
    Platform Platform `json:"platform"`
    // Process configures the container process.
    Process Process `json:"process"`
    // Root configures the container's root filesystem.
    Root Root `json:"root"`
    // Hostname configures the container's hostname.
    Hostname string `json:"hostname,omitempty"`
    // Mounts configures additional mounts (on top of Root).
    Mounts []Mount `json:"mounts,omitempty"`
    // Hooks configures callbacks for container lifecycle events.
    Hooks Hooks `json:"hooks"`
    // Annotations contains arbitrary metadata for the container.
    Annotations map[string]string `json:"annotations,omitempty"`

    // Linux is platform specific configuration for Linux based containers.
    Linux *Linux `json:"linux,omitempty" platform:"linux"`
    // Solaris is platform specific configuration for Solaris containers.
    Solaris *Solaris `json:"solaris,omitempty" platform:"solaris"`
    // Windows is platform specific configuration for Windows based containers, including Hyper-V containers.
    Windows *Windows `json:"windows,omitempty" platform:"windows"`
}

If you want to change one part, you can modify the corresponding files, but you still need to care about that if the modification will influence other fields. As I said before, spec fields are not Independent from each other. That why I say the design before is not reasonable.
Maybe I am not express my meaning totally, we can continue to discuss, @rudyfly

Copy link
Collaborator

@allencloud allencloud Apr 22, 2018

Choose a reason for hiding this comment

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

To be honest, I am not on the side of the original way. This refactoring is my dish. For me, I cannot accept to couple specWrapper with several managers with spec. It breaks the simplicity of code. Although it seems to be quite scalable, but redundant so much.

We can achieve scalability by several ways. If ideal scalability is not included in this part, we can improve this.

Also, could we still add type SetupFunc func(ctx context.Context, m *ContainerMeta, s *SpecWrapper) error ? and aggregate all the original functions into several SetupFunc according the LinuxSpec's fields in runtime-spec. @rudyfly @Ace-Tang

}
} else {
for _, deviceMapping := range c.HostConfig.Devices {
if !opts.ValidateDeviceMode(deviceMapping.CgroupPermissions) {
Copy link
Collaborator

@allencloud allencloud Apr 22, 2018

Choose a reason for hiding this comment

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

I am wondering if we have to do the validation checking here. Is there any possibility to put this ahead to validations in manager layer instead of spec layer.

Of course, we can consider this later.

@@ -73,8 +72,6 @@ func setupMounts(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) error
}
}
}
s.Linux.ReadonlyPaths = nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am wondering why to remove both two lines of code. Just curious. :)

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 move them to Linux, since they are in spec.Linux field. And only depend on if container has privileged.

s.Process.Env = append(s.Process.Env, createEnvironment(c)...)
s.Process.Cwd = cwd
s.Process.Terminal = config.Tty
s.Process.NoNewPrivileges = c.NoNewPrivileges
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this part is not compatible with the original code. Please help to take a look again. @Ace-Tang .
Here is my reason, in the original way, we have:

func setupNoNewPrivileges(ctx context.Context, meta *ContainerMeta, spec *SpecWrapper) error {
	if meta.HostConfig.Privileged {
		return nil
	}

	spec.s.Process.NoNewPrivileges = meta.NoNewPrivileges
	return nil
}

So, if meta.HostConfig.Privileged is false, it will not be assigned value even if user has set one value for this.

While now, no matter privileged is true or not, s.Process.NoNewPrivileges will always be assigned.

WDYT?

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 check the NoNewPrivileges not depend on privileged. Maybe we need to find the one who write it to disscuse.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@allencloud
Copy link
Collaborator

I try to understand the refactoring, while I think we usually feel uneasy to code review just in one way. Let me add some point I may have:

  • Could we add the SetupFunc like the original way, but aggregate serveral functions according to field's in LinuxSpec.
  • I have not found the namespace dealing code within your code change, is it not necessary.

Hope to hear from you soon. Thanks.

@Ace-Tang
Copy link
Contributor Author

@allencloud , I update the pr, PTAL, and about namespace dealing code , locate at daemon/mgr/spec_linux.go , the file is compressed.

Old spec related code is splited messed, lots of fields in spec
have relationship with each other, simple make them as general
funtion is wrong, I try to make spec files splited from runtime
spec struct, make it more reasonable and remove redundancy code.

Signed-off-by: Ace-Tang <[email protected]>
Args: args[1:],
}
// if rootFSQuota not set skip quota prestart set
rootFSQuota := quota.GetDefaultQuota(c.Config.DiskQuota)
Copy link
Collaborator

Choose a reason for hiding this comment

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

change these into a function?

@allencloud
Copy link
Collaborator

LGTM

@pouchrobot pouchrobot added the LGTM one maintainer or community participant agrees to merge the pull reuqest. label Apr 25, 2018
@allencloud allencloud merged commit 30dd372 into AliyunContainerService:master Apr 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/refactor LGTM one maintainer or community participant agrees to merge the pull reuqest. size/XXL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants