Compare commits

...

45 Commits

Author SHA1 Message Date
link
a5fee0ee97 New App Store
Add App Store for installation
Fix favicon display in dark mode
2021-11-03 17:07:46 +08:00
link
cad7af13af Update UI 2021-10-29 19:35:51 +08:00
link
2ed372b3cd Update system.go 2021-10-29 18:39:07 +08:00
link
8bca76b78b Add new features
add casaOS logs
add application  terminal
add application  logs
2021-10-29 18:37:27 +08:00
link
4939fe10aa update disk display
add casaos logs api
update ui
2021-10-27 19:03:59 +08:00
link
d7d53d639b Add some features
Add terminal
Improve single user management function
2021-10-27 17:27:46 +08:00
link
7191735737 update UI 2021-10-22 18:28:00 +08:00
link
ba77e07e36 update initialization config
initialization user config
2021-10-22 17:57:22 +08:00
link
b1d5d9858b update route.go 2021-10-22 17:19:07 +08:00
link
812ffd56a8 update webui 2021-10-22 17:09:43 +08:00
link
5cdd842a3e remove build file
remove main
remove CasaOS
2021-10-22 16:54:17 +08:00
link
b3aa22605d Add authentication
Add user authentication module, Login page and initialization page.
Fixed the problem that the application could not start after the system restarted.
2021-10-22 16:49:09 +08:00
link
39ccbe251f Optimize installation process
auto create file or dir
2021-10-19 19:07:16 +08:00
link
8a28d3c589 update create file and dir api 2021-10-18 18:24:18 +08:00
link
fb15695dab add widget
Add CPU RAM Status
Add Disk Info
2021-10-15 11:43:41 +08:00
老竭力
5f5091f1e2 🦄 refactor: Change build method
Change build method
add static.go to public folder
2021-09-30 18:52:03 +08:00
a624669980
df92766c74 Catalog Adjustment 2021-09-30 18:45:01 +08:00
a624669980
cc8b3e8f06 Modify gitgnore 2021-09-30 18:42:29 +08:00
John Guan
a116db8dbd Update .gitignore 2021-09-30 18:40:16 +08:00
a624669980
d697547cb7 Modify default config 2021-09-30 17:55:59 +08:00
a624669980
01960c0391 Modify default config 2021-09-30 17:54:29 +08:00
a624669980
953c393e71 Modify default config 2021-09-30 17:53:26 +08:00
a624669980
0873f7dd46 Modify the publishing process 2021-09-30 17:00:55 +08:00
a624669980
8d93a7f320 Modify the publishing process 2021-09-30 16:57:10 +08:00
a624669980
801eca0a14 Modify the publishing process 2021-09-30 16:56:03 +08:00
a624669980
a3ec7b70c9 Modify the publishing process 2021-09-30 16:55:00 +08:00
a624669980
4a77548b23 Modify the publishing process 2021-09-30 16:51:20 +08:00
a624669980
15ccade3d3 Modify the publishing process 2021-09-30 16:42:00 +08:00
a624669980
587fb6fb8a Modify the publishing process 2021-09-30 16:29:32 +08:00
a624669980
5bcb663ac8 Modify the publishing process 2021-09-30 16:26:36 +08:00
a624669980
cbd945536d Modify the publishing process 2021-09-30 16:14:09 +08:00
a624669980
081e9213c2 Modify the publishing process 2021-09-30 16:13:14 +08:00
a624669980
966fae2d4c Modify the publishing process 2021-09-30 16:12:45 +08:00
a624669980
dc4f9ea990 Modify the publishing process 2021-09-30 16:06:56 +08:00
a624669980
05b9c75714 Modify the publishing process 2021-09-30 15:55:02 +08:00
a624669980
4aeeea2325 Modify the publishing process 2021-09-30 15:52:56 +08:00
a624669980
72531cf6c2 Modify the publishing process 2021-09-30 15:45:09 +08:00
a624669980
9ad9be8c61 Modify the publishing process 2021-09-30 15:34:02 +08:00
a624669980
1aa15932a0 Modify the publishing process 2021-09-30 15:24:18 +08:00
a624669980
dbc6a4265a Modify the publishing process 2021-09-30 15:22:05 +08:00
a624669980
edea1f144a Modify the publishing process 2021-09-30 15:10:41 +08:00
a624669980
85c59c03cf Modify the publishing process 2021-09-30 14:52:32 +08:00
a624669980
a1f57bf1d1 Modify the publishing version 2021-09-30 14:45:33 +08:00
a624669980
e6f2c46c28 Modify the publishing process 2021-09-30 14:43:45 +08:00
a624669980
55c6c21aa3 Ignore profile 2021-09-29 19:51:40 +08:00
80 changed files with 9492 additions and 7966 deletions

View File

@@ -3,10 +3,20 @@
name: Build CasaOS name: Build CasaOS
on: on:
release: repository_dispatch:
types: workflow_dispatch:
- created inputs:
ssh:
description: 'SSH connection to Actions'
required: false
default: 'false'
#on:
# push:
# branches:
# - 'main'
# tags:
# - 'v*'
env: env:
REPO_URL: https://github.com/IceWhaleTech/CasaOS.git REPO_URL: https://github.com/IceWhaleTech/CasaOS.git
REPO_BRANCH: main REPO_BRANCH: main
@@ -23,80 +33,116 @@ jobs:
- 1.17.1 - 1.17.1
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Get release # - name: Get release
id: get_release # id: get_release
uses: bruceadams/get-release@v1.2.3 # uses: bruceadams/get-release@v1.2.3
env: # env:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN: ${{ github.token }}
- name: Initialization environment - uses: actions/checkout@v2
env: with:
DEBIAN_FRONTEND: noninteractive fetch-depth: 0
submodules: true
# - name: Initialization environment
# env:
# DEBIAN_FRONTEND: noninteractive
# run: |
# sudo timedatectl set-timezone "$TZ"
# sudo mkdir -p /workdir
# sudo chown $USER:$GROUPS /workdir
# - name: Clone source code
# working-directory: /workdir
# run: |
# df -hT $PWD
# git clone $REPO_URL -b $REPO_BRANCH --recursive casa
# ln -sf /workdir/casa $GITHUB_WORKSPACE/casa
# ls
- name: Set enviroment for github-release
run: | run: |
sudo timedatectl set-timezone "$TZ" echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
sudo mkdir -p /workdir echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
sudo chown $USER:$GROUPS /workdir
- name: Clone source code
working-directory: /workdir
run: |
df -hT $PWD
git clone $REPO_URL -b $REPO_BRANCH --recursive casa
ln -sf /workdir/casa $GITHUB_WORKSPACE/casa
ls
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: '14' node-version: '14'
- name: Build frontend with nodejs and yarn - name: Build frontend with nodejs and yarn
run: | run: |
cd casa/UI cd UI
ls ls
yarn install yarn install
yarn build yarn build
- name: list work
run: pwd
- name: Build with xgo - name: Build with xgo
uses: crazy-max/ghaction-xgo@v1 uses: crazy-max/ghaction-xgo@v1
with: with:
working_dir: /workdir/casa
xgo_version: latest xgo_version: latest
go_version: ${{ matrix.go_version }} go_version: ${{ matrix.go_version }}
dest: build dest: build
prefix: casa prefix: casa
targets: linux/amd64,linux/arm64 targets: linux/amd64,linux/arm64,linux/arm-7
v: true v: true
x: false x: false
race: false race: false
ldflags: -s -w ldflags: -s -w
buildmode: default buildmode: default
#
- name: List Files # - name: List Files
run: | # run: |
ls # ls
cd casa/build # mkdir build
ls # ls
echo "::set-output name=status::success" # echo "::set-output name=status::success"
- name: Pack builds - name: Pack builds
run: | run: |
cd /workdir
wget $PACK_SH_URL wget $PACK_SH_URL
chmod +x $PACK_SH chmod +x $PACK_SH
./$PACK_SH ./$PACK_SH
echo "::set-output name=status::success" echo "::set-output name=status::success"
- name: list work
- name: Upload linux-amd64-casaos.tar.gz run: ls
id: upload_assets_amd64
uses: shogo82148/actions-upload-release-asset@v1
- name: Update release
uses: meeDamian/github-release@2.0
with: with:
upload_url: ${{ steps.get_release.outputs.upload_url }} token: ${{ secrets.GITHUB_TOKEN }}
asset_path: /workdir/casa/upload/linux-amd64-casaos.tar.gz files: >
linux-amd64-casaos.tar.gz
- name: Upload linux-arm64-casaos.tar.gz linux-arm64-casaos.tar.gz
id: upload_assets_arm64 linux-arm-7-casaos.tar.gz
uses: shogo82148/actions-upload-release-asset@v1 tag: v${{ env.VERSION }}
with: body: >
upload_url: ${{ steps.get_release.outputs.upload_url }} ${{ env.BODY }}
asset_path: /workdir/casa/upload/linux-arm64-casaos.tar.gz name: v${{ env.VERSION }}
gzip: false
allow_override: false
prerelease: true
# - name: Upload linux-amd64-casaos.tar.gz
# id: upload_assets_amd64
# uses: shogo82148/actions-upload-release-asset@v1
# with:
# upload_url: ${{ steps.get_release.outputs.upload_url }}
# asset_path: /workdir/casa/upload/linux-amd64-casaos.tar.gz
#
# - name: Upload linux-arm64-casaos.tar.gz
# id: upload_assets_arm64
# uses: shogo82148/actions-upload-release-asset@v1
# with:
# upload_url: ${{ steps.get_release.outputs.upload_url }}
# asset_path: /workdir/casa/upload/linux-arm64-casaos.tar.gz

5
.gitignore vendored
View File

@@ -20,6 +20,7 @@
# IntelliJ project files # IntelliJ project files
.idea .idea
.vscode
*.iml *.iml
out out
gen gen
@@ -28,3 +29,7 @@ gen
/out/ /out/
/db/ /db/
/docs/ /docs/
/conf/conf.ini
__debug_bin
main
CasaOS

2
UI

Submodule UI updated: 1f2ebd05fa...4fe7dc7756

View File

@@ -4,7 +4,6 @@ RuntimeRootPath = runtime/
LogSavePath = /casaOS/logs/server/ LogSavePath = /casaOS/logs/server/
LogSaveName = log LogSaveName = log
LogFileExt = log LogFileExt = log
; 必须的格式
DateStrFormat = 20060102 DateStrFormat = 20060102
DateTimeFormat = 2006-01-02 15:04:05 DateTimeFormat = 2006-01-02 15:04:05
TimeFormat = 15:04:05 TimeFormat = 15:04:05
@@ -20,27 +19,24 @@ ServerApi = https://api.casaos.zimaboard.com
[user] [user]
UserName = admin UserName = admin
PWD = zimaboard PWD = zimaboard
Email = aaa@222.ddd Email = user@gmail.com
Description = ddddddd Description = description
Initialized = false
Token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVyZXJlIiwicGFzc3dvcmQiOiJhZHNmZGYiLCJleHAiOjE2MjQwMDU0ODEsImlzcyI6Imdpbi1ibG9nIn0.JNsCccZuFCwlSMLJg62iOIB2xymk_k7xGa11xhZ07bc Token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVyZXJlIiwicGFzc3dvcmQiOiJhZHNmZGYiLCJleHAiOjE2MjQwMDU0ODEsImlzcyI6Imdpbi1ibG9nIn0.JNsCccZuFCwlSMLJg62iOIB2xymk_k7xGa11xhZ07bc
[zerotier] [zerotier]
UserName = ddddd UserName = user
PWD = PWD = pwd
Token = yBKYyavr2RdFAIVN7iTpzlsB1o6CqTgm Token = yBKYyavr2RdFAIVN7iTpzlsB1o6CqTgm
[redis] [redis]
Host = 192.168.2.167:6379 Host = 127.0.0.1:6379
Password = Password =
MaxIdle = 30 MaxIdle = 30
MaxActive = 30 MaxActive = 30
IdleTimeout = 200 IdleTimeout = 200
[system] [system]
AutoUpdate = true ConfigStr =
SearchSwitch = true WidgetList =
WidgetsSwitch = false
ShortcutsSwitch = true
SearchEngine = baidu
Background = http://google.com
BackgroundType = d

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

20
go.mod
View File

