挂载smb
package main
import (
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"os/exec"
"strconv"
"time"
"gopkg.in/ini.v1"
)
func floattostr(input_num float64)
string
{
// to convert a float number to a string
return
strconv.FormatFloat(input_num,
'g'
, -1, 64)
}
func getTime()
string
{
// 得到unix时间戳
t := time.Now()
timestamp := t.Unix()
// 时间戳转时间格式字符串
tm := time.Unix(timestamp, 0)
s_tm := tm.Format(
"2006-01-02 15:04:05"
)
return
s_tm
}
func writeip(s
string
) {
//创建一个新文件,写入内容
filePath :=
"./ip.log"
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if
err != nil {
fmt.Printf(
"打开文件错误= %v \n"
, err)
return
}
//及时关闭
defer file.Close()
//写入内容
ip := getTime() +
" "
+ s +
"\n"
// \n\r表示换行 txt文件要看到换行效果要用 \r\n
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
writer.WriteString(ip)
//因为 writer 是带缓存的,因此在调用 WriterString 方法时,内容是先写入缓存的
//所以要调用 flush方法,将缓存的数据真正写入到文件中。
writer.Flush()
}
func getIpInfo()
string
{
var vmidIpAddr
string
var ipArr [6]
string
var innerIp =
""
var outIp =
""
addrs, err := net.InterfaceAddrs()
if
err != nil {
fmt.Println(err)
os.Exit(1)
}
j := 0
for
_, address := range addrs {
// 检查ip地址判断是否回环地址
if
ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if
ipnet.IP.To4() != nil {
fmt.Println(ipnet.IP.String())
ipArr[j] = ipnet.IP.String()
fmt.Println(j)
j++
}
}
}
innerIp = ipArr[0]
outIp = ipArr[1]
fmt.Println(innerIp)
fmt.Println(outIp)
vmidIpAddr =
"inner_ip="
+ innerIp +
"&outer_ip="
+ outIp
writeip(vmidIpAddr)
vmidIpAddr =
"inner_ip=192.168.10.146&outer_ip=192.168.10.146"
return
vmidIpAddr
}
func main() {
var CacherIp =
""
var vmid =
""
var smb_user =
""
var smb_password =
""
var ipInfo =
""
cfg, err := ini.Load(
"cloudgame_mount.ini"
)
if
err != nil {
fmt.Printf(
"Fail to read file: %v"
, err)
os.Exit(1)
}
// 典型读取操作,默认分区可以使用空字符串表示
CacherIp = cfg.Section(
""
).Key(
"CacherIp"
).String()
// vmid = cfg.Section("").Key("vmid").String()
smb_user = cfg.Section(
""
).Key(
"smb_user"
).String()
smb_password = cfg.Section(
""
).Key(
"smb_password"
).String()
//获取本地IP
ipInfo = getIpInfo()
//获取vmid
//resp, err := http.Get("http://192.168.10.182:8082/cloud_games_shelves_api/v1/getvmid?inner_ip=192.168.10.146&outer_ip=192.168.10.146")
if
err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var vminfo map[
string
]
interface
{}
err1 := json.Unmarshal([]
byte
(
string
(body)), &vminfo)
if
err1 != nil {
fmt.Println(err1)
}
vmid = floattostr(vminfo[
"vmid"
].(float64))
//挂载磁盘
mountstr :=
"net use w: \\\\"
+ CacherIp +
"\\area_vm_data_"
+ vmid +
" "
+ smb_password +
" "
+
"/user:"
+ smb_user
fmt.Println(mountstr)
c := exec.Command(
"cmd"
,
"/C"
, mountstr)
if
err := c.Start(); err != nil {
fmt.Println(
"Error: "
, err)
}
}
------------------
package service
import (
"errors"
"fmt"
"time"
"gitlab.itvgame.org/storage-worker/errno"
"gitlab.itvgame.org/storage-worker/global"
"gitlab.itvgame.org/storage-worker/model"
"gitlab.itvgame.org/storage-worker/utils"
)
func GetCreateGameSymbolicLinkResponseData(req *model.CreateGameSymbolicLinkRquest) *model.CreateSymbolicLinkResponse {
resp := model.CreateSymbolicLinkResponse{
Code: 0,
Message: "",
Data: model.SData{
UserID: req.UserID,
GameID: req.GameID,
VMID: req.VMID,
UserGameSaveSymbolicLink: GetUserGameSaveSymLinkPath(req.VMID),
UserGameSymbolicLink: GetVMGameSymLinkPath(req.VMID),
},
}
return &resp
}
func CreateGameSymbolicLink(req *model.CreateGameSymbolicLinkRquest) (errCode errno.Error, err error) {
if *req.GameVersion == 0 {
// 1. 如果游戏版本号为0,则直接返回游戏不存在
err = errors.New("game version is 0")
global.Zap.Error(err.Error())
return errno.ErrGameVersionIsZero, err
}
// 3. 获取游戏根目录
// 4. 判断游戏根目录是否存在
// 4.1 不存在则直接返回错误
rootGameDir := GetRootGameDirFullPath(req.GameID, *req.GameVersion)
isExist, err := utils.IsDirExist(rootGameDir)
// TODO 多加几个判断
if !isExist {
// 1. 如果存在这个目录直接略过就好了
// 2. 不存在目录,则直接返回游戏不存在
err := errors.New(fmt.Sprintf("check [%s] is not exist,err: %v", rootGameDir, err))
global.Zap.Error(err.Error())
return errno.ErrGameIsNotExist, err
}
// 5. 判断根用户游戏存档目录是否存在
userGameSaveDirFullPath := GetUserGameSaveDir(req.UserID)
isExist, err = utils.IsDirExist(userGameSaveDirFullPath)
if !isExist {
isSuccess := utils.CreateSnapShotUserDir(req.UserID)
if !isSuccess {
err = errors.New(fmt.Sprintf("create root user game save snapshot failed,err: %v", err))
global.Zap.Error(err.Error())
return errno.ErrCreateRootUserGameSaveSnapshot, err
}
}
// 5.0 获取222游戏存档目录
// 如果传入的存档路径为空,则表示该游戏存档是与游戏本体在一起的
if req.GameSavePath != "" {
rootUserGameSaveDir := GetRootUserGameSavePath(1, req.GameSavePath)
isExist, err = utils.IsDirExist(rootUserGameSaveDir)
if !isExist {
err = errors.New(fmt.Sprintf("root user game save [%s] is not exist: %v", rootUserGameSaveDir, err))
global.Zap.Error(err.Error())
return errno.ErrRootGameSaveIsNotExist, err
}
userGameSaveDir := GetUserGameSavePath(req.UserID, req.GameSavePath)
// 5.1 检查用户222游戏存档目录222_1/WWZ 是否存在
isExist, err = utils.IsDirExist(userGameSaveDir)
if !isExist {
isSuccess := utils.CreateSnapShotDir(rootUserGameSaveDir, userGameSaveDir)
if !isSuccess {
err := errors.New(fmt.Sprintf("create snapshot dir fail"))
global.Zap.Error(err.Error())
return errno.ErrCreateUserGameSaveSnapshot, err
}
utils.ChownDirOwner(userGameSaveDir)
}
// 5.2 判断该目录是否是btrfs subvoume
isBtrfs := utils.IsBtrfsDir(userGameSaveDir)
if !isBtrfs {
// 5.2.1 删除 ${uid}_1/${game_name}
err = utils.DeleteDir(userGameSaveDir)
if err != nil {
return errno.ErrDeleteDir, err
}
// 5.2.2 然后执行btrfs subvolume snapshot /snapshot/area_user_game/1_1/${game_name} /snapshot/area_user_game/${uid}_1/${game_name}
isSuccess := utils.CreateSnapShotDir(rootUserGameSaveDir, userGameSaveDir)
if !isSuccess {
return errno.ErrCreateUserGameSaveOperation, err
}
utils.ChownDirOwner(userGameSaveDir)
}
}
// 6. 判断用户游戏目录是否存在
// 6.1 不存在则创建
// 6.2 创建失败则返回错误
userGameDir := GetUserGameDirFullPath(req.UserID, req.GameID, *req.GameVersion)
isExist, err = utils.IsDirExist(userGameDir)
if !isExist {
// 1. 如果存在这个目录直接略过就好了
// 2. 不存在目录,说明用户是第一次启动该游戏,则需要创建游戏目录
isSuccess := utils.CreateSnapShotDir(rootGameDir, userGameDir)
if !isSuccess {
global.Zap.Warn(fmt.Sprintf("create snapshot [%s] failed", userGameDir))
return errno.ErrCreateGameSnapShot, err
}
}
// 7. 获取虚拟机游戏软连接目录
VMGameSymLink := GetVMGameSymLinkPath(req.VMID)
isExist, err = utils.IsDirExist(VMGameSymLink)
// 8. 判断虚拟机游戏软连接是否存在
// 8.1 存在则直接返回错误
if isExist {
err = errors.New(fmt.Sprintf("check [%s] is exist, err: %v", VMGameSymLink, err))
global.Zap.Error(err.Error())
return errno.ErrVMGameSymLinkIsExist, err
}
// 8.2 不存在则创建
// 8.3 创建失败则返回错误
isSuccess := utils.CreateSymbolicLink(userGameDir, VMGameSymLink)
if !isSuccess {
return errno.ErrCreateVMGameSymLink, err
}
// 9. 获取用户游戏存档软连接目录
userGameSaveSymLink := GetUserGameSaveSymLinkPath(req.VMID)
// 10. 判断用户游戏存档软连接目录是否存在
isExist, err = utils.IsDirExist(userGameSaveSymLink)
// 10.1 存在则直接返回错误
if isExist {
err = errors.New(fmt.Sprintf("check [%s] is exist,err: %v", userGameSaveSymLink, err))
global.Zap.Error(err.Error())
return errno.ErrUserGameSaveExist, err
}
// 10.2 不存在则创建
// isSuccess = utils.CreateSymbolicLink(userGameSaveDir, userGameSaveSymLink)
// /snapshot/area_user_data/59314/80_1/
// delete userGameSaveDirForGameVersion := GetUserGameSavePathForGameVersion(req.UserID, req.GameSavePath)
userGameSavePathForUID := GetUserGameSavePathForUID(req.UserID)
isSuccess = utils.CreateSymbolicLink(userGameSavePathForUID, userGameSaveSymLink)
if !isSuccess {
return errno.ErrCreateVMUserGameSaveSymLink, err
}
time.Sleep(66 * time.Millisecond)
return errno.OK, err
}
------
age service
import (
"errors"
"fmt"
"gitlab.itvgame.org/storage-worker/errno"
"gitlab.itvgame.org/storage-worker/global"
"gitlab.itvgame.org/storage-worker/model"
"gitlab.itvgame.org/storage-worker/utils"
)
// DeleteGameSymbolicLink 删除游戏、游戏存档软连接
func DeleteGameSymbolicLink(req *model.CreateGameSymbolicLinkRquest) (errCode errno.Error, err error) {
// 3. 判断虚拟机游戏软连接目录是否存在
VMGameSymLinkDir := GetVMGameSymLinkPath(req.VMID)
isExist, err := utils.IsDirExist(VMGameSymLinkDir)
// TODO 多加几个判断,比如 if err != nil; if isExist{};
if !isExist && err == nil {
err = errors.New(fmt.Sprintf("%s is not exist", VMGameSymLinkDir))
global.Zap.Error(err.Error())
return errno.ErrVMGameSymLinkIsNotExist, err
}
// 4. 判断虚拟机内用户游戏存档目录是否存在
userGameSaveSymLinkDir := GetUserGameSaveSymLinkPath(req.VMID)
isExist, err = utils.IsDirExist(userGameSaveSymLinkDir)
if !isExist {
global.Zap.Error(err.Error())
return errno.ErrVMUserSymLinkIsNotExist, err
}
// 5. 删除软连接
err = utils.DeleteSymbolicLink(VMGameSymLinkDir)
if err != nil {
global.Zap.Error(err.Error())
return errno.ErrDeleteGameSymbolicLink, err
}
err = utils.DeleteSymbolicLink(userGameSaveSymLinkDir)
if err != nil {
global.Zap.Error(err.Error())
return errno.ErrDeleteGameSaveSymBolicLink, err
}
return errno.OK, err
}
分类:
linux
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
2022-03-29 go的gin跨域中间件
2022-03-29 go判断结构体的零值
2022-03-29 go的nil值/零值/空值
2022-03-29 Linux 丢包那些事
2022-03-29 linux查看网络丢包情况 mtr网络连通性判断工具
2022-03-29 Telegraf+Influxdb+Grafana
2021-03-29 Shell中 |和||,&和&&用法