fix(core): keep workspace runtime available
This commit is contained in:
@@ -140,7 +140,8 @@ func Render(installation config.Installation) (map[string][]byte, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Generate publishes all adapters as one directory generation. A failed replacement restores the
|
||||
// Generate publishes all adapters as one directory generation. An unchanged generation stays in
|
||||
// place so active file bind mounts keep their source identity. A failed replacement restores the
|
||||
// previous directory, so callers never observe a successfully returned mixed generation.
|
||||
func Generate(installation config.Installation) error {
|
||||
artifacts, err := Render(installation)
|
||||
@@ -152,6 +153,17 @@ func Generate(installation config.Installation) error {
|
||||
if err := os.MkdirAll(parent, 0o755); err != nil {
|
||||
return fmt.Errorf("create model projection parent: %w", err)
|
||||
}
|
||||
info, statErr := os.Lstat(target)
|
||||
if statErr == nil {
|
||||
if !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
|
||||
return fmt.Errorf("current model projection path is not a regular directory")
|
||||
}
|
||||
if projectionMatches(target, artifacts) {
|
||||
return nil
|
||||
}
|
||||
} else if !os.IsNotExist(statErr) {
|
||||
return fmt.Errorf("inspect current model projection generation: %w", statErr)
|
||||
}
|
||||
candidate, err := os.MkdirTemp(parent, ".model-projections-candidate-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("create model projection candidate: %w", err)
|
||||
@@ -161,19 +173,12 @@ func Generate(installation config.Installation) error {
|
||||
return err
|
||||
}
|
||||
|
||||
info, statErr := os.Lstat(target)
|
||||
if os.IsNotExist(statErr) {
|
||||
if err := renameProjectionDirectory(candidate, target); err != nil {
|
||||
return fmt.Errorf("publish model projection generation: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if statErr != nil {
|
||||
return fmt.Errorf("inspect current model projection generation: %w", statErr)
|
||||
}
|
||||
if !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
|
||||
return fmt.Errorf("current model projection path is not a regular directory")
|
||||
}
|
||||
previous, err := absentTemporaryPath(parent)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reserve previous model projection generation: %w", err)
|
||||
@@ -191,6 +196,21 @@ func Generate(installation config.Installation) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func projectionMatches(directory string, artifacts map[string][]byte) bool {
|
||||
for _, relative := range sortedArtifactPaths(artifacts) {
|
||||
path := filepath.Join(directory, filepath.FromSlash(relative))
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil || !info.Mode().IsRegular() {
|
||||
return false
|
||||
}
|
||||
actual, err := os.ReadFile(path)
|
||||
if err != nil || !bytes.Equal(actual, artifacts[relative]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func writeProjectionCandidate(directory string, artifacts map[string][]byte) error {
|
||||
if err := os.Chmod(directory, 0o755); err != nil {
|
||||
return fmt.Errorf("protect model projection candidate: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user