cmd/containerd: split pkg for ease of 3rd party distribution#1615
cmd/containerd: split pkg for ease of 3rd party distribution#1615AkihiroSuda wants to merge 1 commit intocontainerd:masterfrom
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1615 +/- ##
=======================================
Coverage 45.29% 45.29%
=======================================
Files 95 95
Lines 9461 9461
=======================================
Hits 4285 4285
Misses 4464 4464
Partials 712 712
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
I'd remove the main and only export the cli.App from the package
|
I think this is fine to do. I'm not sure about the |
|
I feel that |
|
We already have |
|
|
There was a problem hiding this comment.
This should not be a separate package.
|
I'd like to propose that this is a post-1.0 change. This makes a lot of changes for a use case we'd like to support but need to consider whether this is the right avenue of support. |
|
Basically, I am worried that merging this will make it hard to do something else in the future. |
|
I'm fine with postponing too, these changes are not really urgent and doesn't break our contract post 1.0 as it only covers the GRPC side. |
|
Lets close this for now and revisit after 1.0 |
|
reopening for 1.1 related: #1934 |
9f0776b to
ad703f6
Compare
|
rebased and addressed comments |
What should we do with this? |
|
I think we need to solve this problem, of compiling a release with the added extra packages and repos. But I don't think this refactoring is the solution. We need to think about how we want to handle this, maybe build some tooling around this. Lets think about what we want to accomplish first before changing code.
Any other requirements? |
Either add a comment explaining the blank import above each one, or add |
|
I also can't express myself fully in how much I don't want to have a package called "daemon". It is probably the most incorrect name in the world. :D For this process to work, we need to be iterative in the following questions:
If we can keep the answer to 1 "yes", then we have a very small problem. An inclusive containerd will be a healthy one. With this approach, we can solve the problem of "how do I exclude package x?" which will effect a smaller subset of users. Then, how do allow arbitrary plugin x? We should consider that on a case by case basis. If the plugin functionality can't be done with vanilla containerd, then we need to reconsider our design to support it. Most users should never have to deal with containerd plugin support. It is not friendly for users and allows vendors to split communities ("we don't ship x"). Making it easier to include or exclude plugins may have an unintended effect on the ecosystem. The underlying problem that caused this PR is that we didn't ship zfs and aufs. I think shipping these is a better solution than refactoring into a daemon package (although, I'm open to an app package) or coming up with a half-broken plugin system. |
I think we are all in agreement that we should just include these by default. We might not be in agreement in how we want to achieve this. In my opinion, having a separate app package is a good idea, I agree |
AUFS, ZFS (and CRI) can be included, but 3rd party plugins can't be included |
What do you mean by |
|
Any thought to move this forward? Another solution I can come up with is to create a tool like this, but I wonder it would be too much: $ containerd-rebuild -o "./containerd-custom" --add "github.com/3rd/party/plugin" --remove "github.com/containerd/containerd/snapshots/overlay"
INFO: Executing `containerd --version`...
RepoURL="https://github.com/containerd/containerd",
Commit="deadbeefdeadbeefdeadbeef",
Go="go1.10",
BuiltinPlugins=["github.com/containerd/containerd/snapshots/overlay",
"github.com/containerd/cri", ...]
INFO: Pulling image "docker.io/library/golang:1.10"
INFO: Checking out https://github.com/containerd/containerd@deadbeefdeadbeefdeadbeef
INFO: Injecting plugin configuration to package "github.com/containerd/containerd/cmd/containerd"
INFO: Creating container "containerd-rebuild-tmp424242"
INFO: Building package "github.com/containerd/containerd/cmd/containerd" in container "containerd-rebuild-tmp424242"
INFO: Copying the build artifact from container "containerd-rebuild-tmp424242" to "./containerd-custom"
INFO: Successful. Please replace your containerd binary with "./containerd-custom".@Random-Liu |
|
Also, it should be worth considering again to promote |
|
LGTM. This will make test in cri-containerd for plugin mode much simpler I think. |
@crosbymichael Another requirement we have is for testing. After we make cri-containerd a containerd plugin, we can't test it without building with containerd. There are several possible solutions, but this PR is definitely a simple one. Other possible solutions:
Given above, I feel like this PR seems to be the best solution, unless we come up with another. |
@AkihiroSuda I tried the plugin mode. I don't think we can rely on it at all. For example, if the plugin uses same packages with containerd, e.g. |
@dmcgowan @stevvooe I agree. We may be able to vendor many different plugins into containerd, but I don't think we can merge all repos into one. That will be very hard to maintain. As long as plugins are in separate repos, we need a way to test them. It is possible to test them case by case, e.g. write specific integration test for ZFS plugin, test cri-containerd in standalone mode. However, I believe there will still be surprise when we update the vendors in containerd, because they are not actually tested with containerd. An example is that: In Kubernetes, kubelet vendors cadvisor. Every release, we need to update cadvisor version a week before release. Although we do have cadvisor integration test in cadvisor repo. There is always surprise. |
|
Vendoring aufs/zfs/cri SGTM, but note that it cannot be the replacement of this PR, as we should do our best to facilitate installation of 3rd party plugins. e.g. continuity/FILEgrain snapshotter/differ/content plugin, and maybe some kind of IPFS-based content plugin I'll rebase this PR soon, but what should be the name of Candidates suggested so far:
|
Agreed, do you know whether the Go maintainers are working on this issue? |
https://golang.org/pkg/plugin/ says
I tried it out and from what I can see Are you sure |
based on what is being exported, I think
Why do we want to support building from vendor? That seems very strange to me. Vendor is for "library dependencies" to "satisfy imports" (ref: https://blog.golang.org/go1.7). It is not designed as a source to build binaries. If we only support building from a git checkout the current solution isn't so bad. We could make a few small changes to make it easier to build.
|
4a39cd9 to
76a865f
Compare
ok, updated PR to use
I meant we should allow 3rd parties to vendor
I didn't meant this, sorry for confusion. |
@dnephin Really? Last time when I tried that, one init function in I remember it is this line https://github.com/golang/net/blob/master/trace/trace.go#L115-L116. |
|
Yes, really 😄 It says so in the docs! and also my test confirmed the documented behaviour. Maybe there was a bug in earlier versions of go? Or maybe there is some case I'm not ware of, but at least the expected case is to only run once.
That doesn't necessarily mean the |
|
@dnephin I tried it.If the plugin project has its own I think golang treats packages in different vendor directories as different packages, which is really not good. :P You can try (please $ cat main/main.go
package main
import "plugin"
import _ "golang.org/x/net/trace"
func main() {
if _, err := plugin.Open("plugin1.so"); err != nil {
panic(err)
}
if _, err := plugin.Open("plugin2.so"); err != nil {
panic(err)
}
}$ cat plugin1/plugin1.go
package main
import "fmt"
import _ "golang.org/x/net/trace"
func init() {
fmt.Println("plugin1")
}$ cat plugin2/plugin2.go
package main
import "fmt"
import _ "golang.org/x/net/trace"
func init() {
fmt.Println("plugin2")
}$ ./main
panic: http: multiple registrations for /debug/requests
goroutine 1 [running]:
net/http.(*ServeMux).Handle(0xc746c0, 0x7fb0bd3f06dc, 0xf, 0xc460a0, 0x7fb0bd729c90)
/usr/local/go/src/net/http/server.go:2270 +0x631
net/http.(*ServeMux).HandleFunc(0xc746c0, 0x7fb0bd3f06dc, 0xf, 0x7fb0bd729c90)
/usr/local/go/src/net/http/server.go:2302 +0x57
net/http.HandleFunc(0x7fb0bd3f06dc, 0xf, 0x7fb0bd729c90)
/usr/local/go/src/net/http/server.go:2314 +0x50
github.com/random-liu/plugin1/vendor/golang.org/x/net/trace.init.0()
/home/lantaol/workspace/src/github.com/random-liu/plugin1/vendor/golang.org/x/net/trace/trace.go:115 +0x44
github.com/random-liu/plugin1/vendor/golang.org/x/net/trace.init()
<autogenerated>:1 +0x1fa
github.com/random-liu/plugin1.init()
<autogenerated>:1 +0x53
plugin.open(0x8ad96b, 0xa, 0x0, 0x0, 0x0)
/usr/local/go/src/plugin/plugin_dlopen.go:136 +0x91a
plugin.Open(0x8ad96b, 0xa, 0x0, 0xc420059f70, 0x800fc9)
/usr/local/go/src/plugin/plugin.go:31 +0x35
main.main()
/home/lantaol/workspace/src/github.com/random-liu/main/main.go:7 +0x3a |
Yes, that's exactly it! I believe all dependency management tools (vndr, dep, glide) should be removing |
|
Let's see a proposed package dependency graph. |
|
@stevvooe Also ref #2096 (comment). Yeah I think if plugin mode works, that might be the best solution for testing containerd plugins. However, I'm not sure how much effort is needed to make plugin mode work. Let's think about it. It may work out. ;) |
76a865f to
e5bcf9c
Compare
Signed-off-by: Akihiro Suda <[email protected]>
e5bcf9c to
40fffad
Compare
|
I think we need to split this PR up into separate steps. There is too much going on and its trying to solve too many things from the discussion but not delivering in the code. The two things we want to solve are:
From the code I see in this PR, I think it is safe to solve (2) first. We can export the Then once that is done, we can start on the default registration/imports. These are two problems but we are not really solving any of the current state of discussion and code of this PR. |
|
ok, opened #2131 for (2) |
|
opened issue #2134 for (1) |
Signed-off-by: Akihiro Suda [email protected]
Currently, to build a custom daemon binary with 3rd-party plugins, we need to put a Go source file (
builtins_foobar.go) to the$GOPATH/src/github.com/containerd/cmd/containerddirectory.This workflow is hard to integrate to Go toolchains such as
vndrandgo get.So I suggest splitting the
cmd/containerdpkg.With this package structure, we can build fully
vendorable andgo-gettable custom daemon binary like this:https://github.com/AkihiroSuda/containerd-example-custom-daemon/blob/40a19a7450fd6f19f70d26db688ee0dee610e8ba/main.go
Note that it is still possible to put a Go source file (
builtins_foobar.go) to the$GOPATH/src/github.com/containerd/cmd/containerddirectory