@@ -7,9 +7,8 @@ require (
github.com/Microsoft/hcsshim v0.8.22 // indirect github.com/Microsoft/hcsshim v0.8.22 // indirect
github.com/PuerkitoBio/goquery v1.7.0 github.com/PuerkitoBio/goquery v1.7.0
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/bits-and-blooms/bitset v1.2.1 // indirect github.com/bits-and-blooms/bitset v1.2.1 // indirect
github.com/containerd/containerd v1.5.5 github.com/containerd/containerd v1.5.7
github.com/containerd/continuity v0.2.0 // indirect github.com/containerd/continuity v0.2.0 // indirect
github.com/docker/docker v20.10.7+incompatible github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
@@ -18,9 +17,7 @@ require (
github.com/gin-gonic/gin v1.7.2 github.com/gin-gonic/gin v1.7.2
github.com/go-ini/ini v1.62.0 github.com/go-ini/ini v1.62.0
github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/spec v0.20.3 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-playground/validator/v10 v10.6.1 // indirect github.com/go-playground/validator/v10 v10.6.1 // indirect
github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/googleapis v1.4.1 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
@@ -35,11 +32,11 @@ require (
github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/compress v1.13.6 // indirect
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/runc v1.0.2 // indirect
github.com/opencontainers/selinux v1.8.5 // indirect github.com/opencontainers/selinux v1.8.5 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109
github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/procfs v0.7.3 // indirect
@@ -50,7 +47,7 @@ require (
github.com/smartystreets/assertions v1.2.0 // indirect github.com/smartystreets/assertions v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.0 github.com/swaggo/swag v1.7.3
github.com/tidwall/gjson v1.8.0 github.com/tidwall/gjson v1.8.0
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.6 // indirect github.com/tklauser/go-sysconf v0.3.6 // indirect
@@ -58,13 +55,12 @@ require (
go.opencensus.io v0.23.0 // indirect go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/mod v0.5.0 // indirect golang.org/x/mod v0.5.0 // indirect
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167 // indirect golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
golang.org/x/sys v0.0.0-20210927052749-1cf2251ac284 // indirect golang.org/x/sys v0.0.0-20211020174200-9d6173849985 // indirect
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/tools v0.1.5 // indirect golang.org/x/tools v0.1.7 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 // indirect google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 // indirect
google.golang.org/grpc v1.41.0 // indirect google.golang.org/grpc v1.41.0 // indirect

46
go.sum
View File

@@ -68,7 +68,7 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.22 h1:CulZ3GW8sNJExknToo+RWD+U+6ZM5kkNfuxywSDPd08= github.com/Microsoft/hcsshim v0.8.22 h1:CulZ3GW8sNJExknToo+RWD+U+6ZM5kkNfuxywSDPd08=
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0= github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
@@ -168,8 +168,8 @@ github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.5 h1:q1gxsZsGZ8ddVe98yO6pR21b5xQSMiR61lD0W96pgQo= github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM=
github.com/containerd/containerd v1.5.5/go.mod h1:oSTh0QpT1w6jYcGmbiSbxv9OSQYaa88mPyWIuU79zyo= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@@ -335,19 +335,17 @@ github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA=
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
@@ -367,6 +365,7 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
@@ -484,6 +483,7 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w= github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
@@ -547,8 +547,8 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
@@ -613,7 +613,6 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@@ -629,6 +628,8 @@ github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.8.5 h1:OkT6bMHOQ1JQQO4ihjQ49sj0+wciDcjziSVTRn8VeTA= github.com/opencontainers/selinux v1.8.5 h1:OkT6bMHOQ1JQQO4ihjQ49sj0+wciDcjziSVTRn8VeTA=
github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo= github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
@@ -685,6 +686,7 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/shirou/gopsutil/v3 v3.21.5 h1:YUBf0w/KPLk7w1803AYBnH7BmA+1Z/Q5MEZxpREUaB4= github.com/shirou/gopsutil/v3 v3.21.5 h1:YUBf0w/KPLk7w1803AYBnH7BmA+1Z/Q5MEZxpREUaB4=
github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
@@ -733,8 +735,8 @@ github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuI
github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI=
github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0=
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= github.com/swaggo/swag v1.7.3 h1:ucB7irEdRrhjmW+Z1Ss4GjO68oPKQFjSgOR8BCAvcbU=
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= github.com/swaggo/swag v1.7.3/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@@ -787,7 +789,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
@@ -903,8 +905,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167 h1:eDd+TJqbgfXruGQ5sJRU7tEtp/58OAx4+Ayjxg4SM+4= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -991,6 +994,7 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1002,8 +1006,10 @@ golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927052749-1cf2251ac284 h1:lBPNCmq8u4zFP3huKCmUQ2Fx8kcY4X+O12UgGnyKsrg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927052749-1cf2251ac284/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211020174200-9d6173849985 h1:LOlKVhfDyahgmqa97awczplwkjzNaELFg3zRIJ13RYo=
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1072,10 +1078,10 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

27
main.go
View File

@@ -3,47 +3,58 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"net/http"
"time"
"github.com/IceWhaleTech/CasaOS/pkg/cache"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/sqlite" "github.com/IceWhaleTech/CasaOS/pkg/sqlite"
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/IceWhaleTech/CasaOS/route" "github.com/IceWhaleTech/CasaOS/route"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
"github.com/robfig/cron" "github.com/robfig/cron"
"gorm.io/gorm" "gorm.io/gorm"
"net/http"
"time"
) )
var sqliteDB *gorm.DB var sqliteDB *gorm.DB
var swagHandler gin.HandlerFunc
var configFlag = flag.String("c", "", "config address") var configFlag = flag.String("c", "", "config address")
var showUserInfo = flag.Bool("show-user-info", false, "show user info")
func init() { func init() {
flag.Parse() flag.Parse()
config.InitSetup(*configFlag) config.InitSetup(*configFlag)
config.UpdateSetup()
loger2.LogSetup() loger2.LogSetup()
sqliteDB = sqlite.GetDb(config.AppInfo.ProjectPath) sqliteDB = sqlite.GetDb(config.AppInfo.ProjectPath)
//gredis.GetRedisConn(config.RedisInfo), //gredis.GetRedisConn(config.RedisInfo),
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger()) service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
service.Cache = cache.Init()
} }
// @title Oasis API // @title casaOS API
// @version 1.0.0 // @version 1.0.0
// @contact.name lauren.pan // @contact.name lauren.pan
// @contact.url https://www.zimaboard.com // @contact.url https://www.zimaboard.com
// @contact.email lauren.pan@icewhale.org // @contact.email lauren.pan@icewhale.org
// @description Oasis v1版本api // @description casaOS v1版本api
// @host 192.168.2.114:8089 // @host 192.168.2.217:8089
// @securityDefinitions.apikey ApiKeyAuth // @securityDefinitions.apikey ApiKeyAuth
// @in header // @in header
// @name Authorization // @name Authorization
// @BasePath /v1 // @BasePath /v1
func main() { func main() {
if *showUserInfo {
fmt.Println("CasaOS User Info")
fmt.Println("UserName:" + config.UserInfo.UserName)
fmt.Println("Password:" + config.UserInfo.PWD)
return
}
//model.Setup() //model.Setup()
//gredis.Setup() //gredis.Setup()
r := route.InitRouter(swagHandler) r := route.InitRouter()
//service.SyncTask(sqliteDB) //service.SyncTask(sqliteDB)
cron2 := cron.New() //创建一个cron实例 cron2 := cron.New() //创建一个cron实例
//执行定时任务每5秒执行一次 //执行定时任务每5秒执行一次

View File

@@ -7,32 +7,35 @@ import (
) )
type ServerAppList struct { type ServerAppList struct {
Id uint `gorm:"column:id;primary_key" json:"id"` Id uint `gorm:"column:id;primary_key" json:"id"`
Title string `json:"title"` Title string `json:"title"`
Description string `json:"description"` Description string `json:"description"`
Tagline string `json:"tagline"` Tagline string `json:"tagline"`
Tags Strings `gorm:"type:json" json:"tags"` Tags Strings `gorm:"type:json" json:"tags"`
Icon string `json:"icon"` Icon string `json:"icon"`
ScreenshotLink Strings `gorm:"type:json" json:"screenshot_link"` ScreenshotLink Strings `gorm:"type:json" json:"screenshot_link"`
Category string `json:"category"` Category string `json:"category"`
TcpPort uint `json:"tcp_port"` PortMap string `json:"port_map"`
PortMap uint `json:"port_map"` ImageVersion string `json:"image_version"`
ImageVersion string `json:"image_version"` Tip string `json:"tip"`
Tip string `json:"tip"` Envs EnvArray `json:"envs"`
Configures configures `gorm:"type:json" json:"configures"` Ports PortArray `json:"ports"`
NetworkModel string `json:"network_mode"` Volumes PathArray `json:"volumes"`
Image string `json:"image"` Devices PathArray `json:"devices"`
Index string `json:"index"` NetworkModel string `json:"network_model"`
CreatedAt time.Time `json:"created_at"` Image string `json:"image"`
UpdatedAt time.Time `json:"updated_at"` Index string `json:"index"`
State string `json:"state"` CreatedAt time.Time `json:"created_at"`
Author string `json:"author"` UpdatedAt time.Time `json:"updated_at"`
MinMemory int `json:"min_memory"` State string `json:"state"`
MinDisk int `json:"min_disk"` Author string `json:"author"`
MaxMemory uint64 `json:"max_memory"` MinMemory int `json:"min_memory"`
Thumbnail string `json:"thumbnail"` MinDisk int `json:"min_disk"`
Healthy string `json:"healthy"` MaxMemory uint64 `json:"max_memory"`
Plugins Strings `json:"plugins"` Thumbnail string `json:"thumbnail"`
Healthy string `json:"healthy"`
Plugins Strings `json:"plugins"`
Origin string `json:"origin"`
} }
type Ports struct { type Ports struct {

View File

@@ -17,20 +17,22 @@ type UdpPorts struct {
/*******************使用gorm支持json************************************/ /*******************使用gorm支持json************************************/
type PortMap struct { type PortMap struct {
ContainerPort string `json:"container,omitempty"` ContainerPort string `json:"container"`
CommendPort string `json:"host,omitempty"` CommendPort string `json:"host"`
Protocol string `json:"protocol"` Protocol string `json:"protocol"`
Desc string `json:"desc"`
Type int `json:"type"`
} }
type PortArrey []PortMap type PortArray []PortMap
// Value 实现方法 // Value 实现方法
func (p PortArrey) Value() (driver.Value, error) { func (p PortArray) Value() (driver.Value, error) {
return json.Marshal(p) return json.Marshal(p)
} }
// Scan 实现方法 // Scan 实现方法
func (p *PortArrey) Scan(input interface{}) error { func (p *PortArray) Scan(input interface{}) error {
return json.Unmarshal(input.([]byte), p) return json.Unmarshal(input.([]byte), p)
} }
@@ -41,20 +43,22 @@ func (p *PortArrey) Scan(input interface{}) error {
type Env struct { type Env struct {
Name string `json:"container"` Name string `json:"container"`
Value string `json:"host"` Value string `json:"host"`
Desc string `json:"desc"`
Type int `json:"type"`
} }
type JSON json.RawMessage type JSON json.RawMessage
type EnvArrey []Env type EnvArray []Env
// Value 实现方法 // Value 实现方法
func (p EnvArrey) Value() (driver.Value, error) { func (p EnvArray) Value() (driver.Value, error) {
return json.Marshal(p) return json.Marshal(p)
//return .MarshalJSON() //return .MarshalJSON()
} }
// Scan 实现方法 // Scan 实现方法
func (p *EnvArrey) Scan(input interface{}) error { func (p *EnvArray) Scan(input interface{}) error {
return json.Unmarshal(input.([]byte), p) return json.Unmarshal(input.([]byte), p)
} }
@@ -65,17 +69,19 @@ func (p *EnvArrey) Scan(input interface{}) error {
type PathMap struct { type PathMap struct {
ContainerPath string `json:"container"` ContainerPath string `json:"container"`
Path string `json:"host"` Path string `json:"host"`
Type int `json:"type"`
Desc string `json:"desc"`
} }
type PathArrey []PathMap type PathArray []PathMap
// Value 实现方法 // Value 实现方法
func (p PathArrey) Value() (driver.Value, error) { func (p PathArray) Value() (driver.Value, error) {
return json.Marshal(p) return json.Marshal(p)
} }
// Scan 实现方法 // Scan 实现方法
func (p *PathArrey) Scan(input interface{}) error { func (p *PathArray) Scan(input interface{}) error {
return json.Unmarshal(input.([]byte), p) return json.Unmarshal(input.([]byte), p)
} }
@@ -103,10 +109,10 @@ type CustomizationPostData struct {
Index string `json:"index"` Index string `json:"index"`
Icon string `json:"icon"` Icon string `json:"icon"`
Image string `json:"image"` Image string `json:"image"`
Envs EnvArrey `json:"envs"` Envs EnvArray `json:"envs"`
Ports PortArrey `json:"ports"` Ports PortArray `json:"ports"`
Volumes PathArrey `json:"volumes"` Volumes PathArray `json:"volumes"`
Devices PathArrey `json:"devices"` Devices PathArray `json:"devices"`
//Port string `json:"port,omitempty"` //Port string `json:"port,omitempty"`
PortMap string `json:"port_map"` PortMap string `json:"port_map"`
CpuShares int64 `json:"cpu_shares"` CpuShares int64 `json:"cpu_shares"`

7
model/search.go Normal file
View File

@@ -0,0 +1,7 @@
package model
type SearchFileInfo struct {
Path string `json:"path"`
Name string `json:"name"`
Type int `json:"type"`
}

View File

@@ -15,6 +15,7 @@ type UserModel struct {
Head string Head string
Email string Email string
Description string Description string
Initialized bool
} }
//服务配置 //服务配置
@@ -60,11 +61,7 @@ type RedisModel struct {
} }
type SystemConfig struct { type SystemConfig struct {
SearchSwitch bool `json:"search_switch"` //搜索开关 ConfigStr string `json:"config_str"`
SearchEngine string `json:"search_engine"` //搜索引擎 WidgetList string `json:"widget_list"`
ShortcutsSwitch bool `json:"shortcuts_switch"` ConfigPath string `json:"config_path"`
WidgetsSwitch bool `json:"widgets_switch"`
BackgroundType string `json:"background_type"`
Background string `json:"background"`
AutoUpdate bool `json:"auto_update"`
} }

View File

@@ -1,6 +1,7 @@
package model package model
type Path struct { type Path struct {
Name string `json:"name"` Name string `json:"name"`
Path string `json:"path"` Path string `json:"path"`
IsDir bool `json:"is_dir"`
} }

11
pkg/cache/cache.go vendored Normal file
View File

@@ -0,0 +1,11 @@
package cache
import (
"time"
"github.com/patrickmn/go-cache"
)
func Init() *cache.Cache {
return cache.New(5*time.Minute, 60*time.Second)
}

View File

@@ -2,14 +2,15 @@ package config
import ( import (
"fmt" "fmt"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/go-ini/ini"
"log" "log"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/go-ini/ini"
) )
//系统配置 //系统配置
@@ -55,6 +56,7 @@ func InitSetup(config string) {
mapTo("redis", RedisInfo) mapTo("redis", RedisInfo)
mapTo("server", ServerInfo) mapTo("server", ServerInfo)
mapTo("system", SystemConfigInfo) mapTo("system", SystemConfigInfo)
SystemConfigInfo.ConfigPath = configDir
// AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd() // AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd()
} }

15
pkg/config/update.go Normal file
View File

@@ -0,0 +1,15 @@
package config
import "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
//检查目录是否存在
func mkdirDATAAll() {
dirArray := [7]string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"}
for _, v := range dirArray {
file.IsNotExistMkDir(v)
}
}
func UpdateSetup() {
mkdirDATAAll()
}

View File

@@ -4,30 +4,35 @@ import (
"bytes" "bytes"
json2 "encoding/json" json2 "encoding/json"
"fmt" "fmt"
"github.com/gorilla/websocket"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
"io" "io"
"regexp" "regexp"
"strconv" "strconv"
"sync" "sync"
"time" "time"
"github.com/gorilla/websocket"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
) )
func NewSshClient() (*ssh.Client, error) { func NewSshClient(user, password string) (*ssh.Client, error) {
// connet to ssh
// addr = fmt.Sprintf("%s:%d", host, port)
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
Timeout: time.Second * 5, Timeout: time.Second * 5,
User: "root", User: user,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), HostKeyCallback: ssh.InsecureIgnoreHostKey(),
//HostKeyCallback: , //HostKeyCallback: ,
//HostKeyCallback: hostKeyCallBackFunc(h.Host), //HostKeyCallback: hostKeyCallBackFunc(h.Host),
} }
//if h.Type == "password" { //if h.Type == "password" {
config.Auth = []ssh.AuthMethod{ssh.Password("123456")} config.Auth = []ssh.AuthMethod{ssh.Password(password)}
//} else { //} else {
// config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)} // config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)}
//} //}
addr := fmt.Sprintf("%s:%d", "192.168.2.142", 22) addr := fmt.Sprintf("%s:%d", "127.0.0.1", 22)
c, err := ssh.Dial("tcp", addr, config) c, err := ssh.Dial("tcp", addr, config)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -98,6 +103,98 @@ const (
wsMsgResize = "resize" wsMsgResize = "resize"
) )
//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin
func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string {
//tells other go routine quit
username := ""
for {
//read websocket msg
_, wsData, err := wsConn.ReadMessage()
if err != nil {
return ""
}
msgObj := wsMsg{}
if err := json2.Unmarshal(wsData, &msgObj); err != nil {
msgObj.Type = "cmd"
msgObj.Cmd = string(wsData)
}
//if err := json.Unmarshal(wsData, &msgObj); err != nil {
// logrus.WithError(err).WithField("wsData", string(wsData)).Error("unmarshal websocket message failed")
//}
switch msgObj.Type {
case wsMsgCmd:
//handle xterm.js stdin
//decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd)
decodeBytes := []byte(msgObj.Cmd)
if msgObj.Cmd == "\u007f" {
if len(username) == 0 {
continue
}
wsConn.WriteMessage(websocket.TextMessage, []byte("\b\x1b[K"))
username = username[:len(username)-1]
continue
}
if msgObj.Cmd == "\r" {
return username
}
username += msgObj.Cmd
if err := wsConn.WriteMessage(websocket.TextMessage, decodeBytes); err != nil {
logrus.WithError(err).Error("ws cmd bytes write to ssh.stdin pipe failed")
}
//write input cmd to log buffer
if _, err := logBuff.Write(decodeBytes); err != nil {
logrus.WithError(err).Error("write received cmd into log buffer failed")
}
}
}
}
func ReceiveWsMsgPassword(wsConn *websocket.Conn, logBuff *bytes.Buffer) string {
//tells other go routine quit
password := ""
for {
//read websocket msg
_, wsData, err := wsConn.ReadMessage()
if err != nil {
logrus.WithError(err).Error("reading webSocket message failed")
return ""
}
msgObj := wsMsg{}
if err := json2.Unmarshal(wsData, &msgObj); err != nil {
msgObj.Type = "cmd"
msgObj.Cmd = string(wsData)
}
//if err := json.Unmarshal(wsData, &msgObj); err != nil {
// logrus.WithError(err).WithField("wsData", string(wsData)).Error("unmarshal websocket message failed")
//}
switch msgObj.Type {
case wsMsgCmd:
//handle xterm.js stdin
//decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd)
if msgObj.Cmd == "\r" {
return password
}
if msgObj.Cmd == "\u007f" {
if len(password) == 0 {
continue
}
password = password[:len(password)-1]
continue
}
password += msgObj.Cmd
}
}
}
//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin //ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin
func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffer, exitCh chan bool) { func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffer, exitCh chan bool) {
//tells other go routine quit //tells other go routine quit
@@ -187,6 +284,64 @@ func flushComboOutput(w *wsBufferWriter, wsConn *websocket.Conn) error {
} }
return nil return nil
} }
//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin
func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exitCh chan bool) {
//tells other go routine quit
defer setQuit(exitCh)
for {
select {
case <-exitCh:
return
default:
//read websocket msg
_, wsData, err := wsConn.ReadMessage()
if err != nil {
logrus.WithError(err).Error("reading webSocket message failed")
return
}
//unmashal bytes into struct
//msgObj := wsMsg{
// Type: "cmd",
// Cmd: "",
// Rows: 50,
// Cols: 180,
//}
msgObj := wsMsg{}
if err := json2.Unmarshal(wsData, &msgObj); err != nil {
msgObj.Type = "cmd"
msgObj.Cmd = string(wsData)
}
//if err := json.Unmarshal(wsData, &msgObj); err != nil {
// logrus.WithError(err).WithField("wsData", string(wsData)).Error("unmarshal websocket message failed")
//}
switch msgObj.Type {
case wsMsgResize:
//handle xterm.js size change
if msgObj.Cols > 0 && msgObj.Rows > 0 {
if err := ssConn.Session.WindowChange(msgObj.Rows, msgObj.Cols); err != nil {
logrus.WithError(err).Error("ssh pty change windows size failed")
}
}
case wsMsgCmd:
//handle xterm.js stdin
//decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd)
decodeBytes := []byte(msgObj.Cmd)
if err != nil {
logrus.WithError(err).Error("websock cmd string base64 decoding failed")
}
if _, err := ssConn.StdinPipe.Write(decodeBytes); err != nil {
logrus.WithError(err).Error("ws cmd bytes write to ssh.stdin pipe failed")
}
//write input cmd to log buffer
if _, err := logBuff.Write(decodeBytes); err != nil {
logrus.WithError(err).Error("write received cmd into log buffer failed")
}
}
}
}
}
func (ssConn *SshConn) SessionWait(quitChan chan bool) { func (ssConn *SshConn) SessionWait(quitChan chan bool) {
if err := ssConn.Session.Wait(); err != nil { if err := ssConn.Session.Wait(); err != nil {
logrus.WithError(err).Error("ssh session wait failed") logrus.WithError(err).Error("ssh session wait failed")
@@ -241,7 +396,7 @@ func WsReaderCopy(reader *websocket.Conn, writer io.Writer) {
if err = json2.Unmarshal(p, &msgObj); err != nil { if err = json2.Unmarshal(p, &msgObj); err != nil {
writer.Write(p) writer.Write(p)
} else if msgObj.Type == wsMsgResize { } else if msgObj.Type == wsMsgResize {
writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r" )) writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r"))
} }
} }
} }

