Wire LIC-/LICOFF- activate/verify/heartbeat to licence.rlwj.cn/api, keep legacy HMAC accepted with deprecation banner, add instance_id fingerprint and licensing docs (product lokistack still needs admin create).
46 lines
1.0 KiB
Go
46 lines
1.0 KiB
Go
package services
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
|
|
"lokistack/config"
|
|
)
|
|
|
|
// instance_id 是部署实例指纹:持久化到 DATA_DIR/instance.id,不含邮箱/姓名等 PII。
|
|
// 对齐 OpsxShell device_id 语义,供 opsx-licence 按实例占座。
|
|
|
|
var (
|
|
instanceIDOnce sync.Once
|
|
instanceIDVal string
|
|
)
|
|
|
|
// GetOrCreateInstanceID 返回稳定实例 ID(机器/安装指纹)。
|
|
func GetOrCreateInstanceID() string {
|
|
instanceIDOnce.Do(func() {
|
|
cfg := config.GetConfig()
|
|
path := filepath.Join(cfg.DataDir, "instance.id")
|
|
if raw, err := os.ReadFile(path); err == nil {
|
|
id := strings.TrimSpace(string(raw))
|
|
if id != "" {
|
|
instanceIDVal = id
|
|
return
|
|
}
|
|
}
|
|
buf := make([]byte, 16)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
instanceIDVal = "lokistack-fallback-instance"
|
|
return
|
|
}
|
|
id := "ls-" + hex.EncodeToString(buf)
|
|
_ = os.MkdirAll(cfg.DataDir, 0o700)
|
|
_ = os.WriteFile(path, []byte(id+"\n"), 0o600)
|
|
instanceIDVal = id
|
|
})
|
|
return instanceIDVal
|
|
}
|