qixiaoning
2025-09-18 fd31206bcb8b084720291a53c986db771d8f5975
抓拍预警记录查询修改,备份还原接口问题修复,应用安装接口调试
12个文件已修改
399 ■■■■ 已修改文件
api-gateway/main.go 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
appcenter-service/main.go 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
appcenter-service/service/SdkInstall.go 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-common/models/Record.go 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-service/controllers/camera.go 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-service/main.go 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/controllers/voice.go 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/main.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/sys/sysinfo.go 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version-control/controller/controller.go 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version-control/main.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version-control/service/backup.go 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api-gateway/main.go
@@ -2,6 +2,7 @@
import (
    "context"
    "encoding/json"
    "flag"
    "basic.com/valib/logc.git"
@@ -21,11 +22,15 @@
    "vamicro/api-gateway/traces"
    "vamicro/config"
    "vamicro/extend/util"
    bh "basic.com/valib/c_bhomebus.git/api/bhsgo"
    bhmsg "basic.com/valib/c_bhomebus.git/proto/source/bhome_msg"
)
var (
    procName = service.ProcName
    env      = flag.String("e", "pro", "")
    procName         = service.ProcName
    env              = flag.String("e", "pro", "")
    VaSystemLogTopic = "VaSystemLogSaveTopic"
)
// func init() {
@@ -53,6 +58,17 @@
    ctx, cancel := context.WithCancel(context.Background())
    defer func() {
        logInfo2 := logc.VaSystemLog{
            HostName: "localhost",
            ProcName: "smartai",
            ProcID:   os.Getpid(),
            Level:    logc.LevelInfo,
            Info:     "smartai停止",
        }
        LogDecoderInfo(ctx, logInfo2)
    }()
    q := make(chan os.Signal, 1)
    signal.Notify(q, os.Interrupt, os.Kill, syscall.SIGTERM)
    signal.Ignore(syscall.SIGPIPE)
@@ -65,6 +81,18 @@
        })
        auth.Oauth2Init()
        util.AuthCheck(ctx) //授权检查
        //记录日志
        logInfo := logc.VaSystemLog{
            HostName: "localhost",
            ProcName: "smartai",
            ProcID:   os.Getpid(),
            Level:    logc.LevelInfo,
            Info:     "smartai启动",
        }
        LogDecoderInfo(ctx, logInfo)
        go func() {
            r := gin.Default()
            r.Use(auth.AuthHandler())
@@ -84,3 +112,22 @@
        logger.Debug("client is nil")
    }
}
// 保存系统日志
func LogDecoderInfo(ctx context.Context, logInfo logc.VaSystemLog) {
    logger.Debug("start LogDecoderInfo")
    go func() {
        logData, _ := json.Marshal(logInfo)
        pub := bhmsg.MsgPublish{
            Topic: []byte(VaSystemLogTopic),
            Data:  logData,
        }
        if !bh.Publish(&pub, 1000) {
            logger.Error("LogDecoderInfo %s failed\n", VaSystemLogTopic)
        }
    }()
}
appcenter-service/main.go
@@ -1,10 +1,6 @@
package main
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "basic.com/valib/version.git"
    "context"
    "flag"
    "net/http"
