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

Bind core volume #477

Merged
merged 6 commits into from
Sep 21, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- run: docker swarm init
- run: docker build -t sleep docker-images/sleep/
- run: docker build -t http-server docker-images/http-server/
- run: env MESG_CORE_IMAGE=mesg/core:$CIRCLE_SHA1 go test -ldflags="-X 'github.com/mesg-foundation/core/config.Path=./'" -timeout 180s -p 1 -coverprofile=coverage.txt ./... # TODO: should remove ldflags when package database is mocked
- run: env MESG_CORE_IMAGE=mesg/core:$CIRCLE_SHA1 go test -timeout 180s -p 1 -coverprofile=coverage.txt ./...
- run: bash <(curl -s https://codecov.io/bash)

"publish_docker_dev":
Expand Down
52 changes: 43 additions & 9 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package config

import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"

"github.com/kelseyhightower/envconfig"
"github.com/mesg-foundation/core/version"
"github.com/mesg-foundation/core/x/xstrings"
homedir "github.com/mitchellh/go-homedir"
"github.com/sirupsen/logrus"
)

Expand All @@ -18,10 +21,6 @@ var (
once sync.Once
)

// Path to a dedicated directory for Core
// TODO: Path should be reverted to a const when the package database is renovated
var Path = "/mesg"

