Skip to content

Commit

Permalink
Merge pull request #641 from mesg-foundation/feature/passing-env
Browse files Browse the repository at this point in the history
Configure services with envs
  • Loading branch information
ilgooz authored Dec 20, 2018
2 parents fbd0df4 + c877557 commit 92c8c63
Show file tree
Hide file tree
Showing 36 changed files with 498 additions and 262 deletions.
15 changes: 9 additions & 6 deletions api/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,27 @@ func DeployServiceStatusOption(statuses chan DeployStatus) DeployServiceOption {
}

// DeployService deploys a service from a gzipped tarball.
func (a *API) DeployService(r io.Reader, options ...DeployServiceOption) (*service.Service,
func (a *API) DeployService(r io.Reader, env map[string]string, options ...DeployServiceOption) (*service.Service,
*importer.ValidationError, error) {
return newServiceDeployer(a, options...).FromGzippedTar(r)
return newServiceDeployer(a, env, options...).FromGzippedTar(r)
}

// DeployServiceFromURL deploys a service living at a Git host.
// Supported URL types:
// - https://github.com/mesg-foundation/service-ethereum
// - https://github.com/mesg-foundation/service-ethereum#branchName
func (a *API) DeployServiceFromURL(url string, options ...DeployServiceOption) (*service.Service,
func (a *API) DeployServiceFromURL(url string, env map[string]string, options ...DeployServiceOption) (*service.Service,
*importer.ValidationError, error) {
return newServiceDeployer(a, options...).FromGitURL(url)
return newServiceDeployer(a, env, options...).FromGitURL(url)
}

// serviceDeployer provides functionalities to deploy a MESG service.
type serviceDeployer struct {
// statuses receives status messages produced during deployment.
statuses chan DeployStatus

env map[string]string

api *API
}

Expand All @@ -70,9 +72,10 @@ type DeployStatus struct {
}

// newServiceDeployer creates a new serviceDeployer with given api and options.
func newServiceDeployer(api *API, options ...DeployServiceOption) *serviceDeployer {
func newServiceDeployer(api *API, env map[string]string, options ...DeployServiceOption) *serviceDeployer {
d := &serviceDeployer{
api: api,
env: env,
}
for _, option := range options {
option(d)
Expand Down Expand Up @@ -126,7 +129,7 @@ func (d *serviceDeployer) deploy(r io.Reader) (*service.Service, *importer.Valid
d.forwardDeployStatuses(statuses)
}()

s, err := service.New(r,
s, err := service.New(r, d.env,
service.ContainerOption(d.api.container),
service.DeployStatusOption(statuses),
)
Expand Down
10 changes: 5 additions & 5 deletions api/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestDeployService(t *testing.T) {
archive, err := xarchive.GzippedTar(path)
require.NoError(t, err)

service, validationError, err := a.DeployService(archive, DeployServiceStatusOption(statuses))
service, validationError, err := a.DeployService(archive, nil, DeployServiceStatusOption(statuses))
require.Nil(t, validationError)
require.NoError(t, err)
require.Len(t, service.Hash, 40)
Expand Down Expand Up @@ -76,7 +76,7 @@ func TestDeployInvalidService(t *testing.T) {
archive, err := xarchive.GzippedTar(path)
require.NoError(t, err)

service, validationError, err := a.DeployService(archive, DeployServiceStatusOption(statuses))
service, validationError, err := a.DeployService(archive, nil, DeployServiceStatusOption(statuses))
require.Nil(t, service)
require.NoError(t, err)
require.Equal(t, (&importer.ValidationError{}).Error(), validationError.Error())
Expand Down Expand Up @@ -114,7 +114,7 @@ func TestDeployServiceFromURL(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
service, validationError, err := a.DeployServiceFromURL(url, DeployServiceStatusOption(statuses))
service, validationError, err := a.DeployServiceFromURL(url, nil, DeployServiceStatusOption(statuses))
require.Nil(t, validationError)
require.NoError(t, err)
require.Len(t, service.Hash, 40)
Expand Down Expand Up @@ -156,7 +156,7 @@ func TestDeployServiceFromURL(t *testing.T) {
func TestCreateTempFolder(t *testing.T) {
a, _, closer := newAPIAndDockerTest(t)
defer closer()
deployer := newServiceDeployer(a)
deployer := newServiceDeployer(a, nil)

path, err := deployer.createTempDir()
defer os.RemoveAll(path)
Expand All @@ -167,7 +167,7 @@ func TestCreateTempFolder(t *testing.T) {
func TestRemoveTempFolder(t *testing.T) {
a, _, closer := newAPIAndDockerTest(t)
defer closer()
deployer := newServiceDeployer(a)
deployer := newServiceDeployer(a, nil)

path, _ := deployer.createTempDir()
err := os.RemoveAll(path)
Expand Down
2 changes: 1 addition & 1 deletion commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ServiceExecutor interface {
ServiceByID(id string) (*coreapi.Service, error)
ServiceDeleteAll(deleteData bool) error
ServiceDelete(deleteData bool, ids ...string) error
ServiceDeploy(path string, statuses chan provider.DeployStatus) (id string, validationError, err error)
ServiceDeploy(path string, env map[string]string, statuses chan provider.DeployStatus) (id string, validationError, err error)
ServiceListenEvents(id, eventFilter string) (chan *coreapi.EventData, chan error, error)
ServiceListenResults(id, taskFilter, outputFilter string, tagFilters []string) (chan *coreapi.ResultData, chan error, error)
ServiceLogs(id string, dependencies ...string) (logs []*provider.Log, closer func(), err error)
Expand Down
18 changes: 9 additions & 9 deletions commands/mocks/Executor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions commands/provider/service_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type deploymentResult struct {
}

// ServiceDeploy deploys service from given path.
func (p *ServiceProvider) ServiceDeploy(path string, statuses chan DeployStatus) (id string,
func (p *ServiceProvider) ServiceDeploy(path string, env map[string]string, statuses chan DeployStatus) (id string,
validationError, err error) {
stream, err := p.client.DeployService(context.Background())
if err != nil {
Expand All @@ -53,11 +53,12 @@ func (p *ServiceProvider) ServiceDeploy(path string, statuses chan DeployStatus)
if govalidator.IsURL(path) {
if err := stream.Send(&coreapi.DeployServiceRequest{
Value: &coreapi.DeployServiceRequest_Url{Url: path},
Env: env,
}); err != nil {
return "", nil, err
}
} else {
if err := deployServiceSendServiceContext(path, stream); err != nil {
if err := deployServiceSendServiceContext(path, env, stream); err != nil {
return "", nil, err
}
}
Expand All @@ -71,14 +72,20 @@ func (p *ServiceProvider) ServiceDeploy(path string, statuses chan DeployStatus)
return result.serviceID, result.validationError, result.err
}

func deployServiceSendServiceContext(path string, stream coreapi.Core_DeployServiceClient) error {
func deployServiceSendServiceContext(path string, env map[string]string, stream coreapi.Core_DeployServiceClient) error {
archive, err := archive.TarWithOptions(path, &archive.TarOptions{
Compression: archive.Gzip,
})
if err != nil {
return err
}

if len(env) > 0 {
if err := stream.Send(&coreapi.DeployServiceRequest{Env: env}); err != nil {
return err
}
}

buf := make([]byte, 1024)
for {
n, err := archive.Read(buf)
Expand Down
7 changes: 5 additions & 2 deletions commands/service_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"github.com/mesg-foundation/core/commands/provider"
"github.com/mesg-foundation/core/utils/pretty"
"github.com/mesg-foundation/core/x/xerrors"
"github.com/mesg-foundation/core/x/xpflag"
"github.com/spf13/cobra"
)

type serviceDeployCmd struct {
baseCmd

path string
env map[string]string

e ServiceExecutor
}
Expand All @@ -27,11 +29,12 @@ func newServiceDeployCmd(e ServiceExecutor) *serviceDeployCmd {
Long: `Deploy a service.
To get more information, see the [deploy page from the documentation](https://docs.mesg.com/guide/service/deploy-a-service.html)`,
Example: `mesg-core service deploy PATH_TO_SERVICE`,
Example: `mesg-core service deploy [PATH_TO_SERVICE|URL_TO_SERVICE]`,
PreRunE: c.preRunE,
RunE: c.runE,
Args: cobra.MaximumNArgs(1),
})
c.cmd.Flags().Var(xpflag.NewStringToStringValue(&c.env, nil), "env", "set env defined in mesg.yml (configuration.env)")
return c
}

Expand All @@ -52,7 +55,7 @@ func (c *serviceDeployCmd) runE(cmd *cobra.Command, args []string) error {
printDeployStatuses(statuses)
}()

id, validationError, err := c.e.ServiceDeploy(c.path, statuses)
id, validationError, err := c.e.ServiceDeploy(c.path, c.env, statuses)
wg.Wait()

pretty.DestroySpinner()
Expand Down
15 changes: 15 additions & 0 deletions commands/service_deploy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package commands

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestServiceDeployCmdFlags(t *testing.T) {
c := newServiceDeployCmd(nil)

flags := c.cmd.Flags()
flags.Set("env", "a=1,b=2")
require.Equal(t, map[string]string{"a": "1", "b": "2"}, c.env)
}
5 changes: 4 additions & 1 deletion commands/service_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/mesg-foundation/core/commands/provider"
"github.com/mesg-foundation/core/utils/pretty"
"github.com/mesg-foundation/core/x/xerrors"
"github.com/mesg-foundation/core/x/xpflag"
"github.com/mesg-foundation/core/x/xsignal"
"github.com/spf13/cobra"
)
Expand All @@ -21,6 +22,7 @@ type serviceDevCmd struct {
taskFilter string
outputFilter string
path string
env map[string]string

e ServiceExecutor
}
Expand All @@ -42,6 +44,7 @@ func newServiceDevCmd(e ServiceExecutor) *serviceDevCmd {
c.cmd.Flags().StringVarP(&c.eventFilter, "event-filter", "e", c.eventFilter, "Only log the data of the given event")
c.cmd.Flags().StringVarP(&c.taskFilter, "task-filter", "t", "", "Only log the result of the given task")
c.cmd.Flags().StringVarP(&c.outputFilter, "output-filter", "o", "", "Only log the data of the given output of a task result. If set, you also need to set the task in --task-filter")
c.cmd.Flags().Var(xpflag.NewStringToStringValue(&c.env, nil), "env", "set env defined in mesg.yml (configuration.env)")
return c
}

Expand All @@ -62,7 +65,7 @@ func (c *serviceDevCmd) runE(cmd *cobra.Command, args []string) error {
printDeployStatuses(statuses)
}()

id, validationError, err := c.e.ServiceDeploy(c.path, statuses)
id, validationError, err := c.e.ServiceDeploy(c.path, c.env, statuses)
wg.Wait()

pretty.DestroySpinner()
Expand Down
14 changes: 0 additions & 14 deletions container/service_options.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package container

import (
"fmt"
"os"
"sort"
"strconv"
"strings"

Expand Down Expand Up @@ -137,15 +135,3 @@ func mergeLabels(l1 map[string]string, l2 map[string]string) map[string]string {
}
return l1
}

// MapToEnv transform a map of key value to a array of env string.
// env vars sorted by names to get an accurate order while testing, otherwise
// comparing a string slice with different orders will fail.
func MapToEnv(data map[string]string) []string {
env := make([]string, 0, len(data))
for key, value := range data {
env = append(env, fmt.Sprintf("%s=%s", key, value))
}
sort.Strings(env)
return env
}
18 changes: 0 additions & 18 deletions container/service_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,3 @@ func TestServiceOptionNetworks(t *testing.T) {
require.Equal(t, 1, len(networks[1].Aliases))
require.Equal(t, "test", networks[1].Aliases[0])
}

func contains(list []string, item string) bool {
for _, itemInList := range list {
if itemInList == item {
return true
}
}
return false
}

func TestMapToEnv(t *testing.T) {
env := MapToEnv(map[string]string{
"first": "first_value",
"second": "second_value",
})
require.True(t, contains(env, "first=first_value"))
require.True(t, contains(env, "second=second_value"))
}
3 changes: 2 additions & 1 deletion daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/mesg-foundation/core/config"
"github.com/mesg-foundation/core/container"
"github.com/mesg-foundation/core/x/xnet"
"github.com/mesg-foundation/core/x/xos"
)

// Daemon is an interface that start, stop etc core as daemon.
Expand Down Expand Up @@ -61,7 +62,7 @@ func (d *ContainerDaemon) buildServiceOptions(sharedNetworkID string) container.
return container.ServiceOptions{
Namespace: []string{},
Image: d.cfg.Core.Image,
Env: container.MapToEnv(d.cfg.DaemonEnv()),
Env: xos.EnvMapToSlice(d.cfg.DaemonEnv()),
Mounts: []container.Mount{
{
Source: d.cfg.Docker.Socket,
Expand Down
Loading

0 comments on commit 92c8c63

Please sign in to comment.