store: support multiple deployments per path
- Add support for multiple deployments per path in the Store - Add a bunch of tests - Change the Lookup deployment API - Add disambiguation in the CLI commands Fixes #231 Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
540f373993
commit
33a7770459
@ -38,7 +38,26 @@ func GetCurrentDeploymentState(ctx context.Context, store *dagger.Store) *dagger
|
|||||||
Str("deploymentPath", wd).
|
Str("deploymentPath", wd).
|
||||||
Msg("failed to lookup deployment by path")
|
Msg("failed to lookup deployment by path")
|
||||||
}
|
}
|
||||||
return st
|
if len(st) == 0 {
|
||||||
|
lg.
|
||||||
|
Fatal().
|
||||||
|
Err(err).
|
||||||
|
Str("deploymentPath", wd).
|
||||||
|
Msg("no deployments match the current directory")
|
||||||
|
}
|
||||||
|
if len(st) > 1 {
|
||||||
|
deployments := []string{}
|
||||||
|
for _, s := range st {
|
||||||
|
deployments = append(deployments, s.Name)
|
||||||
|
}
|
||||||
|
lg.
|
||||||
|
Fatal().
|
||||||
|
Err(err).
|
||||||
|
Str("deploymentPath", wd).
|
||||||
|
Strs("deployments", deployments).
|
||||||
|
Msg("multiple deployments match the current directory, select one with `--deployment`")
|
||||||
|
}
|
||||||
|
return st[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-compute a deployment (equivalent to `dagger up`).
|
// Re-compute a deployment (equivalent to `dagger up`).
|
||||||
|
@ -30,8 +30,8 @@ type Store struct {
|
|||||||
|
|
||||||
// Various indices for fast lookups
|
// Various indices for fast lookups
|
||||||
deploymentsByName map[string]*DeploymentState
|
deploymentsByName map[string]*DeploymentState
|
||||||
deploymentsByPath map[string]*DeploymentState
|
deploymentsByPath map[string][]*DeploymentState
|
||||||
pathsByDeployment map[string][]string
|
pathsByDeploymentID map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStore(root string) (*Store, error) {
|
func NewStore(root string) (*Store, error) {
|
||||||
@ -39,8 +39,8 @@ func NewStore(root string) (*Store, error) {
|
|||||||
root: root,
|
root: root,
|
||||||
deployments: make(map[string]*DeploymentState),
|
deployments: make(map[string]*DeploymentState),
|
||||||
deploymentsByName: make(map[string]*DeploymentState),
|
deploymentsByName: make(map[string]*DeploymentState),
|
||||||
deploymentsByPath: make(map[string]*DeploymentState),
|
deploymentsByPath: make(map[string][]*DeploymentState),
|
||||||
pathsByDeployment: make(map[string][]string),
|
pathsByDeploymentID: make(map[string][]string),
|
||||||
}
|
}
|
||||||
return store, store.loadAll()
|
return store, store.loadAll()
|
||||||
}
|
}
|
||||||
@ -120,8 +120,8 @@ func (s *Store) indexDeployment(r *DeploymentState) {
|
|||||||
if i.Type != InputTypeDir {
|
if i.Type != InputTypeDir {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.deploymentsByPath[i.Dir.Path] = r
|
s.deploymentsByPath[i.Dir.Path] = append(s.deploymentsByPath[i.Dir.Path], r)
|
||||||
s.pathsByDeployment[r.ID] = append(s.pathsByDeployment[r.ID], i.Dir.Path)
|
s.pathsByDeploymentID[r.ID] = append(s.pathsByDeploymentID[r.ID], i.Dir.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapPath(r.PlanSource)
|
mapPath(r.PlanSource)
|
||||||
@ -138,10 +138,18 @@ func (s *Store) deindexDeployment(id string) {
|
|||||||
delete(s.deployments, r.ID)
|
delete(s.deployments, r.ID)
|
||||||
delete(s.deploymentsByName, r.Name)
|
delete(s.deploymentsByName, r.Name)
|
||||||
|
|
||||||
for _, p := range s.pathsByDeployment[r.ID] {
|
for _, p := range s.pathsByDeploymentID[r.ID] {
|
||||||
delete(s.deploymentsByPath, p)
|
// Remove this deployments from the path->deployment mapping
|
||||||
|
deployments := []*DeploymentState{}
|
||||||
|
for _, d := range s.deploymentsByPath[p] {
|
||||||
|
if d.ID == r.ID {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
delete(s.pathsByDeployment, r.ID)
|
deployments = append(deployments, d)
|
||||||
|
}
|
||||||
|
s.deploymentsByPath[p] = deployments
|
||||||
|
}
|
||||||
|
delete(s.pathsByDeploymentID, r.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) reindexDeployment(r *DeploymentState) {
|
func (s *Store) reindexDeployment(r *DeploymentState) {
|
||||||
@ -205,13 +213,13 @@ func (s *Store) LookupDeploymentByName(ctx context.Context, name string) (*Deplo
|
|||||||
return st, nil
|
return st, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) LookupDeploymentByPath(ctx context.Context, path string) (*DeploymentState, error) {
|
func (s *Store) LookupDeploymentByPath(ctx context.Context, path string) ([]*DeploymentState, error) {
|
||||||
s.l.RLock()
|
s.l.RLock()
|
||||||
defer s.l.RUnlock()
|
defer s.l.RUnlock()
|
||||||
|
|
||||||
st, ok := s.deploymentsByPath[path]
|
st, ok := s.deploymentsByPath[path]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("%s: %w", path, ErrDeploymentNotExist)
|
return []*DeploymentState{}, nil
|
||||||
}
|
}
|
||||||
return st, nil
|
return st, nil
|
||||||
}
|
}
|
||||||
|
@ -66,34 +66,58 @@ func TestStoreLookupByPath(t *testing.T) {
|
|||||||
require.NoError(t, store.CreateDeployment(ctx, st))
|
require.NoError(t, store.CreateDeployment(ctx, st))
|
||||||
|
|
||||||
// Lookup by path
|
// Lookup by path
|
||||||
r, err := store.LookupDeploymentByPath(ctx, "/test/path")
|
deployments, err := store.LookupDeploymentByPath(ctx, "/test/path")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, r)
|
require.Len(t, deployments, 1)
|
||||||
require.Equal(t, st.ID, r.ID)
|
require.Equal(t, st.ID, deployments[0].ID)
|
||||||
|
|
||||||
// Add a new path
|
// Add a new path
|
||||||
require.NoError(t, st.AddInput("bar", DirInput("/test/anotherpath", []string{})))
|
require.NoError(t, st.AddInput("bar", DirInput("/test/anotherpath", []string{})))
|
||||||
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
|
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
|
||||||
|
|
||||||
// Lookup by the previous path
|
// Lookup by the previous path
|
||||||
r, err = store.LookupDeploymentByPath(ctx, "/test/path")
|
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, st.ID, r.ID)
|
require.Len(t, deployments, 1)
|
||||||
|
require.Equal(t, st.ID, deployments[0].ID)
|
||||||
|
|
||||||
// Lookup by the new path
|
// Lookup by the new path
|
||||||
r, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
|
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, st.ID, r.ID)
|
require.Len(t, deployments, 1)
|
||||||
|
require.Equal(t, st.ID, deployments[0].ID)
|
||||||
|
|
||||||
// Remove a path
|
// Remove a path
|
||||||
require.NoError(t, st.RemoveInputs("foo"))
|
require.NoError(t, st.RemoveInputs("foo"))
|
||||||
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
|
require.NoError(t, store.UpdateDeployment(ctx, st, nil))
|
||||||
|
|
||||||
// Lookup by the removed path should fail
|
// Lookup by the removed path should fail
|
||||||
_, err = store.LookupDeploymentByPath(ctx, "/test/path")
|
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path")
|
||||||
require.Error(t, err)
|
require.NoError(t, err)
|
||||||
|
require.Len(t, deployments, 0)
|
||||||
|
|
||||||
// Lookup by the other path should still work
|
// Lookup by the other path should still work
|
||||||
_, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
|
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
require.Len(t, deployments, 1)
|
||||||
|
|
||||||
|
// Add another deployment using the same path
|
||||||
|
otherSt := &DeploymentState{
|
||||||
|
Name: "test2",
|
||||||
|
}
|
||||||
|
require.NoError(t, otherSt.AddInput("foo", DirInput("/test/anotherpath", []string{})))
|
||||||
|
require.NoError(t, store.CreateDeployment(ctx, otherSt))
|
||||||
|
|
||||||
|
// Lookup by path should return both deployments
|
||||||
|
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, deployments, 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")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, deployments, 1)
|
||||||
|
require.Equal(t, otherSt.ID, deployments[0].ID)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user