@@ -17,14 +13,19 @@
    "vamicro/appcenter-service/service"
    "vamicro/config"
    versionControlS "vamicro/version-control/service"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    vaversion "basic.com/valib/version.git"
)
var (
    procName = service.ProcName
    proc = &bhomeclient.ProcInfo{
    proc     = &bhomeclient.ProcInfo{
        Name: procName, //进程名称
        ID: procName, //进程id
        Info: "", //进程的描述信息,用于区分同一进程名称下多个进程
        ID:   procName, //进程id
        Info: "",       //进程的描述信息,用于区分同一进程名称下多个进程
    }
    env = flag.String("e", "pro", "")
)
@@ -35,29 +36,29 @@
    config.Init(*env)
    // 日志初始化
    var logFile = config.LogConf.Path + "vamicro-"+procName+".log"
    var logFile = config.LogConf.Path + "vamicro-" + procName + ".log"
    logger.InitLogger(logFile, config.LogConf.Level, config.LogConf.MaxSize, config.LogConf.MaxBackups, config.LogConf.MaxAge)
    logger.Info("log init success !")
}
func main(){
func main() {
    models.Init()
    defer models.CloseDB()
    ctx, cancel := context.WithCancel(context.Background())
    fm,pubTopics := initFuncMap()
    var reg = &bhomeclient.RegisterInfo {
        Proc: *proc,
        Channel: nil,
    fm, pubTopics := initFuncMap()
    var reg = &bhomeclient.RegisterInfo{
        Proc:     *proc,
        Channel:  nil,
        PubTopic: pubTopics,
        SubTopic:  []string{versionControlS.SysUpdateConfigTopic},
        SubTopic: []string{versionControlS.SysUpdateConfigTopic},
    }
    q := make(chan os.Signal, 1)
    signal.Notify(q, os.Interrupt, os.Kill, syscall.SIGTERM)
    ms, err := bhomeclient.NewMicroNode(ctx, q, config.Server.AnalyServerId, reg, logger.Debug)
    if err !=nil {
    if err != nil {
        return
    }
@@ -67,7 +68,7 @@
    go ms.StartServer(fm)
    go handleSubMsg(ctx, ms)
    go service.SelfUpdateStart(ctx) //自动更新
    go service.NoticeTick(ctx)//更新提醒
    go service.NoticeTick(ctx)      //更新提醒
    // pprof 用于分析性能
    go func() {
        logger.Info(http.ListenAndServe("0.0.0.0:7073", nil))
@@ -80,7 +81,8 @@
}
const urlPrefix = "/data/api-v"
func initFuncMap() (map[string]bhomeclient.MicroFunc,[]string) {
func initFuncMap() (map[string]bhomeclient.MicroFunc, []string) {
    funcMap := make(map[string]bhomeclient.MicroFunc)
    sc := new(controllers.SdkController)
    sa := new(controllers.SdkArgController)
@@ -113,7 +115,7 @@
    funcMap[urlPrefix+"/app/upgrade/notice/delay"] = ac.DelayNotice
    var pubTopics []string
    for key,_ := range funcMap {
    for key, _ := range funcMap {
        pubTopics = append(pubTopics, key)
    }
    return funcMap, pubTopics
@@ -129,4 +131,4 @@
            service.PersistentWrapper(string(msg.Topic), msg.Data)
        }
    }
}
}
appcenter-service/service/SdkInstall.go
@@ -1,10 +1,6 @@
package service
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/licence.git"
    "basic.com/valib/logger.git"
    "encoding/json"
    "errors"
    "fmt"
@@ -19,6 +15,11 @@
    "vamicro/appcenter-service/vo"
    "vamicro/config"
    "vamicro/extend/util"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/licence.git"
    "basic.com/valib/logger.git"
)
type SdkInstallService struct {
@@ -410,8 +411,16 @@
                installFile := path.Join(unPackPath, "install.sh")
                if util.Exists(installFile) {
                    logger.Debug("开始执行脚本:" + installFile)
                    // 切换到当前运行目录
                    os.Chdir(unPackPath)
                    err1 := os.Chmod(installFile, 0755)
                    if err1 != nil {
                        logger.Debug("修改权限失败:" + err1.Error())
                    }
                    err2 := os.Chdir(unPackPath)
                    if err2 != nil {
                        logger.Debug("修改权限失败:" + err2.Error())
                    }
                    b, err := ExecCmd(installFile)
                    if err != nil {
                        return false, err
@@ -642,7 +651,8 @@
            var appDefArr []models.App
            if err = json.Unmarshal(defB, &appDefArr); err == nil {
                for _, ap := range appDefArr {
                    if SaveApp(ap) {
                    //保存失败报错
                    if !SaveApp(ap) {
                        insErr = errors.New("注册应用失败,应用id:" + ap.Id + "")
                        return insErr
                    } else {
camera-common/models/Record.go
@@ -4,11 +4,14 @@
    "context"
    "fmt"
    "math"
    "os"
    "path/filepath"
    "sort"
    "strconv"
    "strings"
    "time"
    "basic.com/valib/logger.git"
    "github.com/milvus-io/milvus-sdk-go/v2/entity"
)
@@ -47,6 +50,7 @@
    IsWarning          int64                     `json:"is_warning"`
    ZhDescClass        string                    `json:"zh_desc_class"`
    TaskName           string                    `json:"task_name"`
    WarnTaskName       string                    `json:"warn_task_name"`
    EventLevelName     string                    `json:"event_level_name"`
    DetectNum          int64                     `json:"detect_num"`
    Suggestion         string                    `json:"suggestion"`
@@ -127,8 +131,9 @@
}
type TaskOption struct {
    TaskId   int64  `db:"task_id" json:"taskId"`
    TaskName string `db:"task_name" json:"taskName"`
    TaskId     int64  `db:"task_id" json:"taskId"`
    TaskName   string `db:"task_name" json:"taskName"`
    EventLevel int64  `db:"event_level" json:"eventLevel"`
}
type CheckOption struct {
@@ -187,6 +192,136 @@
    Warning  int64    `json:"warning`
    Page     int64    `json:"page"`
    PageSize int64    `json:"pageSize"`
}
// 时间段
type TimeRange struct {
    StartTime string `json:"startTime"`
    EndTime   string `json:"endTime"`
}
// 删除日志
func DeleteRecord(collectionName string, filterExpr string) (int, error) {
    dataOp := &DataOperator{client: dbClient}
    deletedFiles, err := dataOp.DelRecord(collectionName, filterExpr)
    return deletedFiles, err
}
// 清理日志
func (do *DataOperator) DelRecord(collectionName string, filterExpr string) (int, error) {
    ctx := context.Background()
    queryResult, err := do.client.client.Query(
        ctx,
        collectionName,
        []string{}, // 所有分区
        filterExpr,
        []string{"id", "image_path", "video_path", "image_desc_path"}, // 返回所有字段
        // client.WithLimit(pageSize),
        // client.WithOffset(offset),
    )
    // 2. 提取ID和文件路径
    var ids []int64
    var imgPaths []string
    var videoPaths []string
    var imgDesPaths []string
    if len(queryResult) == 0 {
        return 0, nil
    }
    count := queryResult[0].Len()
    for i := 0; i < count; i++ {
        for _, field := range queryResult {
            switch field.Name() {
            case "id":
                IdColumn := field.(*entity.ColumnInt64).Data()
                if len(IdColumn) > 0 {
                    id := IdColumn[i]
                    ids = append(ids, id)
                }
            case "image_path":
                ImagePathColumn := field.(*entity.ColumnVarChar).Data()
                if len(ImagePathColumn) > 0 {
                    imagePath := ImagePathColumn[i]
                    imgPaths = append(imgPaths, imagePath)
                }
            case "image_desc_path":
                ImageDesPathColumn := field.(*entity.ColumnVarChar).Data()
                if len(ImageDesPathColumn) > 0 {
                    imageDesPath := ImageDesPathColumn[i]
                    imgDesPaths = append(imgDesPaths, imageDesPath)
                }
            case "video_path":
                VideoPathColumn := field.(*entity.ColumnVarChar).Data()
                if len(VideoPathColumn) > 0 {
                    VideoPath := VideoPathColumn[i]
                    videoPaths = append(videoPaths, VideoPath)
                }
            }
        }
    }
    if len(ids) > 0 {
        idField := entity.NewColumnInt64("id", ids)
        err = do.client.client.DeleteByPks(ctx, collectionName, "", idField)
        if err != nil {
            return 0, fmt.Errorf("failed to delete from Milvus: %v", err)
        }
        err = do.client.client.DeleteByPks(ctx, "smartrag", "", idField)
        if err != nil {
            return 0, fmt.Errorf("failed to delete from Milvus: %v", err)
        }
    }
    // 图片删除文件
    deletedFiles := 0
    for _, path := range imgPaths {
        if err := do.deleteFile(path); err != nil {
            logger.Debug("failed to delete file " + path + " " + err.Error())
        } else {
            deletedFiles++
        }
    }
    //删除描述图片
    for _, path := range imgDesPaths {
        if err := do.deleteFile(path); err != nil {
            logger.Debug("failed to delete file " + path + " " + err.Error())
        } else {
            deletedFiles++
        }
    }
    //删除视频文件
    for _, path := range videoPaths {
        if err := do.deleteFile(path); err != nil {
            logger.Debug("failed to delete file " + path + " " + err.Error())
        } else {
            deletedFiles++
        }
    }
    return deletedFiles, err
}
func (do *DataOperator) deleteFile(relativePath string) error {
    fullPath := relativePath
    // 安全检查,防止路径遍历攻击
    if !isSafePath(fullPath) {
        return fmt.Errorf("invalid file path")
    }
    if _, err := os.Stat(fullPath); os.IsNotExist(err) {
        return fmt.Errorf("file does not exist")
    }
    return os.Remove(fullPath)
}
// isSafePath 检查路径是否安全,防止路径遍历攻击
func isSafePath(targetPath string) bool {
    rel := targetPath
    return rel != ".." && rel[:2] != ".."+string(filepath.Separator)
}
// 根据分页取数据
@@ -280,6 +415,11 @@
                if len(TNColumn) > 0 {
                    record.TaskName = TNColumn[i]
                }
            case "warn_task_id":
                WarnColumn := field.(*entity.ColumnVarChar).Data()
                if len(WarnColumn) > 0 {
                    record.WarnTaskName = WarnColumn[i]
                }
            case "event_level_name":
                EVColumn := field.(*entity.ColumnVarChar).Data()
                if len(EVColumn) > 0 {
@@ -353,7 +493,7 @@
        filterExpr,
        []string{"rule_id", "task_id", "is_waning", "zh_desc_class", "task_name", "event_level_name", "detect_num",
            "event_level_id", "video_point_id", "video_point_name", "detect_id", "image_path",
            "video_path", "detect_time", "knowledge_id", "risk_description", "suggestion", "id", "is_desc"}, // 返回所有字段
            "video_path", "detect_time", "knowledge_id", "risk_description", "suggestion", "id", "is_desc", "warn_task_id"}, // 返回所有字段
        // client.WithLimit(pageSize),
        // client.WithOffset(offset),
    )
@@ -422,8 +562,8 @@
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select task_id,task_name from mal_smart_task where task_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr).Scan(&items).Error; err != nil {
    sqlStr := `select task_id,task_name,event_level from mal_smart_task where task_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
camera-service/controllers/camera.go
@@ -1037,6 +1037,31 @@
}
/**
 *  删除记录
 */
func (cc CameraController) DelRecord(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    filter := " id > 0 "
    info := models.TimeRange{}
    if err := c.BindJSON(&info); err != nil {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    startTime := info.StartTime
    endTime := info.EndTime
    if len(startTime) > 0 && len(endTime) > 0 {
        filter += fmt.Sprintf(" and detect_time > '%s'", startTime)
        filter += fmt.Sprintf(" and detect_time < '%s'", endTime)
        deleteRecord, err := models.DeleteRecord("smartobject", filter)
        if err != nil {
            return &bhomeclient.Reply{Success: false, Msg: "删除失败" + err.Error(), Data: nil}
        } else {
            return &bhomeclient.Reply{Success: true, Msg: "删除成功", Data: deleteRecord}
        }
    } else {
        return &bhomeclient.Reply{Success: false, Msg: "删除失败", Data: nil}
    }
}
/**
 *  获取抓拍记录
 */
func (cc CameraController) GetRecord(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
@@ -1152,6 +1177,7 @@
            IsWarning:       v.IsWarning,
            DetectNum:       v.DetectNum,
            TaskName:        v.TaskName,
            WarnTaskName:    v.WarnTaskName,
            ZhDescClass:     v.ZhDescClass,
            EventLevelName:  v.EventLevelName,
            KnowledgeId:     v.KnowledgeId,
@@ -1170,10 +1196,38 @@
            CameraAddr:      v.CameraName,
            CameraName:      v.CameraName,
        }
        var taskId []int64
        //任务名称
        //任务id重新赋值
        if len(v.WarnTaskName) > 0 {
            v.TaskId = []int64{}
            taskId = []int64{}
            arr := strings.Split(v.WarnTaskName, ";")
            for _, temp := range arr {
                if len(temp) > 0 {
                    tempId, _ := strconv.ParseInt(strings.TrimSpace(temp), 10, 64)
                    taskId = append(taskId, tempId)
                }
            }
            v.TaskId = taskId
        }
        items, _ := models.GetTaskByIds(v.TaskId)
        temp.TaskNames = items
        //任务名称重新赋值
        var result string
        if len(taskId) > 0 && len(items) > 0 {
            v.EventLevelId = []int64{}
            for index, item := range items {
                v.EventLevelId = append(v.EventLevelId, item.EventLevel)
                if index > 0 {
                    result += ","
                }
                result += item.TaskName
            }
            temp.TaskName = result
        }
        //视频内容
        // items4, _ := models.GetVideoById(v.VideoPointId)
@@ -1192,6 +1246,18 @@
        items5, _ := models.GetEventByIds(v.EventLevelId)
        temp.EventLevels = items5
        //事件等级重新赋值
        var result2 string
        if len(taskId) > 0 && len(items5) > 0 {
            for i, item5 := range items5 {
                if i > 0 {
                    result2 += ","
                }
                result2 += item5.DictValue
            }
            temp.EventLevelName = result2
        }
        //知识库
        items6, _ := models.GetKnowledgeDocumentByIds(v.KnowledgeId)
        // 知识库路径
camera-service/main.go
@@ -132,6 +132,8 @@
    funcMap[urlPrefix+"/camera/getRecord"] = cc.GetRecord
    //获取任务根据摄像机ids
    funcMap[urlPrefix+"/camera/getTasks"] = cc.GetTasks
    //删除记录
    funcMap[urlPrefix+"/clearData/deleteData"] = cc.DelRecord
    funcMap[urlPrefix+"/task/aggregateTaskList"] = cc.GetAllTasks
system-service/controllers/voice.go
@@ -1,12 +1,13 @@
package controllers
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/bhomeclient.git"
    "encoding/json"
    "github.com/satori/go.uuid"
    "vamicro/system-service/models"
    "vamicro/system-service/service"
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/bhomeclient.git"
    uuid "github.com/satori/go.uuid"
)
type VoiceController struct{}
system-service/main.go
@@ -230,8 +230,8 @@
    funcMap[urlPrefix+"/test/addServer"] = testController.AddServer
    funcMap[urlPrefix+"/test/exitServer"] = testController.ExitServer
    deleteDataController := new(controllers.DeleteDataController)
    funcMap[urlPrefix+"/clearData/deleteData"] = deleteDataController.DeleteEsData
    // deleteDataController := new(controllers.DeleteDataController)
    // funcMap[urlPrefix+"/clearData/deleteData"] = deleteDataController.DeleteEsData
    var dac controllers.DevAuthController
    funcMap[urlPrefix+"/devAuth/authConfig"] = dac.AuthConfig
system-service/sys/sysinfo.go
@@ -12,7 +12,7 @@
    "vamicro/extend/util"
    "basic.com/valib/gogpu.git"
    "basic.com/valib/logger.git"
    "github.com/shirou/gopsutil/cpu"
    "github.com/shirou/gopsutil/disk"
    "github.com/shirou/gopsutil/host"
@@ -85,11 +85,22 @@
    cmd := exec.Command("/bin/sh", "-c", "lsblk -d | grep -v part | grep -v SWAP | grep -v M | grep disk | awk '{printf $4\" \"}'")
    disks, _ := cmd.Output()
    cpu, _ := cpu.Info()
    gpuInfo, err := gogpu.Info()
    var gpuMemTotal int64
    if err == nil {
        for _, gpu := range gpuInfo.Info {
            gpuMemTotal = gpuMemTotal + gpu.GpuMemoryTotal
        }
    } else {
        logger.Debug("gpu error " + err.Error())
    }
    gpu := gpuMemTotal
    mem, _ := mem.VirtualMemory()
    host, _ := host.Info()
    return util.Struct2Map(map[string]interface{}{
        "cpu":  cpu,
        "gpu":  gpu,
        "mem":  mem,
        "host": host,
        "disk": string(disks),
version-control/controller/controller.go
@@ -591,6 +591,16 @@
    auth := util.GetAuthorization()
    data["expireTime"] = ""
    if len(auth) == 0 {
        data["sn"] = ""
        data["authorization"] = ""
        data["expire"] = false
        data["edition"] = "trial"
        data["installTime"] = ""
        data["q"] = ""
        return data
    }
    authInfo, err := util.GetAuthorizationInfo(auth)
    //logger.Debug("授权信息:", authInfo, err, licence.GetMachineCode())
    if err == nil && authInfo.MachineCode == licence.GetMachineCode() {
version-control/main.go
@@ -17,7 +17,7 @@
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "basic.com/valib/version.git"
    vaversion "basic.com/valib/version.git"
)
var (
@@ -57,7 +57,7 @@
    err = syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
    if err != nil {
        fmt.Println("report service is running ")
        fmt.Println("version-control is running ")
        os.Exit(1)
    }
version-control/service/backup.go
@@ -14,14 +14,15 @@
)
/*
    系统备份、备份还原、按设置周期性备份
    备份的数据主要包括sqlite数据、config以及exe(按需要)
    按钮可以触发立即备份
    参数:
        1.备份开关
        2.备份目录文件夹(/opt/vasystem/backup_auto)
        3.备份周期(每7天备份一次,备份时间是夜间0点)
        4.备份数据保存时间
系统备份、备份还原、按设置周期性备份
备份的数据主要包括sqlite数据、config以及exe(按需要)
按钮可以触发立即备份
参数:
    1.备份开关
    2.备份目录文件夹(/opt/vasystem/backup_auto)
    3.备份周期(每7天备份一次,备份时间是夜间0点)
    4.备份数据保存时间
*/
func BakSchedule(ctx context.Context) {
    // tk := time.NewTicker(time.Minute)
@@ -37,7 +38,7 @@
    }
}
//自动清理大于保存时间的备份数据
// 自动清理大于保存时间的备份数据
func removeCheck() {
    var ab models.AutoBackupConf
    i, e := ab.Select()
@@ -144,9 +145,12 @@
    os.Mkdir(recoverBakDir, os.ModePerm)
    util.CopyDirByCmd("/opt/vasystem/config", recoverBakDir)
    // _, err := exec.Command("/bin/sh", "-c", fmt.Sprintf(`
    //     /opt/vasystem/killAllProcs.sh &&
    //     cp -rf %s/* /opt/vasystem/config/ &&
    //     /opt/vasystem/daemon.sh`, dir)).Output()
    _, err := exec.Command("/bin/sh", "-c", fmt.Sprintf(`
        /opt/vasystem/procs/killAllProcs.sh &&
        cp -rf %s/* /opt/vasystem/config/ &&
        /opt/vasystem/daemon.sh`, dir)).Output()
    cp -rf %s/* /opt/vasystem/ &&
    /opt/vasystem/daemon.sh`, dir)).Output()
    return err
}