diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b1f8f7..34cfef9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,14 @@ jobs: goreleaser: runs-on: ubuntu-latest steps: + - + name: Install dependencies for cross-compiling + run: | + sudo apt update + sudo apt-get --no-install-recommends --yes install \ + libc6-dev-amd64-cross \ + gcc-10-aarch64-linux-gnu libc6-dev-arm64-cross \ + gcc-10-arm-linux-gnueabihf libc6-dev-armhf-cross - name: Checkout uses: actions/checkout@v2 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 8a57e2b..67768d0 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -6,19 +6,84 @@ before: # You may remove this if you don't use go modules. - go mod tidy builds: - - binary: build/usr/bin/casaos-user-service + - id: casaos-user-service-amd64 + binary: build/usr/bin/casaos-user-service env: - - CGO_ENABLED=0 + - CGO_ENABLED=1 + - CC=x86_64-linux-gnu-gcc-10 goos: - linux goarch: - amd64 + - id: casaos-user-service-arm64 + binary: build/usr/bin/casaos-user-service + env: + - CGO_ENABLED=1 + - CC=aarch64-linux-gnu-gcc-10 + goos: + - linux + goarch: - arm64 + - id: casaos-user-service-arm-7 + binary: build/usr/bin/casaos-user-service + env: + - CGO_ENABLED=1 + - CC=arm-linux-gnueabihf-gcc-10 + goos: + - linux + goarch: + - arm + goarm: + - 7 + - id: casaos-user-service-migration-tool-amd64 + binary: build/usr/bin/casaos-user-service-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=x86_64-linux-gnu-gcc-10 + goos: + - linux + goarch: + - amd64 + - id: casaos-user-service-migration-tool-arm64 + binary: build/usr/bin/casaos-user-service-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=aarch64-linux-gnu-gcc-10 + goos: + - linux + goarch: + - arm64 + - id: casaos-user-service-migration-tool-arm-7 + binary: build/usr/bin/casaos-user-service-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=arm-linux-gnueabihf-gcc-10 + goos: + - linux + goarch: - arm goarm: - 7 archives: - - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}" + - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}" + id: casaos-user-service + builds: + - casaos-user-service-amd64 + - casaos-user-service-arm64 + - casaos-user-service-arm-7 + replacements: + arm: arm-7 + files: + - build/**/* + - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}" + id: casaos-user-service-migration-tool + builds: + - casaos-user-service-migration-tool-amd64 + - casaos-user-service-migration-tool-arm64 + - casaos-user-service-migration-tool-arm-7 replacements: arm: arm-7 files: diff --git a/build/etc/casaos/user-service.conf b/build/etc/casaos/user-service.conf.sample similarity index 100% rename from build/etc/casaos/user-service.conf rename to build/etc/casaos/user-service.conf.sample diff --git a/build/usr/share/casaos/migration/script.d/01-migrate-user-service.sh b/build/usr/share/casaos/migration/script.d/01-migrate-user-service.sh new file mode 100644 index 0000000..0f61faa --- /dev/null +++ b/build/usr/share/casaos/migration/script.d/01-migrate-user-service.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +__get_existing_version() { + local version + + echo "$version" +} \ No newline at end of file diff --git a/build/usr/share/casaos/migration/service.d/user-service/from-0.2.sh b/build/usr/share/casaos/migration/service.d/user-service/from-0.2.sh new file mode 100644 index 0000000..e69de29 diff --git a/build/usr/share/casaos/migration/service.d/user-service/from-0.3.4.sh b/build/usr/share/casaos/migration/service.d/user-service/from-0.3.4.sh new file mode 120000 index 0000000..2c3a78b --- /dev/null +++ b/build/usr/share/casaos/migration/service.d/user-service/from-0.3.4.sh @@ -0,0 +1 @@ +from-0.3.sh \ No newline at end of file diff --git a/build/usr/share/casaos/migration/service.d/user-service/from-0.3.sh b/build/usr/share/casaos/migration/service.d/user-service/from-0.3.sh new file mode 100644 index 0000000..e69de29 diff --git a/build/usr/share/casaos/setup/script.d/01-setup-user-service.sh b/build/usr/share/casaos/setup/script.d/01-setup-user-service.sh new file mode 100644 index 0000000..94ef7de --- /dev/null +++ b/build/usr/share/casaos/setup/script.d/01-setup-user-service.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +set -e + diff --git a/build/usr/share/casaos/setup/service.d/user-service/debian/bullseye/setup-user-service.sh b/build/usr/share/casaos/setup/service.d/user-service/debian/bullseye/setup-user-service.sh new file mode 120000 index 0000000..d1f69f2 --- /dev/null +++ b/build/usr/share/casaos/setup/service.d/user-service/debian/bullseye/setup-user-service.sh @@ -0,0 +1 @@ +../setup-user-service.sh \ No newline at end of file diff --git a/build/usr/share/casaos/setup/service.d/user-service/debian/setup-user-service.sh b/build/usr/share/casaos/setup/service.d/user-service/debian/setup-user-service.sh new file mode 100644 index 0000000..e69de29 diff --git a/build/usr/share/casaos/setup/service.d/user-service/ubuntu/jammy/setup-user-service.sh b/build/usr/share/casaos/setup/service.d/user-service/ubuntu/jammy/setup-user-service.sh new file mode 120000 index 0000000..d1f69f2 --- /dev/null +++ b/build/usr/share/casaos/setup/service.d/user-service/ubuntu/jammy/setup-user-service.sh @@ -0,0 +1 @@ +../setup-user-service.sh \ No newline at end of file diff --git a/build/usr/share/casaos/setup/service.d/user-service/ubuntu/setup-user-service.sh b/build/usr/share/casaos/setup/service.d/user-service/ubuntu/setup-user-service.sh new file mode 120000 index 0000000..79d764b --- /dev/null +++ b/build/usr/share/casaos/setup/service.d/user-service/ubuntu/setup-user-service.sh @@ -0,0 +1 @@ +../debian/setup-user-service.sh \ No newline at end of file diff --git a/cmd/migration-tool/log.go b/cmd/migration-tool/log.go new file mode 100644 index 0000000..ed69983 --- /dev/null +++ b/cmd/migration-tool/log.go @@ -0,0 +1,37 @@ +package main + +import ( + "log" + "os" +) + +type Logger struct { + DebugMode bool + + _debug *log.Logger + _info *log.Logger + _error *log.Logger +} + +func NewLogger() *Logger { + return &Logger{ + DebugMode: false, + _debug: log.New(os.Stdout, "DEBUG: ", 0), + _info: log.New(os.Stdout, "", 0), + _error: log.New(os.Stderr, "ERROR: ", 0), + } +} + +func (l *Logger) Debug(format string, v ...interface{}) { + if l.DebugMode { + l._debug.Printf(format, v...) + } +} + +func (l *Logger) Info(format string, v ...interface{}) { + l._info.Printf(format, v...) +} + +func (l *Logger) Error(format string, v ...interface{}) { + l._error.Printf(format, v...) +} diff --git a/cmd/migration-tool/main.go b/cmd/migration-tool/main.go new file mode 100644 index 0000000..62bcb30 --- /dev/null +++ b/cmd/migration-tool/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "flag" + "fmt" + "os" + + interfaces "github.com/IceWhaleTech/CasaOS-Common" + "github.com/IceWhaleTech/CasaOS-Common/utils/systemctl" + "github.com/IceWhaleTech/CasaOS-UserService/common" +) + +const ( + userServiceConfigSampleFilePath = "/etc/casaos/user-service.conf.sample" + userServiceName = "casaos-user-service.service" +) + +var _logger *Logger + +func main() { + versionFlag := flag.Bool("v", false, "version") + debugFlag := flag.Bool("d", true, "debug") + forceFlag := flag.Bool("f", false, "force") + flag.Parse() + + if *versionFlag { + fmt.Println(common.Version) + os.Exit(0) + } + + _logger = NewLogger() + + if os.Getuid() != 0 { + _logger.Info("Root privileges are required to run this program.") + os.Exit(1) + } + + if *debugFlag { + _logger.DebugMode = true + } + + if !*forceFlag { + serviceEnabled, err := systemctl.IsServiceEnabled(userServiceName) + if err != nil { + _logger.Error("Failed to check if %s is enabled", userServiceName) + panic(err) + } + + if serviceEnabled { + _logger.Info("%s is already enabled. If migration is still needed, try with -f.", userServiceName) + os.Exit(1) + } + } + + migrationTools := []interfaces.MigrationTool{ + NewMigrationToolFor033_034_035(), + } + + var selectedMigrationTool interfaces.MigrationTool + + // look for the right migration tool matching current version + for _, tool := range migrationTools { + migrationNeeded, err := tool.IsMigrationNeeded() + if err != nil { + panic(err) + } + + if migrationNeeded { + selectedMigrationTool = tool + break + } + } + + if selectedMigrationTool == nil { + _logger.Info("No migration to proceed.") + return + } + + if err := selectedMigrationTool.PreMigrate(); err != nil { + panic(err) + } + + if err := selectedMigrationTool.Migrate(); err != nil { + panic(err) + } + + if err := selectedMigrationTool.PostMigrate(); err != nil { + panic(err) + } +} diff --git a/cmd/migration-tool/migration-033-034-035.go b/cmd/migration-tool/migration-033-034-035.go new file mode 100644 index 0000000..bcec2a5 --- /dev/null +++ b/cmd/migration-tool/migration-033-034-035.go @@ -0,0 +1,97 @@ +package main + +import ( + interfaces "github.com/IceWhaleTech/CasaOS-Common" + "github.com/IceWhaleTech/CasaOS-Common/utils/version" + "github.com/IceWhaleTech/CasaOS-UserService/pkg/config" + "github.com/IceWhaleTech/CasaOS-UserService/pkg/utils/file" + "gopkg.in/ini.v1" +) + +type migrationTool struct{} + +func (u *migrationTool) IsMigrationNeeded() (bool, error) { + _logger.Info("Checking if migration is needed for CasaoS version between 0.3.3 and 0.3.5...") + + minorVersion, err := version.DetectMinorVersion() + if err != nil { + return false, err + } + + if minorVersion != 3 { + return false, nil + } + + // this is the best way to tell if CasaOS version is between 0.3.3 and 0.3.5 + isUserDataInDatabase, err := version.IsUserDataInDatabase() + if err != nil { + return false, err + } + + if !isUserDataInDatabase { + return false, nil + } + + return true, nil +} + +func (u *migrationTool) PreMigrate() error { + _logger.Info("Copying %s to %s if it doesn't exist...", userServiceConfigSampleFilePath, config.UserServiceConfigFilePath) + if err := file.CopySingleFile(userServiceConfigSampleFilePath, config.UserServiceConfigFilePath, "skip"); err != nil { + return err + } + return nil +} + +func (u *migrationTool) Migrate() error { + _logger.Info("Loading legacy %s...", version.LegacyCasaOSConfigFilePath) + legacyConfigFile, err := ini.Load(version.LegacyCasaOSConfigFilePath) + if err != nil { + return err + } + + // LogPath + logPath, err := legacyConfigFile.Section("app").GetKey("LogPath") + if err != nil { + return err + } + + // LogFileExt + logFileExt, err := legacyConfigFile.Section("app").GetKey("LogFileExt") + if err != nil { + return err + } + + // DBPath + dbPath, err := legacyConfigFile.Section("app").GetKey("DBPath") + if err != nil { + return err + } + + // UserDataPath + userDataPath, err := legacyConfigFile.Section("app").GetKey("UserDataPath") + if err != nil { + return err + } + + _logger.Info("Updating %s with settings from legacy configuration...", config.UserServiceConfigFilePath) + config.InitSetup(config.UserServiceConfigFilePath) + + config.AppInfo.LogPath = logPath.Value() + config.AppInfo.LogSaveName = logSaveName.Value() + config.AppInfo.LogFileExt = logFileExt.Value() + config.AppInfo.DBPath = dbPath.Value() + config.AppInfo.UserDataPath = userDataPath.Value() + + config.SaveSetup(config.UserServiceConfigFilePath) + + return nil +} + +func (u *migrationTool) PostMigrate() error { + return nil +} + +func NewMigrationToolFor033_034_035() interfaces.MigrationTool { + return &migrationTool{} +} diff --git a/common/version.go b/common/version.go new file mode 100644 index 0000000..f3f9408 --- /dev/null +++ b/common/version.go @@ -0,0 +1,3 @@ +package common + +const Version = "0.3.5" diff --git a/go.mod b/go.mod index d60fed9..291de40 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,27 @@ module github.com/IceWhaleTech/CasaOS-UserService go 1.18 require ( - github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220804224534-081d69c201cc + github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220811230555-229797f76426 github.com/IceWhaleTech/CasaOS-Gateway v0.0.0-20220804231126-285796241a3b github.com/gin-contrib/gzip v0.0.6 github.com/gin-gonic/gin v1.8.1 github.com/satori/go.uuid v1.2.0 github.com/tidwall/gjson v1.14.1 go.uber.org/zap v1.21.0 - gopkg.in/ini.v1 v1.66.6 + gopkg.in/ini.v1 v1.67.0 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 ) require ( github.com/benbjohnson/clock v1.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.0 // indirect github.com/goccy/go-json v0.9.10 // indirect + github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect diff --git a/go.sum b/go.sum index 3cb538d..3701484 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,13 @@ github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= -github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220804224534-081d69c201cc h1:PVQLOa4Ao9vmVDi8bontpDQct81oE4NQJ72XEuo/7PU= -github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220804224534-081d69c201cc/go.mod h1:2WIgP2lnFQ/1TfCnXW00JJIKm3coLyV3WqAaTCAYY28= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220811230555-229797f76426 h1:+Yc9qJ6AehudNsIRkoyTe8dmHiHDWsPF/QL7qk8Va6o= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220811230555-229797f76426/go.mod h1:XGqdbedN9UlF3/rylcXKJ2BW4ayugBmEMa4Z0tk2KbQ= github.com/IceWhaleTech/CasaOS-Gateway v0.0.0-20220804231126-285796241a3b h1:IiMCqvGelQLGTX151gqVwrzoPQVJy8Q2JAvkhjiQ6tY= github.com/IceWhaleTech/CasaOS-Gateway v0.0.0-20220804231126-285796241a3b/go.mod h1:jcURlZtPPQJJvfIW4ZgDTtpFfak7bPTvKZUxWxf62M8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -28,6 +30,8 @@ github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc= github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -154,8 +158,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/config/config.go b/pkg/config/config.go index ed32f4b..70fbbe2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,15 +1,5 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-09-30 18:18:14 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-21 11:09:30 - * @FilePath: /CasaOS/pkg/config/config.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ package config const ( - USERCONFIGURL = "/etc/casaos/casaos.conf" + UserServiceConfigFilePath = "/etc/casaos/user-service.conf" ) diff --git a/pkg/config/init.go b/pkg/config/init.go index 4045b32..38d9f56 100644 --- a/pkg/config/init.go +++ b/pkg/config/init.go @@ -26,15 +26,14 @@ var AppInfo = &model.APPModel{ var Cfg *ini.File func InitSetup(config string) { - - var configDir = USERCONFIGURL + configFilePath := UserServiceConfigFilePath if len(config) > 0 { - configDir = config + configFilePath = config } var err error - Cfg, err = ini.Load(configDir) + Cfg, err = ini.Load(configFilePath) if err != nil { fmt.Printf("Fail to read file: %v", err) os.Exit(1) @@ -44,9 +43,31 @@ func InitSetup(config string) { mapTo("app", AppInfo) } +func SaveSetup(config string) { + reflectFrom("common", CommonInfo) + reflectFrom("app", AppInfo) + + configFilePath := UserServiceConfigFilePath + if len(config) > 0 { + configFilePath = config + } + + if err := Cfg.SaveTo(configFilePath); err != nil { + fmt.Printf("Fail to save file: %v", err) + os.Exit(1) + } +} + func mapTo(section string, v interface{}) { err := Cfg.Section(section).MapTo(v) if err != nil { log.Fatalf("Cfg.MapTo %s err: %v", section, err) } } + +func reflectFrom(section string, v interface{}) { + err := Cfg.Section(section).ReflectFrom(v) + if err != nil { + log.Fatalf("Cfg.ReflectFrom %s err: %v", section, err) + } +}