mirror of
https://github.com/docker/compose.git
synced 2025-07-23 13:45:00 +02:00
Merge pull request #40 from docker/chore-cleanup
Add comments on exported items, remove example command
This commit is contained in:
commit
f32235b8ba
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -11,23 +11,17 @@ jobs:
|
|||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.13
|
- name: Set up Go 1.14
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.13
|
go-version: 1.14
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Checkout code into the Go module directory
|
- name: Checkout code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install Protoc
|
- name: Lint
|
||||||
uses: arduino/setup-protoc@master
|
run: make lint
|
||||||
|
|
||||||
- name: Get dependencies
|
|
||||||
run: ./scripts/setup/install-go-gen
|
|
||||||
|
|
||||||
- name: Protos
|
|
||||||
run: make protos
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make cli
|
run: make cli
|
||||||
|
35
.golangci.yml
Normal file
35
.golangci.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
linters:
|
||||||
|
run:
|
||||||
|
concurrency: 2
|
||||||
|
enable-all: false
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- deadcode
|
||||||
|
- errcheck
|
||||||
|
- gocyclo
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- golint
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- interfacer
|
||||||
|
- lll
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
linters-settings:
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 16
|
||||||
|
lll:
|
||||||
|
line-length: 200
|
||||||
|
issues:
|
||||||
|
# golangci hides some golint warnings (the warning about exported things
|
||||||
|
# withtout documentation for example), this will make it show them anyway.
|
||||||
|
exclude-use-default: false
|
20
Dockerfile
20
Dockerfile
@ -4,15 +4,20 @@ ARG GO_VERSION=1.14.2
|
|||||||
FROM golang:${GO_VERSION} AS fs
|
FROM golang:${GO_VERSION} AS fs
|
||||||
ARG TARGET_OS=unknown
|
ARG TARGET_OS=unknown
|
||||||
ARG TARGET_ARCH=unknown
|
ARG TARGET_ARCH=unknown
|
||||||
ARG PWD=$GOPATH/src/github.com/docker/api
|
ARG PWD=/api
|
||||||
|
ENV GO111MODULE=on
|
||||||
|
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
make \
|
make \
|
||||||
git \
|
git \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
libprotobuf-dev
|
libprotobuf-dev
|
||||||
RUN go get github.com/golang/protobuf/protoc-gen-go && \
|
|
||||||
|
RUN go get github.com/golang/protobuf/protoc-gen-go@v1.4.1 && \
|
||||||
go get golang.org/x/tools/cmd/goimports && \
|
go get golang.org/x/tools/cmd/goimports && \
|
||||||
go get gotest.tools/gotestsum
|
go get gotest.tools/gotestsum@v0.4.2 && \
|
||||||
|
go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.26.0
|
||||||
|
|
||||||
WORKDIR ${PWD}
|
WORKDIR ${PWD}
|
||||||
ADD go.* ${PWD}
|
ADD go.* ${PWD}
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
@ -32,13 +37,16 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||||||
make -f builder.Makefile cross
|
make -f builder.Makefile cross
|
||||||
|
|
||||||
FROM scratch AS protos
|
FROM scratch AS protos
|
||||||
COPY --from=make-protos /go/src/github.com/docker/api .
|
COPY --from=make-protos /api .
|
||||||
|
|
||||||
FROM scratch AS cli
|
FROM scratch AS cli
|
||||||
COPY --from=make-cli /go/src/github.com/docker/api/bin/* .
|
COPY --from=make-cli /api/bin/* .
|
||||||
|
|
||||||
FROM scratch AS cross
|
FROM scratch AS cross
|
||||||
COPY --from=make-cross /go/src/github.com/docker/api/bin/* .
|
COPY --from=make-cross /api/bin/* .
|
||||||
|
|
||||||
FROM make-protos as test
|
FROM make-protos as test
|
||||||
RUN make -f builder.Makefile test
|
RUN make -f builder.Makefile test
|
||||||
|
|
||||||
|
FROM fs AS lint
|
||||||
|
RUN make -f builder.Makefile lint
|
||||||
|
8
Makefile
8
Makefile
@ -53,8 +53,14 @@ test: ## Run unit tests
|
|||||||
cache-clear: # Clear the builder cache
|
cache-clear: # Clear the builder cache
|
||||||
@docker builder prune --force --filter type=exec.cachemount --filter=unused-for=24h
|
@docker builder prune --force --filter type=exec.cachemount --filter=unused-for=24h
|
||||||
|
|
||||||
|
lint: ## run linter(s)
|
||||||
|
@docker build . \
|
||||||
|
--target lint
|
||||||
|
|
||||||
help: ## Show help
|
help: ## Show help
|
||||||
@echo Please specify a build target. The choices are:
|
@echo Please specify a build target. The choices are:
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
.PHONY: all protos cli cross test cache-clear help
|
FORCE:
|
||||||
|
|
||||||
|
.PHONY: all protos cli cross test cache-clear lint help
|
||||||
|
12
README.md
12
README.md
@ -4,7 +4,17 @@
|
|||||||
|
|
||||||
## Dev Setup
|
## Dev Setup
|
||||||
|
|
||||||
Make sure you have Docker installed and running.
|
The recommended way is to use the main `Makefile` that runs everything inside a container.
|
||||||
|
|
||||||
|
If you don't have or want to use Docker for building you need to make sure you have all the needed tools installed locally:
|
||||||
|
|
||||||
|
* go 1.14
|
||||||
|
* `go get github.com/golang/protobuf/protoc-gen-go@v1.4.1`
|
||||||
|
* `go get golang.org/x/tools/cmd/goimports`
|
||||||
|
* `go get gotest.tools/gotestsum@v0.4.2`
|
||||||
|
* `go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.26.0`
|
||||||
|
|
||||||
|
And then you can call the same make targets but you need to pass it the `builder.Makefile` (`make -f builder.Makefile`).
|
||||||
|
|
||||||
## Building the project
|
## Building the project
|
||||||
|
|
||||||
|
48
azure/aci.go
48
azure/aci.go
@ -32,7 +32,7 @@ func init() {
|
|||||||
func createACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) (c containerinstance.ContainerGroup, err error) {
|
func createACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) (c containerinstance.ContainerGroup, err error) {
|
||||||
containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID)
|
containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c, fmt.Errorf("cannot get container group client: %v", err)
|
return c, errors.Wrapf(err, "cannot get container group client")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the container group already exists
|
// Check if the container group already exists
|
||||||
@ -96,30 +96,11 @@ func createACIContainers(ctx context.Context, aciContext store.AciContext, group
|
|||||||
return containerGroup, err
|
return containerGroup, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func listACIContainers(aciContext store.AciContext) (c []containerinstance.ContainerGroup, err error) {
|
|
||||||
ctx := context.TODO()
|
|
||||||
containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID)
|
|
||||||
if err != nil {
|
|
||||||
return c, fmt.Errorf("cannot get container group client: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var containers []containerinstance.ContainerGroup
|
|
||||||
result, err := containerGroupsClient.ListByResourceGroup(ctx, aciContext.ResourceGroup)
|
|
||||||
if err != nil {
|
|
||||||
return []containerinstance.ContainerGroup{}, err
|
|
||||||
}
|
|
||||||
for result.NotDone() {
|
|
||||||
containers = append(containers, result.Values()...)
|
|
||||||
if err := result.NextWithContext(ctx); err != nil {
|
|
||||||
return []containerinstance.ContainerGroup{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return containers, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func execACIContainer(ctx context.Context, aciContext store.AciContext, command, containerGroup string, containerName string) (c containerinstance.ContainerExecResponse, err error) {
|
func execACIContainer(ctx context.Context, aciContext store.AciContext, command, containerGroup string, containerName string) (c containerinstance.ContainerExecResponse, err error) {
|
||||||
containerClient := getContainerClient(aciContext.SubscriptionID)
|
containerClient, err := getContainerClient(aciContext.SubscriptionID)
|
||||||
|
if err != nil {
|
||||||
|
return c, errors.Wrapf(err, "cannot get container client")
|
||||||
|
}
|
||||||
rows, cols := getTermSize()
|
rows, cols := getTermSize()
|
||||||
containerExecRequest := containerinstance.ContainerExecRequest{
|
containerExecRequest := containerinstance.ContainerExecRequest{
|
||||||
Command: to.StringPtr(command),
|
Command: to.StringPtr(command),
|
||||||
@ -224,7 +205,10 @@ func exec(ctx context.Context, address string, password string, reader io.Reader
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string) (string, error) {
|
func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string) (string, error) {
|
||||||
containerClient := getContainerClient(aciContext.SubscriptionID)
|
containerClient, err := getContainerClient(aciContext.SubscriptionID)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "cannot get container client")
|
||||||
|
}
|
||||||
|
|
||||||
logs, err := containerClient.ListLogs(ctx, aciContext.ResourceGroup, containerGroupName, containerName, nil)
|
logs, err := containerClient.ListLogs(ctx, aciContext.ResourceGroup, containerGroupName, containerName, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -234,15 +218,21 @@ func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, conta
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) {
|
func getContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) {
|
||||||
auth, _ := auth.NewAuthorizerFromCLI()
|
auth, err := auth.NewAuthorizerFromCLI()
|
||||||
|
if err != nil {
|
||||||
|
return containerinstance.ContainerGroupsClient{}, err
|
||||||
|
}
|
||||||
containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID)
|
containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID)
|
||||||
containerGroupsClient.Authorizer = auth
|
containerGroupsClient.Authorizer = auth
|
||||||
return containerGroupsClient, nil
|
return containerGroupsClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerClient(subscriptionID string) containerinstance.ContainerClient {
|
func getContainerClient(subscriptionID string) (containerinstance.ContainerClient, error) {
|
||||||
auth, _ := auth.NewAuthorizerFromCLI()
|
auth, err := auth.NewAuthorizerFromCLI()
|
||||||
|
if err != nil {
|
||||||
|
return containerinstance.ContainerClient{}, err
|
||||||
|
}
|
||||||
containerClient := containerinstance.NewContainerClient(subscriptionID)
|
containerClient := containerinstance.NewContainerClient(subscriptionID)
|
||||||
containerClient.Authorizer = auth
|
containerClient.Authorizer = auth
|
||||||
return containerClient
|
return containerClient, nil
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ func getter() interface{} {
|
|||||||
return &store.AciContext{}
|
return &store.AciContext{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a backend that can manage containers on ACI
|
||||||
func New(ctx context.Context) (containers.ContainerService, error) {
|
func New(ctx context.Context) (containers.ContainerService, error) {
|
||||||
currentContext := apicontext.CurrentContext(ctx)
|
currentContext := apicontext.CurrentContext(ctx)
|
||||||
contextStore, err := store.New()
|
contextStore, err := store.New()
|
||||||
|
@ -21,8 +21,10 @@ const (
|
|||||||
volumeDriveroptsAccountNameKey = "storage_account_name"
|
volumeDriveroptsAccountNameKey = "storage_account_name"
|
||||||
volumeDriveroptsAccountKeyKey = "storage_account_key"
|
volumeDriveroptsAccountKeyKey = "storage_account_key"
|
||||||
singleContainerName = "single--container--aci"
|
singleContainerName = "single--container--aci"
|
||||||
|
secretInlineMark = "inline:"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ToContainerGroup converts a compose project into a ACI container group
|
||||||
func ToContainerGroup(aciContext store.AciContext, p compose.Project) (containerinstance.ContainerGroup, error) {
|
func ToContainerGroup(aciContext store.AciContext, p compose.Project) (containerinstance.ContainerGroup, error) {
|
||||||
project := projectAciHelper(p)
|
project := projectAciHelper(p)
|
||||||
containerGroupName := strings.ToLower(project.Name)
|
containerGroupName := strings.ToLower(project.Name)
|
||||||
@ -98,8 +100,8 @@ func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, err
|
|||||||
var secretVolumes []containerinstance.Volume
|
var secretVolumes []containerinstance.Volume
|
||||||
for secretName, filepathToRead := range p.Secrets {
|
for secretName, filepathToRead := range p.Secrets {
|
||||||
var data []byte
|
var data []byte
|
||||||
if strings.HasPrefix(filepathToRead.File, compose.SecretInlineMark) {
|
if strings.HasPrefix(filepathToRead.File, secretInlineMark) {
|
||||||
data = []byte(filepathToRead.File[len(compose.SecretInlineMark):])
|
data = []byte(filepathToRead.File[len(secretInlineMark):])
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
data, err = ioutil.ReadFile(filepathToRead.File)
|
data, err = ioutil.ReadFile(filepathToRead.File)
|
||||||
|
@ -7,43 +7,46 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNoType = errors.New("backend: no type")
|
errNoType = errors.New("backend: no type")
|
||||||
ErrNoName = errors.New("backend: no name")
|
errNoName = errors.New("backend: no name")
|
||||||
ErrTypeRegistered = errors.New("backend: already registered")
|
errTypeRegistered = errors.New("backend: already registered")
|
||||||
)
|
)
|
||||||
|
|
||||||
type InitFunc func(context.Context) (interface{}, error)
|
type initFunc func(context.Context) (interface{}, error)
|
||||||
|
|
||||||
type Backend struct {
|
type registeredBackend struct {
|
||||||
name string
|
name string
|
||||||
backendType string
|
backendType string
|
||||||
init InitFunc
|
init initFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var backends = struct {
|
var backends = struct {
|
||||||
r []*Backend
|
r []*registeredBackend
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
func Register(name string, backendType string, init InitFunc) {
|
// Register adds a typed backend to the registry
|
||||||
|
func Register(name string, backendType string, init initFunc) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
panic(ErrNoName)
|
panic(errNoName)
|
||||||
}
|
}
|
||||||
if backendType == "" {
|
if backendType == "" {
|
||||||
panic(ErrNoType)
|
panic(errNoType)
|
||||||
}
|
}
|
||||||
for _, b := range backends.r {
|
for _, b := range backends.r {
|
||||||
if b.backendType == backendType {
|
if b.backendType == backendType {
|
||||||
panic(ErrTypeRegistered)
|
panic(errTypeRegistered)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backends.r = append(backends.r, &Backend{
|
backends.r = append(backends.r, ®isteredBackend{
|
||||||
name,
|
name,
|
||||||
backendType,
|
backendType,
|
||||||
init,
|
init,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get returns the backend registered for a particular type, it returns
|
||||||
|
// an error if there is no registered backends for the given type.
|
||||||
func Get(ctx context.Context, backendType string) (interface{}, error) {
|
func Get(ctx context.Context, backendType string) (interface{}, error) {
|
||||||
for _, b := range backends.r {
|
for _, b := range backends.r {
|
||||||
if b.backendType == backendType {
|
if b.backendType == backendType {
|
||||||
|
@ -57,6 +57,10 @@ cross:
|
|||||||
test:
|
test:
|
||||||
@gotestsum ./...
|
@gotestsum ./...
|
||||||
|
|
||||||
|
lint:
|
||||||
|
golangci-lint run --timeout 10m0s ./...
|
||||||
|
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
.PHONY: all protos cli cross test
|
.PHONY: all protos cli cross test lint
|
||||||
|
@ -38,9 +38,7 @@ import (
|
|||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CliContext struct {
|
// ContextCommand manages contexts
|
||||||
}
|
|
||||||
|
|
||||||
func ContextCommand() *cobra.Command {
|
func ContextCommand() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "context",
|
Use: "context",
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2020 Docker Inc.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use, copy,
|
|
||||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH
|
|
||||||
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
v1 "github.com/docker/api/backend/v1"
|
|
||||||
"github.com/docker/api/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ExampleCommand = cobra.Command{
|
|
||||||
Use: "example",
|
|
||||||
Short: "sample command using backend, to be removed later",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
ctx := cmd.Context()
|
|
||||||
|
|
||||||
c, err := client.New(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "cannot connect to backend")
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := c.BackendInformation(ctx, &v1.BackendInformationRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "fetch backend information")
|
|
||||||
}
|
|
||||||
enc := json.NewEncoder(os.Stdout)
|
|
||||||
enc.SetIndent("", " ")
|
|
||||||
return enc.Encode(info)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type backendAddressKey struct{}
|
|
||||||
|
|
||||||
func BackendAddress(ctx context.Context) (string, error) {
|
|
||||||
v, ok := ctx.Value(backendAddressKey{}).(string)
|
|
||||||
if !ok {
|
|
||||||
return "", errors.New("no backend address key")
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -17,6 +18,7 @@ type execOpts struct {
|
|||||||
Tty bool
|
Tty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecCommand runs a command in a running container
|
||||||
func ExecCommand() *cobra.Command {
|
func ExecCommand() *cobra.Command {
|
||||||
var opts execOpts
|
var opts execOpts
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -52,7 +54,9 @@ func runExec(ctx context.Context, opts execOpts, name string, command string) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
con.Reset()
|
if err := con.Reset(); err != nil {
|
||||||
|
fmt.Println("Unable to close the console")
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
stdout = con
|
stdout = con
|
||||||
|
@ -16,6 +16,7 @@ type logsOpts struct {
|
|||||||
Tail string
|
Tail string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogsCommand fetches and shows logs of a container
|
||||||
func LogsCommand() *cobra.Command {
|
func LogsCommand() *cobra.Command {
|
||||||
var opts logsOpts
|
var opts logsOpts
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PsCommand lists containers
|
||||||
var PsCommand = cobra.Command{
|
var PsCommand = cobra.Command{
|
||||||
Use: "ps",
|
Use: "ps",
|
||||||
Short: "List containers",
|
Short: "List containers",
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Command runs a container
|
||||||
func Command() *cobra.Command {
|
func Command() *cobra.Command {
|
||||||
var opts runOpts
|
var opts runOpts
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@ -20,6 +20,7 @@ type serveOpts struct {
|
|||||||
address string
|
address string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServeCommand returns the command to serve the API
|
||||||
func ServeCommand() *cobra.Command {
|
func ServeCommand() *cobra.Command {
|
||||||
var opts serveOpts
|
var opts serveOpts
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -42,9 +43,10 @@ func runServe(ctx context.Context, opts serveOpts) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "listen unix socket")
|
return errors.Wrap(err, "listen unix socket")
|
||||||
}
|
}
|
||||||
|
// nolint errcheck
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
p := proxy.NewContainerApi()
|
p := proxy.NewContainerAPI()
|
||||||
|
|
||||||
containersv1.RegisterContainersServer(s, p)
|
containersv1.RegisterContainersServer(s, p)
|
||||||
cliv1.RegisterCliServer(s, &cliServer{
|
cliv1.RegisterCliServer(s, &cliServer{
|
||||||
|
@ -51,7 +51,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type mainOpts struct {
|
type mainOpts struct {
|
||||||
apicontext.ContextFlags
|
apicontext.Flags
|
||||||
debug bool
|
debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,6 @@ func main() {
|
|||||||
cmd.ContextCommand(),
|
cmd.ContextCommand(),
|
||||||
&cmd.PsCommand,
|
&cmd.PsCommand,
|
||||||
cmd.ServeCommand(),
|
cmd.ServeCommand(),
|
||||||
&cmd.ExampleCommand,
|
|
||||||
run.Command(),
|
run.Command(),
|
||||||
cmd.ExecCommand(),
|
cmd.ExecCommand(),
|
||||||
cmd.LogsCommand(),
|
cmd.LogsCommand(),
|
||||||
|
@ -41,7 +41,7 @@ import (
|
|||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a GRPC client
|
// New returns a backend client
|
||||||
func New(ctx context.Context) (*Client, error) {
|
func New(ctx context.Context) (*Client, error) {
|
||||||
currentContext := apicontext.CurrentContext(ctx)
|
currentContext := apicontext.CurrentContext(ctx)
|
||||||
s := store.ContextStore(ctx)
|
s := store.ContextStore(ctx)
|
||||||
@ -68,6 +68,7 @@ func New(ctx context.Context) (*Client, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client is a multi-backend client
|
||||||
type Client struct {
|
type Client struct {
|
||||||
backendv1.BackendClient
|
backendv1.BackendClient
|
||||||
cliv1.CliClient
|
cliv1.CliClient
|
||||||
@ -78,6 +79,7 @@ type Client struct {
|
|||||||
cc containers.ContainerService
|
cc containers.ContainerService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerService returns the backend service for the current context
|
||||||
func (c *Client) ContainerService() containers.ContainerService {
|
func (c *Client) ContainerService() containers.ContainerService {
|
||||||
return c.cc
|
return c.cc
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,14 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var supportedFilenames = []string{
|
||||||
SecretInlineMark = "inline:"
|
|
||||||
)
|
|
||||||
|
|
||||||
var SupportedFilenames = []string{
|
|
||||||
"compose.yml",
|
"compose.yml",
|
||||||
"compose.yaml",
|
"compose.yaml",
|
||||||
"docker-compose.yml",
|
"docker-compose.yml",
|
||||||
"docker-compose.yaml",
|
"docker-compose.yaml",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProjectOptions configures a compose project
|
||||||
type ProjectOptions struct {
|
type ProjectOptions struct {
|
||||||
Name string
|
Name string
|
||||||
WorkDir string
|
WorkDir string
|
||||||
@ -32,6 +29,7 @@ type ProjectOptions struct {
|
|||||||
Environment []string
|
Environment []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Project represents a compose project with a name
|
||||||
type Project struct {
|
type Project struct {
|
||||||
types.Config
|
types.Config
|
||||||
projectDir string
|
projectDir string
|
||||||
@ -100,7 +98,7 @@ func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
var candidates []string
|
var candidates []string
|
||||||
for _, n := range SupportedFilenames {
|
for _, n := range supportedFilenames {
|
||||||
f := filepath.Join(pwd, n)
|
f := filepath.Join(pwd, n)
|
||||||
if _, err := os.Stat(f); err == nil {
|
if _, err := os.Stat(f); err == nil {
|
||||||
candidates = append(candidates, f)
|
candidates = append(candidates, f)
|
||||||
@ -116,7 +114,7 @@ func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) {
|
|||||||
}
|
}
|
||||||
parent := filepath.Dir(pwd)
|
parent := filepath.Dir(pwd)
|
||||||
if parent == pwd {
|
if parent == pwd {
|
||||||
return nil, fmt.Errorf("Can't find a suitable configuration file in this directory or any parent. Is %q the right directory?", pwd)
|
return nil, fmt.Errorf("can't find a suitable configuration file in this directory or any parent. Is %q the right directory?", pwd)
|
||||||
}
|
}
|
||||||
pwd = parent
|
pwd = parent
|
||||||
}
|
}
|
||||||
@ -129,12 +127,11 @@ func parseConfigs(configPaths []string) ([]types.ConfigFile, error) {
|
|||||||
var err error
|
var err error
|
||||||
if f == "-" {
|
if f == "-" {
|
||||||
return []types.ConfigFile{}, errors.New("reading compose file from stdin is not supported")
|
return []types.ConfigFile{}, errors.New("reading compose file from stdin is not supported")
|
||||||
} else {
|
|
||||||
if _, err := os.Stat(f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b, err = ioutil.ReadFile(f)
|
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(f); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b, err = ioutil.ReadFile(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
30
consts.go
30
consts.go
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2019 Docker Inc.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use, copy,
|
|
||||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH
|
|
||||||
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package api
|
|
||||||
|
|
||||||
const DockerContextKey = "DOCKER_CONTEXT_KEY"
|
|
@ -11,7 +11,7 @@ type Container struct {
|
|||||||
Status string
|
Status string
|
||||||
Image string
|
Image string
|
||||||
Command string
|
Command string
|
||||||
CpuTime uint64
|
CPUTime uint64
|
||||||
MemoryUsage uint64
|
MemoryUsage uint64
|
||||||
MemoryLimit uint64
|
MemoryLimit uint64
|
||||||
PidsCurrent uint64
|
PidsCurrent uint64
|
||||||
@ -37,6 +37,7 @@ type ContainerConfig struct {
|
|||||||
Ports []Port
|
Ports []Port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogsRequest contains configuration about a log request
|
||||||
type LogsRequest struct {
|
type LogsRequest struct {
|
||||||
Follow bool
|
Follow bool
|
||||||
Tail string
|
Tail string
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LoadConfigFile loads the docker configuration
|
||||||
func LoadConfigFile(configDir string, configFileName string) (*ConfigFile, error) {
|
func LoadConfigFile(configDir string, configFileName string) (*ConfigFile, error) {
|
||||||
filename := filepath.Join(configDir, configFileName)
|
filename := filepath.Join(configDir, configFileName)
|
||||||
configFile := &ConfigFile{
|
configFile := &ConfigFile{
|
||||||
@ -45,6 +46,7 @@ func LoadConfigFile(configDir string, configFileName string) (*ConfigFile, error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't read %s: %w", filename, err)
|
return nil, fmt.Errorf("can't read %s: %w", filename, err)
|
||||||
}
|
}
|
||||||
|
// nolint errcheck
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
err = json.NewDecoder(file).Decode(&configFile)
|
err = json.NewDecoder(file).Decode(&configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,6 +61,7 @@ func LoadConfigFile(configDir string, configFileName string) (*ConfigFile, error
|
|||||||
return configFile, nil
|
return configFile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigFile contains the current context from the docker configuration file
|
||||||
type ConfigFile struct {
|
type ConfigFile struct {
|
||||||
Filename string `json:"-"` // Note: for internal use only
|
Filename string `json:"-"` // Note: for internal use only
|
||||||
CurrentContext string `json:"currentContext,omitempty"`
|
CurrentContext string `json:"currentContext,omitempty"`
|
||||||
|
@ -6,10 +6,13 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
const KEY = "context_key"
|
// Key is the key where the current docker context is stored in the metadata
|
||||||
|
// of a gRPC request
|
||||||
|
const Key = "context_key"
|
||||||
|
|
||||||
type currentContextKey struct{}
|
type currentContextKey struct{}
|
||||||
|
|
||||||
|
// WithCurrentContext sets the name of the current docker context
|
||||||
func WithCurrentContext(ctx gocontext.Context, contextName string) context.Context {
|
func WithCurrentContext(ctx gocontext.Context, contextName string) context.Context {
|
||||||
return context.WithValue(ctx, currentContextKey{}, contextName)
|
return context.WithValue(ctx, currentContextKey{}, contextName)
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,14 @@ const (
|
|||||||
configFileDir = ".docker"
|
configFileDir = ".docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContextFlags struct {
|
// Flags are the global cli flags
|
||||||
|
type Flags struct {
|
||||||
Config string
|
Config string
|
||||||
Context string
|
Context string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ContextFlags) AddFlags(flags *pflag.FlagSet) {
|
// AddFlags adds persistent (global) flags
|
||||||
|
func (c *Flags) AddFlags(flags *pflag.FlagSet) {
|
||||||
flags.StringVar(&c.Config, "config", filepath.Join(home(), configFileDir), "Location of the client config files `DIRECTORY`")
|
flags.StringVar(&c.Config, "config", filepath.Join(home(), configFileDir), "Location of the client config files `DIRECTORY`")
|
||||||
flags.StringVarP(&c.Context, "context", "c", os.Getenv("DOCKER_CONTEXT"), "context")
|
flags.StringVarP(&c.Context, "context", "c", os.Getenv("DOCKER_CONTEXT"), "context")
|
||||||
}
|
}
|
||||||
|
@ -47,16 +47,18 @@ const (
|
|||||||
|
|
||||||
type contextStoreKey struct{}
|
type contextStoreKey struct{}
|
||||||
|
|
||||||
|
// WithContextStore adds the store to the context
|
||||||
func WithContextStore(ctx context.Context, store Store) context.Context {
|
func WithContextStore(ctx context.Context, store Store) context.Context {
|
||||||
return context.WithValue(ctx, contextStoreKey{}, store)
|
return context.WithValue(ctx, contextStoreKey{}, store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContextStore returns the store from the context
|
||||||
func ContextStore(ctx context.Context) Store {
|
func ContextStore(ctx context.Context) Store {
|
||||||
s, _ := ctx.Value(contextStoreKey{}).(Store)
|
s, _ := ctx.Value(contextStoreKey{}).(Store)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store
|
// Store is the context store
|
||||||
type Store interface {
|
type Store interface {
|
||||||
// Get returns the context with name, it returns an error if the context
|
// Get returns the context with name, it returns an error if the context
|
||||||
// doesn't exist
|
// doesn't exist
|
||||||
@ -74,16 +76,18 @@ type store struct {
|
|||||||
root string
|
root string
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoreOpt func(*store)
|
// Opt is a functional option for the store
|
||||||
|
type Opt func(*store)
|
||||||
|
|
||||||
func WithRoot(root string) StoreOpt {
|
// WithRoot sets a new root to the store
|
||||||
|
func WithRoot(root string) Opt {
|
||||||
return func(s *store) {
|
return func(s *store) {
|
||||||
s.root = root
|
s.root = root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a configured context store
|
// New returns a configured context store with $HOME/.docker as root
|
||||||
func New(opts ...StoreOpt) (Store, error) {
|
func New(opts ...Opt) (Store, error) {
|
||||||
home, err := os.UserHomeDir()
|
home, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -182,7 +186,7 @@ func (s *store) Create(name string, data TypedContext) error {
|
|||||||
dir := contextdirOf(name)
|
dir := contextdirOf(name)
|
||||||
metaDir := filepath.Join(s.root, contextsDir, metadataDir, dir)
|
metaDir := filepath.Join(s.root, contextsDir, metadataDir, dir)
|
||||||
if _, err := os.Stat(metaDir); !os.IsNotExist(err) {
|
if _, err := os.Stat(metaDir); !os.IsNotExist(err) {
|
||||||
return fmt.Errorf("Context %q already exists", name)
|
return fmt.Errorf("context %q already exists", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := os.Mkdir(metaDir, 0755)
|
err := os.Mkdir(metaDir, 0755)
|
||||||
@ -191,15 +195,15 @@ func (s *store) Create(name string, data TypedContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if data.Data == nil {
|
if data.Data == nil {
|
||||||
data.Data = DummyContext{}
|
data.Data = dummyContext{}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta := Metadata{
|
meta := Metadata{
|
||||||
Name: name,
|
Name: name,
|
||||||
Metadata: data,
|
Metadata: data,
|
||||||
Endpoints: map[string]interface{}{
|
Endpoints: map[string]interface{}{
|
||||||
"docker": DummyContext{},
|
"docker": dummyContext{},
|
||||||
(data.Type): DummyContext{},
|
(data.Type): dummyContext{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,8 +241,9 @@ func contextdirOf(name string) string {
|
|||||||
return digest.FromString(name).Encoded()
|
return digest.FromString(name).Encoded()
|
||||||
}
|
}
|
||||||
|
|
||||||
type DummyContext struct{}
|
type dummyContext struct{}
|
||||||
|
|
||||||
|
// Metadata represents the docker context metadata
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
Name string `json:",omitempty"`
|
Name string `json:",omitempty"`
|
||||||
Metadata TypedContext `json:",omitempty"`
|
Metadata TypedContext `json:",omitempty"`
|
||||||
@ -257,12 +262,14 @@ type untypedContext struct {
|
|||||||
Type string `json:",omitempty"`
|
Type string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TypedContext is a context with a type (moby, aci, etc...)
|
||||||
type TypedContext struct {
|
type TypedContext struct {
|
||||||
Type string `json:",omitempty"`
|
Type string `json:",omitempty"`
|
||||||
Description string `json:",omitempty"`
|
Description string `json:",omitempty"`
|
||||||
Data interface{} `json:",omitempty"`
|
Data interface{} `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AciContext is the context for ACI
|
||||||
type AciContext struct {
|
type AciContext struct {
|
||||||
SubscriptionID string `json:",omitempty"`
|
SubscriptionID string `json:",omitempty"`
|
||||||
Location string `json:",omitempty"`
|
Location string `json:",omitempty"`
|
||||||
|
@ -55,7 +55,8 @@ func (suite *StoreTestSuite) BeforeTest(suiteName, testName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StoreTestSuite) AfterTest(suiteName, testName string) {
|
func (suite *StoreTestSuite) AfterTest(suiteName, testName string) {
|
||||||
os.RemoveAll(suite.dir)
|
err := os.RemoveAll(suite.dir)
|
||||||
|
require.Nil(suite.T(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StoreTestSuite) TestCreate() {
|
func (suite *StoreTestSuite) TestCreate() {
|
||||||
|
@ -13,14 +13,10 @@ type containerService struct{}
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
backend.Register("example", "example", func(ctx context.Context) (interface{}, error) {
|
backend.Register("example", "example", func(ctx context.Context) (interface{}, error) {
|
||||||
return New(), nil
|
return &containerService{}, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() containers.ContainerService {
|
|
||||||
return &containerService{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *containerService) List(ctx context.Context) ([]containers.Container, error) {
|
func (cs *containerService) List(ctx context.Context) ([]containers.Container, error) {
|
||||||
return []containers.Container{
|
return []containers.Container{
|
||||||
{
|
{
|
||||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
|||||||
module github.com/docker/api
|
module github.com/docker/api
|
||||||
|
|
||||||
go 1.13
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible
|
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
go get -u github.com/gogo/protobuf/proto
|
|
||||||
go get -u github.com/gogo/protobuf/jsonpb
|
|
||||||
go get -u github.com/golang/protobuf/protoc-gen-go
|
|
||||||
go get -u github.com/stevvooe/protobuild
|
|
||||||
go get -u gotest.tools/gotestsum
|
|
@ -1,61 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright The containerd Authors.
|
|
||||||
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
#
|
|
||||||
# Downloads and installs protobuf
|
|
||||||
#
|
|
||||||
set -eu -o pipefail
|
|
||||||
|
|
||||||
PROTOBUF_VERSION=3.11.4
|
|
||||||
GOARCH=$(go env GOARCH)
|
|
||||||
GOOS=$(go env GOOS)
|
|
||||||
PROTOBUF_DIR=$(mktemp -d)
|
|
||||||
|
|
||||||
case $GOARCH in
|
|
||||||
|
|
||||||
arm64)
|
|
||||||
wget -O $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-aarch64.zip"
|
|
||||||
unzip $PROTOBUF_DIR/protobuf -d /usr/local
|
|
||||||
;;
|
|
||||||
|
|
||||||
amd64 | 386)
|
|
||||||
if [ "$GOOS" = windows ]; then
|
|
||||||
wget -O $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-win32.zip"
|
|
||||||
elif [ "$GOOS" = linux ]; then
|
|
||||||
wget -O $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-x86_64.zip"
|
|
||||||
elif [ "$GOOS" = darwin ]; then
|
|
||||||
curl -Lo $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-osx-x86_64.zip"
|
|
||||||
fi
|
|
||||||
unzip $PROTOBUF_DIR/protobuf -x readme.txt -d /usr/local
|
|
||||||
;;
|
|
||||||
|
|
||||||
ppc64le)
|
|
||||||
wget -O $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-ppcle_64.zip"
|
|
||||||
unzip $PROTOBUF_DIR/protobuf -d /usr/local
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
wget -O $PROTOBUF_DIR/protobuf "https://github.com/google/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-cpp-$PROTOBUF_VERSION.zip"
|
|
||||||
unzip $PROTOBUF_DIR/protobuf -d /usr/src/protobuf
|
|
||||||
cd /usr/src/protobuf/protobuf-$PROTOBUF_VERSION
|
|
||||||
./autogen.sh
|
|
||||||
./configure --disable-shared
|
|
||||||
make
|
|
||||||
make check
|
|
||||||
make install
|
|
||||||
ldconfig
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
rm -rf $PROTOBUF_DIR
|
|
@ -10,22 +10,25 @@ import (
|
|||||||
|
|
||||||
type clientKey struct{}
|
type clientKey struct{}
|
||||||
|
|
||||||
|
// WithClient adds the client to the context
|
||||||
func WithClient(ctx context.Context, c *client.Client) (context.Context, error) {
|
func WithClient(ctx context.Context, c *client.Client) (context.Context, error) {
|
||||||
return context.WithValue(ctx, clientKey{}, c), nil
|
return context.WithValue(ctx, clientKey{}, c), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client returns the client from the context
|
||||||
func Client(ctx context.Context) *client.Client {
|
func Client(ctx context.Context) *client.Client {
|
||||||
c, _ := ctx.Value(clientKey{}).(*client.Client)
|
c, _ := ctx.Value(clientKey{}).(*client.Client)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContainerApi() v1.ContainersServer {
|
// NewContainerAPI creates a proxy container server
|
||||||
return &proxyContainerApi{}
|
func NewContainerAPI() v1.ContainersServer {
|
||||||
|
return &proxyContainerAPI{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyContainerApi struct{}
|
type proxyContainerAPI struct{}
|
||||||
|
|
||||||
func (p *proxyContainerApi) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) {
|
func (p *proxyContainerAPI) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) {
|
||||||
client := Client(ctx)
|
client := Client(ctx)
|
||||||
|
|
||||||
c, err := client.ContainerService().List(ctx)
|
c, err := client.ContainerService().List(ctx)
|
||||||
@ -46,7 +49,7 @@ func (p *proxyContainerApi) List(ctx context.Context, _ *v1.ListRequest) (*v1.Li
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Create(ctx context.Context, request *v1.CreateRequest) (*v1.CreateResponse, error) {
|
func (p *proxyContainerAPI) Create(ctx context.Context, request *v1.CreateRequest) (*v1.CreateResponse, error) {
|
||||||
client := Client(ctx)
|
client := Client(ctx)
|
||||||
|
|
||||||
err := client.ContainerService().Run(ctx, containers.ContainerConfig{
|
err := client.ContainerService().Run(ctx, containers.ContainerConfig{
|
||||||
@ -57,26 +60,26 @@ func (p *proxyContainerApi) Create(ctx context.Context, request *v1.CreateReques
|
|||||||
return &v1.CreateResponse{}, err
|
return &v1.CreateResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Start(_ context.Context, _ *v1.StartRequest) (*v1.StartResponse, error) {
|
func (p *proxyContainerAPI) Start(_ context.Context, _ *v1.StartRequest) (*v1.StartResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Stop(_ context.Context, _ *v1.StopRequest) (*v1.StopResponse, error) {
|
func (p *proxyContainerAPI) Stop(_ context.Context, _ *v1.StopRequest) (*v1.StopResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Kill(_ context.Context, _ *v1.KillRequest) (*v1.KillResponse, error) {
|
func (p *proxyContainerAPI) Kill(_ context.Context, _ *v1.KillRequest) (*v1.KillResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Delete(_ context.Context, _ *v1.DeleteRequest) (*v1.DeleteResponse, error) {
|
func (p *proxyContainerAPI) Delete(_ context.Context, _ *v1.DeleteRequest) (*v1.DeleteResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Update(_ context.Context, _ *v1.UpdateRequest) (*v1.UpdateResponse, error) {
|
func (p *proxyContainerAPI) Update(_ context.Context, _ *v1.UpdateRequest) (*v1.UpdateResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) Exec(_ context.Context, _ *v1.ExecRequest) (*v1.ExecResponse, error) {
|
func (p *proxyContainerAPI) Exec(_ context.Context, _ *v1.ExecRequest) (*v1.ExecResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func unaryMeta(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
|
|||||||
return nil, errors.New("missing metadata")
|
return nil, errors.New("missing metadata")
|
||||||
}
|
}
|
||||||
|
|
||||||
key := md[apicontext.KEY]
|
key := md[apicontext.Key]
|
||||||
|
|
||||||
if len(key) == 1 {
|
if len(key) == 1 {
|
||||||
s, err := store.New()
|
s, err := store.New()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user