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

feature: add pouch plugin #1278

Merged

Conversation

shaloulcy
Copy link
Contributor

To use existing docker volume and network plugin. We implement pouch plugin
mechanism. We change the plugin discovery directory to /run/pouch/plugins,
/etc/pouch/plugins, /usr/lib/pouch/plugins. In future, maybe we will use the
grpc protocol to implement the plugin

Signed-off-by: Eric Li [email protected]

Ⅰ. Describe what this PR did

To use existing docker volume and network plugin. We implement pouch plugin
mechanism. We change the plugin discovery directory to /run/pouch/plugins,
/etc/pouch/plugins, /usr/lib/pouch/plugins. In future, maybe we will use the
grpc protocol to implement the plugin

Ⅱ. Does this pull request fix one issue?

Ⅲ. Describe how you did it

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@codecov-io
Copy link

codecov-io commented May 8, 2018

Codecov Report

Merging #1278 into master will increase coverage by 0.97%.
The diff coverage is 59.41%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1278      +/-   ##
==========================================
+ Coverage   15.31%   16.29%   +0.97%     
==========================================
  Files         174      178       +4     
  Lines       11014    10994      -20     
==========================================
+ Hits         1687     1791     +104     
+ Misses       9208     9065     -143     
- Partials      119      138      +19
Impacted Files Coverage Δ
plugins/error.go 0% <0%> (ø)
plugins/plugins.go 0% <0%> (ø)
apis/server/server.go 0% <0%> (ø) ⬆️
pkg/httputils/client.go 27.65% <27.65%> (ø)
plugins/client.go 54.32% <54.32%> (ø)
client/client.go 66% <66.66%> (+7.05%) ⬆️
plugins/plugin.go 72% <72%> (ø)
plugins/manager.go 75.17% <75.17%> (ø)
daemon/mgr/image_utils.go 0% <0%> (-40%) ⬇️
pkg/reference/def.go 33.33% <0%> (-11.12%) ⬇️
... and 24 more

)

