129 lines
2.4 KiB
Go
129 lines
2.4 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
const (
|
|
MainDir string = ".homeserver"
|
|
|
|
ComposeFile string = "docker-compose.deploy.yml"
|
|
EnvFile string = ".env"
|
|
NginxFile = "nginx.conf"
|
|
|
|
ConfFile = "hmdeploy.json"
|
|
)
|
|
|
|
var ErrProjectConfFile = errors.New("project error")
|
|
|
|
func getFileInfo(baseDir, filePath string) (fs.FileInfo, error) {
|
|
var fInf fs.FileInfo
|
|
|
|
filePath = filepath.Clean(filePath)
|
|
filePath = filepath.Join(baseDir, filePath)
|
|
|
|
fileAbsPath, err := filepath.Abs(filePath)
|
|
if err != nil {
|
|
return fInf, fmt.Errorf("%w, file=%s, err=%v", ErrProjectConfFile, fileAbsPath, err)
|
|
}
|
|
|
|
fInf, err = os.Stat(fileAbsPath)
|
|
if err != nil {
|
|
return fInf, fmt.Errorf(
|
|
"%w, unable to stat file=%s, err=%v",
|
|
ErrProjectConfFile,
|
|
fileAbsPath,
|
|
err,
|
|
)
|
|
}
|
|
|
|
return fInf, nil
|
|
}
|
|
|
|
type Project struct {
|
|
Name string `json:"name"`
|
|
Dir string
|
|
ImageName string `json:"image"`
|
|
Deps struct {
|
|
EnvFile string `json:"env"`
|
|
EnvFileInfo fs.FileInfo
|
|
|
|
ComposeFile string `json:"compose"`
|
|
ComposeFileInfo fs.FileInfo
|
|
|
|
NginxFile string `json:"nginx"`
|
|
NginxFileInfo fs.FileInfo
|
|
} `json:"dependencies"`
|
|
}
|
|
|
|
func (p *Project) validate() error {
|
|
cfs, err := getFileInfo(p.Dir, p.Deps.ComposeFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
p.Deps.ComposeFileInfo = cfs
|
|
|
|
if p.Deps.EnvFile != "" {
|
|
efs, err := getFileInfo(p.Dir, p.Deps.EnvFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
p.Deps.EnvFileInfo = efs
|
|
} else {
|
|
log.Warn().Msg("no .env file provided, hoping one it's set elsewhere...")
|
|
}
|
|
|
|
nfs, err := getFileInfo(p.Dir, p.Deps.NginxFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
p.Deps.NginxFileInfo = nfs
|
|
|
|
return nil
|
|
}
|
|
|
|
func ProjectFromDir(dir string) (Project, error) {
|
|
var p Project
|
|
|
|
dir = filepath.Join(dir, MainDir)
|
|
p.Dir = dir
|
|
|
|
content, err := os.ReadFile(filepath.Join(dir, ConfFile))
|
|
if err != nil {
|
|
return p, fmt.Errorf(
|
|
"%w, unable to read conf file=%s, err=%v",
|
|
ErrProjectConfFile,
|
|
ConfFile,
|
|
err,
|
|
)
|
|
}
|
|
|
|
if err := json.Unmarshal(content, &p); err != nil {
|
|
return p, fmt.Errorf(
|
|
"%w, unable to parse conf file=%s, err=%v",
|
|
ErrProjectConfFile,
|
|
ConfFile,
|
|
err,
|
|
)
|
|
}
|
|
|
|
if err := p.validate(); err != nil {
|
|
return p, fmt.Errorf(
|
|
"%w, unable to validate project, name=%s, dir=%s, err=%v",
|
|
ErrProjectConfFile,
|
|
p.Name,
|
|
p.Dir,
|
|
err,
|
|
)
|
|
}
|
|
|
|
return p, nil
|
|
}
|