Compare commits

..

11 Commits

Author SHA1 Message Date
Tiger Wang
ec7f6573ad wip 2022-09-28 17:56:28 -04:00
Tiger Wang
50d68f3f76 update goreleaser configuration 2022-09-28 12:21:44 -04:00
Tiger Wang
d9c6a5c875 remove /DATA directory initialization - moved to local-storage (#578) 2022-09-28 11:14:19 -04:00
LinkLeong
4bace9b16a remove temp path 2022-09-28 16:13:42 +01:00
LinkLeong
84dfa7f5bf add share function to common 2022-09-19 10:09:04 +01:00
LinkLeong
582f85c3ba update http status 2022-09-16 04:47:42 +01:00
LinkLeong
7f4562629a remove disk and test common package 2022-09-15 08:13:07 +01:00
LinkLeong
4776b76b16 add system notiry 2022-09-13 07:22:24 +01:00
a624669980@163.com
9f938f65b1 Merge branch 'main' into v0.3.7 2022-09-09 12:02:19 +08:00
LinkLeong
4ccae3f67f add shell script 2022-09-09 04:12:34 +01:00
LinkLeong
9f2e8dae6f add send notify function 2022-09-08 10:55:20 +01:00
20 changed files with 556 additions and 496 deletions

View File

@@ -1,167 +0,0 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
project_name: casaos
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
builds:
- id: casaos-amd64
binary: build/sysroot/usr/bin/casaos
env:
- CGO_ENABLED=1
- CC=x86_64-linux-gnu-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- amd64
hooks:
post:
- find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest
- id: casaos-arm64
binary: build/sysroot/usr/bin/casaos
env:
- CGO_ENABLED=1
- CC=aarch64-linux-gnu-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- arm64
hooks:
post:
- find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest
- id: casaos-arm-7
binary: build/sysroot/usr/bin/casaos
env:
- CGO_ENABLED=1
- CC=arm-linux-gnueabihf-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- arm
goarm:
- "7"
hooks:
post:
- find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest
- id: casaos-migration-tool-amd64
binary: build/sysroot/usr/bin/casaos-migration-tool
main: ./cmd/migration-tool
env:
- CGO_ENABLED=1
- CC=x86_64-linux-gnu-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- amd64
- id: casaos-migration-tool-arm64
binary: build/sysroot/usr/bin/casaos-migration-tool
main: ./cmd/migration-tool
env:
- CGO_ENABLED=1
- CC=aarch64-linux-gnu-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- arm64
- id: casaos-migration-tool-arm-7
binary: build/sysroot/usr/bin/casaos-migration-tool
main: ./cmd/migration-tool
env:
- CGO_ENABLED=1
- CC=arm-linux-gnueabihf-gcc
gcflags:
- all=-N -l
ldflags:
- -extldflags "-static"
tags:
- musl
- netgo
goos:
- linux
goarch:
- arm
goarm:
- "7"
archives:
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}"
id: casaos
builds:
- casaos-amd64
- casaos-arm64
- casaos-arm-7
replacements:
arm: arm-7
files:
- build/**/*
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}"
id: casaos-migration-tool
builds:
- casaos-migration-tool-amd64
- casaos-migration-tool-arm64
- casaos-migration-tool-arm-7
replacements:
arm: arm-7
files:
- build/sysroot/etc/**/*
checksum:
name_template: "checksums.txt"
snapshot:
name_template: "{{ incpatch .Version }}"
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
# release:
# github:
# owner: IceWhaleTech
# name: CasaOS
# draft: true
# prerelease: auto
# mode: replace
# name_template: "v{{ .Version }}"
release:
github:
owner: IceWhaleTech
name: CasaOS
draft: true
prerelease: auto
mode: replace
name_template: "v{{ .Version }}"

View File