View File

@@ -1,10 +1,25 @@
package docker package docker
import "strings"
func GetDir(id, envName string) string { func GetDir(id, envName string) string {
var path string var path string
switch envName {
case "/config": if len(id) == 0 {
path = "/oasis/app_data/" + id + "/" id = "$AppID"
}
switch {
case strings.Contains(strings.ToLower(envName), "config"):
path = "/DATA/AppData/" + id + "/"
case strings.Contains(strings.ToLower(envName), "movie"):
path = "/DATA/Media/Movies/"
case strings.Contains(strings.ToLower(envName), "music"):
path = "/DATA/Media/Music/"
case strings.Contains(strings.ToLower(envName), "download"):
path = "/DATA/Downloads/"
case strings.Contains(strings.ToLower(envName), "photo") || strings.Contains(strings.ToLower(envName), "pictures"):
path = "/DATA/Downloads/"
default: default:
//path = "/media" //path = "/media"
} }

View File

@@ -0,0 +1,10 @@
package docker
import (
"fmt"
"testing"
)
func TestGetDir(t *testing.T) {
fmt.Println(GetDir("", "config"))
}

View File

@@ -1,7 +0,0 @@
package github
import "testing"
func TestGetRepos(t *testing.T) {
GetRepos()
}

View File

@@ -1,9 +1,10 @@
package gredis package gredis
import ( import (
"github.com/gomodule/redigo/redis"
"oasis/model"
"time" "time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/gomodule/redigo/redis"
) )
func GetRedisConn(m *model.RedisModel) *redis.Pool { func GetRedisConn(m *model.RedisModel) *redis.Pool {

View File

@@ -1,8 +1,9 @@
package upnp package upnp
import ( import (
ip_helper2 "oasis/pkg/utils/ip_helper"
"testing" "testing"
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
) )
func TestGetCtrlUrl(t *testing.T) { func TestGetCtrlUrl(t *testing.T) {

View File

@@ -0,0 +1,19 @@
package env_helper
import "strings"
func ReplaceDefaultENV(key string) string {
temp := ""
switch key {
case "$DefaultPassword":
temp = "casaos"
case "$DefaultUserName":
temp = "admin"
}
return temp
}
//replace env default setting
func ReplaceStringDefaultENV(str string) string {
return strings.ReplaceAll(strings.ReplaceAll(str, "$DefaultPassword", ReplaceDefaultENV("$DefaultPassword")), "$DefaultUserName", ReplaceDefaultENV("$DefaultUserName"))
}

View File

@@ -50,6 +50,7 @@ func MkDir(src string) error {
if err != nil { if err != nil {
return err return err
} }
os.Chmod(src, 0777)
return nil return nil
} }
@@ -100,10 +101,9 @@ func MustOpen(fileName, filePath string) (*os.File, error) {
return f, nil return f, nil
} }
// 判断所给路径文件/文件夹是否存在 // 判断所给路径文件/文件夹是否存在
func Exists(path string) bool { func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息 _, err := os.Stat(path) //os.Stat获取文件信息
if err != nil { if err != nil {
if os.IsExist(err) { if os.IsExist(err) {
return true return true
@@ -126,3 +126,23 @@ func IsDir(path string) bool {
func IsFile(path string) bool { func IsFile(path string) bool {
return !IsDir(path) return !IsDir(path)
} }
func CreateFile(path string) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}
// IsNotExistMkDir create a directory if it does not exist
func IsNotExistCreateFile(src string) error {
if notExist := CheckNotExist(src); notExist == true {
if err := CreateFile(src); err != nil {
return err
}
}
return nil
}

176
pkg/utils/file/reader.go Normal file
View File

@@ -0,0 +1,176 @@
package file
import (
"bytes"
"fmt"
"io"
"os"
)
var (
buffSize = 1 << 20
)
// ReadLineFromEnd --
type ReadLineFromEnd struct {
f *os.File
fileSize int
bwr *bytes.Buffer
lineBuff []byte
swapBuff []byte
isFirst bool
}
// NewReadLineFromEnd --
func NewReadLineFromEnd(name string) (rd *ReadLineFromEnd, err error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
info, err := f.Stat()
if info.IsDir() {
return nil, fmt.Errorf("not file")
}
fileSize := int(info.Size())
rd = &ReadLineFromEnd{
f: f,
fileSize: fileSize,
bwr: bytes.NewBuffer([]byte{}),
lineBuff: make([]byte, 0),
swapBuff: make([]byte, buffSize),
isFirst: true,
}
return rd, nil
}
// ReadLine 结尾包含'\n'
func (c *ReadLineFromEnd) ReadLine() (line []byte, err error) {
var ok bool
for {
ok, err = c.buff()
if err != nil {
return nil, err
}
if ok {
break
}
}
line, err = c.bwr.ReadBytes('\n')
if err == io.EOF && c.fileSize > 0 {
err = nil
}
return line, err
}
// Close --
func (c *ReadLineFromEnd) Close() (err error) {
return c.f.Close()
}
func (c *ReadLineFromEnd) buff() (ok bool, err error) {
if c.fileSize == 0 {
return true, nil
}
if c.bwr.Len() >= buffSize {
return true, nil
}
offset := 0
if c.fileSize > buffSize {
offset = c.fileSize - buffSize
}
_, err = c.f.Seek(int64(offset), 0)
if err != nil {
return false, err
}
n, err := c.f.Read(c.swapBuff)
if err != nil && err != io.EOF {
return false, err
}
if c.fileSize < n {
n = c.fileSize
}
if n == 0 {
return true, nil
}
for {
m := bytes.LastIndex(c.swapBuff[:n], []byte{'\n'})
if m == -1 {
break
}
if m < n-1 {
err = c.writeLine(c.swapBuff[m+1 : n])
if err != nil {
return false, err
}
ok = true
} else if m == n-1 && !c.isFirst {
err = c.writeLine(nil)
if err != nil {
return false, err
}
ok = true
}
n = m
if n == 0 {
break
}
}
if n > 0 {
reverseBytes(c.swapBuff[:n])
c.lineBuff = append(c.lineBuff, c.swapBuff[:n]...)
}
if offset == 0 {
err = c.writeLine(nil)
if err != nil {
return false, err
}
ok = true
}
c.fileSize = offset
if c.isFirst {
c.isFirst = false
}
return ok, nil
}
func (c *ReadLineFromEnd) writeLine(b []byte) (err error) {
if len(b) > 0 {
_, err = c.bwr.Write(b)
if err != nil {
return err
}
}
if len(c.lineBuff) > 0 {
reverseBytes(c.lineBuff)
_, err = c.bwr.Write(c.lineBuff)
if err != nil {
return err
}
c.lineBuff = c.lineBuff[:0]
}
_, err = c.bwr.Write([]byte{'\n'})
if err != nil {
return err
}
return nil
}
func reverseBytes(b []byte) {
n := len(b)
if n <= 1 {
return
}
for i := 0; i < n; i++ {
k := n - 1
if k != i {
b[i], b[k] = b[k], b[i]
}
n--
}
}

View File

@@ -3,12 +3,13 @@ package httper
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/tidwall/gjson"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"time" "time"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/tidwall/gjson"
) )
//发送GET请求 //发送GET请求

View File

@@ -1,8 +1,9 @@
package jwt package jwt
import ( import (
jwt "github.com/golang-jwt/jwt"
"time" "time"
jwt "github.com/golang-jwt/jwt"
) )
type Claims struct { type Claims struct {
@@ -15,8 +16,7 @@ var jwtSecret []byte
//创建token //创建token
func GenerateToken(username, password string) (string, error) { func GenerateToken(username, password string) (string, error) {
nowTime := time.Now() expireTime := time.Now().AddDate(999, 0, 0)
expireTime := nowTime.Add(3 * time.Hour)
clims := Claims{ clims := Claims{
username, username,
password, password,

View File

@@ -2,11 +2,12 @@ package jwt
import ( import (
"fmt" "fmt"
"net/http"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err" oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
) )
func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc { func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc {

View File

@@ -2,13 +2,13 @@ package loger
import ( import (
"fmt" "fmt"
"github.com/IceWhaleTech/CasaOS/pkg/config"
file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"time"
"github.com/IceWhaleTech/CasaOS/pkg/config"
file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
) )
//定义一个int的别名 //定义一个int的别名
@@ -20,6 +20,7 @@ type OLog interface {
Warn(v ...interface{}) Warn(v ...interface{})
Error(v ...interface{}) Error(v ...interface{})
Fatal(v ...interface{}) Fatal(v ...interface{})
Path() string
} }
type oLog struct { type oLog struct {
@@ -47,9 +48,8 @@ const (
func LogSetup() { func LogSetup() {
var err error var err error
filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath) filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
fileName := fmt.Sprintf("%s%s.%s", fileName := fmt.Sprintf("%s.%s",
config.AppInfo.LogSaveName, config.AppInfo.LogSaveName,
time.Now().Format(config.AppInfo.DateStrFormat),
config.AppInfo.LogFileExt, config.AppInfo.LogFileExt,
) )
F, err = file2.MustOpen(fileName, filePath) F, err = file2.MustOpen(fileName, filePath)
@@ -60,7 +60,14 @@ func LogSetup() {
logger = log.New(F, DefaultPrefix, log.LstdFlags) logger = log.New(F, DefaultPrefix, log.LstdFlags)
} }
func (o *oLog) Path() string {
filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
fileName := fmt.Sprintf("%s.%s",
config.AppInfo.LogSaveName,
config.AppInfo.LogFileExt,
)
return filePath + fileName
}
func (o *oLog) Debug(v ...interface{}) { func (o *oLog) Debug(v ...interface{}) {
setPrefix(DEBUG) setPrefix(DEBUG)
logger.Println(v) logger.Println(v)

View File

@@ -7,10 +7,14 @@ const (
ERROR_AUTH_TOKEN = 401 ERROR_AUTH_TOKEN = 401
//user //user
PWD_INVALID = 10001 PWD_INVALID = 10001
PWD_IS_EMPTY = 10002
PWD_INVALID_OLD = 10003
//system //system
DIR_ALREADY_EXISTS = 20001 DIR_ALREADY_EXISTS = 20001
FILE_ALREADY_EXISTS = 20002
FILE_OR_DIR_EXISTS = 20003
//zerotier //zerotier
GET_TOKEN_ERROR = 30001 GET_TOKEN_ERROR = 30001
@@ -35,11 +39,14 @@ var MsgFlags = map[int]string{
ERROR_AUTH_TOKEN: "error auth token", ERROR_AUTH_TOKEN: "error auth token",
//user //user
PWD_INVALID: "Password invalid", PWD_INVALID: "Password invalid",
PWD_IS_EMPTY: "Password is empty",
PWD_INVALID_OLD: "Old Password invalid",
//system //system
DIR_ALREADY_EXISTS: "Directory already exists", DIR_ALREADY_EXISTS: "Directory already exists",
FILE_ALREADY_EXISTS: "File already exists",
FILE_OR_DIR_EXISTS: "File or directory already exists",
//zerotier //zerotier
GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available", GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available",

View File

@@ -47,6 +47,7 @@ func IsPortAvailable(port int, t string) bool {
uc, err := net.ListenUDP("udp", sadd) uc, err := net.ListenUDP("udp", sadd)
if err != nil { if err != nil {
fmt.Println(err.Error())
return false return false
} else { } else {
defer uc.Close() defer uc.Close()

View File

@@ -1,8 +1,9 @@
package sort package sort
import ( import (
"github.com/IceWhaleTech/CasaOS/model"
"sort" "sort"
"github.com/IceWhaleTech/CasaOS/model"
) )
// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool // 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool

View File

@@ -2,13 +2,14 @@ package version
import ( import (
json2 "encoding/json" json2 "encoding/json"
"strconv"
"strings"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper" "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/types" "github.com/IceWhaleTech/CasaOS/types"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"strconv"
"strings"
) )
func IsNeedUpdate() (bool, model.Version) { func IsNeedUpdate() (bool, model.Version) {
@@ -35,3 +36,23 @@ func IsNeedUpdate() (bool, model.Version) {
} }
return false, version return false, version
} }
//a版本大于b版本
func VersionCompared(a string, b string) bool {
v1 := strings.Split(a, ".")
v2 := strings.Split(b, ".")
for len(v1) < len(v2) {
v1 = append(v1, "0")
}
for len(v2) < len(v1) {
v2 = append(v2, "0")
}
for i := 0; i < len(v1); i++ {
a, _ := strconv.Atoi(v1[i])
b, _ := strconv.Atoi(v2[i])
if a > b {
return true
}
}
return false
}

View File

@@ -1,3 +1,4 @@
//go:build doc
// +build doc // +build doc
package route package route
@@ -5,9 +6,10 @@ package route
import ( import (
_ "github.com/IceWhaleTech/CasaOS/docs" _ "github.com/IceWhaleTech/CasaOS/docs"
ginSwagger "github.com/swaggo/gin-swagger" ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles" swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles"
) )
func init() { func init() {
// swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler) swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
} }

View File

@@ -1,18 +1,19 @@
package route package route
import ( import (
"net/http"
"github.com/IceWhaleTech/CasaOS/middleware" "github.com/IceWhaleTech/CasaOS/middleware"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
v1 "github.com/IceWhaleTech/CasaOS/route/v1" v1 "github.com/IceWhaleTech/CasaOS/route/v1"
"github.com/IceWhaleTech/CasaOS/web" "github.com/IceWhaleTech/CasaOS/web"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
) )
var swagHandler gin.HandlerFunc var swagHandler gin.HandlerFunc
func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine { func InitRouter() *gin.Engine {
r := gin.Default() r := gin.Default()
r.Use(middleware.Cors()) r.Use(middleware.Cors())
@@ -26,11 +27,16 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
if swagHandler != nil { if swagHandler != nil {
r.GET("/swagger/*any", swagHandler) r.GET("/swagger/*any", swagHandler)
} }
//登录
r.POST("/v1/user/login", v1.Login) r.POST("/v1/user/login", v1.Login)
r.GET("/debug", v1.GetSystemConfigDebug) r.GET("/v1/guide/check", v1.GetGuideCheck)
r.GET("/debug", v1.GetSystemConfigDebug)
//set user
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
//get user info
r.GET("/v1/user/info", v1.UserInfo)
v1Group := r.Group("/v1") v1Group := r.Group("/v1")
v1Group.Use(jwt2.JWT(swagHandler)) v1Group.Use(jwt2.JWT(swagHandler))
@@ -38,8 +44,7 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
v1UserGroup := v1Group.Group("/user") v1UserGroup := v1Group.Group("/user")
v1UserGroup.Use() v1UserGroup.Use()
{ {
//设置用户
v1UserGroup.POST("/setusernamepwd", v1.Set_Name_Pwd)
//chang head //chang head
v1UserGroup.POST("/changhead", v1.Up_Load_Head) v1UserGroup.POST("/changhead", v1.Up_Load_Head)
//chang user name //chang user name
@@ -48,8 +53,7 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
v1UserGroup.PUT("/changuserpwd", v1.Chang_User_Pwd) v1UserGroup.PUT("/changuserpwd", v1.Chang_User_Pwd)
//edit user info //edit user info
v1UserGroup.POST("/changuserinfo", v1.Chang_User_Info) v1UserGroup.POST("/changuserinfo", v1.Chang_User_Info)
//get user info
v1UserGroup.GET("/info", v1.UserInfo)
} }
v1ZiMaGroup := v1Group.Group("/zima") v1ZiMaGroup := v1Group.Group("/zima")
@@ -182,7 +186,10 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
v1SysGroup.GET("/sys", v1.Sys) v1SysGroup.GET("/sys", v1.Sys)
v1SysGroup.GET("/wsssh", v1.WsSsh) v1SysGroup.GET("/wsssh", v1.WsSsh)
v1SysGroup.GET("/config", v1.GetSystemConfig) v1SysGroup.GET("/config", v1.GetSystemConfig)
v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
v1SysGroup.POST("/config", v1.PostSetSystemConfig) v1SysGroup.POST("/config", v1.PostSetSystemConfig)
v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
} }
v1FileGroup := v1Group.Group("/file") v1FileGroup := v1Group.Group("/file")
v1FileGroup.Use() v1FileGroup.Use()
@@ -194,6 +201,7 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
v1FileGroup.GET("/dirpath", v1.DirPath) v1FileGroup.GET("/dirpath", v1.DirPath)
//创建目录 //创建目录
v1FileGroup.POST("/mkdir", v1.MkdirAll) v1FileGroup.POST("/mkdir", v1.MkdirAll)
v1FileGroup.POST("/create", v1.PostCreateFile)
v1FileGroup.GET("/download", v1.GetDownloadFile) v1FileGroup.GET("/download", v1.GetDownloadFile)
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) //v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
@@ -252,6 +260,11 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
v1NotifyGroup.GET("/ws", v1.NotifyWS) v1NotifyGroup.GET("/ws", v1.NotifyWS)
v1NotifyGroup.PUT("/read/:id", v1.PutNotifyRead) v1NotifyGroup.PUT("/read/:id", v1.PutNotifyRead)
} }
v1SearchGroup := v1Group.Group("/search")
v1SearchGroup.Use()
{
v1SearchGroup.GET("/search", v1.GetSearchList)
}
} }
return r return r
} }

View File

@@ -1,15 +1,17 @@
package v1 package v1
import ( import (
"net/http"
"strconv"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/docker"
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err" oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
"github.com/IceWhaleTech/CasaOS/pkg/utils/sort"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
"strconv"
) )
// @Summary 获取远程列表 // @Summary 获取远程列表
@@ -110,51 +112,66 @@ func MyAppList(c *gin.Context) {
func AppInfo(c *gin.Context) { func AppInfo(c *gin.Context) {
id := c.Param("id") id := c.Param("id")
info := service.MyService.App().GetServerAppInfo(id) info := service.MyService.OAPI().GetServerAppInfo(id)
if info.NetworkModel != "host" { if info.NetworkModel != "host" {
port, _ := port2.GetAvailablePort("tcp") for i := 0; i < len(info.Ports); i++ {
info.PortMap = uint(port) if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
for i := 0; i < len(info.Configures.TcpPorts); i++ { info.Ports[i].CommendPort = strconv.Itoa(p)
info.Configures.TcpPorts[i].CommendPort, _ = port2.GetAvailablePort("tcp") } else {
} if info.Ports[i].Protocol == "tcp" {
for i := 0; i < len(info.Configures.UdpPorts); i++ { if p, err := port2.GetAvailablePort("tcp"); err == nil {
info.Configures.UdpPorts[i].CommendPort, _ = port2.GetAvailablePort("udp") info.Ports[i].CommendPort = strconv.Itoa(p)
} }
} else { } else if info.Ports[i].Protocol == "upd" {
info.PortMap = info.TcpPort if p, err := port2.GetAvailablePort("udp"); err == nil {
} info.Ports[i].CommendPort = strconv.Itoa(p)
}
}
}
for i := 0; i < len(info.Configures.Devices); i++ { if info.Ports[i].Type == 0 {
if !file.CheckNotExist(info.Configures.Devices[i].ContainerPath) { info.PortMap = info.Ports[i].CommendPort
info.Configures.Devices[i].Path = info.Configures.Devices[i].ContainerPath }
} }
} }
portOrder := func(c1, c2 *model.Ports) bool { for i := 0; i < len(info.Devices); i++ {
return c1.Type < c2.Type if !file.CheckNotExist(info.Devices[i].ContainerPath) {
info.Devices[i].Path = info.Devices[i].ContainerPath
}
}
if len(info.Tip) > 0 {
info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
} }
envOrder := func(c1, c2 *model.Envs) bool { for i := 0; i < len(info.Volumes); i++ {
return c1.Type < c2.Type info.Volumes[i].Path = docker.GetDir("", info.Volumes[i].ContainerPath)
} }
// portOrder := func(c1, c2 *model.Ports) bool {
// return c1.Type < c2.Type
// }
volOrder := func(c1, c2 *model.Volume) bool { // envOrder := func(c1, c2 *model.Envs) bool {
return c1.Type < c2.Type // return c1.Type < c2.Type
} // }
devOrder := func(c1, c2 *model.Devices) bool { // volOrder := func(c1, c2 *model.Volume) bool {
return c1.Type < c2.Type // return c1.Type < c2.Type
} // }
// devOrder := func(c1, c2 *model.Devices) bool {
// return c1.Type < c2.Type
// }
//sort //sort
if info.NetworkModel != "host" { // if info.NetworkModel != "host" {
sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts) // sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts)
sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts) // sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts)
} // }
sort.EnvSort(envOrder).Sort(info.Configures.Envs) // sort.EnvSort(envOrder).Sort(info.Envs)
sort.VolSort(volOrder).Sort(info.Configures.Volumes) // sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
sort.DevSort(devOrder).Sort(info.Configures.Devices) // sort.DevSort(devOrder).Sort(info.Devices)
info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20 info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20

View File

@@ -3,6 +3,12 @@ package v1
import ( import (
"bytes" "bytes"
json2 "encoding/json" json2 "encoding/json"
"net/http"
"reflect"
"strconv"
"strings"
"time"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/docker" "github.com/IceWhaleTech/CasaOS/pkg/docker"
upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp" upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
@@ -19,11 +25,8 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
uuid "github.com/satori/go.uuid" uuid "github.com/satori/go.uuid"
"net/http" "github.com/tidwall/gjson"
"reflect" "golang.org/x/crypto/ssh"
"strconv"
"strings"
"time"
) )
var upgrader = websocket.Upgrader{ var upgrader = websocket.Upgrader{
@@ -64,19 +67,46 @@ func DockerTerminal(c *gin.Context) {
//打开本机的ssh接口 //打开本机的ssh接口
func WsSsh(c *gin.Context) { func WsSsh(c *gin.Context) {
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil) wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
defer wsConn.Close()
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
client, _ := docker.NewSshClient()
defer client.Close()
ssConn, _ := docker.NewSshConn(cols, rows, client)
defer ssConn.Close()
quitChan := make(chan bool, 3)
var logBuff = new(bytes.Buffer) var logBuff = new(bytes.Buffer)
quitChan := make(chan bool, 3)
user := ""
password := ""
var login int = 1
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
var client *ssh.Client
for login != 0 {
var err error
wsConn.WriteMessage(websocket.TextMessage, []byte("login:"))
user = docker.ReceiveWsMsgUser(wsConn, logBuff)
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
wsConn.WriteMessage(websocket.TextMessage, []byte("password:"))
password = docker.ReceiveWsMsgPassword(wsConn, logBuff)
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
client, err = docker.NewSshClient(user, password)
if err != nil && client == nil {
wsConn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
} else {
login = 0
}
}
if client != nil {
defer client.Close()
}
ssConn, _ := docker.NewSshConn(cols, rows, client)
defer ssConn.Close()
go ssConn.ReceiveWsMsg(wsConn, logBuff, quitChan) go ssConn.ReceiveWsMsg(wsConn, logBuff, quitChan)
go ssConn.SendComboOutput(wsConn, quitChan) go ssConn.SendComboOutput(wsConn, quitChan)
go ssConn.SessionWait(quitChan) go ssConn.SessionWait(quitChan)
<-quitChan <-quitChan
} }
@@ -143,7 +173,7 @@ func InstallApp(c *gin.Context) {
dockerImageVersion = "latest" dockerImageVersion = "latest"
} }
if m.Origin != "custom" { if m.Origin != "custom" {
appInfo = service.MyService.App().GetServerAppInfo(appId) appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
} else { } else {
@@ -209,10 +239,9 @@ func InstallApp(c *gin.Context) {
var relyMap = make(map[string]string) var relyMap = make(map[string]string)
go func() { go func() {
installLog := model2.AppNotify{} installLog := model2.AppNotify{}
installLog.CustomId = id
installLog.State = 0 installLog.State = 0
installLog.CustomId = id
installLog.Message = "installing rely" installLog.Message = "installing rely"
installLog.Speed = 10
installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10) installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10) installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
@@ -250,16 +279,13 @@ func InstallApp(c *gin.Context) {
} else { } else {
docker_base.MysqlDelete(mysqlContainerId) docker_base.MysqlDelete(mysqlContainerId)
installLog.State = 0 installLog.State = 0
installLog.Speed = 30
installLog.Message = err.Error() installLog.Message = err.Error()
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
} }
} }
} }
} }
installLog.Speed = 50
installLog.Message = "pulling" installLog.Message = "pulling"
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
@@ -267,7 +293,6 @@ func InstallApp(c *gin.Context) {
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog) err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
if err != nil { if err != nil {
installLog.State = 0 installLog.State = 0
installLog.Speed = 70
installLog.Message = err.Error() installLog.Message = err.Error()
installLog.Type = types.NOTIFY_TYPE_ERROR installLog.Type = types.NOTIFY_TYPE_ERROR
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
@@ -283,36 +308,45 @@ func InstallApp(c *gin.Context) {
//} //}
//step创建容器 //step创建容器
// networkName, err := service.MyService.Docker().GetNetWorkNameByNetWorkID(appInfo.NetworkModel)
// if err != nil {
// //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
// installLog.State = 0
// installLog.Speed = 75
// installLog.Type = types.NOTIFY_TYPE_ERROR
// installLog.Message = err.Error()
// service.MyService.Notify().UpdateLog(installLog)
// return
// }
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel) containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
installLog.ContainerId = containerId installLog.Name = appInfo.Title
installLog.Icon = appInfo.Icon
if err != nil { if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100) //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
installLog.State = 0 installLog.State = 0
installLog.Speed = 80
installLog.Type = types.NOTIFY_TYPE_ERROR installLog.Type = types.NOTIFY_TYPE_ERROR
installLog.Message = err.Error() installLog.Message = err.Error()
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
return return
} else { } else {
//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"starting\",\"speed\":80}", 100) //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"starting\",\"speed\":80}", 100)
installLog.Speed = 80
installLog.Message = "starting" installLog.Message = "starting"
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
} }
// echo -e "hellow\nworld" >>
//step启动容器 //step启动容器
err = service.MyService.Docker().DockerContainerStart(id) err = service.MyService.Docker().DockerContainerStart(id)
if err != nil { if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100) //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
installLog.State = 0 installLog.State = 0
installLog.Type = types.NOTIFY_TYPE_ERROR installLog.Type = types.NOTIFY_TYPE_ERROR
installLog.Speed = 90
installLog.Message = err.Error() installLog.Message = err.Error()
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
return return
} else { } else {
//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"setting upnp\",\"speed\":90}", 100) //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"setting upnp\",\"speed\":90}", 100)
installLog.Speed = 90
if m.Origin != CUSTOM { if m.Origin != CUSTOM {
installLog.Message = "setting upnp" installLog.Message = "setting upnp"
} else { } else {
@@ -357,13 +391,11 @@ func InstallApp(c *gin.Context) {
if err != nil { if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":95}", 100) //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":95}", 100)
installLog.State = 0 installLog.State = 0
installLog.Speed = 95
installLog.Type = types.NOTIFY_TYPE_ERROR installLog.Type = types.NOTIFY_TYPE_ERROR
installLog.Message = err.Error() installLog.Message = err.Error()
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
} else { } else {
//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"checking\",\"speed\":95}", 100) //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"checking\",\"speed\":95}", 100)
installLog.Speed = 95
installLog.Message = "checking" installLog.Message = "checking"
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
} }
@@ -375,14 +407,12 @@ func InstallApp(c *gin.Context) {
if err != nil && container.ContainerJSONBase.State.Running { if err != nil && container.ContainerJSONBase.State.Running {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":100}", 100) //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":100}", 100)
installLog.State = 0 installLog.State = 0
installLog.Speed = 100
installLog.Type = types.NOTIFY_TYPE_ERROR installLog.Type = types.NOTIFY_TYPE_ERROR
installLog.Message = err.Error() installLog.Message = err.Error()
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
return return
} else { } else {
//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"installed\",\"speed\":100}", 100) //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"installed\",\"speed\":100}", 100)
installLog.Speed = 100
installLog.Message = "installed" installLog.Message = "installed"
service.MyService.Notify().UpdateLog(installLog) service.MyService.Notify().UpdateLog(installLog)
} }
@@ -658,7 +688,11 @@ func UnInstallApp(c *gin.Context) {
if info.Origin != "custom" { if info.Origin != "custom" {
//step: 删除文件夹 //step: 删除文件夹
service.MyService.App().DelAppConfigDir(appId) vol := gjson.Get(info.Volumes, "#.host")
for _, v := range vol.Array() {
service.MyService.App().DelAppConfigDir(appId, v.String())
}
//step: 删除install log //step: 删除install log
service.MyService.Notify().DelLog(appId) service.MyService.Notify().DelLog(appId)
@@ -763,7 +797,6 @@ func ContainerLog(c *gin.Context) {
func GetInstallSpeed(c *gin.Context) { func GetInstallSpeed(c *gin.Context) {
id := c.Param("id") id := c.Param("id")
b := service.MyService.Notify().GetLog(id) b := service.MyService.Notify().GetLog(id)
b.Id = b.CustomId
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: b}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: b})
} }
@@ -873,12 +906,17 @@ func UpdateSetting(c *gin.Context) {
envsStr, _ := json2.Marshal(m.Envs) envsStr, _ := json2.Marshal(m.Envs)
volumesStr, _ := json2.Marshal(m.Volumes) volumesStr, _ := json2.Marshal(m.Volumes)
devicesStr, _ := json2.Marshal(m.Devices) devicesStr, _ := json2.Marshal(m.Devices)
if !reflect.DeepEqual(string(portsStr), appInfo.Ports) || !reflect.DeepEqual(string(envsStr), appInfo.Envs) || !reflect.DeepEqual(string(volumesStr), appInfo.Volumes) || m.PortMap != appInfo.PortMap { if !reflect.DeepEqual(string(portsStr), appInfo.Ports) || !reflect.DeepEqual(string(envsStr), appInfo.Envs) || !reflect.DeepEqual(string(volumesStr), appInfo.Volumes) || m.PortMap != appInfo.PortMap || m.NetworkModel != appInfo.NetModel {
var newUUid = uuid.NewV4().String() var newUUid = uuid.NewV4().String()
var err error var err error
containerId, err = service.MyService.Docker().DockerContainerCreate(appInfo.Image+":"+appInfo.Version, newUUid, cpd, appInfo.NetModel) // networkName, err := service.MyService.Docker().GetNetWorkNameByNetWorkID(appInfo.NetModel)
// if err != nil {
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
// return
// }
containerId, err = service.MyService.Docker().DockerContainerCreate(appInfo.Image+":"+appInfo.Version, newUUid, cpd, m.NetworkModel)
if err != nil { if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
@@ -980,6 +1018,7 @@ func UpdateSetting(c *gin.Context) {
appInfo.Icon = m.Icon appInfo.Icon = m.Icon
appInfo.Volumes = string(volumesStr) appInfo.Volumes = string(volumesStr)
appInfo.Devices = string(devicesStr) appInfo.Devices = string(devicesStr)
appInfo.NetModel = m.NetworkModel
appInfo.Position = m.Position appInfo.Position = m.Position
appInfo.EnableUPNP = m.EnableUPNP appInfo.EnableUPNP = m.EnableUPNP
appInfo.Restart = m.Restart appInfo.Restart = m.Restart
@@ -1087,16 +1126,16 @@ func ContainerUpdateInfo(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: err.Error()}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: err.Error()})
return return
} }
var port model.PortArrey var port model.PortArray
json2.Unmarshal([]byte(appInfo.Ports), &port) json2.Unmarshal([]byte(appInfo.Ports), &port)
var envs model.EnvArrey var envs model.EnvArray
json2.Unmarshal([]byte(appInfo.Envs), &envs) json2.Unmarshal([]byte(appInfo.Envs), &envs)
var vol model.PathArrey var vol model.PathArray
json2.Unmarshal([]byte(appInfo.Volumes), &vol) json2.Unmarshal([]byte(appInfo.Volumes), &vol)
var dir model.PathArrey var dir model.PathArray
json2.Unmarshal([]byte(appInfo.Devices), &dir) json2.Unmarshal([]byte(appInfo.Devices), &dir)
//volumesStr, _ := json2.Marshal(m.Volumes) //volumesStr, _ := json2.Marshal(m.Volumes)

View File

@@ -4,16 +4,17 @@ import (
"bufio" "bufio"
"encoding/csv" "encoding/csv"
"fmt" "fmt"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"path" "path"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
) )
func downloadReadFile(c *gin.Context) { func downloadReadFile(c *gin.Context) {
@@ -218,6 +219,25 @@ func MkdirAll(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)}) c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
} }
// @Summary 创建文件
// @Produce application/json
// @Accept multipart/form-data
// @Tags file
// @Security ApiKeyAuth
// @Param path formData string false "路径"
// @Success 200 {string} string "ok"
// @Router /file/create [post]
func PostCreateFile(c *gin.Context) {
path := c.PostForm("path")
var code int
if len(path) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
code, _ = service.MyService.ZiMa().CreateFile(path)
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
}
// @Summary 上传文件 // @Summary 上传文件
// @Produce application/json // @Produce application/json
// @Accept multipart/form-data // @Accept multipart/form-data

22
route/v1/search.go Normal file
View File

@@ -0,0 +1,22 @@
package v1
import (
"net/http"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
)
func GetSearchList(c *gin.Context) {
key := c.DefaultQuery("key", "")
if len(key) == 0 {
return
}
list, err := service.MyService.Search().SearchList(key)
if err != nil {
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
}

View File

@@ -1,7 +1,12 @@
package v1 package v1
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http"
"strconv"
"time"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
@@ -10,9 +15,6 @@ import (
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types" "github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
"strconv"
"time"
) )
// @Summary 系统信息 // @Summary 系统信息
@@ -26,13 +28,12 @@ func CheckVersion(c *gin.Context) {
need, version := version.IsNeedUpdate() need, version := version.IsNeedUpdate()
if need { if need {
installLog := model2.AppNotify{} installLog := model2.AppNotify{}
installLog.CustomId = ""
installLog.State = 0 installLog.State = 0
installLog.Message = "New version " + version.Version + " is ready, ready to upgrade" installLog.Message = "New version " + version.Version + " is ready, ready to upgrade"
installLog.Speed = 100
installLog.Type = types.NOTIFY_TYPE_NEED_CONFIRM installLog.Type = types.NOTIFY_TYPE_NEED_CONFIRM
installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10) installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10) installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.Name = "CasaOS System"
service.MyService.Notify().AddLog(installLog) service.MyService.Notify().AddLog(installLog)
} }
data := make(map[string]interface{}, 1) data := make(map[string]interface{}, 1)
@@ -51,10 +52,8 @@ func CheckVersion(c *gin.Context) {
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/update [post] // @Router /sys/update [post]
func SystemUpdate(c *gin.Context) { func SystemUpdate(c *gin.Context) {
fmt.Println("开始更新")
need, version := version.IsNeedUpdate() need, version := version.IsNeedUpdate()
if need { if need {
fmt.Println("进入更新")
service.MyService.System().UpdateSystemVersion(version.Version) service.MyService.System().UpdateSystemVersion(version.Version)
} }
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)}) c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
@@ -62,28 +61,40 @@ func SystemUpdate(c *gin.Context) {
//系统配置 //系统配置
func GetSystemConfig(c *gin.Context) { func GetSystemConfig(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: config.SystemConfigInfo}) c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: json.RawMessage(config.SystemConfigInfo.ConfigStr)})
}
// @Summary get logs
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/error/logs [get]
func GetCasaOSErrorLogs(c *gin.Context) {
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
} }
// @Summary 修改配置文件 // @Summary 修改配置文件
// @Produce application/json // @Produce application/json
// @Accept multipart/form-data // @Accept multipart/form-data
// @Tags user // @Tags sys
// @Param file formData file true "用户头像" // @Param file formData file true "用户头像"
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /user/changhead [post] // @Router /sys/changhead [post]
func PostSetSystemConfig(c *gin.Context) { func PostSetSystemConfig(c *gin.Context) {
var systemConfig model.SystemConfig buf := make([]byte, 1024)
c.BindJSON(&systemConfig) n, _ := c.Request.Body.Read(buf)
service.MyService.System().UpSystemConfig(systemConfig)
service.MyService.System().UpSystemConfig(string(buf[0:n]), "")
c.JSON(http.StatusOK, c.JSON(http.StatusOK,
model.Result{ model.Result{
Success: oasis_err.SUCCESS, Success: oasis_err.SUCCESS,
Message: oasis_err.GetMsg(oasis_err.SUCCESS), Message: oasis_err.GetMsg(oasis_err.SUCCESS),
Data: config.SystemConfigInfo, Data: json.RawMessage(config.SystemConfigInfo.ConfigStr),
}) })
return
} }
//系统配置 //系统配置
@@ -98,3 +109,50 @@ func GetSystemConfigDebug(c *gin.Context) {
func Sys(c *gin.Context) { func Sys(c *gin.Context) {
service.DockerPull() service.DockerPull()
} }
//widget配置
func GetWidgetConfig(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: json.RawMessage(config.SystemConfigInfo.WidgetList)})
}
// @Summary 修改组件配置文件
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/widget/config [post]
func PostSetWidgetConfig(c *gin.Context) {
buf := make([]byte, 1024)
n, _ := c.Request.Body.Read(buf)
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
c.JSON(http.StatusOK,
model.Result{
Success: oasis_err.SUCCESS,
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
Data: json.RawMessage(config.SystemConfigInfo.WidgetList),
})
}
// @Summary 检查是否进入引导状态
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /guide/check [get]
func GetGuideCheck(c *gin.Context) {
initUser := false
if !config.UserInfo.Initialized {
initUser = true
}
data := make(map[string]interface{}, 1)
data["need_init_user"] = initUser
c.JSON(http.StatusOK,
model.Result{
Success: oasis_err.SUCCESS,
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
Data: data,
})
}

View File

@@ -2,13 +2,15 @@ package v1
import ( import (
"fmt" "fmt"
"net/http"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err" oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
) )
var user_service service.UserService var user_service service.UserService
@@ -32,7 +34,7 @@ func Set_Name_Pwd(c *gin.Context) {
username := c.PostForm("username") username := c.PostForm("username")
pwd := c.PostForm("pwd") pwd := c.PostForm("pwd")
//老用户名是否存在即新用户名和密码的验证 //老用户名是否存在即新用户名和密码的验证
if len(config.UserInfo.UserName) > 0 || len(username) == 0 || len(pwd) == 0 { if config.UserInfo.Initialized || len(username) == 0 || len(pwd) == 0 {
c.JSON(http.StatusOK, c.JSON(http.StatusOK,
model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)}) model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return return
@@ -69,15 +71,18 @@ func Login(c *gin.Context) {
return return
} }
//if config.UserInfo.UserName == username && config.UserInfo.PWD == pwd { if config.UserInfo.UserName == username && config.UserInfo.PWD == pwd {
if username == "admin" && pwd == "admin" { //if username == "admin" && pwd == "admin" {
token := jwt2.GetToken(username, pwd)
data := make(map[string]string, 2)
data["token"] = jwt2.GetToken(username, pwd)
data["version"] = types.CURRENTVERSION
//user_service.SetUser("", "", token, "", "") //user_service.SetUser("", "", token, "", "")
c.JSON(http.StatusOK, c.JSON(http.StatusOK,
model.Result{ model.Result{
Success: oasis_err2.SUCCESS, Success: oasis_err2.SUCCESS,
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
Data: token, Data: data,
}) })
return return
} }
@@ -106,7 +111,6 @@ func Up_Load_Head(c *gin.Context) {
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
Data: config.UserInfo.Head, Data: config.UserInfo.Head,
}) })
return
} }
// @Summary 修改用户名 // @Summary 修改用户名
@@ -127,7 +131,6 @@ func Chang_User_Name(c *gin.Context) {
} }
user_service.SetUser(username, "", "", "", "") user_service.SetUser(username, "", "", "", "")
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
return
} }
// @Summary 修改密码 // @Summary 修改密码
@@ -142,13 +145,16 @@ func Chang_User_Name(c *gin.Context) {
func Chang_User_Pwd(c *gin.Context) { func Chang_User_Pwd(c *gin.Context) {
oldpwd := c.PostForm("oldpwd") oldpwd := c.PostForm("oldpwd")
pwd := c.PostForm("pwd") pwd := c.PostForm("pwd")
if len(pwd) == 0 || config.UserInfo.PWD != oldpwd { if config.UserInfo.PWD != oldpwd {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_INVALID_OLD, Message: oasis_err2.GetMsg(oasis_err2.PWD_INVALID_OLD)})
return
}
if len(pwd) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_IS_EMPTY, Message: oasis_err2.GetMsg(oasis_err2.PWD_IS_EMPTY)})
return return
} }
user_service.SetUser("", pwd, "", "", "") user_service.SetUser("", pwd, "", "", "")
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
return
} }
// @Summary 修改用户信息 // @Summary 修改用户信息
@@ -174,21 +180,23 @@ func Chang_User_Info(c *gin.Context) {
return return
} }
user_service.SetUser(username, pwd, "", email, description) user_service.SetUser(username, pwd, "", email, description)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) data := make(map[string]string, 2)
return
data["token"] = jwt2.GetToken(username, pwd)
data["user_name"] = username
data["head"] = config.UserInfo.Head
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
} }
// @Summary 获取用户详情 // @Summary 获取用户详情
// @Produce application/json // @Produce application/json
// @Accept mapplication/json // @Accept mapplication/json
// @Tags user // @Tags user
// @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /user/info [get] // @Router /user/info [get]
func UserInfo(c *gin.Context) { func UserInfo(c *gin.Context) {
var u = make(map[string]string, 2) var u = make(map[string]string, 2)
u["user_name"] = config.UserInfo.UserName u["user_name"] = config.UserInfo.UserName
u["token"] = config.UserInfo.Token
u["head"] = config.UserInfo.Head u["head"] = config.UserInfo.Head
u["email"] = config.UserInfo.Email u["email"] = config.UserInfo.Email
u["description"] = config.UserInfo.Description u["description"] = config.UserInfo.Description
@@ -198,5 +206,4 @@ func UserInfo(c *gin.Context) {
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
Data: u, Data: u,
}) })
return
} }

