Config: Initialize storage folder with serial

To detect non-permanent storage and configuration issues.

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-12-05 06:21:16 +01:00
parent 7d41857bbd
commit 5acc02e248
7 changed files with 55 additions and 18 deletions

View file

@ -2,6 +2,9 @@ package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
@ -33,6 +36,7 @@ type Config struct {
settings *Settings
hub *hub.Config
token string
serial string
}
func init() {
@ -95,6 +99,10 @@ func (c *Config) Init() error {
return err
}
if err := c.initStorage(); err != nil {
return err
}
c.initSettings()
c.initHub()
@ -103,6 +111,28 @@ func (c *Config) Init() error {
return c.connectDb()
}
// initStorage initializes storage directories with a random serial.
func (c *Config) initStorage() error {
const serialName = "serial"
c.serial = rnd.PPID('z')
storageName := filepath.Join(c.StoragePath(), serialName)
backupName := filepath.Join(c.BackupPath(), serialName)
if data, err := ioutil.ReadFile(storageName); err == nil {
c.serial = string(data)
} else if data, err := ioutil.ReadFile(backupName); err == nil {
c.serial = string(data)
} else if err := ioutil.WriteFile(storageName, []byte(c.serial), os.ModePerm); err != nil {
return fmt.Errorf("failed creating %s: %s", storageName, err)
} else if err := ioutil.WriteFile(backupName, []byte(c.serial), os.ModePerm); err != nil {
return fmt.Errorf("failed creating %s: %s", backupName, err)
}
return nil
}
// Name returns the application name ("PhotoPrism").
func (c *Config) Name() string {
return c.params.Name
@ -294,7 +324,7 @@ func (c *Config) UpdateHub() {
// initHub initializes PhotoPrism hub config.
func (c *Config) initHub() {
c.hub = hub.NewConfig(c.Version(), c.HubConfigFile())
c.hub = hub.NewConfig(c.Version(), c.HubConfigFile(), c.serial)
if err := c.hub.Load(); err == nil {
// Do nothing.

View file

@ -30,17 +30,19 @@ type Config struct {
Session string `json:"session" yaml:"session"`
Status string `json:"status" yaml:"status"`
Version string `json:"version" yaml:"version"`
Serial string `json:"serial" yaml:"serial"`
FileName string `json:"-" yaml:"-"`
}
// NewConfig creates a new backend api credentials instance.
func NewConfig(version string, fileName string) *Config {
func NewConfig(version, fileName, serial string) *Config {
return &Config{
Key: "",
Secret: "",
Session: "",
Status: "",
Version: version,
Serial: serial,
FileName: fileName,
}
}
@ -140,7 +142,7 @@ func (c *Config) Refresh() (err error) {
log.Debugf("requesting api key for maps & places from %s", ApiHost())
}
if j, err := json.Marshal(NewRequest(c.Version)); err != nil {
if j, err := json.Marshal(NewRequest(c.Version, c.Serial)); err != nil {
return err
} else if req, err = http.NewRequest(method, url, bytes.NewReader(j)); err != nil {
return err

View file

@ -8,7 +8,7 @@ import (
func TestConfig_MapKey(t *testing.T) {
t.Run("success", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/new.yml")
c := NewConfig("0.0.0", "testdata/new.yml", "zqkunt22r0bewti9")
assert.Equal(t, "", c.MapKey())
})
}

View file

@ -23,15 +23,17 @@ type Feedback struct {
UserAgent string `json:"UserAgent"`
ApiKey string `json:"ApiKey"`
ClientVersion string `json:"ClientVersion"`
ClientSerial string `json:"ClientSerial"`
ClientOS string `json:"ClientOS"`
ClientArch string `json:"ClientArch"`
ClientCPU int `json:"ClientCPU"`
}
// NewFeedback creates a new hub feedback instance.
func NewFeedback(version string) *Feedback {
func NewFeedback(version, serial string) *Feedback {
return &Feedback{
ClientVersion: version,
ClientSerial: serial,
ClientOS: runtime.GOOS,
ClientArch: runtime.GOARCH,
ClientCPU: runtime.NumCPU(),
@ -39,7 +41,7 @@ func NewFeedback(version string) *Feedback {
}
func (c *Config) SendFeedback(f form.Feedback) (err error) {
feedback := NewFeedback(c.Version)
feedback := NewFeedback(c.Version, c.Serial)
feedback.Category = f.Category
feedback.Subject = txt.TrimLen(f.Message, 50)
feedback.Message = f.Message

View file

@ -9,14 +9,15 @@ import (
func TestNewFeedback(t *testing.T) {
t.Run("success", func(t *testing.T) {
feedback := NewFeedback("xxx")
feedback := NewFeedback("xxx", "zqkunt22r0bewti9")
assert.Equal(t, "xxx", feedback.ClientVersion)
assert.Equal(t, "zqkunt22r0bewti9", feedback.ClientSerial)
})
}
func TestSendFeedback(t *testing.T) {
t.Run("success", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/new.yml")
c := NewConfig("0.0.0", "testdata/new.yml", "zqkunt22r0bewti9")
feedback := Feedback{
Category: "Bug Report",

View file

@ -49,13 +49,13 @@ func Token(size uint) string {
}
func TestNewConfig(t *testing.T) {
c := NewConfig("0.0.0", "testdata/new.yml")
c := NewConfig("0.0.0", "testdata/new.yml", "zqkunt22r0bewti9")
assert.IsType(t, &Config{}, c)
}
func TestNewRequest(t *testing.T) {
r := NewRequest("0.0.0")
r := NewRequest("0.0.0", "zqkunt22r0bewti9")
assert.IsType(t, &Request{}, r)
@ -72,7 +72,7 @@ func TestConfig_Refresh(t *testing.T) {
t.Run("success", func(t *testing.T) {
fileName := fmt.Sprintf("testdata/hub.%s.yml", Token(8))
c := NewConfig("0.0.0", fileName)
c := NewConfig("0.0.0", fileName, "zqkunt22r0bewti9")
if err := c.Refresh(); err != nil {
t.Fatal(err)
@ -122,7 +122,7 @@ func TestConfig_Refresh(t *testing.T) {
func TestConfig_DecodeSession(t *testing.T) {
t.Run("hub3.yml", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/hub3.yml")
c := NewConfig("0.0.0", "testdata/hub3.yml", "zqkunt22r0bewti9")
err := c.Load()
@ -138,7 +138,7 @@ func TestConfig_DecodeSession(t *testing.T) {
func TestConfig_Load(t *testing.T) {
t.Run("hub1.yml", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/hub1.yml")
c := NewConfig("0.0.0", "testdata/hub1.yml", "zqkunt22r0bewti9")
if err := c.Load(); err != nil {
t.Logf(err.Error())
@ -151,7 +151,7 @@ func TestConfig_Load(t *testing.T) {
assert.Equal(t, "0.0.0", c.Version)
})
t.Run("hub2.yml", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/hub2.yml")
c := NewConfig("0.0.0", "testdata/hub2.yml", "zqkunt22r0bewti9")
if err := c.Load(); err != nil {
t.Logf(err.Error())
@ -164,7 +164,7 @@ func TestConfig_Load(t *testing.T) {
assert.Equal(t, "200925-f8e2b580-Darwin-i386-DEBUG", c.Version)
})
t.Run("not existing filename", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/hub_xxx.yml")
c := NewConfig("0.0.0", "testdata/hub_xxx.yml", "zqkunt22r0bewti9")
if err := c.Load(); err == nil {
t.Fatal("file should not exist")
@ -180,7 +180,7 @@ func TestConfig_Save(t *testing.T) {
t.Run("existing filename", func(t *testing.T) {
assert.FileExists(t, "testdata/hub1.yml")
c := NewConfig("0.0.0", "testdata/hub1.yml")
c := NewConfig("0.0.0", "testdata/hub1.yml", "zqkunt22r0bewti9")
if err := c.Load(); err != nil {
t.Logf(err.Error())
@ -219,7 +219,7 @@ func TestConfig_Save(t *testing.T) {
assert.Equal(t, "0.0.0", c.Version)
})
t.Run("not existing filename", func(t *testing.T) {
c := NewConfig("0.0.0", "testdata/hub_new.yml")
c := NewConfig("0.0.0", "testdata/hub_new.yml", "zqkunt22r0bewti9")
c.Key = "F60F5B25D59C397989E3CD374F81CDD7710A4FCA"
c.Secret = "foo"
c.Session = "bar"

View file

@ -10,15 +10,17 @@ var ServiceURL = "https://hub.photoprism.app/v1/hello"
// Backend api credentials request incl basic runtime specs.
type Request struct {
ClientVersion string `json:"ClientVersion"`
ClientSerial string `json:"ClientSerial"`
ClientOS string `json:"ClientOS"`
ClientArch string `json:"ClientArch"`
ClientCPU int `json:"ClientCPU"`
}
// NewRequest creates a new hub key request instance.
func NewRequest(version string) *Request {
func NewRequest(version, serial string) *Request {
return &Request{
ClientVersion: version,
ClientSerial: serial,
ClientOS: runtime.GOOS,
ClientArch: runtime.GOARCH,
ClientCPU: runtime.NumCPU(),