// TLSConfig contains information of tls which users can specify
type TLSConfig struct {
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 we have already defined a TLSConfig in the code base package client. I am wondering if we could avoid the duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

plugins.TLSConfig is different from client.TLSConfig

// defaultContentTypeis the default content type accepted and sent by the plugins.
const defaultContentType = "application/vnd.docker.plugins.v1.1+json"

// PluginClient the client which call Plugin ServiceMethod
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add every a . in every function's comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Get it


u, err := url.Parse(addr)
if err != nil {
return nil, fmt.Errorf("failed to parse plugin addr: %s", addr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

fmt.Errorf("failed to parse plugin addr %s: %v", addr, err) ?

if tlsconfig != nil && tlsconfig.InsecureSkipVerify == false {
config, err = client.GenTLSConfig(tlsconfig.KeyFile, tlsconfig.CertFile, tlsconfig.CAFile)
if err != nil {
return nil, fmt.Errorf("failed to parse plugin tls config")
Copy link
Collaborator

Choose a reason for hiding this comment

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

please throw out the error. I think that will make the error message more explicit.

return nil, err
}

if resp.StatusCode != http.StatusOK {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does only 200 make sense?
In my opinion, 2xx and 3xx are both regarded valid.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that the resp should be handled out of this function. 101 / 20x / 30x are the OK.

return nil, err
}
counter++
logrus.Warnf("plugin %s call %s failed, retry after %d seconds", cli.address, service, delay)
Copy link
Collaborator

Choose a reason for hiding this comment

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

throw out the error in the log message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's an warning msg.


resp, err := cli.client.Do(req)
if err != nil {
if retry {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would suggest that we could use return fast to reduce more ident, like:

if !retry {
    return nil, err
}
delay := backoff(counter)
if timeout(start, delay) {
    return nil, err
}
......

"github.com/sirupsen/logrus"
)

var defaultTimeout = 30
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about make this type of time.Duration instead of a type of int?

plugins/error.go Outdated
var ErrNotFound = errors.New("plugin not found")

// ErrNotImplement represents that the plugin not implement the given protocol
var ErrNotImplement = errors.New("plugin not implement")
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/NotImplement/NotImplemented ?

for {
plugin, err := m.newPlugin(name)
if err != nil {
if retry {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can use return fast here.

}

for _, path := range specPaths {
fi, err := os.Open(path)
Copy link
Collaborator

@allencloud allencloud May 8, 2018

Choose a reason for hiding this comment

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

I think we should close this fi when finishing dealing.

@allencloud
Copy link
Collaborator

allencloud commented May 8, 2018

Thank @shaloulcy for your work.
While I put forward some minor tips:

  • I am wondering if we should encapsulate all the httpClient implementation into a single package to avoid duplication. Since I found that in package plugin and package client, we both implemented some structs and some functions.

also cc @fuweid

@fuweid fuweid self-requested a review May 8, 2018 07:25
Copy link
Contributor

@fuweid fuweid left a comment

Choose a reason for hiding this comment

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

@allencloud , In my option, most functions has been covered in pkg client.
I think we can upgrade the pkg client instead of new pkg plugin.

return nil, err
}

if resp.StatusCode != http.StatusOK {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that the resp should be handled out of this function. 101 / 20x / 30x are the OK.

@shaloulcy shaloulcy force-pushed the v1_plugin_manager branch 2 times, most recently from 789b5c2 to 4dcd71b Compare May 9, 2018 10:58
"github.com/sirupsen/logrus"
)

// pluginManager is a pluginManager, which manages all plugin events.
Copy link
Collaborator

Choose a reason for hiding this comment

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

pluginManager is a plugin manager is it better?

"github.com/sirupsen/logrus"
)

// pluginManager is a pluginManager, which manages all plugin events.
Copy link
Collaborator

Choose a reason for hiding this comment

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

pluginManager is a plugin manager is it better?

var manager = &pluginManager{
plugins: make(map[string]*Plugin),
pluginSockPaths: []string{"/run/pouch/plugins"},
pluginSpecPaths: []string{"/etc/pouch/plugins", "/usr/lib/pouch/plugins"},
Copy link
Collaborator

Choose a reason for hiding this comment

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

/usr/lib/pouch/plugins I think it should change to /var/lib/pouch/plugins.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree it

pluginSpecPaths: []string{"/etc/pouch/plugins", "/usr/lib/pouch/plugins"},
}

// Get return the requested plugin.
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/return/returns

return manager.getPluginByName(pluginType, name)
}

// SetPluginSockPaths set the plugin sock paths.
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/set/sets

manager.setPluginSockPaths(paths)
}

// SetPluginSpecPaths set the plugin spec paths.
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/set/sets

@shaloulcy shaloulcy force-pushed the v1_plugin_manager branch 2 times, most recently from b176f4d to b45eec4 Compare May 10, 2018 02:27

// ParseHost inputs a host address string, and output three type:
// url.URL, basePath and an error.
func ParseHost(host string) (*url.URL, string, string, error) {
Copy link
Collaborator

@allencloud allencloud May 10, 2018

Choose a reason for hiding this comment

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

In the comment, you wrote that this function returns three types. While I found that this function actually returns four types (*url.URL, string, string, error).
I am afraid inconsistency exists.

}
}

if out != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about

if out == nil {
    return nil
}

return json.NewDecoder(resp.Body).Decode(out)

To use existing docker volume and network plugin. We implement pouch plugin
mechanism. We change the plugin discovery directory to /run/pouch/plugins,
/etc/pouch/plugins, /usr/lib/pouch/plugins. In future, maybe we will use the
grpc protocol to implement the plugin

Signed-off-by: Eric Li <[email protected]>
@shaloulcy shaloulcy force-pushed the v1_plugin_manager branch from b45eec4 to 2caa0d4 Compare May 10, 2018 03:23
@allencloud
Copy link
Collaborator

LGTM

@pouchrobot pouchrobot added the LGTM one maintainer or community participant agrees to merge the pull reuqest. label May 10, 2018
@allencloud allencloud merged commit 49dea30 into AliyunContainerService:master May 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature 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.

6 participants