// Config contains all the configuration needed.
type Config struct {
Server struct {
Expand All @@ -39,35 +38,69 @@ type Config struct {

Core struct {
Image string
Path string
}

Docker struct {
Socket string
Core struct {
Path string
}
}
}

// New creates a new config with default values.
func New() *Config {
func New() (*Config, error) {
home, err := homedir.Dir()
if err != nil {
return nil, err
}

var c Config
c.Server.Address = ":50052"
c.Client.Address = "localhost:50052"
c.Log.Format = "text"
c.Log.Level = "info"
c.Core.Image = "mesg/core:" + strings.Split(version.Version, " ")[0]
return &c
c.Core.Path = filepath.Join(home, ".mesg")
c.Docker.Core.Path = "/mesg"
c.Docker.Socket = "/var/run/docker.sock"
return &c, nil
}

// Global returns a singleton of a Config after loaded ENV and validate the values.
func Global() (*Config, error) {
var err error
once.Do(func() {
instance = New()
instance.Load()
instance, err = New()
if err != nil {
return
}
if err = instance.Load(); err != nil {
return
}
if err = instance.Prepare(); err != nil {
return
}
})
if err != nil {
return nil, err
}
if err := instance.Validate(); err != nil {
return nil, err
}
return instance, nil
}

// Load reads config from environmental variables.
func (c *Config) Load() {
func (c *Config) Load() error {
envconfig.MustProcess(envPrefix, c)
return nil
}

// Prepare setups local directories or any other required thing based on config
func (c *Config) Prepare() error {
return os.MkdirAll(c.Core.Path, os.FileMode(0755))
}

// Validate checks values and return an error if any validation failed.
Expand All @@ -86,5 +119,6 @@ func (c *Config) DaemonEnv() map[string]string {
return map[string]string{
"MESG_LOG_FORMAT": c.Log.Format,
"MESG_LOG_LEVEL": c.Log.Level,
"MESG_CORE_PATH": c.Docker.Core.Path,
}
}
19 changes: 13 additions & 6 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ package config

import (
"os"
"path/filepath"
"strings"
"testing"

homedir "github.com/mitchellh/go-homedir"
"github.com/stretchr/testify/require"
)

func TestDefaultValue(t *testing.T) {
c := New()
home, _ := homedir.Dir()
c, err := New()
require.NoError(t, err)
require.Equal(t, ":50052", c.Server.Address)
require.Equal(t, "localhost:50052", c.Client.Address)
require.Equal(t, "text", c.Log.Format)
require.Equal(t, "info", c.Log.Level)
require.Equal(t, filepath.Join(home, ".mesg"), c.Core.Path)
require.Equal(t, "/mesg", c.Docker.Core.Path)
require.Equal(t, "/var/run/docker.sock", c.Docker.Socket)
require.True(t, strings.HasPrefix(c.Core.Image, "mesg/core:"))
}

Expand Down Expand Up @@ -45,7 +52,7 @@ func TestLoad(t *testing.T) {
os.Setenv("MESG_LOG_FORMAT", "test_log_format")
os.Setenv("MESG_LOG_LEVEL", "test_log_level")
os.Setenv("MESG_CORE_IMAGE", "test_core_image")
c := New()
c, _ := New()
c.Load()
require.Equal(t, "test_server_address", c.Server.Address)
require.Equal(t, "test_client_address", c.Client.Address)
Expand All @@ -55,20 +62,20 @@ func TestLoad(t *testing.T) {
}

func TestValidate(t *testing.T) {
c := New()
c, _ := New()
require.NoError(t, c.Validate())

c = New()
c, _ = New()
c.Log.Format = "wrongValue"
require.Error(t, c.Validate())

c = New()
c, _ = New()
c.Log.Level = "wrongValue"
require.Error(t, c.Validate())
}

func TestDaemonEnv(t *testing.T) {
c := New()
c, _ := New()
env := c.DaemonEnv()
require.Equal(t, c.Log.Format, env["MESG_LOG_FORMAT"])
require.Equal(t, c.Log.Level, env["MESG_LOG_LEVEL"])
Expand Down
4 changes: 1 addition & 3 deletions daemon/const.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package daemon

const (
name = "core"
dockerSocket = "/var/run/docker.sock"
volume = "mesg-core"
name = "core"
)

// Namespace returns the namespace of the MESG Core.
Expand Down
9 changes: 5 additions & 4 deletions daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ func serviceSpec() (spec container.ServiceOptions, err error) {
Env: container.MapToEnv(c.DaemonEnv()),
Mounts: []container.Mount{
{
Source: dockerSocket,
Target: dockerSocket,
Source: c.Docker.Socket,
Target: c.Docker.Socket,
Bind: true,
},
{
Source: volume,
Target: config.Path,
Source: c.Core.Path,
Target: c.Docker.Core.Path,
Bind: true,
},
},
Ports: []container.Port{
Expand Down
37 changes: 12 additions & 25 deletions daemon/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,24 @@ func startForTest() {
return
}

// func TestStart(t *testing.T) {
// <-testForceAndWaitForFullStop()
// service, err := Start()
// require.Nil(t, err)
// require.NotNil(t, service)
// }

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

func TestStartConfig(t *testing.T) {
c, _ := config.Global()
spec, err := serviceSpec()
require.Nil(t, err)
require.NoError(t, err)
// Make sure that the config directory is passed in parameter to write on the same folder
require.True(t, contains(spec.Env, "MESG_LOG_LEVEL=info"))
require.True(t, contains(spec.Env, "MESG_LOG_FORMAT=text"))
require.Contains(t, spec.Env, "MESG_LOG_LEVEL=info")
require.Contains(t, spec.Env, "MESG_LOG_FORMAT=text")
require.Contains(t, spec.Env, "MESG_CORE_PATH="+c.Docker.Core.Path)
// Ensure that the port is shared
c, err := config.Global()
_, port, err := xnet.SplitHostPort(c.Server.Address)
_, port, _ := xnet.SplitHostPort(c.Server.Address)
require.Equal(t, spec.Ports[0].Published, uint32(port))
require.Equal(t, spec.Ports[0].Target, uint32(port))
// Ensure that the docker socket is shared in the core
require.Equal(t, spec.Mounts[0].Source, dockerSocket)
require.Equal(t, spec.Mounts[0].Target, dockerSocket)
require.Equal(t, spec.Mounts[0].Source, c.Docker.Socket)
require.Equal(t, spec.Mounts[0].Target, c.Docker.Socket)
require.True(t, spec.Mounts[0].Bind)
// Ensure that the host users folder is sync with the core
require.Equal(t, spec.Mounts[1].Source, volume)
require.Equal(t, spec.Mounts[1].Target, config.Path)
require.Equal(t, spec.Mounts[1].Source, c.Core.Path)
require.Equal(t, spec.Mounts[1].Target, c.Docker.Core.Path)
require.True(t, spec.Mounts[1].Bind)
}
8 changes: 6 additions & 2 deletions database/services/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ func open() (db *leveldb.DB, err error) {
instanceMutex.Lock()
defer instanceMutex.Unlock()
if _instance == nil {
storagePath := filepath.Join(config.Path, "database", "services")
c, err := config.Global()
if err != nil {
return nil, err
}
storagePath := filepath.Join(c.Core.Path, "database", "services")
ilgooz marked this conversation as resolved.
Show resolved Hide resolved
_instance, err = leveldb.OpenFile(storagePath, nil)
if err != nil {
panic(err) // TODO: this should just be returned?
return nil, err
}
}
instances++
Expand Down