diff --git a/cmd/kraken/kraken.go b/cmd/kraken/kraken.go index 56a0b2d..756aaf4 100644 --- a/cmd/kraken/kraken.go +++ b/cmd/kraken/kraken.go @@ -11,7 +11,7 @@ func main() { } func Execute() { - err := commands.CreateServerCmd().Execute() + err := commands.CreateServerCmd(nil).Execute() if err != nil { os.Exit(1) } diff --git a/go.mod b/go.mod index 239b0af..0b2c312 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,13 @@ require ( git.front.kjuulh.io/kjuulh/curre v1.2.2 github.com/gin-gonic/gin v1.8.1 github.com/spf13/cobra v1.5.0 + github.com/stretchr/testify v1.8.0 go.uber.org/zap v1.23.0 + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect @@ -22,14 +25,15 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ugorji/go/codec v1.2.7 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9b28f4b..8460cab 100644 --- a/go.sum +++ b/go.sum @@ -59,11 +59,13 @@ github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= @@ -105,3 +107,4 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/integration_test/main_test.go b/integration_test/main_test.go new file mode 100644 index 0000000..df419b6 --- /dev/null +++ b/integration_test/main_test.go @@ -0,0 +1,25 @@ +//go:build integration +// +build integration + +package integrationtest_test + +import ( + "os" + "testing" + + "git.front.kjuulh.io/kjuulh/kraken/internal/server" + "go.uber.org/zap" +) + +func MainTest(t *testing.M) { + logger, err := zap.NewDevelopment() + if err != nil { + panic(err) + } + err = server.Start(logger) + if err != nil { + panic(err) + } + + os.Exit(t.Run()) +} diff --git a/integration_test/storage_test.go b/integration_test/storage_test.go new file mode 100644 index 0000000..40a7956 --- /dev/null +++ b/integration_test/storage_test.go @@ -0,0 +1,74 @@ +//go:build integration +// +build integration + +package integrationtest_test + +import ( + "context" + "os" + "path" + "testing" + + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "github.com/stretchr/testify/require" +) + +func TestInitializeStorage(t *testing.T) { + t.Parallel() + storage, cfg := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + if _, err := os.Stat(path.Join(cfg.Path, "storage")); os.IsNotExist(err) { + require.NoError(t, err, "could not create storage directory") + } +} + +func TestCleanupStorage(t *testing.T) { + t.Parallel() + storage, _ := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + err = storage.CleanupStorage(context.Background()) + require.NoError(t, err) +} + +func TestCreateArea(t *testing.T) { + t.Parallel() + storage, cfg := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + area, err := storage.CreateArea(context.Background()) + require.NoError(t, err) + require.NotNil(t, area) + require.NotEmpty(t, area.Path) + require.Contains(t, area.Path, cfg.Path) +} + +func TestRemoveArea(t *testing.T) { + t.Parallel() + storage, _ := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + area, err := storage.CreateArea(context.Background()) + require.NoError(t, err) + + err = storage.RemoveArea(context.Background(), area) + require.NoError(t, err) + + if _, err := os.Stat(area.Path); os.IsNotExist(err) { + require.Error(t, err, "directory could not be removed") + return + } + t.Fatal("directory could not be removed") +} + +func prepareService(t *testing.T) (*storage.Service, *storage.StorageConfig) { + cfg := &storage.StorageConfig{ + Path: t.TempDir(), + } + + return storage.NewService(cfg), cfg +} diff --git a/internal/server/server.go b/internal/server/server.go index a983253..39fd300 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -15,5 +15,6 @@ func Start(logger *zap.Logger) error { return curre.NewManager(). Register(NewGinHttpServer(deps)). + Register(NewStorageServer(logger.With(zap.String("app", "storageServer")), deps)). Run(ctx) } diff --git a/internal/server/storage_server.go b/internal/server/storage_server.go new file mode 100644 index 0000000..cb79b1f --- /dev/null +++ b/internal/server/storage_server.go @@ -0,0 +1,26 @@ +package server + +import ( + "context" + + "git.front.kjuulh.io/kjuulh/curre" + "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "go.uber.org/zap" +) + +func NewStorageServer(logger *zap.Logger, deps *serverdeps.ServerDeps) curre.Component { + storage := deps.GetStorageService() + return curre.NewFunctionalComponent(&curre.FunctionalComponent{ + InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + logger.Debug("Initializing storage") + return storage.InitializeStorage(ctx) + }, + StartFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + return nil + }, + StopFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + logger.Debug("Cleaning up storage") + return storage.CleanupStorage(ctx) + }, + }) +} diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index 0ca2c40..8673432 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -1,13 +1,29 @@ package serverdeps -import "go.uber.org/zap" +import ( + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "go.uber.org/zap" +) type ServerDeps struct { - logger *zap.Logger + logger *zap.Logger + storageConfig *storage.StorageConfig } func NewServerDeps(logger *zap.Logger) *ServerDeps { - return &ServerDeps{ + deps := &ServerDeps{ logger: logger.With(zap.String("app", "serverdeps")), } + + if storageCfg, err := storage.NewDefaultStorageConfig(); err != nil { + panic(err) + } else { + deps.storageConfig = storageCfg + } + + return deps +} + +func (deps *ServerDeps) GetStorageService() *storage.Service { + return storage.NewService(deps.storageConfig) } diff --git a/internal/services/actions/action.go b/internal/services/actions/action.go new file mode 100644 index 0000000..9d39eb6 --- /dev/null +++ b/internal/services/actions/action.go @@ -0,0 +1,2 @@ +package action + diff --git a/internal/services/storage/models.go b/internal/services/storage/models.go new file mode 100644 index 0000000..eac33dc --- /dev/null +++ b/internal/services/storage/models.go @@ -0,0 +1,7 @@ +package storage + +type ( + Area struct { + Path string + } +) diff --git a/internal/services/storage/storage.go b/internal/services/storage/storage.go new file mode 100644 index 0000000..7ef0ab5 --- /dev/null +++ b/internal/services/storage/storage.go @@ -0,0 +1,60 @@ +package storage + +import ( + "os" + "path" + + "golang.org/x/net/context" +) + +// The idea behind storage is that we have file dir, with a git repo. +// This file repo can now take certain actions + +type StorageConfig struct { + Path string +} + +func NewDefaultStorageConfig() (*StorageConfig, error) { + tempDir, err := os.MkdirTemp(os.TempDir(), "") + if err != nil { + return nil, err + } + return &StorageConfig{ + Path: path.Join(tempDir, "kraken"), + }, nil +} + +type Service struct { + cfg *StorageConfig +} + +func NewService(cfg *StorageConfig) *Service { + return &Service{cfg: cfg} +} + +func (s *Service) getStoragePath(ctx context.Context) string { + return path.Join(s.cfg.Path, "storage") +} + +func (s *Service) InitializeStorage(ctx context.Context) error { + return os.MkdirAll(s.getStoragePath(ctx), 0755) +} + +func (s *Service) CleanupStorage(ctx context.Context) error { + return os.RemoveAll(s.getStoragePath(ctx)) +} + +func (s *Service) CreateArea(ctx context.Context) (*Area, error) { + dir, err := os.MkdirTemp(s.getStoragePath(ctx), "*") + if err != nil { + return nil, err + } + + return &Area{ + Path: dir, + }, nil +} + +func (s *Service) RemoveArea(ctx context.Context, area *Area) error { + return os.RemoveAll(area.Path) +} diff --git a/roadmap.md b/roadmap.md index facf6d7..cc57dcd 100644 --- a/roadmap.md +++ b/roadmap.md @@ -2,7 +2,9 @@ ## POC: -- [ ] Create test action. +- [x] Create storage mechanism +- [ ] Pull repository into storage +- [ ] Create test action to run on repository - [ ] List git repositories on git.front.kjuulh.io. - [ ] Run action on each repo in list (hard-coded) using ssh and gpg. - [ ] Create PR