View File

@@ -2,35 +2,31 @@ package service
import ( import (
"context" "context"
json2 "encoding/json" "strings"
"github.com/IceWhaleTech/CasaOS/model" "time"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/docker" "github.com/IceWhaleTech/CasaOS/pkg/docker"
"github.com/IceWhaleTech/CasaOS/pkg/utils/command" "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
client2 "github.com/docker/docker/client" client2 "github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tidwall/gjson"
"gorm.io/gorm" "gorm.io/gorm"
"strings"
"time"
) )
type AppService interface { type AppService interface {
GetMyList(index, size int, position bool) *[]model2.MyAppList GetMyList(index, size int, position bool) *[]model2.MyAppList
SaveContainer(m model2.AppListDBModel) SaveContainer(m model2.AppListDBModel)
GetServerAppInfo(id string) model.ServerAppList
GetUninstallInfo(id string) model2.AppListDBModel GetUninstallInfo(id string) model2.AppListDBModel
RemoveContainerById(id string) RemoveContainerById(id string)
GetContainerInfo(name string) (types.Container, error) GetContainerInfo(name string) (types.Container, error)
GetAppDBInfo(id string) model2.AppListDBModel GetAppDBInfo(id string) model2.AppListDBModel
UpdateApp(m model2.AppListDBModel) UpdateApp(m model2.AppListDBModel)
GetSimpleContainerInfo(name string) (types.Container, error) GetSimpleContainerInfo(name string) (types.Container, error)
DelAppConfigDir(id string) DelAppConfigDir(id, path string)
} }
type appStruct struct { type appStruct struct {
@@ -155,27 +151,6 @@ func (a *appStruct) GetUninstallInfo(id string) model2.AppListDBModel {
return m return m
} }
func (a *appStruct) GetServerAppInfo(id string) model.ServerAppList {
head := make(map[string]string)
t := make(chan string)
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
t <- gjson.Get(str, "data").String()
}()
head["Authorization"] = <-t
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/info/"+id, head)
info := model.ServerAppList{}
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
return info
}
//创建容器成功后保存容器 //创建容器成功后保存容器
func (a *appStruct) SaveContainer(m model2.AppListDBModel) { func (a *appStruct) SaveContainer(m model2.AppListDBModel) {
a.db.Table(model2.CONTAINERTABLENAME).Create(&m) a.db.Table(model2.CONTAINERTABLENAME).Create(&m)
@@ -185,8 +160,8 @@ func (a *appStruct) UpdateApp(m model2.AppListDBModel) {
a.db.Table(model2.CONTAINERTABLENAME).Save(&m) a.db.Table(model2.CONTAINERTABLENAME).Save(&m)
} }
func (a *appStruct) DelAppConfigDir(id string) { func (a *appStruct) DelAppConfigDir(id, path string) {
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;DelAppConfigDir " + docker.GetDir(id, "/config")) command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;DelAppConfigDir " + docker.GetDir(id, path))
} }
func (a *appStruct) RemoveContainerById(id string) { func (a *appStruct) RemoveContainerById(id string) {

View File

@@ -2,34 +2,29 @@ package service
import ( import (
json2 "encoding/json" json2 "encoding/json"
"strconv"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"strconv"
) )
type OasisService interface { type CasaService interface {
GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64)
GetServerCategoryList() []model.ServerCategoryList GetServerCategoryList() []model.ServerCategoryList
GetTaskList(size int) []model2.TaskDBModel GetTaskList(size int) []model2.TaskDBModel
GetServerAppInfo(id string) model.ServerAppList
} }
type oasisService struct { type casaService struct {
} }
func (o *oasisService) GetTaskList(size int) []model2.TaskDBModel { func (o *casaService) GetTaskList(size int) []model2.TaskDBModel {
head := make(map[string]string) head := make(map[string]string)
t := make(chan string) head["Authorization"] = GetToken()
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
t <- gjson.Get(str, "data").String()
}()
head["Authorization"] = <-t
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/"+strconv.Itoa(size), head) listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/"+strconv.Itoa(size), head)
@@ -39,18 +34,11 @@ func (o *oasisService) GetTaskList(size int) []model2.TaskDBModel {
return list return list
} }
func (o *oasisService) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) { func (o *casaService) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) {
head := make(map[string]string) head := make(map[string]string)
t := make(chan string) head["Authorization"] = GetToken()
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
t <- gjson.Get(str, "data").String()
}()
head["Authorization"] = <-t
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/list?index="+index+"&size="+size+"&type="+tp+"&category_id="+categoryId+"&key="+key, head) listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/list?index="+index+"&size="+size+"&type="+tp+"&category_id="+categoryId+"&key="+key, head)
@@ -62,18 +50,10 @@ func (o *oasisService) GetServerList(index, size, tp, categoryId, key string) ([
return list, count return list, count
} }
func (o *oasisService) GetServerCategoryList() []model.ServerCategoryList { func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
head := make(map[string]string) head := make(map[string]string)
head["Authorization"] = GetToken()
t := make(chan string)
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
t <- gjson.Get(str, "data").String()
}()
head["Authorization"] = <-t
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/category", head) listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/category", head)
@@ -83,7 +63,42 @@ func (o *oasisService) GetServerCategoryList() []model.ServerCategoryList {
return list return list
} }
func (o *casaService) GetServerAppInfo(id string) model.ServerAppList {
func NewOasisService() OasisService { head := make(map[string]string)
return &oasisService{}
head["Authorization"] = GetToken()
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/info/"+id, head)
info := model.ServerAppList{}
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
return info
}
func GetToken() string {
t := make(chan string)
keyName := "casa_token"
var auth string
if result, ok := Cache.Get(keyName); ok {
auth, ok = result.(string)
if ok {
return auth
}
}
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
t <- gjson.Get(str, "data").String()
}()
auth = <-t
Cache.SetDefault(keyName, auth)
return auth
}
func NewOasisService() CasaService {
return &casaService{}
} }

