Rename "deployment" to "environment": code

Signed-off-by: Solomon Hykes <sh.github.6811@hykes.org>
This commit is contained in:
Solomon Hykes
2021-04-27 18:59:04 +00:00
parent d1853f9e4b
commit e6e8ab390d
29 changed files with 282 additions and 282 deletions

View File

@@ -60,14 +60,14 @@ func NewClient(ctx context.Context, host string, noCache bool) (*Client, error)
}, nil
}
type ClientDoFunc func(context.Context, *Deployment, Solver) error
type ClientDoFunc func(context.Context, *Environment, Solver) error
// FIXME: return completed *Route, instead of *compiler.Value
func (c *Client) Do(ctx context.Context, state *DeploymentState, fn ClientDoFunc) (*Deployment, error) {
func (c *Client) Do(ctx context.Context, state *EnvironmentState, fn ClientDoFunc) (*Environment, error) {
lg := log.Ctx(ctx)
eg, gctx := errgroup.WithContext(ctx)
deployment, err := NewDeployment(state)
environment, err := NewEnvironment(state)
if err != nil {
return nil, err
}
@@ -83,17 +83,17 @@ func (c *Client) Do(ctx context.Context, state *DeploymentState, fn ClientDoFunc
// Spawn build function
eg.Go(func() error {
return c.buildfn(gctx, deployment, fn, events)
return c.buildfn(gctx, environment, fn, events)
})
return deployment, eg.Wait()
return environment, eg.Wait()
}
func (c *Client) buildfn(ctx context.Context, deployment *Deployment, fn ClientDoFunc, ch chan *bk.SolveStatus) error {
func (c *Client) buildfn(ctx context.Context, environment *Environment, fn ClientDoFunc, ch chan *bk.SolveStatus) error {
lg := log.Ctx(ctx)
// Scan local dirs to grant access
localdirs := deployment.LocalDirs()
localdirs := environment.LocalDirs()
for label, dir := range localdirs {
abs, err := filepath.Abs(dir)
if err != nil {
@@ -121,24 +121,24 @@ func (c *Client) buildfn(ctx context.Context, deployment *Deployment, fn ClientD
s := NewSolver(c.c, gw, ch, auth, c.noCache)
lg.Debug().Msg("loading configuration")
if err := deployment.LoadPlan(ctx, s); err != nil {
if err := environment.LoadPlan(ctx, s); err != nil {
return nil, err
}
// Compute output overlay
if fn != nil {
if err := fn(ctx, deployment, s); err != nil {
if err := fn(ctx, environment, s); err != nil {
return nil, compiler.Err(err)
}
}
// Export deployment to a cue directory
// Export environment to a cue directory
// FIXME: this should be elsewhere
lg.Debug().Msg("exporting deployment")
span, _ := opentracing.StartSpanFromContext(ctx, "Deployment.Export")
lg.Debug().Msg("exporting environment")
span, _ := opentracing.StartSpanFromContext(ctx, "Environment.Export")
defer span.Finish()
computed := deployment.Computed().JSON().PrettyString()
computed := environment.Computed().JSON().PrettyString()
st := llb.
Scratch().
File(

View File

@@ -19,8 +19,8 @@ import (
"github.com/rs/zerolog/log"
)
type Deployment struct {
state *DeploymentState
type Environment struct {
state *EnvironmentState
// Layer 1: plan configuration
plan *compiler.Value
@@ -32,8 +32,8 @@ type Deployment struct {
computed *compiler.Value
}
func NewDeployment(st *DeploymentState) (*Deployment, error) {
d := &Deployment{
func NewEnvironment(st *EnvironmentState) (*Environment, error) {
d := &Environment{
state: st,
plan: compiler.NewValue(),
@@ -60,33 +60,33 @@ func NewDeployment(st *DeploymentState) (*Deployment, error) {
return d, nil
}
func (d *Deployment) ID() string {
func (d *Environment) ID() string {
return d.state.ID
}
func (d *Deployment) Name() string {
func (d *Environment) Name() string {
return d.state.Name
}
func (d *Deployment) PlanSource() Input {
func (d *Environment) PlanSource() Input {
return d.state.PlanSource
}
func (d *Deployment) Plan() *compiler.Value {
func (d *Environment) Plan() *compiler.Value {
return d.plan
}
func (d *Deployment) Input() *compiler.Value {
func (d *Environment) Input() *compiler.Value {
return d.input
}
func (d *Deployment) Computed() *compiler.Value {
func (d *Environment) Computed() *compiler.Value {
return d.computed
}
// LoadPlan loads the plan
func (d *Deployment) LoadPlan(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "deployment.LoadPlan")
func (d *Environment) LoadPlan(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "environment.LoadPlan")
defer span.Finish()
planSource, err := d.state.PlanSource.Compile()
@@ -114,11 +114,11 @@ func (d *Deployment) LoadPlan(ctx context.Context, s Solver) error {
return nil
}
// Scan all scripts in the deployment for references to local directories (do:"local"),
// Scan all scripts in the environment for references to local directories (do:"local"),
// and return all referenced directory names.
// This is used by clients to grant access to local directories when they are referenced
// by user-specified scripts.
func (d *Deployment) LocalDirs() map[string]string {
func (d *Environment) LocalDirs() map[string]string {
dirs := map[string]string{}
localdirs := func(code ...*compiler.Value) {
Analyze(
@@ -140,7 +140,7 @@ func (d *Deployment) LocalDirs() map[string]string {
code...,
)
}
// 1. Scan the deployment state
// 1. Scan the environment state
// FIXME: use a common `flow` instance to avoid rescanning the tree.
src, err := compiler.InstanceMerge(d.plan, d.input)
if err != nil {
@@ -165,9 +165,9 @@ func (d *Deployment) LocalDirs() map[string]string {
return dirs
}
// Up missing values in deployment configuration, and write them to state.
func (d *Deployment) Up(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "deployment.Up")
// Up missing values in environment configuration, and write them to state.
func (d *Environment) Up(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "environment.Up")
defer span.Finish()
// Reset the computed values
@@ -194,7 +194,7 @@ func (d *Deployment) Up(ctx context.Context, s Solver) error {
type DownOpts struct{}
func (d *Deployment) Down(ctx context.Context, _ *DownOpts) error {
func (d *Environment) Down(ctx context.Context, _ *DownOpts) error {
panic("NOT IMPLEMENTED")
}
@@ -292,7 +292,7 @@ func newPipelineRunner(inst *cue.Instance, computed *compiler.Value, s Solver) c
})
}
func (d *Deployment) ScanInputs() ([]cue.Value, error) {
func (d *Environment) ScanInputs() ([]cue.Value, error) {
vals, err := cuetils.ScanForInputs(d.plan.Cue())
if err != nil {
return nil, err

View File

@@ -7,15 +7,15 @@ import (
)
func TestInputDir(t *testing.T) {
st := &DeploymentState{
st := &EnvironmentState{
PlanSource: DirInput("/tmp/source", []string{}),
}
require.NoError(t, st.SetInput("www.source", DirInput("/", []string{})))
deployment, err := NewDeployment(st)
environment, err := NewEnvironment(st)
require.NoError(t, err)
localdirs := deployment.LocalDirs()
localdirs := environment.LocalDirs()
require.Len(t, localdirs, 2)
require.Contains(t, localdirs, "/")
require.Contains(t, localdirs, "/tmp/source")

View File

@@ -1,16 +1,16 @@
package dagger
// Contents of a deployment serialized to a file
type DeploymentState struct {
// Globally unique deployment ID
// Contents of an environment serialized to a file
type EnvironmentState struct {
// Globally unique environment ID
ID string `json:"id,omitempty"`
// Human-friendly deployment name.
// A deployment may have more than one name.
// Human-friendly environment name.
// A environment may have more than one name.
// FIXME: store multiple names?
Name string `json:"name,omitempty"`
// Cue module containing the deployment plan
// Cue module containing the environment plan
// The input's top-level artifact is used as a module directory.
PlanSource Input `json:"plan,omitempty"`
@@ -26,7 +26,7 @@ type inputKV struct {
Value Input `json:"value,omitempty"`
}
func (s *DeploymentState) SetInput(key string, value Input) error {
func (s *EnvironmentState) SetInput(key string, value Input) error {
for i, inp := range s.Inputs {
if inp.Key != key {
continue
@@ -42,7 +42,7 @@ func (s *DeploymentState) SetInput(key string, value Input) error {
// Remove all inputs at the given key, including sub-keys.
// For example RemoveInputs("foo.bar") will remove all inputs
// at foo.bar, foo.bar.baz, etc.
func (s *DeploymentState) RemoveInputs(key string) error {
func (s *EnvironmentState) RemoveInputs(key string) error {
newInputs := make([]inputKV, 0, len(s.Inputs))
for _, i := range s.Inputs {
if i.Key == key {

View File

@@ -13,8 +13,8 @@ import (
)
var (
ErrDeploymentExist = errors.New("deployment already exists")
ErrDeploymentNotExist = errors.New("deployment doesn't exist")
ErrEnvironmentExist = errors.New("environment already exists")
ErrEnvironmentNotExist = errors.New("environment doesn't exist")
)
const (
@@ -26,26 +26,26 @@ type Store struct {
l sync.RWMutex
// ID -> Deployment
deployments map[string]*DeploymentState
// ID -> Environment
environments map[string]*EnvironmentState
// Name -> Deployment
deploymentsByName map[string]*DeploymentState
// Name -> Environment
environmentsByName map[string]*EnvironmentState
// Path -> (ID->Deployment)
deploymentsByPath map[string]map[string]*DeploymentState
// Path -> (ID->Environment)
environmentsByPath map[string]map[string]*EnvironmentState
// ID -> (Path->{})
pathsByDeploymentID map[string]map[string]struct{}
pathsByEnvironmentID map[string]map[string]struct{}
}
func NewStore(root string) (*Store, error) {
store := &Store{
root: root,
deployments: make(map[string]*DeploymentState),
deploymentsByName: make(map[string]*DeploymentState),
deploymentsByPath: make(map[string]map[string]*DeploymentState),
pathsByDeploymentID: make(map[string]map[string]struct{}),
root: root,
environments: make(map[string]*EnvironmentState),
environmentsByName: make(map[string]*EnvironmentState),
environmentsByPath: make(map[string]map[string]*EnvironmentState),
pathsByEnvironmentID: make(map[string]map[string]struct{}),
}
return store, store.loadAll()
}
@@ -58,8 +58,8 @@ func DefaultStore() (*Store, error) {
return NewStore(os.ExpandEnv(defaultStoreRoot))
}
func (s *Store) deploymentPath(name string) string {
return path.Join(s.root, name, "deployment.json")
func (s *Store) environmentPath(name string) string {
return path.Join(s.root, name, "environment.json")
}
func (s *Store) loadAll() error {
@@ -75,7 +75,7 @@ func (s *Store) loadAll() error {
if !f.IsDir() {
continue
}
if err := s.loadDeployment(f.Name()); err != nil {
if err := s.loadEnvironment(f.Name()); err != nil {
return err
}
}
@@ -83,21 +83,21 @@ func (s *Store) loadAll() error {
return nil
}
func (s *Store) loadDeployment(name string) error {
data, err := os.ReadFile(s.deploymentPath(name))
func (s *Store) loadEnvironment(name string) error {
data, err := os.ReadFile(s.environmentPath(name))
if err != nil {
return err
}
var st DeploymentState
var st EnvironmentState
if err := json.Unmarshal(data, &st); err != nil {
return err
}
s.indexDeployment(&st)
s.indexEnvironment(&st)
return nil
}
func (s *Store) syncDeployment(r *DeploymentState) error {
p := s.deploymentPath(r.Name)
func (s *Store) syncEnvironment(r *EnvironmentState) error {
p := s.environmentPath(r.Name)
if err := os.MkdirAll(path.Dir(p), 0755); err != nil {
return err
@@ -112,28 +112,28 @@ func (s *Store) syncDeployment(r *DeploymentState) error {
return err
}
s.reindexDeployment(r)
s.reindexEnvironment(r)
return nil
}
func (s *Store) indexDeployment(r *DeploymentState) {
s.deployments[r.ID] = r
s.deploymentsByName[r.Name] = r
func (s *Store) indexEnvironment(r *EnvironmentState) {
s.environments[r.ID] = r
s.environmentsByName[r.Name] = r
mapPath := func(i Input) {
if i.Type != InputTypeDir {
return
}
if s.deploymentsByPath[i.Dir.Path] == nil {
s.deploymentsByPath[i.Dir.Path] = make(map[string]*DeploymentState)
if s.environmentsByPath[i.Dir.Path] == nil {
s.environmentsByPath[i.Dir.Path] = make(map[string]*EnvironmentState)
}
s.deploymentsByPath[i.Dir.Path][r.ID] = r
s.environmentsByPath[i.Dir.Path][r.ID] = r
if s.pathsByDeploymentID[r.ID] == nil {
s.pathsByDeploymentID[r.ID] = make(map[string]struct{})
if s.pathsByEnvironmentID[r.ID] == nil {
s.pathsByEnvironmentID[r.ID] = make(map[string]struct{})
}
s.pathsByDeploymentID[r.ID][i.Dir.Path] = struct{}{}
s.pathsByEnvironmentID[r.ID][i.Dir.Path] = struct{}{}
}
mapPath(r.PlanSource)
@@ -142,108 +142,108 @@ func (s *Store) indexDeployment(r *DeploymentState) {
}
}
func (s *Store) deindexDeployment(id string) {
r, ok := s.deployments[id]
func (s *Store) deindexEnvironment(id string) {
r, ok := s.environments[id]
if !ok {
return
}
delete(s.deployments, r.ID)
delete(s.deploymentsByName, r.Name)
delete(s.environments, r.ID)
delete(s.environmentsByName, r.Name)
for p := range s.pathsByDeploymentID[r.ID] {
delete(s.deploymentsByPath[p], r.ID)
for p := range s.pathsByEnvironmentID[r.ID] {
delete(s.environmentsByPath[p], r.ID)
}
delete(s.pathsByDeploymentID, r.ID)
delete(s.pathsByEnvironmentID, r.ID)
}
func (s *Store) reindexDeployment(r *DeploymentState) {
s.deindexDeployment(r.ID)
s.indexDeployment(r)
func (s *Store) reindexEnvironment(r *EnvironmentState) {
s.deindexEnvironment(r.ID)
s.indexEnvironment(r)
}
func (s *Store) CreateDeployment(ctx context.Context, st *DeploymentState) error {
func (s *Store) CreateEnvironment(ctx context.Context, st *EnvironmentState) error {
s.l.Lock()
defer s.l.Unlock()
if _, ok := s.deploymentsByName[st.Name]; ok {
return fmt.Errorf("%s: %w", st.Name, ErrDeploymentExist)
if _, ok := s.environmentsByName[st.Name]; ok {
return fmt.Errorf("%s: %w", st.Name, ErrEnvironmentExist)
}
st.ID = uuid.New().String()
return s.syncDeployment(st)
return s.syncEnvironment(st)
}
type UpdateOpts struct{}
func (s *Store) UpdateDeployment(ctx context.Context, r *DeploymentState, o *UpdateOpts) error {
func (s *Store) UpdateEnvironment(ctx context.Context, r *EnvironmentState, o *UpdateOpts) error {
s.l.Lock()
defer s.l.Unlock()
return s.syncDeployment(r)
return s.syncEnvironment(r)
}
type DeleteOpts struct{}
func (s *Store) DeleteDeployment(ctx context.Context, r *DeploymentState, o *DeleteOpts) error {
func (s *Store) DeleteEnvironment(ctx context.Context, r *EnvironmentState, o *DeleteOpts) error {
s.l.Lock()
defer s.l.Unlock()
if err := os.Remove(s.deploymentPath(r.Name)); err != nil {
if err := os.Remove(s.environmentPath(r.Name)); err != nil {
return err
}
s.deindexDeployment(r.ID)
s.deindexEnvironment(r.ID)
return nil
}
func (s *Store) LookupDeploymentByID(ctx context.Context, id string) (*DeploymentState, error) {
func (s *Store) LookupEnvironmentByID(ctx context.Context, id string) (*EnvironmentState, error) {
s.l.RLock()
defer s.l.RUnlock()
st, ok := s.deployments[id]
st, ok := s.environments[id]
if !ok {
return nil, fmt.Errorf("%s: %w", id, ErrDeploymentNotExist)
return nil, fmt.Errorf("%s: %w", id, ErrEnvironmentNotExist)
}
return st, nil
}
func (s *Store) LookupDeploymentByName(ctx context.Context, name string) (*DeploymentState, error) {
func (s *Store) LookupEnvironmentByName(ctx context.Context, name string) (*EnvironmentState, error) {
s.l.RLock()
defer s.l.RUnlock()
st, ok := s.deploymentsByName[name]
st, ok := s.environmentsByName[name]
if !ok {
return nil, fmt.Errorf("%s: %w", name, ErrDeploymentNotExist)
return nil, fmt.Errorf("%s: %w", name, ErrEnvironmentNotExist)
}
return st, nil
}
func (s *Store) LookupDeploymentByPath(ctx context.Context, path string) ([]*DeploymentState, error) {
func (s *Store) LookupEnvironmentByPath(ctx context.Context, path string) ([]*EnvironmentState, error) {
s.l.RLock()
defer s.l.RUnlock()
res := []*DeploymentState{}
res := []*EnvironmentState{}
deployments, ok := s.deploymentsByPath[path]
environments, ok := s.environmentsByPath[path]
if !ok {
return res, nil
}
for _, d := range deployments {
for _, d := range environments {
res = append(res, d)
}
return res, nil
}
func (s *Store) ListDeployments(ctx context.Context) ([]*DeploymentState, error) {
func (s *Store) ListEnvironments(ctx context.Context) ([]*EnvironmentState, error) {
s.l.RLock()
defer s.l.RUnlock()
deployments := make([]*DeploymentState, 0, len(s.deployments))
environments := make([]*EnvironmentState, 0, len(s.environments))
for _, st := range s.deployments {
deployments = append(deployments, st)
for _, st := range s.environments {
environments = append(environments, st)
}
return deployments, nil
return environments, nil
}

View File

@@ -17,38 +17,38 @@ func TestStoreLoad(t *testing.T) {
store, err := NewStore(root)
require.NoError(t, err)
_, err = store.LookupDeploymentByName(ctx, "notexist")
_, err = store.LookupEnvironmentByName(ctx, "notexist")
require.Error(t, err)
require.True(t, errors.Is(err, ErrDeploymentNotExist))
require.True(t, errors.Is(err, ErrEnvironmentNotExist))
st := &DeploymentState{
st := &EnvironmentState{
Name: "test",
}
require.NoError(t, store.CreateDeployment(ctx, st))
require.NoError(t, store.CreateEnvironment(ctx, st))
checkDeployments := func(store *Store) {
r, err := store.LookupDeploymentByID(ctx, st.ID)
checkEnvironments := func(store *Store) {
r, err := store.LookupEnvironmentByID(ctx, st.ID)
require.NoError(t, err)
require.NotNil(t, r)
require.Equal(t, "test", r.Name)
r, err = store.LookupDeploymentByName(ctx, "test")
r, err = store.LookupEnvironmentByName(ctx, "test")
require.NoError(t, err)
require.NotNil(t, r)
require.Equal(t, "test", r.Name)
deployments, err := store.ListDeployments(ctx)
environments, err := store.ListEnvironments(ctx)
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Equal(t, "test", deployments[0].Name)
require.Len(t, environments, 1)
require.Equal(t, "test", environments[0].Name)
}
checkDeployments(store)
checkEnvironments(store)
// Reload the deployments from disk and check again
// Reload the environments from disk and check again
newStore, err := NewStore(root)
require.NoError(t, err)
checkDeployments(newStore)
checkEnvironments(newStore)
}
func TestStoreLookupByPath(t *testing.T) {
@@ -59,65 +59,65 @@ func TestStoreLookupByPath(t *testing.T) {
store, err := NewStore(root)
require.NoError(t, err)
st := &DeploymentState{
st := &EnvironmentState{
Name: "test",
}
require.NoError(t, st.SetInput("foo", DirInput("/test/path", []string{})))
require.NoError(t, store.CreateDeployment(ctx, st))
require.NoError(t, store.CreateEnvironment(ctx, st))
// Lookup by path
deployments, err := store.LookupDeploymentByPath(ctx, "/test/path")
environments, err := store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Equal(t, st.ID, deployments[0].ID)
require.Len(t, environments, 1)
require.Equal(t, st.ID, environments[0].ID)
// Add a new path
require.NoError(t, st.SetInput("bar", DirInput("/test/anotherpath", []string{})))
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
require.NoError(t, store.UpdateEnvironment(ctx, st, nil))
// Lookup by the previous path
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path")
environments, err = store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Equal(t, st.ID, deployments[0].ID)
require.Len(t, environments, 1)
require.Equal(t, st.ID, environments[0].ID)
// Lookup by the new path
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Equal(t, st.ID, deployments[0].ID)
require.Len(t, environments, 1)
require.Equal(t, st.ID, environments[0].ID)
// Remove a path
require.NoError(t, st.RemoveInputs("foo"))
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
require.NoError(t, store.UpdateEnvironment(ctx, st, nil))
// Lookup by the removed path should fail
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path")
environments, err = store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err)
require.Len(t, deployments, 0)
require.Len(t, environments, 0)
// Lookup by the other path should still work
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Len(t, environments, 1)
// Add another deployment using the same path
otherSt := &DeploymentState{
// Add another environment using the same path
otherSt := &EnvironmentState{
Name: "test2",
}
require.NoError(t, otherSt.SetInput("foo", DirInput("/test/anotherpath", []string{})))
require.NoError(t, store.CreateDeployment(ctx, otherSt))
require.NoError(t, store.CreateEnvironment(ctx, otherSt))
// Lookup by path should return both deployments
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
// Lookup by path should return both environments
environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err)
require.Len(t, deployments, 2)
require.Len(t, environments, 2)
// Remove the first deployment. Lookup by path should still return the
// second deployment.
require.NoError(t, store.DeleteDeployment(ctx, st, nil))
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
// Remove the first environment. Lookup by path should still return the
// second environment.
require.NoError(t, store.DeleteEnvironment(ctx, st, nil))
environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err)
require.Len(t, deployments, 1)
require.Equal(t, otherSt.ID, deployments[0].ID)
require.Len(t, environments, 1)
require.Equal(t, otherSt.ID, environments[0].ID)
}