@@ -60,6 +60,8 @@ BUILD_PATH=$(dirname "${BASH_SOURCE[0]}")/../../..
SOURCE_ROOT=${BUILD_PATH}/sysroot
APP_NAME="casaos"
APP_NAME_FORMAL="CasaOS"
#APP_NAME_FORMAL="casaos-alpha"
# check if migration is needed
SOURCE_BIN_PATH=${SOURCE_ROOT}/usr/bin
@@ -83,6 +85,45 @@ if [ "${NEED_MIGRATION}" = "false" ]; then
exit 0
fi
MIGRATION_SERVICE_DIR=${1}
if [ -z "${MIGRATION_SERVICE_DIR}" ]; then
MIGRATION_SERVICE_DIR=${BUILD_PATH}/scripts/migration/service.d/${APP_NAME}
fi
MIGRATION_LIST_FILE=${MIGRATION_SERVICE_DIR}/migration.list
MIGRATION_PATH=()
CURRENT_VERSION_FOUND="false"
# a VERSION_PAIR looks like "v0.3.5 v0.3.6-alpha2"
#
# - "v0.3.5" is the current version installed on this host
# - "v0.3.6-alpha2" is the version of the migration tool from GitHub
while read -r VERSION_PAIR; do
if [ -z "${VERSION_PAIR}" ]; then
continue
fi
# obtain "v0.3.5" from "v0.3.5 v0.3.6-alpha2"
VER1=$(echo "${VERSION_PAIR}" | cut -d' ' -f1)
# obtain "v0.3.6-alpha2" from "v0.3.5 v0.3.6-alpha2"
VER2=$(echo "${VERSION_PAIR}" | cut -d' ' -f2)
if [ "${CURRENT_VERSION}" = "${VER1// /}" ] || [ "${CURRENT_VERSION}" = "LEGACY_WITHOUT_VERSION" ]; then
CURRENT_VERSION_FOUND="true"
fi
if [ "${CURRENT_VERSION_FOUND}" = "true" ]; then
MIGRATION_PATH+=("${VER2// /}")
fi
done < "${MIGRATION_LIST_FILE}"
if [ ${#MIGRATION_PATH[@]} -eq 0 ]; then
__warning "No migration path found from ${CURRENT_VERSION} to ${SOURCE_VERSION}"
exit 0
fi
ARCH="unknown"
case $(uname -m) in
@@ -100,59 +141,22 @@ case $(uname -m) in
;;
esac
__info "ARCH: ${ARCH}"
MIGRATION_SERVICE_DIR=${1}
if [ -z "${MIGRATION_SERVICE_DIR}" ]; then
MIGRATION_SERVICE_DIR=${BUILD_PATH}/scripts/migration/service.d/${APP_NAME}
fi
MIGRATION_LIST_FILE=${MIGRATION_SERVICE_DIR}/migration.list
MIGRATION_PATH=()
CURRENT_VERSION_FOUND="false"
# a VERSION_PAIR looks like "v0.3.5 <url>"
#
# - "v0.3.5" is the current version installed on this host
# - "<url>" is the url of the migration tool
while read -r VERSION_PAIR; do
if [ -z "${VERSION_PAIR}" ]; then
continue
fi
# obtain "v0.3.5" from "v0.3.5 v0.3.6-alpha2"
VER1=$(echo "${VERSION_PAIR}" | cut -d' ' -f1)
# obtain "<url>" from "v0.3.5 <url>"
URL=$(eval echo "${VERSION_PAIR}" | cut -d' ' -f2)
if [ "${CURRENT_VERSION}" = "${VER1// /}" ] || [ "${CURRENT_VERSION}" = "LEGACY_WITHOUT_VERSION" ]; then
CURRENT_VERSION_FOUND="true"
fi
if [ "${CURRENT_VERSION_FOUND}" = "true" ]; then
MIGRATION_PATH+=("${URL// /}")
fi
done < "${MIGRATION_LIST_FILE}"
if [ ${#MIGRATION_PATH[@]} -eq 0 ]; then
__warning "No migration path found from ${CURRENT_VERSION} to ${SOURCE_VERSION}"
exit 0
fi
pushd "${MIGRATION_SERVICE_DIR}"
{ for URL in "${MIGRATION_PATH[@]}"; do
MIGRATION_TOOL_FILE=$(basename "${URL}")
{ for VER2 in "${MIGRATION_PATH[@]}"; do
MIGRATION_TOOL_FILE=linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz
if [ -f "${MIGRATION_TOOL_FILE}" ]; then
__info "Migration tool ${MIGRATION_TOOL_FILE} exists. Skip downloading."
continue
fi
__info "Dowloading ${URL}..."
curl -fsSL -o "${MIGRATION_TOOL_FILE}" -O "${URL}"
# MIGRATION_TOOL_URL=http://192.168.2.197:8000/v1/package/migration?type=release&name="${APP_NAME_FORMAL}"&version=${VER2}&arch=${ARCH}
MIGRATION_TOOL_URL=https://github.com/IceWhaleTech/"${APP_NAME_FORMAL}"/releases/download/"${VER2}"/linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz
echo "Dowloading ${MIGRATION_TOOL_URL}..."
curl -sL -O "${MIGRATION_TOOL_URL}"
done
} || {
popd
@@ -160,8 +164,8 @@ pushd "${MIGRATION_SERVICE_DIR}"
}
{
for URL in "${MIGRATION_PATH[@]}"; do
MIGRATION_TOOL_FILE=$(basename "${URL}")
for VER2 in "${MIGRATION_PATH[@]}"; do
MIGRATION_TOOL_FILE=linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz
__info "Extracting ${MIGRATION_TOOL_FILE}..."
tar zxvf "${MIGRATION_TOOL_FILE}" || __error "Failed to extract ${MIGRATION_TOOL_FILE}"

View File

@@ -1,3 +1,4 @@
LEGACY_WITHOUT_VERSION https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
v0.3.5 https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
v0.3.5.1 https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
LEGACY_WITHOUT_VERSION v0.3.6
v0.3.5 v0.3.6
v0.3.5.1 v0.3.6
v0.3.6 v0.3.7

View File

@@ -40,6 +40,6 @@ else
echo "Enabling service..."
systemctl enable --force --no-ask-password "${APP_NAME}.service"
#echo "Starting service..."
#systemctl start --force --no-ask-password "${APP_NAME}.service"
echo "Starting service..."
systemctl start --force --no-ask-password "${APP_NAME}.service"
fi

View File

@@ -9,4 +9,4 @@
###
curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash
curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/new.update.sh | bash

View File

@@ -83,7 +83,8 @@ func main() {
}
migrationTools := []interfaces.MigrationTool{
// nothing to migrate from last version
NewMigrationToolFor_035(),
NewMigrationToolFor_036(),
}
var selectedMigrationTool interfaces.MigrationTool
@@ -114,7 +115,8 @@ func main() {
panic(err)
}
if err := selectedMigrationTool.PostMigrate(); err != nil {
_logger.Error("Migration succeeded, but post-migration failed: %s", err)
}
selectedMigrationTool.PostMigrate()
_logger.Info("casaos migration ok")
// panic(err)
}

View File

@@ -0,0 +1,182 @@
/*
* @Author: LinkLeong link@icewhale.org
* @Date: 2022-08-24 17:36:00
* @LastEditors: LinkLeong
* @LastEditTime: 2022-09-05 11:24:27
* @FilePath: /CasaOS/cmd/migration-tool/migration-034-035.go
* @Description:
* @Website: https://www.casaos.io
* Copyright (c) 2022 by icewhale, All Rights Reserved.
*/
package main
import (
"io"
"io/ioutil"
"os"
"path"
"strings"
interfaces "github.com/IceWhaleTech/CasaOS-Common"
"github.com/IceWhaleTech/CasaOS-Common/utils/version"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/service"
)
type migrationTool036 struct{}
func (u *migrationTool036) IsMigrationNeeded() (bool, error) {
majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion()
if err != nil {
if err == version.ErrLegacyVersionNotFound {
return false, nil
}
return false, err
}
if majorVersion > 0 {
return false, nil
}
if minorVersion > 3 {
return false, nil
}
if minorVersion == 3 && patchVersion > 5 {
return false, nil
}
_logger.Info("Migration is needed for a CasaOS version 0.3.5 and older...")
return true, nil
}
func (u *migrationTool036) PreMigrate() error {
return nil
}
func (u *migrationTool036) Migrate() error {
if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") {
service.MyService.System().UpdateUSBAutoMount("False")
service.MyService.System().ExecUSBAutoMountShell("False")
}
newAPIUrl := "https://api.casaos.io/casaos-api"
if config.ServerInfo.ServerApi == "https://api.casaos.zimaboard.com" {
config.ServerInfo.ServerApi = newAPIUrl
config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
command.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/assist.sh | bash")
if !file.CheckNotExist("/casaOS") {
command.OnlyExec("source /casaOS/server/shell/update.sh ;")
command.OnlyExec("source " + config.AppInfo.ShellPath + "/delete-old-service.sh ;")
}
service.MyService.App().ImportApplications(true)
src := "/casaOS/server/conf/conf.ini"
if file.Exists(src) {
dst := "/etc/casaos/casaos.conf"
source, err := os.Open(src)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
if err != nil {
return err
}
}
if file.Exists("/casaOS/server/db") {
var fds []os.FileInfo
var err error
to := "/var/lib/casaos/db"
file.IsNotExistMkDir(to)
from := "/casaOS/server/db"
if fds, err = ioutil.ReadDir(from); err != nil {
return err
}
for _, fd := range fds {
srcfp := path.Join(from, fd.Name())
dstfp := path.Join(to, fd.Name())
source, err := os.Open(srcfp)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dstfp)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
if err != nil {
return err
}
}
}
if file.Exists("/casaOS/server/conf") {
var fds []os.FileInfo
var err error
to := "/var/lib/casaos/conf"
file.IsNotExistMkDir(to)
from := "/casaOS/server/conf"
if fds, err = ioutil.ReadDir(from); err != nil {
return err
}
for _, fd := range fds {
fExt := path.Ext(fd.Name())
if fExt != ".json" {
continue
}
srcfp := path.Join(from, fd.Name())
dstfp := path.Join(to, fd.Name())
source, err := os.Open(srcfp)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dstfp)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
if err != nil {
return err
}
}
}
_logger.Info("update done")
return nil
}
func (u *migrationTool036) PostMigrate() error {
return nil
}
func NewMigrationToolFor_035() interfaces.MigrationTool {
return &migrationTool{}
}

View File

@@ -0,0 +1,74 @@
/*
* @Author: LinkLeong link@icewhale.org
* @Date: 2022-08-24 17:36:00
* @LastEditors: LinkLeong
* @LastEditTime: 2022-09-05 11:24:27
* @FilePath: /CasaOS/cmd/migration-tool/migration-034-035.go
* @Description:
* @Website: https://www.casaos.io
* Copyright (c) 2022 by icewhale, All Rights Reserved.
*/
package main
import (
"strings"
interfaces "github.com/IceWhaleTech/CasaOS-Common"
"github.com/IceWhaleTech/CasaOS-Common/utils/version"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/service"
)
type migrationTool struct{}
func (u *migrationTool) IsMigrationNeeded() (bool, error) {
majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion()
if err != nil {
if err == version.ErrLegacyVersionNotFound {
return false, nil
}
return false, err
}
if majorVersion > 0 {
return false, nil
}
if minorVersion > 3 {
return false, nil
}
if minorVersion == 3 && patchVersion > 5 {
return false, nil
}
_logger.Info("Migration is needed for a CasaOS version 0.3.5 and older...")
return true, nil
}
func (u *migrationTool) PreMigrate() error {
return nil
}
func (u *migrationTool) Migrate() error {
if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") {
service.MyService.System().UpdateUSBAutoMount("False")
service.MyService.System().ExecUSBAutoMountShell("False")
}
_logger.Info("update done")
return nil
}
func (u *migrationTool) PostMigrate() error {
return nil
}
func NewMigrationToolFor_036() interfaces.MigrationTool {
return &migrationTool{}
}

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.16
require (
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9
github.com/IceWhaleTech/CasaOS-Gateway v0.3.6
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/ambelovsky/go-structs v1.1.0 // indirect

3
go.sum
View File

@@ -83,9 +83,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9 h1:q4I/lSsCooxdd6LxinGy90y0n6V8EcaPBV1JCfpEnV4=
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk=
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8 h1:r8nhgQ6tnrn6ikXN9aLH/K4H4H64Nc0hZ6jyW2B22x0=
github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk=
github.com/IceWhaleTech/CasaOS-Gateway v0.3.6 h1:2tQQo85+jzbbjqIsKKn77QlAA73bc7vZsVCFvWnK4mg=
github.com/IceWhaleTech/CasaOS-Gateway v0.3.6/go.mod h1:hnZwGUzcOyiufMpVO7l3gu2gAm6Ws4TY4Nlj3kMshXA=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=

62
middleware/gin.go Normal file
View File

@@ -0,0 +1,62 @@
/*
* @Author: LinkLeong link@icewhale.com
* @Date: 2021-10-08 10:29:08
* @LastEditors: LinkLeong
* @LastEditTime: 2022-07-22 11:06:07
* @FilePath: /CasaOS/middleware/gin.go
* @Description:
* @Website: https://www.casaos.io
* Copyright (c) 2022 by icewhale, All Rights Reserved.
*/
package middleware
import (
"fmt"
"net/http"
"strings"
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language,Content-Type,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Connection,Host,Origin,Referer,User-Agent,X-Requested-With")
// 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
//设置缓存时间
c.Header("Access-Control-Max-Age", "172800")
c.Header("Access-Control-Allow-Credentials", "true")
c.Set("Content-Type", "application/json")
//}
//允许类型校验
if method == "OPTIONS" {
c.JSON(http.StatusOK, "ok!")
}
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
c.Next()
}
}
func WriteLog() gin.HandlerFunc {
return func(c *gin.Context) {
if !strings.Contains(c.Request.URL.String(), "password") {
loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("method", c.Request.Method))
c.Next()
}
}
}

View File

@@ -17,8 +17,6 @@ type DockerStatsModel struct {
Previous interface{} `json:"previous"`
}
// reference - https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
type DockerDaemonConfigurationModel struct {
// e.g. `/var/lib/docker`
Root string `json:"data-root,omitempty"`
type DeckerDaemonModel struct {
Graph string `json:"graph"`
}

View File

@@ -15,6 +15,7 @@ import (
)
func NewSshClient(user, password string, port string) (*ssh.Client, error) {
// connet to ssh
// addr = fmt.Sprintf("%s:%d", host, port)
@@ -89,11 +90,11 @@ func (w *wsBufferWriter) Write(p []byte) (int, error) {
defer w.mu.Unlock()
return w.buffer.Write(p)
}
func (s *SshConn) Close() {
if s.Session != nil {
s.Session.Close()
}
}
const (
@@ -110,6 +111,7 @@ func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string {
//read websocket msg
_, wsData, err := wsConn.ReadMessage()
if err != nil {
return ""
}
@@ -271,7 +273,6 @@ func (ssConn *SshConn) SendComboOutput(wsConn *websocket.Conn, exitCh chan bool)
}
}
}
func flushComboOutput(w *wsBufferWriter, wsConn *websocket.Conn) error {
if w.buffer.Len() != 0 {
err := wsConn.WriteMessage(websocket.TextMessage, w.buffer.Bytes())
@@ -340,7 +341,6 @@ func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exit
}
}
}
func (ssConn *SshConn) SessionWait(quitChan chan bool) {
if err := ssConn.Session.Wait(); err != nil {
logrus.WithError(err).Error("ssh session wait failed")

View File

@@ -36,7 +36,7 @@ func ExecResultStrArray(cmdStr string) []string {
return nil
}
//str, err := ioutil.ReadAll(stdout)
networklist := []string{}
var networklist = []string{}
outputBuf := bufio.NewReader(stdout)
for {
output, _, err := outputBuf.ReadLine()
@@ -54,8 +54,6 @@ func ExecResultStrArray(cmdStr string) []string {
func ExecResultStr(cmdStr string) string {
cmd := exec.Command("/bin/bash", "-c", cmdStr)
println(cmd.String())
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Println(err)
@@ -109,5 +107,6 @@ func ExecSmartCTLByPath(path string) []byte {
}
func ExecEnabledSMART(path string) {
exec.Command("smartctl", "-s on", path).Output()
}

View File

@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"io/ioutil"
"log"
"mime/multipart"
@@ -61,7 +60,7 @@ func MkDir(src string) error {
if err != nil {
return err
}
os.Chmod(src, 0o777)
os.Chmod(src, 0777)
return nil
}
@@ -104,7 +103,7 @@ func MustOpen(fileName, filePath string) (*os.File, error) {
return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err)
}
f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o644)
f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, fmt.Errorf("Fail to OpenFile :%v", err)
}
@@ -148,7 +147,7 @@ func CreateFile(path string) error {
}
func CreateFileAndWriteContent(path string, content string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o666)
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
@@ -164,7 +163,7 @@ func CreateFileAndWriteContent(path string, content string) error {
// IsNotExistMkDir create a directory if it does not exist
func IsNotExistCreateFile(src string) error {
if notExist := CheckNotExist(src); notExist {
if notExist := CheckNotExist(src); notExist == true {
if err := CreateFile(src); err != nil {
return err
}
@@ -337,17 +336,10 @@ func WriteToPath(data []byte, path, name string) error {
} else {
fullPath += "/" + name
}
return WriteToFullPath(data, fullPath, 0o666)
}
func WriteToFullPath(data []byte, fullPath string, perm fs.FileMode) error {
if err := IsNotExistCreateFile(fullPath); err != nil {
return err
}
IsNotExistCreateFile(fullPath)
file, err := os.OpenFile(fullPath,
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
perm,
0666,
)
if err != nil {
return err
@@ -360,29 +352,24 @@ func WriteToFullPath(data []byte, fullPath string, perm fs.FileMode) error {
//最终拼接
func SpliceFiles(dir, path string, length int, startPoint int) error {
fullPath := path
if err := IsNotExistCreateFile(fullPath); err != nil {
return err
}
IsNotExistCreateFile(fullPath)
file, _ := os.OpenFile(fullPath,
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
0o666,
0666,
)
defer file.Close()
bufferedWriter := bufio.NewWriter(file)
// todo: here should have a goroutine to remove each partial file after it is read, to save disk space
for i := 0; i < length+startPoint; i++ {
data, err := ioutil.ReadFile(dir + "/" + strconv.Itoa(i+startPoint))
if err != nil {
return err
}
if _, err := bufferedWriter.Write(data); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster write
_, err = bufferedWriter.Write(data)
if err != nil {
return err
}
}
@@ -393,6 +380,7 @@ func SpliceFiles(dir, path string, length int, startPoint int) error {
}
func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) {
switch t {
case "zip", "":
return ".zip", archiver.NewZip(), nil
@@ -412,8 +400,8 @@ func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) {
return "", nil, errors.New("format not implemented")
}
}
func AddFile(ar archiver.Writer, path, commonPath string) error {
info, err := os.Stat(path)
if err != nil {
return err
@@ -459,7 +447,6 @@ func AddFile(ar archiver.Writer, path, commonPath string) error {
return nil
}
func CommonPrefix(sep byte, paths ...string) string {
// Handle special cases.
switch len(paths) {

View File

@@ -1,10 +1,8 @@
package route
import (
"os"
"github.com/IceWhaleTech/CasaOS-Common/middleware"
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
"github.com/IceWhaleTech/CasaOS/middleware"
"github.com/IceWhaleTech/CasaOS/pkg/config"
v1 "github.com/IceWhaleTech/CasaOS/route/v1"
@@ -13,22 +11,13 @@ import (
)
func InitRouter() *gin.Engine {
ginMode := gin.ReleaseMode
if config.ServerInfo.RunMode != "" {
ginMode = config.ServerInfo.RunMode
}
if os.Getenv(gin.EnvGinMode) != "" {
ginMode = os.Getenv(gin.EnvGinMode)
}
gin.SetMode(ginMode)
r := gin.New()
r.Use(gin.Recovery())
r := gin.Default()
r.Use(middleware.Cors())
r.Use(gzip.Gzip(gzip.DefaultCompression))
if ginMode != gin.ReleaseMode {
r.Use(middleware.WriteLog())
}
r.Use(gzip.Gzip(gzip.DefaultCompression))
gin.SetMode(config.ServerInfo.RunMode)
// r.StaticFS("/ui", http.FS(web.Static))
// r.GET("/", WebUIHome)
@@ -111,8 +100,8 @@ func InitRouter() *gin.Engine {
v1ContainerGroup.PUT("/:id/latest", v1.PutAppUpdate)
//Not used
v1ContainerGroup.POST("/share", v1.ShareAppFile)
v1ContainerGroup.GET("/info", v1.GetDockerDaemonConfiguration)
v1ContainerGroup.PUT("/info", v1.PutDockerDaemonConfiguration)
v1ContainerGroup.GET("/info", v1.GetcontainerInfo)
v1ContainerGroup.PUT("/info", v1.PutcontainerInfo)
}
v1AppCategoriesGroup := v1Group.Group("/app-categories")

View File

@@ -2,9 +2,8 @@ package v1
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"path/filepath"
"strconv"
"github.com/IceWhaleTech/CasaOS/model"
@@ -17,11 +16,6 @@ import (
"github.com/gin-gonic/gin"
)
const (
dockerRootDirFilePath = "/var/lib/casaos/docker_root"
dockerDaemonConfigurationFilePath = "/etc/docker/daemon.json"
)
// @Summary 获取远程列表
// @Produce application/json
// @Accept application/json
@@ -35,6 +29,7 @@ const (
// @Success 200 {string} string "ok"
// @Router /app/list [get]
func AppList(c *gin.Context) {
//service.MyService.Docker().DockerContainerCommit("test2")
index := c.DefaultQuery("index", "1")
@@ -156,6 +151,7 @@ func AppUsageList(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /app/appinfo/{id} [get]
func AppInfo(c *gin.Context) {
id := c.Param("id")
language := c.GetHeader("Language")
info, err := service.MyService.Casa().GetServerAppInfo(id, "", language)
@@ -269,87 +265,53 @@ func ShareAppFile(c *gin.Context) {
c.JSON(common_err.SUCCESS, json.RawMessage(content))
}
func GetDockerDaemonConfiguration(c *gin.Context) {
func GetcontainerInfo(c *gin.Context) {
// info, err := service.MyService.Docker().GetDockerInfo()
// if err != nil {
// c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
// return
// }
data := make(map[string]interface{})
if file.Exists(dockerRootDirFilePath) {
buf := file.ReadFullFile(dockerRootDirFilePath)
err := json.Unmarshal(buf, &data)
daemon := model.DeckerDaemonModel{}
data := make(map[string]interface{}, 1)
data["docker_root_dir"] = ""
if file.Exists("/etc/docker/daemon.json") {
byteResult := file.ReadFullFile("/etc/docker/daemon.json")
err := json.Unmarshal(byteResult, &daemon)
if err != nil {
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err})
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()})
return
}
data["docker_root_dir"] = daemon.Graph
}
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
}
func PutDockerDaemonConfiguration(c *gin.Context) {
request := make(map[string]interface{})
if err := c.BindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err})
return
}
value, ok := request["docker_root_dir"]
if !ok {
c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "`docker_root_dir` should not empty"})
return
}
dockerConfig := model.DockerDaemonConfigurationModel{}
if file.Exists(dockerDaemonConfigurationFilePath) {
byteResult := file.ReadFullFile(dockerDaemonConfigurationFilePath)
err := json.Unmarshal(byteResult, &dockerConfig)
func PutcontainerInfo(c *gin.Context) {
js := make(map[string]interface{})
err := c.BindJSON(&js)
if err != nil {
c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to deserialize " + dockerDaemonConfigurationFilePath, Data: err})
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()})
return
}
dockerRootDir := js["docker_root_dir"].(string)
daemon := model.DeckerDaemonModel{}
if file.Exists("/etc/docker/daemon.json") {
byteResult := file.ReadFullFile("/etc/docker/daemon.json")
err := json.Unmarshal(byteResult, &daemon)
if err != nil {
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()})
return
}
}
dockerRootDir := value.(string)
if dockerRootDir == "/" {
dockerConfig.Root = "" // omitempty - empty string will not be serialized
} else {
if !file.Exists(dockerRootDir) {
c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS), Data: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS), Data: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
return
}
daemon.Graph = dockerRootDir
byteMode, _ := json.Marshal(daemon)
file.WriteToPath(byteMode, "/etc/docker", "daemon.json")
dockerConfig.Root = filepath.Join(dockerRootDir, "docker")
fmt.Println(command.ExecResultStr("systemctl daemon-reload"))
fmt.Println(command.ExecResultStr("systemctl restart docker"))
if err := file.IsNotExistMkDir(dockerConfig.Root); err != nil {
c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to create " + dockerConfig.Root, Data: err})
return
}
}
if buf, err := json.Marshal(request); err != nil {
c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker root json", Data: err})
return
} else {
if err := file.WriteToFullPath(buf, dockerRootDirFilePath, 0o644); err != nil {
c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write " + dockerRootDirFilePath, Data: err})
return
}
}
if buf, err := json.Marshal(dockerConfig); err != nil {
c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker config", Data: dockerConfig})
return
} else {
if err := file.WriteToFullPath(buf, dockerDaemonConfigurationFilePath, 0o644); err != nil {
c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write to " + dockerDaemonConfigurationFilePath, Data: err})
return
}
}
println(command.ExecResultStr("systemctl daemon-reload"))
println(command.ExecResultStr("systemctl restart docker"))
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: request})
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: js})
}

View File

@@ -1126,7 +1126,7 @@ func ContainerUpdateInfo(c *gin.Context) {
}
}
for _, v := range info.Config.Env {
if len(showENVList) > 0 && info.Config.Labels["origin"] != "local" {
if len(showENVList) > 0 {
if _, ok := showENVMap[strings.Split(v, "=")[0]]; ok {
temp := model.Env{
Name: strings.Split(v, "=")[0],

View File

@@ -18,11 +18,9 @@ import (
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"go.uber.org/zap"
)
// @Summary 读取文件
@@ -85,6 +83,7 @@ func GetLocalFile(c *gin.Context) {
return
}
c.File(path)
return
}
// @Summary download
@@ -97,6 +96,7 @@ func GetLocalFile(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/download [get]
func GetDownloadFile(c *gin.Context) {
t := c.Query("format")
files := c.Query("files")
@@ -179,6 +179,7 @@ func GetDownloadFile(c *gin.Context) {
log.Printf("Failed to archive %s: %v", fname, err)
}
}
}
func GetDownloadSingleFile(c *gin.Context) {
@@ -360,6 +361,7 @@ func PostCreateFile(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/upload [get]
func GetFileUpload(c *gin.Context) {
relative := c.Query("relativePath")
fileName := c.Query("filename")
chunkNumber := c.Query("chunkNumber")
@@ -403,92 +405,55 @@ func PostFileUpload(c *gin.Context) {
hash := file.GetHashByContent([]byte(fileName))
if len(path) == 0 {
loger.Error("path should not be empty")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
if fileName != relative {
dirPath = strings.TrimSuffix(relative, fileName)
tempDir += dirPath
if err := file.MkDir(path + "/" + dirPath); err != nil {
loger.Error("error when trying to create `"+path+"/"+dirPath+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
file.MkDir(path + "/" + dirPath)
}
path += "/" + relative
if !file.CheckNotExist(tempDir + chunkNumber) {
if err := file.RMDir(tempDir + chunkNumber); err != nil {
loger.Error("error when trying to remove existing `"+tempDir+chunkNumber+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
file.RMDir(tempDir + chunkNumber)
}
if totalChunks > 1 {
if err := file.IsNotExistMkDir(tempDir); err != nil {
loger.Error("error when trying to create `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
out, err := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil {
loger.Error("error when trying to open `"+tempDir+chunkNumber+"` for creation", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
file.IsNotExistMkDir(tempDir)
out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644)
defer out.Close()
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
loger.Error("error when trying to write to `"+tempDir+chunkNumber+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
fileNum, err := ioutil.ReadDir(tempDir)
_, err := io.Copy(out, f)
if err != nil {
loger.Error("error when trying to read number of files under `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
}
if totalChunks == len(fileNum) {
if err := file.SpliceFiles(tempDir, path, totalChunks, 1); err != nil {
loger.Error("error when trying to splice files under `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
if err := file.RMDir(tempDir); err != nil {
loger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
}
} else {
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil {
loger.Error("error when trying to open `"+path+"` for creation", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
defer out.Close()
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
loger.Error("error when trying to write to `"+path+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
_, err := io.Copy(out, f)
if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
}
}
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
return
}
fileNum, err := ioutil.ReadDir(tempDir)
if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
}
if totalChunks == len(fileNum) {
file.SpliceFiles(tempDir, path, totalChunks, 1)
file.RMDir(tempDir)
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
// @Summary copy or move file
@@ -500,6 +465,7 @@ func PostFileUpload(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/operate [post]
func PostOperateFileOrDir(c *gin.Context) {
list := model.FileOperate{}
c.ShouldBind(&list)
@@ -549,6 +515,7 @@ func PostOperateFileOrDir(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/delete [delete]
func DeleteFile(c *gin.Context) {
paths := []string{}
c.ShouldBind(&paths)
if len(paths) == 0 {
@@ -580,6 +547,7 @@ func DeleteFile(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/update [put]
func PutFileContent(c *gin.Context) {
fi := model.FileUpdate{}
c.ShouldBind(&fi)

View File

@@ -221,7 +221,7 @@ func (s *systemService) UpdateSystemVersion(version string) {
}
file.CreateFile(config.AppInfo.LogPath + "/upgrade.log")
//go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/update.sh | bash")
go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash")
go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | sudo bash")
//s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
//s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version))
}