View File

@@ -3,14 +3,15 @@ package service
import ( import (
json2 "encoding/json" json2 "encoding/json"
"fmt" "fmt"
"strconv"
"strings"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/disk"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"strconv"
"strings"
) )
type DiskService interface { type DiskService interface {

View File

@@ -7,27 +7,24 @@ import (
"encoding/binary" "encoding/binary"
json2 "encoding/json" json2 "encoding/json"
"fmt" "fmt"
"regexp"
"syscall"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
types2 "github.com/IceWhaleTech/CasaOS/types" types2 "github.com/IceWhaleTech/CasaOS/types"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/cio" "github.com/containerd/containerd/cio"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"syscall"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/docker" "github.com/IceWhaleTech/CasaOS/pkg/docker"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
//"github.com/containerd/containerd/oci" //"github.com/containerd/containerd/oci"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
client2 "github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
@@ -35,6 +32,14 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
client2 "github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
) )
type DockerService interface { type DockerService interface {
@@ -55,6 +60,8 @@ type DockerService interface {
DockerContainerCommit(name string) DockerContainerCommit(name string)
DockerNetworkModelList() []types.NetworkResource DockerNetworkModelList() []types.NetworkResource
DockerImageInfo(image string) DockerImageInfo(image string)
GetNetWorkNameByNetWorkID(id string) (string, error)
ContainerExecShell(container_id string) string
} }
type dockerService struct { type dockerService struct {
@@ -62,15 +69,20 @@ type dockerService struct {
log loger2.OLog log loger2.OLog
} }
func DockerPs() { func (ds *dockerService) ContainerExecShell(container_id string) string {
cli, _ := client2.NewClientWithOpts(client2.FromEnv) cli, _ := client2.NewClientWithOpts(client2.FromEnv)
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) exec, err := cli.ContainerExecCreate(context.Background(), container_id, types.ExecConfig{
User: "1000:1000",
Cmd: []string{"echo -e \"hellow\nworld\" >> /a.txt"},
})
if err != nil { if err != nil {
os.Exit(5) os.Exit(5)
} }
for _, container := range containers { err = cli.ContainerExecStart(context.Background(), exec.ID, types.ExecStartCheck{})
fmt.Printf("%s %s\n", container.ID[:10], container.Image) if err != nil {
fmt.Println("exec script error ", err)
} }
return exec.ID
} }
//创建默认网络 //创建默认网络
@@ -79,6 +91,7 @@ func DockerNetwork() {
cli, _ := client2.NewClientWithOpts(client2.FromEnv) cli, _ := client2.NewClientWithOpts(client2.FromEnv)
defer cli.Close() defer cli.Close()
d, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{}) d, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
for _, resource := range d { for _, resource := range d {
if resource.Name == docker.NETWORKNAME { if resource.Name == docker.NETWORKNAME {
return return
@@ -87,6 +100,19 @@ func DockerNetwork() {
cli.NetworkCreate(context.Background(), docker.NETWORKNAME, types.NetworkCreate{}) cli.NetworkCreate(context.Background(), docker.NETWORKNAME, types.NetworkCreate{})
} }
//根据网络id获取网络名
func (ds *dockerService) GetNetWorkNameByNetWorkID(id string) (string, error) {
cli, _ := client2.NewClientWithOpts(client2.FromEnv)
defer cli.Close()
filter := filters.NewArgs()
filter.Add("id", id)
d, err := cli.NetworkList(context.Background(), types.NetworkListOptions{filter})
if err == nil && len(d) > 0 {
return d[0].Name, nil
}
return "", err
}
//拉取镜像 //拉取镜像
func DockerPull() { func DockerPull() {
@@ -308,7 +334,6 @@ func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) e
} }
m.Type = types2.NOTIFY_TYPE_INSTALL_LOG m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
m.State = 0 m.State = 0
m.Speed = 70
m.Message = string(buf[:n]) m.Message = string(buf[:n])
MyService.Notify().UpdateLog(m) MyService.Notify().UpdateLog(m)
} }
@@ -337,9 +362,13 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
// if net != "host" { // if net != "host" {
// portMaps[nat.Port(fmt.Sprint(m.Port)+"/tcp")] = []nat.PortBinding{{HostIP: "", HostPort: m.PortMap}} // portMaps[nat.Port(fmt.Sprint(m.Port)+"/tcp")] = []nat.PortBinding{{HostIP: "", HostPort: m.PortMap}}
// } // }
port := ""
for _, portMap := range m.Ports { for _, portMap := range m.Ports {
if portMap.CommendPort == m.PortMap && portMap.Protocol == "tcp" || portMap.Protocol == "both" {
port = portMap.ContainerPort
}
if portMap.Protocol == "tcp" { if portMap.Protocol == "tcp" {
tContainer, _ := strconv.Atoi(portMap.ContainerPort) tContainer, _ := strconv.Atoi(portMap.ContainerPort)
if tContainer > 0 { if tContainer > 0 {
ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{} ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{}
@@ -379,6 +408,10 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
var envArr []string var envArr []string
for _, e := range m.Envs { for _, e := range m.Envs {
if strings.HasPrefix(e.Value, "$") {
envArr = append(envArr, e.Name+"="+env_helper.ReplaceDefaultENV(e.Value))
continue
}
if len(e.Value) > 0 { if len(e.Value) > 0 {
if e.Value == "port_map" { if e.Value == "port_map" {
envArr = append(envArr, e.Name+"="+m.PortMap) envArr = append(envArr, e.Name+"="+m.PortMap)
@@ -400,6 +433,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath}) res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath})
} }
} }
hostConfingBind := []string{}
// volumes bind // volumes bind
volumes := []mount.Mount{} volumes := []mount.Mount{}
for _, v := range m.Volumes { for _, v := range m.Volumes {
@@ -409,12 +443,22 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
if len(path) == 0 { if len(path) == 0 {
continue continue
} }
} }
err = file.IsNotExistMkDir(path) path = strings.ReplaceAll(path, "$AppID", containerDbId)
if err != nil { reg1 := regexp.MustCompile(`([^<>/\\\|:""\*\?]+\.\w+$)`)
ds.log.Error("mkdir error", err) result1 := reg1.FindAllStringSubmatch(path, -1)
continue if len(result1) == 0 {
err = file.IsNotExistMkDir(path)
if err != nil {
ds.log.Error("mkdir error", err)
continue
}
} else {
err = file.IsNotExistCreateFile(path)
if err != nil {
ds.log.Error("mkdir error", err)
continue
}
} }
volumes = append(volumes, mount.Mount{ volumes = append(volumes, mount.Mount{
@@ -423,6 +467,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
Target: v.ContainerPath, Target: v.ContainerPath,
}) })
hostConfingBind = append(hostConfingBind, v.Path+":"+v.ContainerPath)
} }
rp := container.RestartPolicy{} rp := container.RestartPolicy{}
@@ -430,11 +475,24 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
if len(m.Restart) > 0 { if len(m.Restart) > 0 {
rp.Name = m.Restart rp.Name = m.Restart
} }
//fmt.Print(port)
healthTest := []string{}
if len(port) > 0 {
healthTest = []string{"CMD-SHELL", "curl -f http://localhost:" + port + m.Index + " || exit 1"}
}
health := &container.HealthConfig{
Test: healthTest,
//Test: []string{},
StartPeriod: 0,
Retries: 1000,
}
fmt.Print(health)
config := &container.Config{ config := &container.Config{
Image: imageName, Image: imageName,
Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin}, Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin},
Env: envArr, Env: envArr,
// Healthcheck: health,
} }
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net)} hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net)}
//if net != "host" { //if net != "host" {
@@ -771,7 +829,6 @@ func Containerd() {
) )
if err != nil { if err != nil {
fmt.Println("333")
fmt.Println(err) fmt.Println(err)
} }
defer container.Delete(ctx, containerd.WithSnapshotCleanup) defer container.Delete(ctx, containerd.WithSnapshotCleanup)
@@ -779,7 +836,6 @@ func Containerd() {
// create a task from the container // create a task from the container
task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio)) task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
if err != nil { if err != nil {
fmt.Println("444")
fmt.Println(err) fmt.Println(err)
} }
defer task.Delete(ctx) defer task.Delete(ctx)
@@ -792,7 +848,6 @@ func Containerd() {
// call start on the task to execute the redis server // call start on the task to execute the redis server
if err = task.Start(ctx); err != nil { if err = task.Start(ctx); err != nil {
fmt.Println("555")
fmt.Println(err) fmt.Println(err)
} }
@@ -802,7 +857,6 @@ func Containerd() {
// kill the process and get the exit status // kill the process and get the exit status
if err = task.Kill(ctx, syscall.SIGTERM); err != nil { if err = task.Kill(ctx, syscall.SIGTERM); err != nil {
fmt.Println("666")
fmt.Println(err) fmt.Println(err)
} }
@@ -811,7 +865,6 @@ func Containerd() {
status := <-exitStatusC status := <-exitStatusC
code, _, err := status.Result() code, _, err := status.Result()
if err != nil { if err != nil {
fmt.Println("777")
fmt.Println(err) fmt.Println(err)
} }
fmt.Printf("redis-server exited with status: %d\n", code) fmt.Printf("redis-server exited with status: %d\n", code)

View File

@@ -3,7 +3,7 @@ package docker_base
import "github.com/IceWhaleTech/CasaOS/model" import "github.com/IceWhaleTech/CasaOS/model"
//过滤mysql关键字 //过滤mysql关键字
func MysqlFilter(c MysqlConfig, envs model.EnvArrey) model.EnvArrey { func MysqlFilter(c MysqlConfig, envs model.EnvArray) model.EnvArray {
for i := 0; i < len(envs); i++ { for i := 0; i < len(envs); i++ {
switch envs[i].Value { switch envs[i].Value {
case "$MYSQL_HOST": case "$MYSQL_HOST":

View File

@@ -1,15 +1,15 @@
package model package model
type AppNotify struct { type AppNotify struct {
CustomId string `gorm:"column:custom_id;primary_key" json:"custom_id"` State int `json:"state"` //0:一直在变动的未读消息 1:未读 2:已读
ContainerId string `json:"container_id,omitempty"` Message string `json:"message"`
State int `json:"state"` //0:一直在变动的未读消息 1:未读 2:已读 CreatedAt string `json:"created_at"`
Message string `json:"message"` UpdatedAt string `json:"updated_at"`
CreatedAt string `gorm:"<-:create;autoCreateTime" json:"created_at"` Id string `json:"id"`
UpdatedAt string `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at"` Type int `json:"type"` // 1:显示即为已读 2:info 3:warning 4:error 5:success
Speed int `json:"speed"` Icon string `json:"icon"`
Id string `gorm:"-" json:"id"` Name string `json:"name"`
Type int `json:"type"` // 1:显示即为已读 2:必须手动点掉 3:error CustomId string `gorm:"column:custom_id;primary_key" json:"custom_id"`
} }
func (p *AppNotify) TableName() string { func (p *AppNotify) TableName() string {

57
service/search.go Normal file
View File

@@ -0,0 +1,57 @@
package service
import (
"fmt"
"io/ioutil"
"path"
"strings"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/types"
)
type SearchService interface {
SearchList(key string) ([]model.SearchFileInfo, error)
}
type searchService struct {
}
func (s *searchService) SearchList(key string) ([]model.SearchFileInfo, error) {
pathName := "/Users/liangjianli/go/CasaOSNew/searchTest"
resArr := []model.SearchFileInfo{}
files, _ := ioutil.ReadDir(pathName)
for _, file := range files {
if file.IsDir() {
tempArr, err := s.SearchList(pathName + "/" + file.Name())
if err != nil {
resArr = append(resArr, tempArr...)
}
} else {
if strings.Contains(file.Name(), key) {
resArr = append(resArr, model.SearchFileInfo{Path: pathName, Name: file.Name(), Type: GetSearchType(path.Ext(file.Name()))})
}
fmt.Println(pathName + "/" + file.Name())
}
}
return resArr, nil
}
func GetSearchType(ext string) int {
var reType int = types.UNKNOWN
switch ext {
case ".png":
reType = types.PICTURE
case ".mp4":
reType = types.MEDIA
case ".mp3":
reType = types.MUSIC
default:
reType = types.UNKNOWN
}
return reType
}
func NewSearchService() SearchService {
return &searchService{}
}

View File

@@ -2,9 +2,12 @@ package service
import ( import (
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/patrickmn/go-cache"
"gorm.io/gorm" "gorm.io/gorm"
) )
var Cache *cache.Cache
var MyService Repository var MyService Repository
type Repository interface { type Repository interface {
@@ -15,7 +18,7 @@ type Repository interface {
//Redis() RedisService //Redis() RedisService
ZeroTier() ZeroTierService ZeroTier() ZeroTierService
ZiMa() ZiMaService ZiMa() ZiMaService
OAPI() OasisService OAPI() CasaService
Disk() DiskService Disk() DiskService
Notify() NotifyServer Notify() NotifyServer
ShareDirectory() ShareDirService ShareDirectory() ShareDirService
@@ -23,6 +26,7 @@ type Repository interface {
Rely() RelyService Rely() RelyService
System() SystemService System() SystemService
Shortcuts() ShortcutsService Shortcuts() ShortcutsService
Search() SearchService
} }
func NewService(db *gorm.DB, log loger2.OLog) Repository { func NewService(db *gorm.DB, log loger2.OLog) Repository {
@@ -42,6 +46,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
rely: NewRelyService(db, log), rely: NewRelyService(db, log),
system: NewSystemService(log), system: NewSystemService(log),
shortcuts: NewShortcutsService(db), shortcuts: NewShortcutsService(db),
search: NewSearchService(),
} }
} }
@@ -53,7 +58,7 @@ type store struct {
docker DockerService docker DockerService
zerotier ZeroTierService zerotier ZeroTierService
zima ZiMaService zima ZiMaService
oapi OasisService oapi CasaService
disk DiskService disk DiskService
notify NotifyServer notify NotifyServer
shareDirectory ShareDirService shareDirectory ShareDirService
@@ -61,6 +66,7 @@ type store struct {
rely RelyService rely RelyService
system SystemService system SystemService
shortcuts ShortcutsService shortcuts ShortcutsService
search SearchService
} }
func (c *store) Rely() RelyService { func (c *store) Rely() RelyService {
@@ -99,7 +105,7 @@ func (c *store) ZeroTier() ZeroTierService {
func (c *store) ZiMa() ZiMaService { func (c *store) ZiMa() ZiMaService {
return c.zima return c.zima
} }
func (c *store) OAPI() OasisService { func (c *store) OAPI() CasaService {
return c.oapi return c.oapi
} }
@@ -112,3 +118,6 @@ func (c *store) ShareDirectory() ShareDirService {
func (c *store) Task() TaskService { func (c *store) Task() TaskService {
return c.task return c.task
} }
func (c *store) Search() SearchService {
return c.search
}

View File

@@ -1,24 +1,25 @@
package service package service
import ( import (
"github.com/IceWhaleTech/CasaOS/model" "io/ioutil"
"os"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"strconv"
) )
type SystemService interface { type SystemService interface {
UpSystemConfig(systemConfig model.SystemConfig) UpSystemConfig(str string, widget string)
UpdateSystemVersion(version string) UpdateSystemVersion(version string)
GetSystemConfigDebug() []string GetSystemConfigDebug() []string
GetCasaOSLogs(lineNumber int) string
} }
type systemService struct { type systemService struct {
log loger.OLog log loger.OLog
} }
func (s *systemService) UpdateSystemVersion(version string) { func (s *systemService) UpdateSystemVersion(version string) {
s.log.Error(version)
//command2.OnlyExec(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) //command2.OnlyExec(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
//s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) //s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/tools.sh ;update " + version)) s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/tools.sh ;update " + version))
@@ -27,41 +28,32 @@ func (s *systemService) UpdateSystemVersion(version string) {
func (s *systemService) GetSystemConfigDebug() []string { func (s *systemService) GetSystemConfigDebug() []string {
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetSysInfo") return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetSysInfo")
} }
func (s *systemService) UpSystemConfig(systemConfig model.SystemConfig) { func (s *systemService) UpSystemConfig(str string, widget string) {
if systemConfig.AutoUpdate != config.SystemConfigInfo.AutoUpdate { if len(str) > 0 && str != config.SystemConfigInfo.ConfigStr {
config.Cfg.Section("system").Key("AutoUpdate").SetValue(strconv.FormatBool(systemConfig.AutoUpdate)) config.Cfg.Section("system").Key("ConfigStr").SetValue(str)
config.SystemConfigInfo.AutoUpdate = systemConfig.AutoUpdate config.SystemConfigInfo.ConfigStr = str
} }
if systemConfig.SearchSwitch != config.SystemConfigInfo.SearchSwitch { if len(widget) > 0 && widget != config.SystemConfigInfo.WidgetList {
config.Cfg.Section("system").Key("SearchSwitch").SetValue(strconv.FormatBool(systemConfig.SearchSwitch)) config.Cfg.Section("system").Key("WidgetList").SetValue(widget)
config.SystemConfigInfo.SearchSwitch = systemConfig.SearchSwitch config.SystemConfigInfo.WidgetList = widget
} }
if systemConfig.WidgetsSwitch != config.SystemConfigInfo.WidgetsSwitch { config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
config.Cfg.Section("system").Key("WidgetsSwitch").SetValue(strconv.FormatBool(systemConfig.WidgetsSwitch))
config.SystemConfigInfo.WidgetsSwitch = systemConfig.WidgetsSwitch
}
if systemConfig.ShortcutsSwitch != config.SystemConfigInfo.ShortcutsSwitch {
config.Cfg.Section("system").Key("ShortcutsSwitch").SetValue(strconv.FormatBool(systemConfig.ShortcutsSwitch))
config.SystemConfigInfo.ShortcutsSwitch = systemConfig.ShortcutsSwitch
}
if len(systemConfig.SearchEngine) > 0 && systemConfig.SearchEngine != config.SystemConfigInfo.SearchEngine {
config.Cfg.Section("system").Key("SearchEngine").SetValue(systemConfig.SearchEngine)
config.SystemConfigInfo.SearchEngine = systemConfig.SearchEngine
}
// if len(systemConfig.Version) > 0 && systemConfig.Version != config.SystemConfigInfo.Version {
// config.Cfg.Section("system").Key("Version").SetValue(systemConfig.Version)
// config.SystemConfigInfo.Version = systemConfig.Version
//}
if len(systemConfig.Background) > 0 && systemConfig.Background != config.SystemConfigInfo.Background {
config.Cfg.Section("system").Key("Background").SetValue(systemConfig.Background)
config.SystemConfigInfo.Background = systemConfig.Background
}
if len(systemConfig.BackgroundType) > 0 && systemConfig.BackgroundType != config.SystemConfigInfo.BackgroundType {
config.Cfg.Section("system").Key("BackgroundType").SetValue(systemConfig.BackgroundType)
config.SystemConfigInfo.BackgroundType = systemConfig.BackgroundType
}
config.Cfg.SaveTo("conf/conf.ini")
} }
func (s *systemService) GetCasaOSLogs(lineNumber int) string {
file, err := os.Open(s.log.Path())
if err != nil {
return err.Error()
}
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil {
return err.Error()
}
return string(content)
}
func NewSystemService(log loger.OLog) SystemService { func NewSystemService(log loger.OLog) SystemService {
return &systemService{log: log} return &systemService{log: log}
} }

View File

@@ -1,10 +1,11 @@
package service package service
import ( import (
"github.com/IceWhaleTech/CasaOS/pkg/config"
"io" "io"
"mime/multipart" "mime/multipart"
"os" "os"
"github.com/IceWhaleTech/CasaOS/pkg/config"
) )
type UserService interface { type UserService interface {
@@ -20,6 +21,8 @@ func (c *user) SetUser(username, pwd, token, email, desc string) error {
if len(username) > 0 { if len(username) > 0 {
config.Cfg.Section("user").Key("UserName").SetValue(username) config.Cfg.Section("user").Key("UserName").SetValue(username)
config.UserInfo.UserName = username config.UserInfo.UserName = username
config.Cfg.Section("user").Key("Initialized").SetValue("true")
config.UserInfo.Initialized = true
} }
if len(pwd) > 0 { if len(pwd) > 0 {
config.Cfg.Section("user").Key("PWD").SetValue(pwd) config.Cfg.Section("user").Key("PWD").SetValue(pwd)
@@ -37,7 +40,7 @@ func (c *user) SetUser(username, pwd, token, email, desc string) error {
config.Cfg.Section("user").Key("Description").SetValue(desc) config.Cfg.Section("user").Key("Description").SetValue(desc)
config.UserInfo.Description = desc config.UserInfo.Description = desc
} }
config.Cfg.SaveTo("conf/conf.ini") config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
return nil return nil
} }

View File

@@ -2,20 +2,22 @@ package service
import ( import (
"fmt" "fmt"
"io/ioutil"
"os"
"runtime"
"strconv"
"strings"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/host"
"github.com/shirou/gopsutil/v3/mem" "github.com/shirou/gopsutil/v3/mem"
"github.com/shirou/gopsutil/v3/net" "github.com/shirou/gopsutil/v3/net"
"io/ioutil"
"os"
"runtime"
"strconv"
"strings"
) )
//系统信息 //系统信息
@@ -30,6 +32,7 @@ type ZiMaService interface {
GetSysInfo() host.InfoStat GetSysInfo() host.InfoStat
GetDirPath(path string) []model.Path GetDirPath(path string) []model.Path
MkdirAll(path string) (int, error) MkdirAll(path string) (int, error)
CreateFile(path string) (int, error)
RenameFile(oldF, newF string) (int, error) RenameFile(oldF, newF string) (int, error)
GetCpuInfo() []cpu.InfoStat GetCpuInfo() []cpu.InfoStat
} }
@@ -81,17 +84,12 @@ func (c *zima) GetDirPath(path string) []model.Path {
ls, _ := ioutil.ReadDir(path) ls, _ := ioutil.ReadDir(path)
dirs := []model.Path{} dirs := []model.Path{}
if strings.Count(path, "/") > 1 { if strings.Count(path, "/") > 0 {
for _, l := range ls { for _, l := range ls {
if !strings.HasPrefix(l.Name(), ".") && l.IsDir() { dirs = append(dirs, model.Path{Name: l.Name(), Path: path + "/" + l.Name(), IsDir: l.IsDir()})
dirs = append(dirs, model.Path{Name: l.Name(), Path: path + l.Name() + "/"})
}
} }
} else { } else {
dirs = append(dirs, model.Path{Name: "mnt", Path: "/mnt/"}) dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true})
dirs = append(dirs, model.Path{Name: "media", Path: "/media/"})
dirs = append(dirs, model.Path{Name: "home", Path: "/home/"})
} }
return dirs return dirs
} }
@@ -133,6 +131,22 @@ func (c *zima) MkdirAll(path string) (int, error) {
if os.IsNotExist(err) { if os.IsNotExist(err) {
os.MkdirAll(path, os.ModePerm) os.MkdirAll(path, os.ModePerm)
return oasis_err.SUCCESS, nil return oasis_err.SUCCESS, nil
} else if strings.Contains(err.Error(), ": not a directory") {
return oasis_err.FILE_OR_DIR_EXISTS, err
}
}
return oasis_err.ERROR, err
}
//create
func (c *zima) CreateFile(path string) (int, error) {
_, err := os.Stat(path)
if err == nil {
return oasis_err.FILE_OR_DIR_EXISTS, nil
} else {
if os.IsNotExist(err) {
file.CreateFile(path)
return oasis_err.SUCCESS, nil
} }
} }
return oasis_err.ERROR, err return oasis_err.ERROR, err

10
types/search.go Normal file
View File

@@ -0,0 +1,10 @@
package types
const (
APPLICATION = iota
MEDIA
PICTURE
MUSIC
SEARCH
UNKNOWN
)

View File

@@ -1,3 +1,4 @@
package types package types
const CURRENTVERSION = "0.1.2" const CURRENTVERSION = "0.1.10"
const BODY = "<li>Add App Store for installation</li><li>add casaOS logs</li><li>add application terminal</li><li>add application logs</li>"

9
web/browserconfig.xml Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/ui/img/icon/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

BIN
web/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
web/img/bg.afedbc0b.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

11
web/img/casa.2579f069.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
</style>
<path class="st0" d="M12,22c5.5,0,10-4.5,10-10S17.5,2,12,2S2,6.5,2,12S6.5,22,12,22z"/>
<path class="st0" d="M12,22c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S8.1,22,12,22z"/>
<path class="st0" d="M12,22c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S9.8,22,12,22z"/>
</svg>

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
web/img/disk.573d4b55.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
web/img/folder.c8ff81f3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="200.000000pt" height="200.000000pt" viewBox="0 0 200.000000 200.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M875 1894 c-11 -2 -51 -11 -88 -20 -341 -78 -610 -364 -673 -714 -82
-459 197 -902 647 -1030 94 -27 277 -37 378 -21 303 47 575 261 690 540 55
133 66 192 65 361 -1 136 -4 165 -27 235 -36 116 -62 170 -123 261 -123 186
-347 336 -566 379 -42 8 -276 15 -303 9z m250 -168 c11 -2 42 -9 70 -16 131
-30 288 -135 387 -260 160 -201 198 -506 93 -745 l-22 -50 2 80 c3 180 -64
351 -184 476 -209 216 -544 260 -807 105 -201 -117 -326 -347 -319 -587 l2
-74 -19 44 c-63 140 -80 332 -44 476 24 94 87 219 147 292 109 133 290 238
448 259 25 3 47 7 49 9 5 4 173 -3 197 -9z m8 -501 c33 -8 85 -31 116 -50 227
-137 305 -418 183 -651 l-21 -39 -1 35 c-9 251 -245 439 -490 389 -186 -38
-323 -200 -330 -389 l-1 -35 -23 45 c-101 194 -61 429 99 578 130 122 292 162
468 117z m-27 -499 c182 -85 183 -345 1 -438 -53 -27 -161 -26 -215 1 -146 75
-180 267 -69 390 63 69 190 90 283 47z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

15
web/img/user.89095c02.svg Normal file
View File

@@ -0,0 +1,15 @@
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_420:1626)">
<path d="M105.303 90.2303C101.758 84.7641 96.8971 80.2755 91.1663 77.1761C85.4355 74.0767 79.0183 72.4657 72.5032 72.4909H47.5032C40.9874 72.4663 34.5698 74.0782 28.839 77.1787C23.1082 80.2792 18.2477 84.769 14.7032 90.2363C13.5758 91.9796 12.5966 93.8143 11.7759 95.7212C13.5427 98.0944 15.4812 100.335 17.5759 102.424C28.8279 113.675 44.0882 119.996 60.0001 119.996C75.9121 119.996 91.1724 113.675 102.424 102.424C104.515 100.333 106.452 98.0929 108.218 95.7212C107.398 93.8145 106.423 91.978 105.303 90.2303Z" fill="#585858"/>
<path d="M102.424 17.5757C94.0333 9.18545 83.3428 3.4717 71.7045 1.15695C60.0662 -1.15781 48.0028 0.0303833 37.0398 4.57128C26.0768 9.11219 16.7064 16.8019 10.1134 26.668C3.5205 36.5342 0.0010934 48.1337 0.000237319 60C-0.0360734 72.8664 4.09527 85.3987 11.776 95.7212C13.5428 98.0944 15.4813 100.335 17.576 102.424C28.828 113.675 44.0883 119.996 60.0002 119.996C75.9122 119.996 91.1725 113.675 102.424 102.424C104.516 100.333 106.452 98.0929 108.218 95.7212C116.773 84.1613 120.894 69.9144 119.83 55.5727C118.767 41.231 112.591 27.7476 102.424 17.5757ZM105.297 90.2303C103.301 93.1993 101.022 95.9678 98.4911 98.4969C88.2822 108.7 74.4396 114.431 60.0063 114.431C45.573 114.431 31.7304 108.7 21.5215 98.4969C18.9927 95.97 16.7154 93.2035 14.7214 90.2363C7.24501 78.996 4.21031 65.3792 6.20611 52.0277C8.20191 38.6763 15.0859 26.5422 25.5226 17.9795C35.9592 9.41683 49.2044 5.03605 62.6885 5.68711C76.1725 6.33817 88.9341 11.9746 98.4972 21.503C107.396 30.4094 112.936 42.1221 114.177 54.6509C115.418 67.1796 112.282 79.7515 105.303 90.2303H105.297Z" fill="#585858"/>
<path d="M39.0305 44.8545C39.0305 47.6083 39.5729 50.3351 40.6267 52.8793C41.6806 55.4234 43.2252 57.7351 45.1724 59.6823C47.1196 61.6296 49.4313 63.1742 51.9755 64.228C54.5196 65.2818 57.2464 65.8242 60.0002 65.8242C62.754 65.8242 65.4808 65.2818 68.025 64.228C70.5691 63.1742 72.8808 61.6296 74.828 59.6823C76.7752 57.7351 78.3199 55.4234 79.3737 52.8793C80.4275 50.3351 80.9699 47.6083 80.9699 44.8545C80.9699 42.1007 80.4275 39.3739 79.3737 36.8298C78.3199 34.2856 76.7752 31.9739 74.828 30.0267C72.8808 28.0795 70.5691 26.5349 68.025 25.4811C65.4808 24.4272 62.754 23.8848 60.0002 23.8848C57.2464 23.8848 54.5196 24.4272 51.9755 25.4811C49.4313 26.5349 47.1196 28.0795 45.1724 30.0267C43.2252 31.9739 41.6806 34.2856 40.6267 36.8298C39.5729 39.3739 39.0305 42.1007 39.0305 44.8545Z" fill="#585858"/>
<circle cx="60" cy="60" r="60" fill="#2276F3"/>
<circle cx="59.9998" cy="45.0001" r="20" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.2061 99.9198C21.2482 82.8587 39.0184 70.5001 59.9998 70.5001C80.9812 70.5001 98.7515 82.8589 104.794 99.9201C93.805 112.242 77.8085 120 60 120C42.1912 120 26.1946 112.241 15.2061 99.9198Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_420:1626">
<rect width="120" height="120" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
web/img/xfile.402f9e59.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

37
web/index.html Normal file
View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script>
if (document.URL.indexOf("ui") === -1) {
window.location.replace("ui")
}
</script>
<link rel="apple-touch-icon" sizes="180x180" href="/ui/img/icon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/ui/img/icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/ui/img/icon/favicon-16x16.png">
<link rel="manifest" href="/ui/site.webmanifest">
<link rel="mask-icon" href="/ui/img/icon/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="/ui/favicon.ico">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@mdi/font@6.2.95/css/materialdesignicons.min.css">
<title>
CasaOS
</title>
<link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/chunk-vendors.js" rel="preload" as="script"></head>
<body>
<noscript>
<strong>We're sorry but CasaOS doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/ui/js/chunk-vendors.js"></script><script type="text/javascript" src="/ui/js/app.js"></script></body>
</html>

221
web/js/0.js Normal file

File diff suppressed because one or more lines are too long

26
web/js/1.js Normal file

File diff suppressed because one or more lines are too long

4165
web/js/2.js Normal file

File diff suppressed because one or more lines are too long

108
web/js/3.js Normal file

File diff suppressed because one or more lines are too long

63
web/js/4.js Normal file

File diff suppressed because one or more lines are too long

627
web/js/app.js Normal file

File diff suppressed because one or more lines are too long

2859
web/js/chunk-vendors.js Normal file

File diff suppressed because one or more lines are too long

14
web/site.webmanifest Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/ui/img/icon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}