mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 21:14:41 +00:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7ebdc040f | ||
|
|
6c235d3f2a | ||
|
|
997d912f4d | ||
|
|
2508a4e07d | ||
|
|
90b997337c | ||
|
|
0bb3c92335 | ||
|
|
7fd539c57e | ||
|
|
52bd22ab2b | ||
|
|
46e9458e82 | ||
|
|
3f5595e794 | ||
|
|
d22cc7d3f6 | ||
|
|
eb03a3e6c7 | ||
|
|
65cc1f4752 | ||
|
|
99db197a39 | ||
|
|
7e2a5d553c | ||
|
|
f02337b83b | ||
|
|
f66b67b0c9 | ||
|
|
91087b5341 | ||
|
|
c67191d8c2 | ||
|
|
0fac461783 | ||
|
|
ec5bc922e7 | ||
|
|
7194792c3f | ||
|
|
76c8bade7f | ||
|
|
126857fab0 | ||
|
|
9ca57e105e | ||
|
|
2651140095 | ||
|
|
14175bc438 | ||
|
|
956328da86 | ||
|
|
cc46a96a75 | ||
|
|
049090444e | ||
|
|
796c25b7a5 | ||
|
|
9057290188 | ||
|
|
fcc57bb734 | ||
|
|
a98f5e087c | ||
|
|
403d563869 | ||
|
|
88c15104b4 | ||
|
|
6176289b88 | ||
|
|
5cfd44da79 | ||
|
|
2437da33a6 | ||
|
|
49ca0af746 | ||
|
|
9440b89fab | ||
|
|
f020c1162d | ||
|
|
120fb2cea2 | ||
|
|
37130966cf | ||
|
|
795b82c42c | ||
|
|
57ad33d53a | ||
|
|
a6ceee7bc0 | ||
|
|
44bb05fad0 | ||
|
|
a5fee0ee97 | ||
|
|
da99b2d01a | ||
|
|
1433e3297b | ||
|
|
cad7af13af | ||
|
|
39cb8904a3 | ||
|
|
2ed372b3cd | ||
|
|
8bca76b78b | ||
|
|
595e0f28af | ||
|
|
4939fe10aa | ||
|
|
d2962a8e70 | ||
|
|
d7d53d639b | ||
|
|
d2ff1b0506 | ||
|
|
7191735737 | ||
|
|
21f3fd85d9 | ||
|
|
ba77e07e36 | ||
|
|
0d6e7ca339 | ||
|
|
b1d5d9858b | ||
|
|
4f06be0e45 | ||
|
|
812ffd56a8 | ||
|
|
6ba845eec5 | ||
|
|
4fa72289ed | ||
|
|
5cdd842a3e | ||
|
|
cc5504c0a9 | ||
|
|
b3aa22605d | ||
|
|
32e00b17b1 | ||
|
|
16108f03ac | ||
|
|
e7f990b224 | ||
|
|
c5d824c4ba | ||
|
|
39ccbe251f | ||
|
|
e69d2e587b | ||
|
|
8a28d3c589 | ||
|
|
8fe0e4aa73 | ||
|
|
30a23a93a2 | ||
|
|
53157fbb1f | ||
|
|
fb15695dab | ||
|
|
5f5091f1e2 | ||
|
|
df92766c74 | ||
|
|
cc8b3e8f06 | ||
|
|
a116db8dbd | ||
|
|
d697547cb7 | ||
|
|
01960c0391 | ||
|
|
953c393e71 | ||
|
|
0873f7dd46 | ||
|
|
8d93a7f320 | ||
|
|
801eca0a14 | ||
|
|
a3ec7b70c9 | ||
|
|
4a77548b23 | ||
|
|
15ccade3d3 | ||
|
|
587fb6fb8a | ||
|
|
5bcb663ac8 | ||
|
|
cbd945536d | ||
|
|
081e9213c2 | ||
|
|
966fae2d4c | ||
|
|
dc4f9ea990 | ||
|
|
05b9c75714 | ||
|
|
4aeeea2325 | ||
|
|
72531cf6c2 | ||
|
|
9ad9be8c61 | ||
|
|
1aa15932a0 | ||
|
|
dbc6a4265a | ||
|
|
edea1f144a | ||
|
|
85c59c03cf | ||
|
|
a1f57bf1d1 | ||
|
|
e6f2c46c28 | ||
|
|
55c6c21aa3 | ||
|
|
40617185e9 | ||
|
|
c3dba45e17 | ||
|
|
83f58366a6 | ||
|
|
3fa09dad8e | ||
|
|
f0f0eb2ef0 | ||
|
|
436b87f8a8 | ||
|
|
f0888ef2ac | ||
|
|
03e23ec203 |
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: Submit application
|
||||||
|
about: Add an app to this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: LinkLeong
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Tested platform
|
||||||
|
e.g. linux/amd64,linux/arm-v7,linux-arm64
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Please export and upload the configuration file of this application
|
||||||
148
.github/workflows/casa.yml
vendored
Normal file
148
.github/workflows/casa.yml
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# This is a basic workflow to help you get started with Actions
|
||||||
|
|
||||||
|
name: Build CasaOS
|
||||||
|
|
||||||
|
on:
|
||||||
|
repository_dispatch:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
ssh:
|
||||||
|
description: 'SSH connection to Actions'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
|
||||||
|
#on:
|
||||||
|
# push:
|
||||||
|
# branches:
|
||||||
|
# - 'main'
|
||||||
|
# tags:
|
||||||
|
# - 'v*'
|
||||||
|
env:
|
||||||
|
REPO_URL: https://github.com/IceWhaleTech/CasaOS.git
|
||||||
|
REPO_BRANCH: main
|
||||||
|
PACK_SH_URL: https://raw.githubusercontent.com/jerrykuku/actions-casa/main/pack.sh
|
||||||
|
PACK_SH: pack.sh
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
xgo:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
go_version:
|
||||||
|
- 1.17.1
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# - name: Get release
|
||||||
|
# id: get_release
|
||||||
|
# uses: bruceadams/get-release@v1.2.3
|
||||||
|
# env:
|
||||||
|
# GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
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: |
|
||||||
|
echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||||
|
echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: Build frontend with nodejs and yarn
|
||||||
|
run: |
|
||||||
|
cd UI
|
||||||
|
ls
|
||||||
|
yarn install
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
- name: list work
|
||||||
|
run: pwd
|
||||||
|
|
||||||
|
- name: Build with xgo
|
||||||
|
uses: crazy-max/ghaction-xgo@v1
|
||||||
|
with:
|
||||||
|
xgo_version: latest
|
||||||
|
go_version: ${{ matrix.go_version }}
|
||||||
|
dest: build
|
||||||
|
prefix: casa
|
||||||
|
targets: linux/amd64,linux/arm64,linux/arm-7
|
||||||
|
v: true
|
||||||
|
x: false
|
||||||
|
race: false
|
||||||
|
ldflags: -s -w
|
||||||
|
buildmode: default
|
||||||
|
#
|
||||||
|
# - name: List Files
|
||||||
|
# run: |
|
||||||
|
# ls
|
||||||
|
# mkdir build
|
||||||
|
# ls
|
||||||
|
# echo "::set-output name=status::success"
|
||||||
|
|
||||||
|
- name: Pack builds
|
||||||
|
run: |
|
||||||
|
wget $PACK_SH_URL
|
||||||
|
chmod +x $PACK_SH
|
||||||
|
./$PACK_SH
|
||||||
|
echo "::set-output name=status::success"
|
||||||
|
- name: list work
|
||||||
|
run: ls
|
||||||
|
|
||||||
|
|
||||||
|
- name: Update release
|
||||||
|
uses: meeDamian/github-release@2.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
files: >
|
||||||
|
linux-amd64-casaos.tar.gz
|
||||||
|
linux-arm64-casaos.tar.gz
|
||||||
|
linux-arm-7-casaos.tar.gz
|
||||||
|
tag: v${{ env.VERSION }}
|
||||||
|
body: >
|
||||||
|
${{ env.BODY }}
|
||||||
|
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
|
||||||
79
.github/workflows/demo.yml
vendored
Normal file
79
.github/workflows/demo.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
name: Demo Reset
|
||||||
|
|
||||||
|
# Controls when the workflow will run
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 * * * *"
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "CasaOS-Demo-Snapshot-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')
|
||||||
|
# OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')
|
||||||
|
# NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
# This workflow contains a single job called "build"
|
||||||
|
reset:
|
||||||
|
# The type of runner that the job will run on
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
|
steps:
|
||||||
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Configure AWS credentials from Test account
|
||||||
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
|
with:
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-region: us-west-2
|
||||||
|
|
||||||
|
- name: Get old instance and snapshot name, create new instance name
|
||||||
|
run: |
|
||||||
|
echo "OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "CasaOS-Demo-Snapshot-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||||
|
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||||
|
echo "NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Create instances from snapshot
|
||||||
|
run: |
|
||||||
|
aws lightsail create-instances-from-snapshot \
|
||||||
|
--instance-snapshot-name ${{ env.OLD_INSTANCE_SNAPSHOT_NAME }} \
|
||||||
|
--instance-names ${{ env.NEW_INSTANCE_NAME }} \
|
||||||
|
--availability-zone us-west-2a \
|
||||||
|
--bundle-id large_2_0
|
||||||
|
|
||||||
|
- name: Wait for new instance running
|
||||||
|
run: |
|
||||||
|
TIMEOUT=$(($(date +%s)+600))
|
||||||
|
while [ $TIMEOUT -gt $(date +%s) ]
|
||||||
|
do
|
||||||
|
NEW_INSTANCE_STATE=$(aws lightsail get-instance-state --instance-name ${{ env.NEW_INSTANCE_NAME }} | grep '"name":' | sed 's/ //g' | sed 's/"//g' | sed 's/name://g')
|
||||||
|
if [ $NEW_INSTANCE_STATE == running ]
|
||||||
|
then
|
||||||
|
echo "New instance is running now"
|
||||||
|
sleep 10s
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Put instance public ports
|
||||||
|
run: |
|
||||||
|
aws lightsail put-instance-public-ports \
|
||||||
|
--port-infos fromPort=0,toPort=65535,protocol=all \
|
||||||
|
--instance-name ${{ env.NEW_INSTANCE_NAME }}
|
||||||
|
|
||||||
|
- name: Attach static ip
|
||||||
|
run: |
|
||||||
|
aws lightsail attach-static-ip \
|
||||||
|
--static-ip-name CasaOS-Demo-IP \
|
||||||
|
--instance-name ${{ env.NEW_INSTANCE_NAME }}
|
||||||
|
|
||||||
|
- name: Delete old instance
|
||||||
|
run: |
|
||||||
|
aws lightsail delete-instance \
|
||||||
|
--instance-name ${{ env.OLD_INSTANCE_NAME }}
|
||||||
|
|
||||||
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -1,3 +1,4 @@
|
|||||||
[submodule "CasaOS-UI"]
|
[submodule "UI"]
|
||||||
path = CasaOS-UI
|
path = UI
|
||||||
url = https://github.com/IceWhaleTech/CasaOS-UI.git
|
url = https://github.com/IceWhaleTech/CasaOS-UI.git
|
||||||
|
branch = main
|
||||||
Submodule CasaOS-UI deleted from 6139d87e80
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
89
README.md
89
README.md
@@ -1,4 +1,4 @@
|
|||||||
# CasaOS - A simple, easy-to-use, elegant open-source home server system.
|
# CasaOS - A simple, easy-to-use, elegant open-source Home Cloud system.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -8,23 +8,59 @@
|
|||||||
[](https://github.com/IceWhaleTech/CasaOS/stargazers)
|
[](https://github.com/IceWhaleTech/CasaOS/stargazers)
|
||||||
[](https://discord.gg/Gx4BCEtHjx)
|
[](https://discord.gg/Gx4BCEtHjx)
|
||||||
|
|
||||||
CasaOS is an open-source home server system based on the Docker ecosystem and designed for home scenarios. It is committed to building the world's most simple, easy-to-use, and elegant home server system.
|
CasaOS is an open-source Home Cloud system based on the Docker ecosystem and designed for home scenarios. It is committed to building the world's most simple, easy-to-use, and elegant Home Cloud system.
|
||||||
|
|
||||||
IceWhale team believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
IceWhale team believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
## Features
|
## Getting Started
|
||||||
|
|
||||||
|
> ⚠️ Note:
|
||||||
|
>
|
||||||
|
> CasaOS is still in the early development stage and may vary significantly with the final release. Feel free to test run and share your feedback in the [Discord server](https://discord.gg/Gx4BCEtHjx)!
|
||||||
|
|
||||||
|
### Quick Setup CasaOS
|
||||||
|
|
||||||
|
Fresh install a system from the list below and run the this command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wget -qO- https://get.icewhale.io/casaos.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -fsSL https://get.icewhale.io/casaos.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Uninstall CasaOS
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Compatibility
|
||||||
|
|
||||||
|
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
||||||
|
- Raspberry Pi Lite OS aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
||||||
|
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
||||||
|
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
||||||
|
- OpenWrt 21.02 aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
||||||
|
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
- UI designed for home scenarios - simple, elegant, and easy-to-use
|
- UI designed for home scenarios - simple, elegant, and easy-to-use
|
||||||
- Quick Docker app installation with only three steps
|
- Quick Docker app installation with only three steps, plus automatic management
|
||||||
- Automatic Docker application management
|
- App Store for Home Cloud 🚧
|
||||||
- App Store for private cloud 🚧
|
|
||||||
- Home data/digital asset management 🚧
|
- Home data/digital asset management 🚧
|
||||||
- Smart home manager 🚧
|
- Smart home manager 🚧
|
||||||
|
|
||||||
🚧 is under development.
|
🚧 is under development.
|
||||||
|
|
||||||
We are actively moving forward with development, and you are more than welcome to share any idea in the [Discord server](https://discord.gg/Gx4BCEtHjx)!
|
We are actively moving forward with development, and you are more than welcome to share any idea with us!
|
||||||
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
@@ -40,43 +76,6 @@ So, we set out to build this open source project to develop CasaOS with our own
|
|||||||
[](https://discord.gg/Gx4BCEtHjx)
|
[](https://discord.gg/Gx4BCEtHjx)
|
||||||
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
> ⚠️ Note:
|
|
||||||
>
|
|
||||||
> CasaOS is still in the early development stage and may vary significantly with the final release. Feel free to test run and share your feedback in the [Discord server](https://discord.gg/Gx4BCEtHjx)!
|
|
||||||
|
|
||||||
### System Compatibility
|
|
||||||
|
|
||||||
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
|
||||||
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- Raspberry Pi OS aarch64/arm64 (🚧 Under Planning)
|
|
||||||
- OpenWrt 21.02 aarch64/arm64 (🚧 Under Planning)
|
|
||||||
|
|
||||||
### Quick Setup CasaOS
|
|
||||||
|
|
||||||
Fresh install a system from the above list and run the below command:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
curl -fsSL https://get.icewhale.io/casaos.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## To Do
|
|
||||||
|
|
||||||
**v 0.1.x**
|
|
||||||
|
|
||||||
- [x] An elegant UI for home scenarios
|
|
||||||
- [x] Custom installation of Docker Apps
|
|
||||||
- [x] Update, stop, uninstall, restart, etc. of Docker apps
|
|
||||||
- [x] Docker CLI parser
|
|
||||||
- [x] System Update
|
|
||||||
- [ ] Getting Started tutorial
|
|
||||||
- [ ] Docker Compose parser
|
|
||||||
- [ ] App config file import and export
|
|
||||||
- [ ] macvlan network mode
|
|
||||||
|
|
||||||
|
|
||||||
## Maintainers
|
## Maintainers
|
||||||
- Jerry Liu
|
- Jerry Liu
|
||||||
@@ -84,4 +83,4 @@ curl -fsSL https://get.icewhale.io/casaos.sh | bash
|
|||||||
- Ober Zhang
|
- Ober Zhang
|
||||||
- Zyaire Ann
|
- Zyaire Ann
|
||||||
- John Guan
|
- John Guan
|
||||||
- More seats vacant for the right person
|
- Right here, waiting for YOU!
|
||||||
1
UI
Submodule
1
UI
Submodule
Submodule UI added at a982eb4bdd
@@ -1,52 +1,42 @@
|
|||||||
[app]
|
[app]
|
||||||
PAGE_SIZE = 10
|
PAGE_SIZE = 10
|
||||||
RuntimeRootPath = runtime/
|
RuntimeRootPath = runtime/
|
||||||
;LogSavePath = /casaOS/logs/server/
|
LogSavePath = /casaOS/logs/server/
|
||||||
LogSavePath = /oasis/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
|
||||||
DateFormat = 2006-01-02
|
DateFormat = 2006-01-02
|
||||||
;ProjectPath = /casaOS/server
|
ProjectPath = /casaOS/server
|
||||||
ProjectPath = /oasis/server
|
|
||||||
|
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
HttpPort = 8089
|
HttpPort = 8089
|
||||||
RunMode = debug
|
RunMode = release
|
||||||
;ServerApi = http://113.52.135.30:8090
|
ServerApi = https://api.casaos.zimaboard.com
|
||||||
;ServerApi = https://casaos.zimaboard.com
|
|
||||||
;ServerApi = http://192.168.2.167:8090
|
|
||||||
ServerApi = http://192.168.2.142:8090
|
|
||||||
|
|
||||||
[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://baidu.com1
|
|
||||||
BackgroundType = d
|
|
||||||
|
|
||||||
2901
docs/docs.go
2901
docs/docs.go
File diff suppressed because it is too large
Load Diff
2839
docs/swagger.json
2839
docs/swagger.json
File diff suppressed because it is too large
Load Diff
1753
docs/swagger.yaml
1753
docs/swagger.yaml
File diff suppressed because it is too large
Load Diff
24
go.mod
24
go.mod
@@ -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,21 +47,20 @@ 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.10.2
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/sjson v1.2.3
|
||||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
||||||
github.com/ugorji/go v1.2.6 // indirect
|
github.com/ugorji/go v1.2.6 // indirect
|
||||||
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
|
||||||
|
|||||||
57
go.sum
57
go.sum
@@ -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,19 +735,20 @@ 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=
|
||||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/tidwall/gjson v1.8.0 h1:Qt+orfosKn0rbNTZqHYDqBrmm3UDA4KRkv70fDzG+PQ=
|
github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
|
||||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
|
||||||
|
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
||||||
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
|
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
|
||||||
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
|
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
|
||||||
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
||||||
@@ -787,7 +790,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 +906,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 +995,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 +1007,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 +1079,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=
|
||||||
|
|||||||
32
main.go
32
main.go
@@ -3,53 +3,65 @@ 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()
|
||||||
|
route.InitFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
// @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秒执行一次)
|
||||||
err := cron2.AddFunc("0 0 0 1/1 * *", func() {
|
err := cron2.AddFunc("0 0 0 1/1 * *", func() {
|
||||||
//service.UpdataDDNSList(mysqldb)
|
//service.UpdataDDNSList(mysqldb)
|
||||||
service.SyncTask(sqliteDB)
|
//service.SyncTask(sqliteDB)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Cors() gin.HandlerFunc {
|
func Cors() gin.HandlerFunc {
|
||||||
@@ -17,7 +18,7 @@ func Cors() gin.HandlerFunc {
|
|||||||
//服务器支持的所有跨域请求的方法
|
//服务器支持的所有跨域请求的方法
|
||||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
|
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
|
||||||
//允许跨域设置可以返回其他子段,可以自定义字段
|
//允许跨域设置可以返回其他子段,可以自定义字段
|
||||||
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session")
|
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language")
|
||||||
// 允许浏览器(客户端)可以解析的头部 (重要)
|
// 允许浏览器(客户端)可以解析的头部 (重要)
|
||||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
|
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
|
||||||
//设置缓存时间
|
//设置缓存时间
|
||||||
|
|||||||
55
model/app.go
55
model/app.go
@@ -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 {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type LSBLKModel struct {
|
|||||||
Tran string `json:"tran"`
|
Tran string `json:"tran"`
|
||||||
MinIO uint64 `json:"min-io"`
|
MinIO uint64 `json:"min-io"`
|
||||||
UsedPercent float64 `json:"used_percent"`
|
UsedPercent float64 `json:"used_percent"`
|
||||||
|
Serial string `json:"serial"`
|
||||||
Children []LSBLKModel `json:"children"`
|
Children []LSBLKModel `json:"children"`
|
||||||
//详情特有
|
//详情特有
|
||||||
StartSector uint64 `json:"start_sector,omitempty"`
|
StartSector uint64 `json:"start_sector,omitempty"`
|
||||||
|
|||||||
8
model/docker.go
Normal file
8
model/docker.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type DockerStatsModel struct {
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
Pre interface{} `json:"pre"`
|
||||||
|
}
|
||||||
@@ -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
7
model/search.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type SearchFileInfo struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
}
|
||||||
@@ -15,13 +15,15 @@ type UserModel struct {
|
|||||||
Head string
|
Head string
|
||||||
Email string
|
Email string
|
||||||
Description string
|
Description string
|
||||||
|
Initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//服务配置
|
//服务配置
|
||||||
type ServerModel struct {
|
type ServerModel struct {
|
||||||
HttpPort string
|
HttpPort string
|
||||||
RunMode string
|
RunMode string
|
||||||
ServerApi string
|
ServerApi string
|
||||||
|
LockAccount bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//服务配置
|
//服务配置
|
||||||
@@ -60,11 +62,13 @@ 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"`
|
SyncPort string `json:"sync_port"`
|
||||||
BackgroundType string `json:"background_type"`
|
SyncKey string `json:"sync_key"`
|
||||||
Background string `json:"background"`
|
}
|
||||||
AutoUpdate bool `json:"auto_update"`
|
|
||||||
|
type CasaOSGlobalVariables struct {
|
||||||
|
AddApp bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8
model/system_app/sync.go
Normal file
8
model/system_app/sync.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package system_app
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type SyncConfig struct {
|
||||||
|
XMLName xml.Name `xml:"configuration"`
|
||||||
|
Key string `xml:"gui>apikey"`
|
||||||
|
}
|
||||||
@@ -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
11
pkg/cache/cache.go
vendored
Normal 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)
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
//系统配置
|
//系统配置
|
||||||
@@ -32,6 +33,8 @@ var ServerInfo = &model.ServerModel{}
|
|||||||
|
|
||||||
var SystemConfigInfo = &model.SystemConfig{}
|
var SystemConfigInfo = &model.SystemConfig{}
|
||||||
|
|
||||||
|
var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
|
||||||
|
|
||||||
var Cfg *ini.File
|
var Cfg *ini.File
|
||||||
|
|
||||||
//初始化设置,获取系统的部分信息。
|
//初始化设置,获取系统的部分信息。
|
||||||
@@ -55,6 +58,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
15
pkg/config/update.go
Normal 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()
|
||||||
|
}
|
||||||
@@ -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"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,33 @@
|
|||||||
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") || strings.Contains(strings.ToLower(envName), "photoprism/storage") || strings.Contains(strings.ToLower(envName), "config"):
|
||||||
|
path = "/DATA/AppData/" + id + "/"
|
||||||
|
case strings.Contains(strings.ToLower(envName), "media"):
|
||||||
|
path = "/DATA/Media/"
|
||||||
|
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), "photoprism/originals"):
|
||||||
|
path = "/DATA/Gallery"
|
||||||
|
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/"
|
||||||
|
case strings.ToLower(envName) == "/srv":
|
||||||
|
path = "/DATA/"
|
||||||
|
case strings.ToLower(envName) == "/tv":
|
||||||
|
path = "/DATA/Media/TV Shows"
|
||||||
default:
|
default:
|
||||||
//path = "/media"
|
//path = "/media"
|
||||||
}
|
}
|
||||||
|
|||||||
10
pkg/docker/volumes_test.go
Normal file
10
pkg/docker/volumes_test.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetDir(t *testing.T) {
|
||||||
|
fmt.Println(GetDir("", "config"))
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func GetGithubClient() *github.Client {
|
func GetGithubClient() *github.Client {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ts := oauth2.StaticTokenSource(
|
ts := oauth2.StaticTokenSource(
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package github
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestGetRepos(t *testing.T) {
|
|
||||||
GetRepos()
|
|
||||||
}
|
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetCtrlUrl(host,device string) string {
|
func GetCtrlUrl(host, device string) string {
|
||||||
request := ctrlUrlRequest(host, device)
|
request := ctrlUrlRequest(host, device)
|
||||||
response, _ := http.DefaultClient.Do(request)
|
response, _ := http.DefaultClient.Do(request)
|
||||||
resultBody, _ := ioutil.ReadAll(response.Body)
|
resultBody, _ := ioutil.ReadAll(response.Body)
|
||||||
@@ -86,4 +86,4 @@ func resolve(resultStr string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return controlURL
|
return controlURL
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -22,21 +22,21 @@ func send() (string, error) {
|
|||||||
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
|
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
|
||||||
"MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n"
|
"MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n"
|
||||||
var conn *net.UDPConn
|
var conn *net.UDPConn
|
||||||
remotAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
|
remoteAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("组播地址格式不正确")
|
return "", errors.New("组播地址格式不正确")
|
||||||
}
|
}
|
||||||
locaAddr, err := net.ResolveUDPAddr("udp", ip_helper2.GetLoclIp()+":")
|
localAddr, err := net.ResolveUDPAddr("udp", ip_helper2.GetLoclIp()+":")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("本地ip地址格式不正确")
|
return "", errors.New("本地ip地址格式不正确")
|
||||||
}
|
}
|
||||||
conn, err = net.ListenUDP("udp", locaAddr)
|
conn, err = net.ListenUDP("udp", localAddr)
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("监听udp出错")
|
return "", errors.New("监听udp出错")
|
||||||
}
|
}
|
||||||
_, err = conn.WriteToUDP([]byte(str), remotAddr)
|
_, err = conn.WriteToUDP([]byte(str), remoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("发送msg到组播地址出错")
|
return "", errors.New("发送msg到组播地址出错")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ import "testing"
|
|||||||
func TestGateway(t *testing.T) {
|
func TestGateway(t *testing.T) {
|
||||||
|
|
||||||
Gateway()
|
Gateway()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,40 +2,37 @@ package upnp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
////添加一个端口映射
|
////添加一个端口映射
|
||||||
func (n *Upnp)AddPortMapping(localPort, remotePort int, protocol string) (err error) {
|
func (n *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) {
|
||||||
defer func(err error) {
|
defer func() {
|
||||||
if errTemp := recover(); errTemp != nil {
|
if errTemp := recover(); errTemp != nil {
|
||||||
//log.Println("upnp模块报错了", errTemp)
|
loger2.NewOLoger().Error("upnp模块报错了", errTemp)
|
||||||
err = errTemp.(error)
|
|
||||||
}
|
}
|
||||||
}(err)
|
}()
|
||||||
if issuccess := addSend(localPort, remotePort, protocol,n.GatewayHost, n.CtrlUrl,n.LocalHost); issuccess {
|
|
||||||
|
if isSuccess := addSend(localPort, remotePort, protocol, n.GatewayHost, n.CtrlUrl, n.LocalHost); isSuccess {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return errors.New("添加一个端口映射失败")
|
return errors.New("添加一个端口映射失败")
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSend(localPort, remotePort int, protocol, host, ctrUrl,localHost string) bool {
|
func addSend(localPort, remotePort int, protocol, host, ctrUrl, localHost string) bool {
|
||||||
request := addRequest(localPort, remotePort, protocol, host, ctrUrl,localHost)
|
request := addRequest(localPort, remotePort, protocol, host, ctrUrl, localHost)
|
||||||
response, _ := http.DefaultClient.Do(request)
|
response, _ := http.DefaultClient.Do(request)
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
//resultBody, _ := ioutil.ReadAll(response.Body)
|
//resultBody, _ := ioutil.ReadAll(response.Body)
|
||||||
//fmt.Println(string(resultBody))
|
//fmt.Println(string(resultBody))
|
||||||
if response.StatusCode == 200 {
|
return response.StatusCode == 200
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
@@ -45,7 +42,7 @@ type Node struct {
|
|||||||
Child []Node
|
Child []Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl,localHost string) *http.Request {
|
func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl, localHost string) *http.Request {
|
||||||
//请求头
|
//请求头
|
||||||
header := http.Header{}
|
header := http.Header{}
|
||||||
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
||||||
@@ -109,27 +106,25 @@ func (n *Node) BuildXML() string {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Upnp)DelPortMapping(remotePort int, protocol string) bool {
|
func (n *Upnp) DelPortMapping(remotePort int, protocol string) bool {
|
||||||
issuccess := delSendSend(remotePort, protocol,n.GatewayHost,n.CtrlUrl)
|
isSuccess := delSendSend(remotePort, protocol, n.GatewayHost, n.CtrlUrl)
|
||||||
if issuccess {
|
if isSuccess {
|
||||||
//this.MappingPort.delMapping(remotePort, protocol)
|
//this.MappingPort.delMapping(remotePort, protocol)
|
||||||
//fmt.Println("删除了一个端口映射: remote:", remotePort)
|
//fmt.Println("删除了一个端口映射: remote:", remotePort)
|
||||||
}
|
}
|
||||||
return issuccess
|
return isSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
func delSendSend(remotePort int, protocol,host,ctlUrl string) bool {
|
func delSendSend(remotePort int, protocol, host, ctlUrl string) bool {
|
||||||
delrequest := delbuildRequest(remotePort, protocol,host,ctlUrl)
|
delrequest := delbuildRequest(remotePort, protocol, host, ctlUrl)
|
||||||
response, _ := http.DefaultClient.Do(delrequest)
|
response, _ := http.DefaultClient.Do(delrequest)
|
||||||
//resultBody, _ := ioutil.ReadAll(response.Body)
|
//resultBody, _ := ioutil.ReadAll(response.Body)
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
if response.StatusCode == 200 {
|
|
||||||
// log.Println(string(resultBody))
|
return response.StatusCode == 200
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func delbuildRequest(remotePort int, protocol,host,ctlUrl string) *http.Request {
|
|
||||||
|
func delbuildRequest(remotePort int, protocol, host, ctlUrl string) *http.Request {
|
||||||
//请求头
|
//请求头
|
||||||
header := http.Header{}
|
header := http.Header{}
|
||||||
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
||||||
@@ -160,4 +155,4 @@ func delbuildRequest(remotePort int, protocol,host,ctlUrl string) *http.Request
|
|||||||
request.Header = header
|
request.Header = header
|
||||||
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
|
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import (
|
|||||||
|
|
||||||
type Upnp struct {
|
type Upnp struct {
|
||||||
LocalHost string `json:"local_host"`
|
LocalHost string `json:"local_host"`
|
||||||
GatewayName string `json:"gateway_name"` //网关名称
|
GatewayName string `json:"gateway_name"` //网关名称
|
||||||
GatewayHost string `json:"gateway_host"` //网关ip和端口
|
GatewayHost string `json:"gateway_host"` //网关ip和端口
|
||||||
DeviceDescUrl string `json:"device_desc_url"` //设备描述url
|
DeviceDescUrl string `json:"device_desc_url"` //设备描述url
|
||||||
CtrlUrl string `json:"ctrl_url"` //控制请求url
|
CtrlUrl string `json:"ctrl_url"` //控制请求url
|
||||||
}
|
}
|
||||||
|
|
||||||
func Testaaa() {
|
func Testaaa() {
|
||||||
@@ -23,4 +23,3 @@ func Testaaa() {
|
|||||||
fmt.Println("gateway ip address: ", upnpMan.Gateway.Host)
|
fmt.Println("gateway ip address: ", upnpMan.Gateway.Host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ import (
|
|||||||
|
|
||||||
func TestTestaaa(t *testing.T) {
|
func TestTestaaa(t *testing.T) {
|
||||||
(Testaaa())
|
(Testaaa())
|
||||||
}
|
}
|
||||||
|
|||||||
19
pkg/utils/env_helper/env.go
Normal file
19
pkg/utils/env_helper/env.go
Normal 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"))
|
||||||
|
}
|
||||||
@@ -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,36 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadFullFile(path string) []byte {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return []byte("")
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
content, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return []byte("")
|
||||||
|
}
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|||||||
176
pkg/utils/file/reader.go
Normal file
176
pkg/utils/file/reader.go
Normal 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--
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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请求
|
||||||
@@ -52,10 +53,13 @@ func Get(url string, head map[string]string) (response string) {
|
|||||||
//发送POST请求
|
//发送POST请求
|
||||||
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
||||||
//content:请求放回的内容
|
//content:请求放回的内容
|
||||||
func Post(url string, data interface{}, contentType string) (content string) {
|
func Post(url string, data []byte, contentType string, head map[string]string) (content string) {
|
||||||
jsonStr, _ := json.Marshal(data)
|
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||||
req.Header.Add("content-type", contentType)
|
req.Header.Add("content-type", contentType)
|
||||||
|
for k, v := range head {
|
||||||
|
req.Header.Add(k, v)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -2,12 +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"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc {
|
func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc {
|
||||||
@@ -22,13 +22,15 @@ func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc {
|
|||||||
code = oasis_err2.INVALID_PARAMS
|
code = oasis_err2.INVALID_PARAMS
|
||||||
}
|
}
|
||||||
if swagHandler == nil {
|
if swagHandler == nil {
|
||||||
claims, err := ParseToken(token)
|
//claims, err := ParseToken(token)
|
||||||
|
_, err := ParseToken(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
code = oasis_err2.ERROR_AUTH_TOKEN
|
code = oasis_err2.ERROR_AUTH_TOKEN
|
||||||
|
|
||||||
} else if time.Now().Unix() > claims.ExpiresAt {
|
|
||||||
code = oasis_err2.ERROR_AUTH_TOKEN
|
|
||||||
}
|
}
|
||||||
|
//else if time.Now().Unix() > claims.ExpiresAt {
|
||||||
|
// code = oasis_err2.ERROR_AUTH_TOKEN
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if code != oasis_err2.SUCCESS {
|
if code != oasis_err2.SUCCESS {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -7,10 +7,16 @@ 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
|
||||||
|
ACCOUNT_LOCK = 10004
|
||||||
//system
|
//system
|
||||||
DIR_ALREADY_EXISTS = 20001
|
DIR_ALREADY_EXISTS = 20001
|
||||||
|
FILE_ALREADY_EXISTS = 20002
|
||||||
|
FILE_OR_DIR_EXISTS = 20003
|
||||||
|
PORT_IS_OCCUPIED = 20004
|
||||||
|
|
||||||
//zerotier
|
//zerotier
|
||||||
GET_TOKEN_ERROR = 30001
|
GET_TOKEN_ERROR = 30001
|
||||||
@@ -35,11 +41,16 @@ 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",
|
||||||
|
ACCOUNT_LOCK: "Account Lock",
|
||||||
|
|
||||||
//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",
|
||||||
|
PORT_IS_OCCUPIED: "Port is occupied",
|
||||||
|
|
||||||
//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",
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRandomString(t *testing.T) {
|
func TestRandomString(t *testing.T) {
|
||||||
fmt.Println(RandomString(6,true))
|
fmt.Println(RandomString(6, true))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
201
route/init.go
Normal file
201
route/init.go
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model/system_app"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
||||||
|
"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/port"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitFunction() {
|
||||||
|
go checkSystemApp()
|
||||||
|
Update2_3()
|
||||||
|
}
|
||||||
|
|
||||||
|
var syncIsExistence = false
|
||||||
|
|
||||||
|
func installSyncthing(appId string) {
|
||||||
|
|
||||||
|
var appInfo model.ServerAppList
|
||||||
|
m := model.CustomizationPostData{}
|
||||||
|
var dockerImage string
|
||||||
|
var dockerImageVersion string
|
||||||
|
|
||||||
|
appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
|
||||||
|
|
||||||
|
dockerImage = appInfo.Image
|
||||||
|
|
||||||
|
if len(appInfo.ImageVersion) == 0 {
|
||||||
|
dockerImageVersion = "latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
if appInfo.NetworkModel != "host" {
|
||||||
|
for i := 0; i < len(appInfo.Ports); i++ {
|
||||||
|
if p, _ := strconv.Atoi(appInfo.Ports[i].ContainerPort); port.IsPortAvailable(p, appInfo.Ports[i].Protocol) {
|
||||||
|
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
||||||
|
} else {
|
||||||
|
if appInfo.Ports[i].Protocol == "tcp" {
|
||||||
|
if p, err := port.GetAvailablePort("tcp"); err == nil {
|
||||||
|
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
||||||
|
}
|
||||||
|
} else if appInfo.Ports[i].Protocol == "upd" {
|
||||||
|
if p, err := port.GetAvailablePort("udp"); err == nil {
|
||||||
|
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if appInfo.Ports[i].Type == 0 {
|
||||||
|
appInfo.PortMap = appInfo.Ports[i].CommendPort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(appInfo.Devices); i++ {
|
||||||
|
if !file.CheckNotExist(appInfo.Devices[i].ContainerPath) {
|
||||||
|
appInfo.Devices[i].Path = appInfo.Devices[i].ContainerPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(appInfo.Tip) > 0 {
|
||||||
|
appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(appInfo.Volumes); i++ {
|
||||||
|
appInfo.Volumes[i].Path = docker.GetDir("", appInfo.Volumes[i].ContainerPath)
|
||||||
|
}
|
||||||
|
appInfo.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
|
||||||
|
|
||||||
|
id := uuid.NewV4().String()
|
||||||
|
|
||||||
|
installLog := model2.AppNotify{}
|
||||||
|
|
||||||
|
// step:下载镜像
|
||||||
|
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
|
||||||
|
if err != nil {
|
||||||
|
//pull image error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.CpuShares = 50
|
||||||
|
m.Envs = appInfo.Envs
|
||||||
|
m.Memory = int64(appInfo.MaxMemory)
|
||||||
|
m.Origin = "system"
|
||||||
|
m.PortMap = appInfo.PortMap
|
||||||
|
m.Ports = appInfo.Ports
|
||||||
|
m.Restart = "always"
|
||||||
|
m.Volumes = appInfo.Volumes
|
||||||
|
|
||||||
|
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// create container error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//step:start container
|
||||||
|
err = service.MyService.Docker().DockerContainerStart(id)
|
||||||
|
if err != nil {
|
||||||
|
//start container error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
portsStr, _ := json.Marshal(appInfo.Ports)
|
||||||
|
envsStr, _ := json.Marshal(appInfo.Envs)
|
||||||
|
volumesStr, _ := json.Marshal(appInfo.Volumes)
|
||||||
|
devicesStr, _ := json.Marshal(appInfo.Devices)
|
||||||
|
//step: 保存数据到数据库
|
||||||
|
md := model2.AppListDBModel{
|
||||||
|
CustomId: id,
|
||||||
|
Title: appInfo.Title,
|
||||||
|
//ScreenshotLink: appInfo.ScreenshotLink,
|
||||||
|
Slogan: appInfo.Tagline,
|
||||||
|
Description: appInfo.Description,
|
||||||
|
//Tags: appInfo.Tags,
|
||||||
|
Icon: appInfo.Icon,
|
||||||
|
Version: dockerImageVersion,
|
||||||
|
ContainerId: containerId,
|
||||||
|
Image: dockerImage,
|
||||||
|
Index: appInfo.Index,
|
||||||
|
PortMap: appInfo.PortMap,
|
||||||
|
Label: appInfo.Title,
|
||||||
|
EnableUPNP: false,
|
||||||
|
Ports: string(portsStr),
|
||||||
|
Envs: string(envsStr),
|
||||||
|
Volumes: string(volumesStr),
|
||||||
|
Position: true,
|
||||||
|
NetModel: appInfo.NetworkModel,
|
||||||
|
Restart: m.Restart,
|
||||||
|
CpuShares: 50,
|
||||||
|
Memory: int64(appInfo.MaxMemory),
|
||||||
|
Devices: string(devicesStr),
|
||||||
|
Origin: m.Origin,
|
||||||
|
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
|
||||||
|
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
|
||||||
|
}
|
||||||
|
service.MyService.App().SaveContainer(md)
|
||||||
|
|
||||||
|
checkSystemApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the system application is installed
|
||||||
|
func checkSystemApp() {
|
||||||
|
list := service.MyService.App().GetSystemAppList()
|
||||||
|
for _, v := range *list {
|
||||||
|
if v.Image == "linuxserver/syncthing" {
|
||||||
|
if v.State != "running" {
|
||||||
|
//step:start container
|
||||||
|
service.MyService.Docker().DockerContainerStart(v.CustomId)
|
||||||
|
}
|
||||||
|
syncIsExistence = true
|
||||||
|
if config.SystemConfigInfo.SyncPort != v.Port {
|
||||||
|
config.SystemConfigInfo.SyncPort = v.Port
|
||||||
|
}
|
||||||
|
var paths []model.PathMap
|
||||||
|
json.Unmarshal([]byte(v.Volumes), &paths)
|
||||||
|
path := ""
|
||||||
|
for _, i := range paths {
|
||||||
|
if i.ContainerPath == "/config" {
|
||||||
|
path = docker.GetDir(v.CustomId, i.ContainerPath) + "config.xml"
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
if file.CheckNotExist(path) {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content := file.ReadFullFile(path)
|
||||||
|
syncConfig := &system_app.SyncConfig{}
|
||||||
|
xml.Unmarshal(content, &syncConfig)
|
||||||
|
config.SystemConfigInfo.SyncKey = syncConfig.Key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !syncIsExistence {
|
||||||
|
installSyncthing("44")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func CheckSerialDiskMount() {
|
||||||
|
// 检查挂载点重新挂载
|
||||||
|
// 检查新硬盘是否有多个分区,如有多个分区需提示
|
||||||
|
}
|
||||||
|
func Update2_3() {
|
||||||
|
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
|
||||||
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
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
|
||||||
|
var OnlineDemo bool = false
|
||||||
|
|
||||||
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,10 +28,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("/v1/guide/check", v1.GetGuideCheck)
|
||||||
|
|
||||||
r.GET("/debug", v1.GetSystemConfigDebug)
|
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")
|
||||||
|
|
||||||
@@ -38,8 +46,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 +55,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")
|
||||||
@@ -135,6 +141,8 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
|
|||||||
{
|
{
|
||||||
//获取我的已安装的列表
|
//获取我的已安装的列表
|
||||||
v1AppGroup.GET("/mylist", v1.MyAppList)
|
v1AppGroup.GET("/mylist", v1.MyAppList)
|
||||||
|
//
|
||||||
|
v1AppGroup.GET("/usage", v1.AppUsageList)
|
||||||
//app详情
|
//app详情
|
||||||
v1AppGroup.GET("/appinfo/:id", v1.AppInfo)
|
v1AppGroup.GET("/appinfo/:id", v1.AppInfo)
|
||||||
//获取未安装的列表
|
//获取未安装的列表
|
||||||
@@ -170,7 +178,7 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
|
|||||||
v1AppGroup.GET("/rely/:id/info", v1.ContainerRelyInfo)
|
v1AppGroup.GET("/rely/:id/info", v1.ContainerRelyInfo)
|
||||||
v1AppGroup.GET("/install/config", v1.GetDockerInstallConfig)
|
v1AppGroup.GET("/install/config", v1.GetDockerInstallConfig)
|
||||||
//v1AppGroup.POST("/custom/install", v1.CustomInstallApp)
|
//v1AppGroup.POST("/custom/install", v1.CustomInstallApp)
|
||||||
|
v1AppGroup.POST("/share", v1.ShareAppFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
v1SysGroup := v1Group.Group("/sys")
|
v1SysGroup := v1Group.Group("/sys")
|
||||||
@@ -182,7 +190,13 @@ 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)
|
||||||
|
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
||||||
|
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||||
|
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
|
||||||
}
|
}
|
||||||
v1FileGroup := v1Group.Group("/file")
|
v1FileGroup := v1Group.Group("/file")
|
||||||
v1FileGroup.Use()
|
v1FileGroup.Use()
|
||||||
@@ -194,6 +208,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)
|
||||||
@@ -211,7 +226,7 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
|
|||||||
v1DiskGroup.POST("/format", v1.FormatDisk)
|
v1DiskGroup.POST("/format", v1.FormatDisk)
|
||||||
|
|
||||||
//添加分区
|
//添加分区
|
||||||
v1DiskGroup.POST("/addpart", v1.AddPartition)
|
v1DiskGroup.POST("/part", v1.AddPartition)
|
||||||
|
|
||||||
//获取可以格式化的内容
|
//获取可以格式化的内容
|
||||||
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
||||||
@@ -219,6 +234,12 @@ func InitRouter(swagHandler gin.HandlerFunc) *gin.Engine {
|
|||||||
//删除分区
|
//删除分区
|
||||||
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
||||||
|
|
||||||
|
//mount SATA disk
|
||||||
|
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||||
|
|
||||||
|
//umount SATA disk
|
||||||
|
v1DiskGroup.POST("/umount", v1.DeleteUmountDisk)
|
||||||
|
|
||||||
}
|
}
|
||||||
v1ShareGroup := v1Group.Group("/share")
|
v1ShareGroup := v1Group.Group("/share")
|
||||||
v1ShareGroup.Use()
|
v1ShareGroup.Use()
|
||||||
@@ -252,6 +273,14 @@ 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)
|
||||||
|
}
|
||||||
|
v1Group.GET("/sync/config", v1.GetSyncConfig)
|
||||||
|
v1Group.Any("/syncthing/*url", v1.SyncToSyncthing)
|
||||||
|
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
125
route/v1/app.go
125
route/v1/app.go
@@ -1,15 +1,19 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"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 获取远程列表
|
||||||
@@ -99,6 +103,18 @@ func MyAppList(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary my app hardware usage list
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags app
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /app/usage [get]
|
||||||
|
func AppUsageList(c *gin.Context) {
|
||||||
|
list := service.MyService.App().GetHardwareUsage()
|
||||||
|
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary 应用详情
|
// @Summary 应用详情
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -110,51 +126,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
|
||||||
|
|
||||||
@@ -180,3 +211,27 @@ func CategoryList(c *gin.Context) {
|
|||||||
list = append(list, rear...)
|
list = append(list, rear...)
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary 分享该应用配置
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags app
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /app/share [post]
|
||||||
|
func ShareAppFile(c *gin.Context) {
|
||||||
|
str, _ := ioutil.ReadAll(c.Request.Body)
|
||||||
|
content := service.MyService.OAPI().ShareAppFile(str)
|
||||||
|
c.JSON(http.StatusOK, json.RawMessage(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Resource Usage
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags app
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /app/share [post]
|
||||||
|
func AppListResourceUsage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func DDNSAddConfig(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var m model2.DDNSUpdataDBModel
|
var m model2.DDNSUpdateDBModel
|
||||||
c.Bind(&m)
|
c.Bind(&m)
|
||||||
if err := service.MyService.DDNS().SaveConfig(m); err != nil {
|
if err := service.MyService.DDNS().SaveConfig(m); err != nil {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/shirou/gopsutil/v3/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Summary 获取磁盘列表
|
// @Summary 获取磁盘列表
|
||||||
@@ -59,7 +59,7 @@ func GetPlugInDisk(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: lst})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: lst})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取磁盘列表
|
// @Summary get disk list
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
@@ -76,12 +76,12 @@ func GetPlugInDisks(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: result})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: result})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 磁盘详情
|
// @Summary disk detail
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path query string true "要获取的磁盘详情 例如/dev/sda"
|
// @Param path query string true "for example /dev/sda"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/info [get]
|
// @Router /disk/info [get]
|
||||||
func GetDiskInfo(c *gin.Context) {
|
func GetDiskInfo(c *gin.Context) {
|
||||||
@@ -93,7 +93,7 @@ func GetDiskInfo(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: m})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: m})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 磁盘详情
|
// @Summary format disk
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
@@ -109,15 +109,9 @@ func FormatDisk(c *gin.Context) {
|
|||||||
if len(path) == 0 || len(t) == 0 {
|
if len(path) == 0 || len(t) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
//删除挂载点
|
|
||||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
|
||||||
|
|
||||||
//格式化磁盘
|
//格式化磁盘
|
||||||
service.MyService.Disk().FormatDisk(path, t)
|
service.MyService.Disk().FormatDisk(path, t)
|
||||||
|
|
||||||
//重新挂载
|
|
||||||
|
|
||||||
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)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,25 +148,43 @@ func RemovePartition(c *gin.Context) {
|
|||||||
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)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 添加分区
|
// @Summary serial number
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string true "磁盘路径 例如/dev/sda"
|
// @Param path formData string true "磁盘路径 例如/dev/sda"
|
||||||
// @Param size formData string true "需要分区容量大小(MB)"
|
// @Param serial formData string true "serial"
|
||||||
// @Param num formData string true "磁盘符号"
|
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/addpart [post]
|
// @Router /disk/addpart [post]
|
||||||
func AddPartition(c *gin.Context) {
|
func AddPartition(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
size, _ := strconv.Atoi(c.DefaultPostForm("size", "0"))
|
serial := c.PostForm("serial")
|
||||||
num := c.DefaultPostForm("num", "9")
|
if len(path) == 0 || len(serial) == 0 {
|
||||||
if len(path) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
service.MyService.Disk().AddPartition(path)
|
||||||
//size*1024*1024/512
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
service.MyService.Disk().AddPartition(path, num, uint64(size*1024*2))
|
}
|
||||||
|
|
||||||
|
func PostMountDisk(c *gin.Context) {
|
||||||
|
// for example: path=/dev/sda1
|
||||||
|
path := c.PostForm("path")
|
||||||
|
//执行挂载目录
|
||||||
|
service.MyService.Disk().MountDisk(path, "volume")
|
||||||
|
//添加到数据库
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteUmountDisk(c *gin.Context) {
|
||||||
|
|
||||||
|
// for example: path=/dev/sda1
|
||||||
|
path := c.PostForm("path")
|
||||||
|
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||||
|
|
||||||
|
//删除数据库记录
|
||||||
|
|
||||||
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)})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,14 @@ 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/config"
|
||||||
"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"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
@@ -19,11 +26,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 +68,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 +174,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 +240,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)
|
||||||
@@ -238,11 +268,11 @@ func InstallApp(c *gin.Context) {
|
|||||||
rely.ContainerId = mysqlContainerId
|
rely.ContainerId = mysqlContainerId
|
||||||
rely.CustomId = mid
|
rely.CustomId = mid
|
||||||
rely.ContainerCustomId = id
|
rely.ContainerCustomId = id
|
||||||
var msqlConfig model2.MysqlConfigs
|
var mysqlConfig model2.MysqlConfigs
|
||||||
|
|
||||||
//结构体转换
|
//结构体转换
|
||||||
copier.Copy(&msqlConfig, &mc)
|
copier.Copy(&mysqlConfig, &mc)
|
||||||
rely.Config = msqlConfig
|
rely.Config = mysqlConfig
|
||||||
service.MyService.Rely().Create(rely)
|
service.MyService.Rely().Create(rely)
|
||||||
|
|
||||||
relyMap["mysql"] = mid
|
relyMap["mysql"] = mid
|
||||||
@@ -250,16 +280,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 +294,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 +309,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 +392,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 +408,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)
|
||||||
}
|
}
|
||||||
@@ -390,6 +421,12 @@ func InstallApp(c *gin.Context) {
|
|||||||
rely := model.MapStrings{}
|
rely := model.MapStrings{}
|
||||||
|
|
||||||
copier.Copy(&rely, &relyMap)
|
copier.Copy(&rely, &relyMap)
|
||||||
|
if m.Origin != "custom" {
|
||||||
|
for i := 0; i < len(m.Volumes); i++ {
|
||||||
|
m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].ContainerPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
portsStr, _ := json2.Marshal(m.Ports)
|
portsStr, _ := json2.Marshal(m.Ports)
|
||||||
envsStr, _ := json2.Marshal(m.Envs)
|
envsStr, _ := json2.Marshal(m.Envs)
|
||||||
volumesStr, _ := json2.Marshal(m.Volumes)
|
volumesStr, _ := json2.Marshal(m.Volumes)
|
||||||
@@ -429,6 +466,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
// m.PortMap = m.Port
|
// m.PortMap = m.Port
|
||||||
//}
|
//}
|
||||||
service.MyService.App().SaveContainer(md)
|
service.MyService.App().SaveContainer(md)
|
||||||
|
config.CasaOSGlobalVariables.AddApp = true
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -643,7 +681,7 @@ func UnInstallApp(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//step:删除容器
|
//step:删除容器
|
||||||
err = service.MyService.Docker().DockerContainerRemove(appId)
|
err = service.MyService.Docker().DockerContainerRemove(appId, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.UNINSTALL_APP_ERROR, Message: oasis_err2.GetMsg(oasis_err2.UNINSTALL_APP_ERROR), Data: err.Error()})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.UNINSTALL_APP_ERROR, Message: oasis_err2.GetMsg(oasis_err2.UNINSTALL_APP_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
@@ -658,7 +696,12 @@ 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() {
|
||||||
|
if strings.Contains(v.String(), appId) {
|
||||||
|
service.MyService.App().DelAppConfigDir(v.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//step: 删除install log
|
//step: 删除install log
|
||||||
service.MyService.Notify().DelLog(appId)
|
service.MyService.Notify().DelLog(appId)
|
||||||
@@ -763,7 +806,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,19 +915,24 @@ 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)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = service.MyService.Docker().DockerContainerRemove(id)
|
err = service.MyService.Docker().DockerContainerRemove(id, true)
|
||||||
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)})
|
||||||
return
|
return
|
||||||
@@ -980,6 +1027,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 +1135,20 @@ 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
|
for i := 0; i < len(vol); i++ {
|
||||||
|
vol[i].Path = strings.ReplaceAll(vol[i].Path, "$AppID", appId)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|||||||
@@ -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
22
route/v1/search.go
Normal 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})
|
||||||
|
}
|
||||||
35
route/v1/sync.go
Normal file
35
route/v1/sync.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SyncToSyncthing(c *gin.Context) {
|
||||||
|
u := c.Param("url")
|
||||||
|
target := "http://" + strings.Split(c.Request.Host, ":")[0] + ":" + config.SystemConfigInfo.SyncPort
|
||||||
|
remote, err := url.Parse(target)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proxy := httputil.NewSingleHostReverseProxy(remote)
|
||||||
|
c.Request.Header.Add("X-API-Key", config.SystemConfigInfo.SyncKey)
|
||||||
|
//c.Request.Header.Add("X-API-Key", config.SystemConfigInfo.SyncKey)
|
||||||
|
c.Request.URL.Path = u
|
||||||
|
|
||||||
|
proxy.ServeHTTP(c.Writer, c.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSyncConfig(c *gin.Context) {
|
||||||
|
data := make(map[string]string)
|
||||||
|
data["key"] = config.SystemConfigInfo.SyncKey
|
||||||
|
data["port"] = config.SystemConfigInfo.SyncPort
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
|
||||||
|
}
|
||||||
@@ -1,18 +1,22 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"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"
|
||||||
|
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
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 +30,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 +54,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 +63,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 config formData string true "config json string"
|
||||||
// @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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//系统配置
|
//系统配置
|
||||||
@@ -91,10 +104,120 @@ func GetSystemConfigDebug(c *gin.Context) {
|
|||||||
|
|
||||||
array := service.MyService.System().GetSystemConfigDebug()
|
array := service.MyService.System().GetSystemConfigDebug()
|
||||||
disk := service.MyService.ZiMa().GetDiskInfo()
|
disk := service.MyService.ZiMa().GetDiskInfo()
|
||||||
array = append(array, fmt.Sprintf("disk,totle:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: array})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: array})
|
||||||
}
|
}
|
||||||
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 get casaos server port
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/port [get]
|
||||||
|
func GetCasaOSPort(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: oasis_err.SUCCESS,
|
||||||
|
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
||||||
|
Data: config.ServerInfo.HttpPort,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit casaos server port
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param port formData string true "port"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/port [put]
|
||||||
|
func PutCasaOSPort(c *gin.Context) {
|
||||||
|
port, err := strconv.Atoi(c.PostForm("port"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: oasis_err.ERROR,
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isAvailable := port2.IsPortAvailable(port, "tcp")
|
||||||
|
if !isAvailable {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: oasis_err.PORT_IS_OCCUPIED,
|
||||||
|
Message: oasis_err.GetMsg(oasis_err.PORT_IS_OCCUPIED),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.MyService.System().UpSystemPort(strconv.Itoa(port))
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: oasis_err.SUCCESS,
|
||||||
|
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary active killing casaos
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/kill [post]
|
||||||
|
func PostKillCasaOS(c *gin.Context) {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 修改用户名
|
||||||
@@ -119,6 +123,10 @@ func Up_Load_Head(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/changusername [put]
|
// @Router /user/changusername [put]
|
||||||
func Chang_User_Name(c *gin.Context) {
|
func Chang_User_Name(c *gin.Context) {
|
||||||
|
if config.ServerInfo.LockAccount {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ACCOUNT_LOCK, Message: oasis_err2.GetMsg(oasis_err2.ACCOUNT_LOCK)})
|
||||||
|
return
|
||||||
|
}
|
||||||
oldname := c.PostForm("oldname")
|
oldname := c.PostForm("oldname")
|
||||||
username := c.PostForm("username")
|
username := c.PostForm("username")
|
||||||
if len(username) == 0 || config.UserInfo.UserName != oldname {
|
if len(username) == 0 || config.UserInfo.UserName != oldname {
|
||||||
@@ -127,7 +135,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 +149,20 @@ 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 config.ServerInfo.LockAccount {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ACCOUNT_LOCK, Message: oasis_err2.GetMsg(oasis_err2.ACCOUNT_LOCK)})
|
||||||
|
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 +188,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 +214,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
|
|
||||||
}
|
}
|
||||||
|
|||||||
229
service/app.go
229
service/app.go
@@ -2,35 +2,40 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
json2 "encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"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/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(path string)
|
||||||
|
GetSystemAppList() *[]model2.MyAppList
|
||||||
|
GetHardwareUsageSteam()
|
||||||
|
GetHardwareUsage() []model.DockerStatsModel
|
||||||
|
GetAppStats(id string) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type appStruct struct {
|
type appStruct struct {
|
||||||
@@ -52,11 +57,10 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取本地数据库应用
|
//获取本地数据库应用
|
||||||
|
|
||||||
var lm []model2.AppListDBModel
|
var lm []model2.AppListDBModel
|
||||||
a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan").Find(&lm)
|
a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image").Find(&lm)
|
||||||
|
|
||||||
list := []model2.MyAppList{}
|
list := []model2.MyAppList{}
|
||||||
lMap := make(map[string]interface{})
|
lMap := make(map[string]interface{})
|
||||||
@@ -71,9 +75,8 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||||||
}
|
}
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
|
|
||||||
if lMap[container.ID] != nil {
|
if lMap[container.ID] != nil && container.Labels["origin"] != "system" {
|
||||||
var m model2.AppListDBModel
|
m := lMap[container.ID].(model2.AppListDBModel)
|
||||||
m = lMap[container.ID].(model2.AppListDBModel)
|
|
||||||
if len(m.Label) == 0 {
|
if len(m.Label) == 0 {
|
||||||
m.Label = m.Title
|
m.Label = m.Title
|
||||||
}
|
}
|
||||||
@@ -93,6 +96,7 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||||||
Port: m.PortMap,
|
Port: m.PortMap,
|
||||||
Index: m.Index,
|
Index: m.Index,
|
||||||
UpTime: tm,
|
UpTime: tm,
|
||||||
|
Image: m.Image,
|
||||||
Slogan: m.Slogan,
|
Slogan: m.Slogan,
|
||||||
//Rely: m.Rely,
|
//Rely: m.Rely,
|
||||||
})
|
})
|
||||||
@@ -104,6 +108,66 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//system application list
|
||||||
|
func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
|
||||||
|
//获取docker应用
|
||||||
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
|
if err != nil {
|
||||||
|
a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
fts := filters.NewArgs()
|
||||||
|
fts.Add("label", "origin=system")
|
||||||
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||||
|
if err != nil {
|
||||||
|
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取本地数据库应用
|
||||||
|
|
||||||
|
var lm []model2.AppListDBModel
|
||||||
|
a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
|
||||||
|
|
||||||
|
list := []model2.MyAppList{}
|
||||||
|
lMap := make(map[string]interface{})
|
||||||
|
for _, dbModel := range lm {
|
||||||
|
lMap[dbModel.ContainerId] = dbModel
|
||||||
|
}
|
||||||
|
for _, container := range containers {
|
||||||
|
|
||||||
|
if lMap[container.ID] != nil {
|
||||||
|
m := lMap[container.ID].(model2.AppListDBModel)
|
||||||
|
if len(m.Label) == 0 {
|
||||||
|
m.Label = m.Title
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||||
|
var tm string
|
||||||
|
if err != nil {
|
||||||
|
tm = time.Now().String()
|
||||||
|
} else {
|
||||||
|
tm = info.State.StartedAt
|
||||||
|
}
|
||||||
|
list = append(list, model2.MyAppList{
|
||||||
|
Name: m.Label,
|
||||||
|
Icon: m.Icon,
|
||||||
|
State: container.State,
|
||||||
|
CustomId: strings.ReplaceAll(container.Names[0], "/", ""),
|
||||||
|
Port: m.PortMap,
|
||||||
|
Index: m.Index,
|
||||||
|
UpTime: tm,
|
||||||
|
Image: m.Image,
|
||||||
|
Slogan: m.Slogan,
|
||||||
|
Volumes: m.Volumes,
|
||||||
|
//Rely: m.Rely,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &list
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//获取我的应用列表
|
//获取我的应用列表
|
||||||
func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
||||||
//获取docker应用
|
//获取docker应用
|
||||||
@@ -135,6 +199,10 @@ func (a *appStruct) GetSimpleContainerInfo(name string) (types.Container, error)
|
|||||||
filters := filters.NewArgs()
|
filters := filters.NewArgs()
|
||||||
filters.Add("name", name)
|
filters.Add("name", name)
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
||||||
|
if err != nil {
|
||||||
|
return types.Container{}, err
|
||||||
|
}
|
||||||
|
|
||||||
if len(containers) > 0 {
|
if len(containers) > 0 {
|
||||||
return containers[0], nil
|
return containers[0], nil
|
||||||
}
|
}
|
||||||
@@ -155,27 +223,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,14 +232,124 @@ 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(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 " + path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appStruct) RemoveContainerById(id string) {
|
func (a *appStruct) RemoveContainerById(id string) {
|
||||||
a.db.Table(model2.CONTAINERTABLENAME).Where("custom_id = ?", id).Delete(&model2.AppListDBModel{})
|
a.db.Table(model2.CONTAINERTABLENAME).Where("custom_id = ?", id).Delete(&model2.AppListDBModel{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dataStr map[string]model.DockerStatsModel
|
||||||
|
|
||||||
|
var isFinish bool = false
|
||||||
|
|
||||||
|
func (a *appStruct) GetAppStats(id string) string {
|
||||||
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
con, err := cli.ContainerStats(context.Background(), id, false)
|
||||||
|
if err != nil {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
defer con.Body.Close()
|
||||||
|
c, _ := ioutil.ReadAll(con.Body)
|
||||||
|
return string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel {
|
||||||
|
|
||||||
|
steam := true
|
||||||
|
for !isFinish {
|
||||||
|
if steam {
|
||||||
|
steam = false
|
||||||
|
go func() {
|
||||||
|
a.GetHardwareUsageSteam()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// 切一下,再次分配任务
|
||||||
|
runtime.Gosched()
|
||||||
|
}
|
||||||
|
list := []model.DockerStatsModel{}
|
||||||
|
for _, v := range dataStr {
|
||||||
|
list = append(list, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *appStruct) GetHardwareUsageSteam() {
|
||||||
|
var lock = &sync.Mutex{}
|
||||||
|
if len(dataStr) == 0 {
|
||||||
|
lock.Lock()
|
||||||
|
dataStr = make(map[string]model.DockerStatsModel)
|
||||||
|
lock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
|
var lm []model2.AppListDBModel
|
||||||
|
a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
|
||||||
|
var list []types.ContainerStats
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
if config.CasaOSGlobalVariables.AddApp {
|
||||||
|
a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
|
||||||
|
}
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for _, v := range lm {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(v model2.AppListDBModel, lock *sync.Mutex) {
|
||||||
|
defer wg.Done()
|
||||||
|
stats, err := cli.ContainerStats(ctx, v.ContainerId, true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decode := json.NewDecoder(stats.Body)
|
||||||
|
var data interface{}
|
||||||
|
if err := decode.Decode(&data); err == io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lock.Lock()
|
||||||
|
dockerStats := model.DockerStatsModel{}
|
||||||
|
dockerStats.Pre = dataStr[v.ContainerId].Data
|
||||||
|
|
||||||
|
dockerStats.Data = data
|
||||||
|
dockerStats.Icon = v.Icon
|
||||||
|
dockerStats.Title = v.Label
|
||||||
|
dataStr[v.ContainerId] = dockerStats
|
||||||
|
lock.Unlock()
|
||||||
|
}(v, lock)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
isFinish = true
|
||||||
|
if i == 99 {
|
||||||
|
for _, v := range list {
|
||||||
|
v.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 2)
|
||||||
|
}
|
||||||
|
isFinish = false
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// init install
|
||||||
|
func Init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func NewAppService(db *gorm.DB, logger loger2.OLog) AppService {
|
func NewAppService(db *gorm.DB, logger loger2.OLog) AppService {
|
||||||
|
Init()
|
||||||
return &appStruct{db: db, log: logger}
|
return &appStruct{db: db, log: logger}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,34 +2,39 @@ 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
|
||||||
|
ShareAppFile(body []byte) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type oasisService struct {
|
type casaService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *oasisService) GetTaskList(size int) []model2.TaskDBModel {
|
func (o *casaService) ShareAppFile(body []byte) string {
|
||||||
head := make(map[string]string)
|
head := make(map[string]string)
|
||||||
|
|
||||||
t := make(chan string)
|
head["Authorization"] = GetToken()
|
||||||
|
|
||||||
go func() {
|
content := httper2.Post(config.ServerInfo.ServerApi+"/v1/community/add", body, "application/json", head)
|
||||||
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
t <- gjson.Get(str, "data").String()
|
func (o *casaService) GetTaskList(size int) []model2.TaskDBModel {
|
||||||
}()
|
head := make(map[string]string)
|
||||||
head["Authorization"] = <-t
|
|
||||||
|
head["Authorization"] = GetToken()
|
||||||
|
|
||||||
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 +44,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 +60,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 +73,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{}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
||||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
"github.com/IceWhaleTech/CasaOS/service/ddns"
|
"github.com/IceWhaleTech/CasaOS/service/ddns"
|
||||||
"github.com/IceWhaleTech/CasaOS/service/model"
|
"github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"os/exec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ddnsStruct struct {
|
type ddnsStruct struct {
|
||||||
@@ -20,17 +21,15 @@ type DDNSService interface {
|
|||||||
GetConfigList() *[]model.DDNSList
|
GetConfigList() *[]model.DDNSList
|
||||||
DeleteConfig(id uint) bool
|
DeleteConfig(id uint) bool
|
||||||
GetType(name string) (uint, string)
|
GetType(name string) (uint, string)
|
||||||
SaveConfig(model model.DDNSUpdataDBModel) error
|
SaveConfig(model model.DDNSUpdateDBModel) error
|
||||||
}
|
}
|
||||||
|
|
||||||
//判断当前添加的是否存在
|
//判断当前添加的是否存在
|
||||||
func (d *ddnsStruct) IsExis(t int, domain string, host string) bool {
|
func (d *ddnsStruct) IsExis(t int, domain string, host string) bool {
|
||||||
var count int64
|
var count int64
|
||||||
d.db.Table(model.DDNSLISTTABLENAME).Where("type=? AND domain=? AND host=?", t, domain, host).Count(&count)
|
d.db.Table(model.DDNSLISTTABLENAME).Where("type=? AND domain=? AND host=?", t, domain, host).Count(&count)
|
||||||
if count > 0 {
|
|
||||||
return true
|
return count > 0
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//前台获取已配置的ddns列表
|
//前台获取已配置的ddns列表
|
||||||
@@ -41,7 +40,7 @@ func (d *ddnsStruct) GetConfigList() *[]model.DDNSList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *ddnsStruct) DeleteConfig(id uint) bool {
|
func (d *ddnsStruct) DeleteConfig(id uint) bool {
|
||||||
d.db.Delete(&model.DDNSUpdataDBModel{Id: id})
|
d.db.Delete(&model.DDNSUpdateDBModel{Id: id})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,12 +65,12 @@ func (d *ddnsStruct) GetType(name string) (uint, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//保存配置到数据库
|
//保存配置到数据库
|
||||||
func (d *ddnsStruct) GetDockerRootDir(model model.DDNSUpdataDBModel) error {
|
func (d *ddnsStruct) GetDockerRootDir(model model.DDNSUpdateDBModel) error {
|
||||||
return d.db.Create(&model).Error
|
return d.db.Create(&model).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
//保存配置到数据库
|
//保存配置到数据库
|
||||||
func (d *ddnsStruct) SaveConfig(model model.DDNSUpdataDBModel) error {
|
func (d *ddnsStruct) SaveConfig(model model.DDNSUpdateDBModel) error {
|
||||||
return d.db.Create(&model).Error
|
return d.db.Create(&model).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ func chackPing(b chan bool, url string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//更新列表
|
//更新列表
|
||||||
func UpdataDDNSList(db *gorm.DB) {
|
func UpdateDDNSList(db *gorm.DB) {
|
||||||
var s []model.DDNSCoreList
|
var s []model.DDNSCoreList
|
||||||
db.Table(model.DDNSLISTTABLENAME).Select("o_ddns_type.name as name,o_ddns_type.api_host as api_host,o_ddns.id,`host`,domain,user_name,`password`,`key`,secret,type").Joins("left join o_ddns_type on o_ddns.type=o_ddns_type.id").Scan(&s)
|
db.Table(model.DDNSLISTTABLENAME).Select("o_ddns_type.name as name,o_ddns_type.api_host as api_host,o_ddns.id,`host`,domain,user_name,`password`,`key`,secret,type").Joins("left join o_ddns_type on o_ddns.type=o_ddns_type.id").Scan(&s)
|
||||||
for _, item := range s {
|
for _, item := range s {
|
||||||
|
|||||||
@@ -31,4 +31,3 @@ func SetOauth(request *http.Request, value string) {
|
|||||||
func SetXFilter(request *http.Request, value string) {
|
func SetXFilter(request *http.Request, value string) {
|
||||||
request.Header.Set("X-Filter", value)
|
request.Header.Set("X-Filter", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,17 @@ 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"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"github.com/shirou/gopsutil/v3/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"strconv"
|
"gorm.io/gorm"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiskService interface {
|
type DiskService interface {
|
||||||
@@ -20,11 +23,14 @@ type DiskService interface {
|
|||||||
UmountPointAndRemoveDir(path string) string
|
UmountPointAndRemoveDir(path string) string
|
||||||
GetDiskInfo(path string) model.LSBLKModel
|
GetDiskInfo(path string) model.LSBLKModel
|
||||||
DelPartition(path, num string) string
|
DelPartition(path, num string) string
|
||||||
AddPartition(path, num string, size uint64) string
|
AddPartition(path string) string
|
||||||
GetDiskInfoByPath(path string) *disk.UsageStat
|
GetDiskInfoByPath(path string) *disk.UsageStat
|
||||||
|
MountDisk(path, volume string)
|
||||||
|
SerialAll(mountPoint string) *[]model2.SerialDisk
|
||||||
}
|
}
|
||||||
type diskService struct {
|
type diskService struct {
|
||||||
log loger2.OLog
|
log loger2.OLog
|
||||||
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
//通过脚本获取外挂磁盘
|
//通过脚本获取外挂磁盘
|
||||||
@@ -54,28 +60,17 @@ func (d *diskService) DelPartition(path, num string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
//添加分区
|
//part
|
||||||
func (d *diskService) AddPartition(path, num string, size uint64) string {
|
func (d *diskService) AddPartition(path string) string {
|
||||||
|
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
|
||||||
var maxSector uint64 = 0
|
|
||||||
|
|
||||||
chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + path)
|
|
||||||
if len(chiList) == 0 {
|
|
||||||
d.log.Error("chiList length error")
|
|
||||||
}
|
|
||||||
for i := 0; i < len(chiList); i++ {
|
|
||||||
tempArr := strings.Split(chiList[i], ",")
|
|
||||||
tempSector, _ := strconv.ParseUint(tempArr[2], 10, 64)
|
|
||||||
if tempSector > maxSector {
|
|
||||||
maxSector = tempSector
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r := command2.ExecResultStrArray("source ./shell/helper.sh ;AddPartition " + path + " " + num + " " + strconv.FormatUint(maxSector+1, 10) + " " + strconv.FormatUint(size+maxSector+1, 10))
|
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *diskService) AddAllPartition(path string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//获取硬盘详情
|
//获取硬盘详情
|
||||||
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
||||||
diskInfo, err := disk.Usage(path + "1")
|
diskInfo, err := disk.Usage(path + "1")
|
||||||
@@ -89,7 +84,7 @@ func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
|||||||
return diskInfo
|
return diskInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取磁盘信息
|
//get disk details
|
||||||
func (d *diskService) LSBLK() []model.LSBLKModel {
|
func (d *diskService) LSBLK() []model.LSBLKModel {
|
||||||
str := command2.ExecLSBLK()
|
str := command2.ExecLSBLK()
|
||||||
if str == nil {
|
if str == nil {
|
||||||
@@ -110,7 +105,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||||||
|
|
||||||
var health = true
|
var health = true
|
||||||
for _, i := range m {
|
for _, i := range m {
|
||||||
if i.Children != nil {
|
if i.Type != "loop" && !i.RO {
|
||||||
fsused = 0
|
fsused = 0
|
||||||
for _, child := range i.Children {
|
for _, child := range i.Children {
|
||||||
if child.RM {
|
if child.RM {
|
||||||
@@ -133,7 +128,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||||||
i.Children = c
|
i.Children = c
|
||||||
if fsused > 0 {
|
if fsused > 0 {
|
||||||
i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64)
|
i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64)
|
||||||
fmt.Println(err)
|
d.log.Fatal("diskservice_lsblk_fsused", err)
|
||||||
}
|
}
|
||||||
n = append(n, i)
|
n = append(n, i)
|
||||||
health = true
|
health = true
|
||||||
@@ -196,17 +191,21 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
//func GetDiskInfo(path string) *disk.UsageStat {
|
func (d *diskService) MountDisk(path, volume string) {
|
||||||
// diskInfo, _ := disk.Usage(path)
|
r := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_mount " + path + " " + volume)
|
||||||
// diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
|
fmt.Print(r)
|
||||||
// diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
|
}
|
||||||
// return diskInfo
|
|
||||||
//}
|
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||||
|
d.db.Save(&m)
|
||||||
//func (d *diskService) GetPlugInDisk() []string {
|
}
|
||||||
// return disk.Partitions(false)
|
|
||||||
//}
|
func (d *diskService) SerialAll(mountPoint string) *[]model2.SerialDisk {
|
||||||
|
var m []model2.SerialDisk
|
||||||
func NewDiskService(log loger2.OLog) DiskService {
|
d.db.Find(&m)
|
||||||
return &diskService{log: log}
|
return &m
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
|
||||||
|
return &diskService{log: log, db: db}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,27 +7,25 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
json2 "encoding/json"
|
json2 "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"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 +33,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 {
|
||||||
@@ -47,7 +53,7 @@ type DockerService interface {
|
|||||||
DockerListByImage(image, version string) (*types.Container, error)
|
DockerListByImage(image, version string) (*types.Container, error)
|
||||||
DockerContainerInfo(name string) (*types.ContainerJSON, error)
|
DockerContainerInfo(name string) (*types.ContainerJSON, error)
|
||||||
DockerImageRemove(name string) error
|
DockerImageRemove(name string) error
|
||||||
DockerContainerRemove(name string) error
|
DockerContainerRemove(name string, update bool) error
|
||||||
DockerContainerStop(id string) error
|
DockerContainerStop(id string) error
|
||||||
DockerContainerUpdateName(name, id string) (err error)
|
DockerContainerUpdateName(name, id string) (err error)
|
||||||
DockerContainerUpdate(m model.CustomizationPostData, id string) (err error)
|
DockerContainerUpdate(m model.CustomizationPostData, id string) (err error)
|
||||||
@@ -55,6 +61,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 +70,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 +92,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 +101,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{Filters: filter})
|
||||||
|
if err == nil && len(d) > 0 {
|
||||||
|
return d[0].Name, nil
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
//拉取镜像
|
//拉取镜像
|
||||||
func DockerPull() {
|
func DockerPull() {
|
||||||
|
|
||||||
@@ -131,7 +158,7 @@ func DockerEx() {
|
|||||||
importResponse.Close()
|
importResponse.Close()
|
||||||
println(string(response))
|
println(string(response))
|
||||||
if string(response) != "response" {
|
if string(response) != "response" {
|
||||||
fmt.Println("expected response to contain 'response', got %s", string(response))
|
fmt.Printf("expected response to contain 'response', got %s", string(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +187,6 @@ func (ds *dockerService) DockerImageInfo(image string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func MsqlExec(container string) error {
|
func MsqlExec(container string) error {
|
||||||
@@ -239,6 +265,8 @@ func DockerLogs() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer i.Close()
|
||||||
|
|
||||||
hdr := make([]byte, 8)
|
hdr := make([]byte, 8)
|
||||||
for {
|
for {
|
||||||
_, err := i.Read(hdr)
|
_, err := i.Read(hdr)
|
||||||
@@ -257,7 +285,6 @@ func DockerLogs() {
|
|||||||
_, err = i.Read(dat)
|
_, err = i.Read(dat)
|
||||||
fmt.Fprint(w, string(dat))
|
fmt.Fprint(w, string(dat))
|
||||||
}
|
}
|
||||||
defer i.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//正式内容
|
//正式内容
|
||||||
@@ -306,11 +333,13 @@ func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) e
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
|
if !reflect.DeepEqual(m, model2.AppNotify{}) {
|
||||||
m.State = 0
|
m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
|
||||||
m.Speed = 70
|
m.State = 0
|
||||||
m.Message = string(buf[:n])
|
m.Message = string(buf[:n])
|
||||||
MyService.Notify().UpdateLog(m)
|
MyService.Notify().UpdateLog(m)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -323,7 +352,7 @@ func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) e
|
|||||||
//param udp 容器其他udp端口
|
//param udp 容器其他udp端口
|
||||||
func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId string, m model.CustomizationPostData, net string) (containerId string, err error) {
|
func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId string, m model.CustomizationPostData, net string) (containerId string, err error) {
|
||||||
if len(net) == 0 {
|
if len(net) == 0 {
|
||||||
net = "oasis"
|
net = "bridge"
|
||||||
}
|
}
|
||||||
|
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
@@ -337,9 +366,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 +412,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 +437,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 +447,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 +471,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 +479,22 @@ 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
|
||||||
}
|
}
|
||||||
|
healthTest := []string{}
|
||||||
|
if len(port) > 0 {
|
||||||
|
healthTest = []string{"CMD-SHELL", "curl -f http://localhost:" + port + m.Index + " || exit 1"}
|
||||||
|
}
|
||||||
|
|
||||||
|
health := &container.HealthConfig{
|
||||||
|
Test: healthTest,
|
||||||
|
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" {
|
||||||
@@ -455,7 +515,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
|
|||||||
}
|
}
|
||||||
|
|
||||||
//删除容器
|
//删除容器
|
||||||
func (ds *dockerService) DockerContainerRemove(name string) error {
|
func (ds *dockerService) DockerContainerRemove(name string, update bool) error {
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -464,9 +524,11 @@ func (ds *dockerService) DockerContainerRemove(name string) error {
|
|||||||
err = cli.ContainerRemove(context.Background(), name, types.ContainerRemoveOptions{})
|
err = cli.ContainerRemove(context.Background(), name, types.ContainerRemoveOptions{})
|
||||||
|
|
||||||
//路径处理
|
//路径处理
|
||||||
path := docker.GetDir(name, "/config")
|
if !update {
|
||||||
if !file.CheckNotExist(path) {
|
path := docker.GetDir(name, "/config")
|
||||||
file.RMDir(path)
|
if !file.CheckNotExist(path) {
|
||||||
|
file.RMDir(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -727,7 +789,7 @@ func (ds *dockerService) DockerNetworkModelList() []types.NetworkResource {
|
|||||||
networks, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
|
networks, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||||
return networks
|
return networks
|
||||||
}
|
}
|
||||||
func NewDcokerService(log loger2.OLog) DockerService {
|
func NewDockerService(log loger2.OLog) DockerService {
|
||||||
return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`), log: log}
|
return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`), log: log}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,7 +833,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 +840,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 +852,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 +861,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 +869,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)
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -7,5 +7,3 @@ type MysqlConfig struct {
|
|||||||
DataBasePassword string `json:"data_base_password"`
|
DataBasePassword string `json:"data_base_password"`
|
||||||
DataBaseDB string `json:"data_base_db"`
|
DataBaseDB string `json:"data_base_db"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,14 +26,10 @@ type AppListDBModel struct {
|
|||||||
PortMap string `json:"port_map"`
|
PortMap string `json:"port_map"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
EnableUPNP bool `json:"enable_upnp"`
|
EnableUPNP bool `json:"enable_upnp"`
|
||||||
//Envs model.EnvArrey `json:"envs" bson:"envs"`
|
Envs string `json:"envs"`
|
||||||
//Ports model.PortArrey `json:"ports" bson:"ports"`
|
Ports string `json:"ports"`
|
||||||
//Volumes model.PathArrey `json:"volumes" bson:"volumes"`
|
Volumes string `json:"volumes"`
|
||||||
//Devices model.PathArrey `json:"devices" bson:"devices"`
|
Devices string `json:"devices"`
|
||||||
Envs string `json:"envs"`
|
|
||||||
Ports string `json:"ports"`
|
|
||||||
Volumes string `json:"volumes"`
|
|
||||||
Devices string `json:"devices"`
|
|
||||||
//Envs []model.Env `json:"envs"`
|
//Envs []model.Env `json:"envs"`
|
||||||
//Ports []model.PortMap `gorm:"type:json" json:"ports"`
|
//Ports []model.PortMap `gorm:"type:json" json:"ports"`
|
||||||
//Volumes []model.PathMap `gorm:"type:json" json:"volumes"`
|
//Volumes []model.PathMap `gorm:"type:json" json:"volumes"`
|
||||||
@@ -61,4 +57,6 @@ type MyAppList struct {
|
|||||||
UpTime string `json:"up_time"`
|
UpTime string `json:"up_time"`
|
||||||
Slogan string `json:"slogan"`
|
Slogan string `json:"slogan"`
|
||||||
Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
|
Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
|
||||||
|
Image string `json:"image"`
|
||||||
|
Volumes string `json:"volumes"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package model
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
func (p *DDNSUpdataDBModel) TableName() string {
|
func (p *DDNSUpdateDBModel) TableName() string {
|
||||||
return "o_ddns"
|
return "o_ddns"
|
||||||
}
|
}
|
||||||
|
|
||||||
type DDNSUpdataDBModel struct {
|
type DDNSUpdateDBModel struct {
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
Ipv4 string `gorm:"-"`
|
Ipv4 string `gorm:"-"`
|
||||||
Ipv6 string `gorm:"-"`
|
Ipv6 string `gorm:"-"`
|
||||||
@@ -17,8 +17,8 @@ type DDNSUpdataDBModel struct {
|
|||||||
Secret string `json:"secret" form:"secret"`
|
Secret string `json:"secret" form:"secret"`
|
||||||
UserName string `json:"user_name" form:"user_name"`
|
UserName string `json:"user_name" form:"user_name"`
|
||||||
Password string `json:"password" form:"password"`
|
Password string `json:"password" form:"password"`
|
||||||
CreatedAt time.Time `gorm:"<-:create" json:"created_at"`
|
CreatedAt time.Time `gorm:"<-:create" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const DDNSLISTTABLENAME = "o_ddns"
|
const DDNSLISTTABLENAME = "o_ddns"
|
||||||
@@ -39,9 +39,9 @@ type DDNSList struct {
|
|||||||
|
|
||||||
//定时任务使用
|
//定时任务使用
|
||||||
type DDNSCoreList struct {
|
type DDNSCoreList struct {
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
Domain string `json:"domain" form:"domain"`
|
Domain string `json:"domain" form:"domain"`
|
||||||
Name string `json:"domain" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
Type uint `json:"type"`
|
Type uint `json:"type"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
|
|||||||
14
service/model/o_disk.go
Normal file
14
service/model/o_disk.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
//SerialAdvanced Technology Attachment (STAT)
|
||||||
|
type SerialDisk struct {
|
||||||
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
|
DiskId string `json:"disk_id"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
State int `json:"state"`
|
||||||
|
MountPoint string `json:"mount_point"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SerialDisk) TableName() string {
|
||||||
|
return "o_disk"
|
||||||
|
}
|
||||||
@@ -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
57
service/search.go
Normal 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{}
|
||||||
|
}
|
||||||
@@ -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,25 +26,28 @@ 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 {
|
||||||
|
|
||||||
return &store{
|
return &store{
|
||||||
app: NewAppService(db, log),
|
app: NewAppService(db, log),
|
||||||
ddns: NewDDNSService(db, log),
|
ddns: NewDDNSService(db, log),
|
||||||
user: NewUserService(),
|
user: NewUserService(),
|
||||||
docker: NewDcokerService(log),
|
docker: NewDockerService(log),
|
||||||
//redis: NewRedisService(rp),
|
//redis: NewRedisService(rp),
|
||||||
zerotier: NewZeroTierService(),
|
zerotier: NewZeroTierService(),
|
||||||
zima: NewZiMaService(),
|
zima: NewZiMaService(),
|
||||||
oapi: NewOasisService(),
|
oapi: NewOasisService(),
|
||||||
disk: NewDiskService(log),
|
disk: NewDiskService(log, db),
|
||||||
notify: NewNotifyService(db),
|
notify: NewNotifyService(db),
|
||||||
shareDirectory: NewShareDirService(db, log),
|
shareDirectory: NewShareDirService(db, log),
|
||||||
task: NewTaskService(db, log),
|
task: NewTaskService(db, log),
|
||||||
rely: NewRelyService(db, log),
|
rely: NewRelyService(db, log),
|
||||||
system: NewSystemService(log),
|
system: NewSystemService(log),
|
||||||
shortcuts: NewShortcutsService(db),
|
shortcuts: NewShortcutsService(db),
|
||||||
|
search: NewSearchService(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +59,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 +67,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 +106,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 +119,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
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,67 +1,70 @@
|
|||||||
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
|
||||||
|
UpdateAssist()
|
||||||
|
UpSystemPort(port 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))
|
||||||
//s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version))
|
//s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version))
|
||||||
}
|
}
|
||||||
|
func (s *systemService) UpdateAssist() {
|
||||||
|
s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/assist.sh"))
|
||||||
|
}
|
||||||
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) UpSystemPort(port string) {
|
||||||
|
if len(port) > 0 && port != config.ServerInfo.HttpPort {
|
||||||
|
config.Cfg.Section("server").Key("HttpPort").SetValue(port)
|
||||||
|
config.ServerInfo.HttpPort = port
|
||||||
|
}
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
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}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
json2 "encoding/json"
|
json2 "encoding/json"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"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"
|
||||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
@@ -9,7 +11,6 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS/types"
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskService interface {
|
type TaskService interface {
|
||||||
@@ -80,12 +81,12 @@ func (s *taskService) GetServerTasks() []model.TaskDBModel {
|
|||||||
list := []model.TaskDBModel{}
|
list := []model.TaskDBModel{}
|
||||||
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
|
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
|
||||||
|
|
||||||
go func(list []model.TaskDBModel) {
|
//go func(list []model.TaskDBModel) {
|
||||||
for _, dbModel := range list {
|
// for _, dbModel := range list {
|
||||||
dbModel.Id = 0
|
// dbModel.Id = 0
|
||||||
s.db.Create(&dbModel)
|
// s.db.Create(&dbModel)
|
||||||
}
|
// }
|
||||||
}(list)
|
//}(list)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
func (s *taskService) SyncTaskService() {
|
func (s *taskService) SyncTaskService() {
|
||||||
@@ -133,12 +134,12 @@ func SyncTask(db *gorm.DB) {
|
|||||||
list := []model.TaskDBModel{}
|
list := []model.TaskDBModel{}
|
||||||
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
|
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
|
||||||
|
|
||||||
//go func(list []model.TaskDBModel) {
|
go func(list []model.TaskDBModel) {
|
||||||
// for _, dbModel := range list {
|
for _, dbModel := range list {
|
||||||
// dbModel.Id = 0
|
dbModel.Id = 0
|
||||||
// db.Create(&dbModel)
|
db.Create(&dbModel)
|
||||||
// }
|
}
|
||||||
//}(list)
|
}(list)
|
||||||
}
|
}
|
||||||
func NewTaskService(db *gorm.DB, log loger2.OLog) TaskService {
|
func NewTaskService(db *gorm.DB, log loger2.OLog) TaskService {
|
||||||
return &taskService{db: db, log: log}
|
return &taskService{db: db, log: log}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,20 +34,20 @@ type ZeroTierService interface {
|
|||||||
DeleteNetwork(token, id string) interface{}
|
DeleteNetwork(token, id string) interface{}
|
||||||
GetJoinNetworks() string
|
GetJoinNetworks() string
|
||||||
}
|
}
|
||||||
type zerotierstruct struct {
|
type zerotierStruct struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var client http.Client
|
var client http.Client
|
||||||
|
|
||||||
func (c *zerotierstruct) ZeroTierJoinNetwork(networkId string) {
|
func (c *zerotierStruct) ZeroTierJoinNetwork(networkId string) {
|
||||||
command2.OnlyExec(`zerotier-cli join ` + networkId)
|
command2.OnlyExec(`zerotier-cli join ` + networkId)
|
||||||
}
|
}
|
||||||
func (c *zerotierstruct) ZeroTierLeaveNetwork(networkId string) {
|
func (c *zerotierStruct) ZeroTierLeaveNetwork(networkId string) {
|
||||||
command2.OnlyExec(`zerotier-cli leave ` + networkId)
|
command2.OnlyExec(`zerotier-cli leave ` + networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
//登录并获取token
|
//登录并获取token
|
||||||
func (c *zerotierstruct) GetToken(username, pwd string) string {
|
func (c *zerotierStruct) GetToken(username, pwd string) string {
|
||||||
if len(config.ZeroTierInfo.Token) > 0 {
|
if len(config.ZeroTierInfo.Token) > 0 {
|
||||||
return config.ZeroTierInfo.Token
|
return config.ZeroTierInfo.Token
|
||||||
} else {
|
} else {
|
||||||
@@ -55,7 +55,7 @@ func (c *zerotierstruct) GetToken(username, pwd string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) ZeroTierRegister(email, lastName, firstName, password string) string {
|
func (c *zerotierStruct) ZeroTierRegister(email, lastName, firstName, password string) string {
|
||||||
|
|
||||||
url := "https://accounts.zerotier.com/auth/realms/zerotier/protocol/openid-connect/registrations?client_id=zt-central&redirect_uri=https%3A%2F%2Fmy.zerotier.com%2Fapi%2F_auth%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=state"
|
url := "https://accounts.zerotier.com/auth/realms/zerotier/protocol/openid-connect/registrations?client_id=zt-central&redirect_uri=https%3A%2F%2Fmy.zerotier.com%2Fapi%2F_auth%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=state"
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ func ZeroTierGet(url string, cookies []*http.Cookie, t uint8) (action string, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
//模拟提交表单
|
//模拟提交表单
|
||||||
func ZeroTierPost(str bytes.Buffer, action string, cookes []*http.Cookie, isLogin bool) (url, errInfo string, err error) {
|
func ZeroTierPost(str bytes.Buffer, action string, cookies []*http.Cookie, isLogin bool) (url, errInfo string, err error) {
|
||||||
req, err := http.NewRequest(http.MethodPost, action, strings.NewReader(str.String()))
|
req, err := http.NewRequest(http.MethodPost, action, strings.NewReader(str.String()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", errors.New("newrequest error")
|
return "", "", errors.New("newrequest error")
|
||||||
@@ -219,7 +219,7 @@ func ZeroTierPost(str bytes.Buffer, action string, cookes []*http.Cookie, isLogi
|
|||||||
req.Header.Set(k, v)
|
req.Header.Set(k, v)
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
for _, cookie := range cookes {
|
for _, cookie := range cookies {
|
||||||
req.AddCookie(cookie)
|
req.AddCookie(cookie)
|
||||||
}
|
}
|
||||||
res, err := client.Do(req)
|
res, err := client.Do(req)
|
||||||
@@ -273,62 +273,62 @@ func ZeroTierPost(str bytes.Buffer, action string, cookes []*http.Cookie, isLogi
|
|||||||
}
|
}
|
||||||
|
|
||||||
//获取zerotile网络列表和本地用户已加入的网络
|
//获取zerotile网络列表和本地用户已加入的网络
|
||||||
func (c *zerotierstruct) ZeroTierNetworkList(token string) (interface{}, []string) {
|
func (c *zerotierStruct) ZeroTierNetworkList(token string) (interface{}, []string) {
|
||||||
url := "https://my.zerotier.com/api/network"
|
url := "https://my.zerotier.com/api/network"
|
||||||
return zerotier.GetData(url, token), command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
|
return zerotier.GetData(url, token), command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get network info
|
// get network info
|
||||||
func (c *zerotierstruct) ZeroTierGetInfo(token, id string) (interface{}, []string) {
|
func (c *zerotierStruct) ZeroTierGetInfo(token, id string) (interface{}, []string) {
|
||||||
url := "https://my.zerotier.com/api/network/" + id
|
url := "https://my.zerotier.com/api/network/" + id
|
||||||
info := zerotier.GetData(url, token)
|
info := zerotier.GetData(url, token)
|
||||||
return info, command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
|
return info, command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
//get status
|
//get status
|
||||||
func (c *zerotierstruct) ZeroTierGetStatus(token string) interface{} {
|
func (c *zerotierStruct) ZeroTierGetStatus(token string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/status"
|
url := "https://my.zerotier.com/api/v1/status"
|
||||||
info := zerotier.GetData(url, token)
|
info := zerotier.GetData(url, token)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) EditNetwork(token string, data string, id string) interface{} {
|
func (c *zerotierStruct) EditNetwork(token string, data string, id string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network/" + id
|
url := "https://my.zerotier.com/api/v1/network/" + id
|
||||||
info := zerotier.PostData(url, token, data)
|
info := zerotier.PostData(url, token, data)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) EditNetworkMember(token string, data string, id, mId string) interface{} {
|
func (c *zerotierStruct) EditNetworkMember(token string, data string, id, mId string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
|
url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
|
||||||
info := zerotier.PostData(url, token, data)
|
info := zerotier.PostData(url, token, data)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) MemberList(token string, id string) interface{} {
|
func (c *zerotierStruct) MemberList(token string, id string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network/" + id + "/member"
|
url := "https://my.zerotier.com/api/v1/network/" + id + "/member"
|
||||||
info := zerotier.GetData(url, token)
|
info := zerotier.GetData(url, token)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) DeleteMember(token string, id, mId string) interface{} {
|
func (c *zerotierStruct) DeleteMember(token string, id, mId string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
|
url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
|
||||||
info := zerotier.DeleteMember(url, token)
|
info := zerotier.DeleteMember(url, token)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) DeleteNetwork(token, id string) interface{} {
|
func (c *zerotierStruct) DeleteNetwork(token, id string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network/" + id
|
url := "https://my.zerotier.com/api/v1/network/" + id
|
||||||
info := zerotier.DeleteMember(url, token)
|
info := zerotier.DeleteMember(url, token)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) CreateNetwork(token string) interface{} {
|
func (c *zerotierStruct) CreateNetwork(token string) interface{} {
|
||||||
url := "https://my.zerotier.com/api/v1/network"
|
url := "https://my.zerotier.com/api/v1/network"
|
||||||
info := zerotier.PostData(url, token, "{}")
|
info := zerotier.PostData(url, token, "{}")
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *zerotierstruct) GetJoinNetworks() string {
|
func (c *zerotierStruct) GetJoinNetworks() string {
|
||||||
json := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetLocalJoinNetworks")
|
json := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetLocalJoinNetworks")
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
@@ -339,5 +339,5 @@ func NewZeroTierService() ZeroTierService {
|
|||||||
return http.ErrUseLastResponse //禁止重定向
|
return http.ErrUseLastResponse //禁止重定向
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return &zerotierstruct{}
|
return &zerotierStruct{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -118,7 +116,6 @@ func (c *zima) GetNetState(name string) string {
|
|||||||
|
|
||||||
//网络信息
|
//网络信息
|
||||||
func (c *zima) GetNetInfo() []net.IOCountersStat {
|
func (c *zima) GetNetInfo() []net.IOCountersStat {
|
||||||
//loger.Error("输出个内容试试")
|
|
||||||
parts, _ := net.IOCounters(true)
|
parts, _ := net.IOCounters(true)
|
||||||
//fmt.Println(net.ConntrackStatsWithContext(true))
|
//fmt.Println(net.ConntrackStatsWithContext(true))
|
||||||
return parts
|
return parts
|
||||||
@@ -133,6 +130,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
|
||||||
|
|||||||
12
shell/assist.sh
Normal file
12
shell/assist.sh
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#add in v0.2.3
|
||||||
|
version_0_2_3() {
|
||||||
|
((EUID)) && sudo_cmd="sudo"
|
||||||
|
$sudo_cmd cp -rf /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
|
||||||
|
$sudo_cmd chmod +x /casaOS/server/shell/usb-mount.sh
|
||||||
|
$sudo_cmd cp -rf /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
version_0_2_3
|
||||||
100
shell/helper.sh
100
shell/helper.sh
@@ -103,20 +103,22 @@ DelPartition() {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
#添加分区
|
#添加分区只有一个分区
|
||||||
#param 路径 /dev/sdb
|
#param 路径 /dev/sdb
|
||||||
#param 磁盘号 最大128
|
#param 要挂载的目录
|
||||||
#param 磁盘大小 字节 512*2048=1024kb=1M
|
|
||||||
AddPartition() {
|
AddPartition() {
|
||||||
# fdisk $1 <<EOF
|
|
||||||
# n
|
|
||||||
# $2
|
|
||||||
# $3
|
|
||||||
# $4
|
|
||||||
# wq
|
|
||||||
#EOF
|
|
||||||
|
|
||||||
parted $1 mkpart primary ext4 s3 s4
|
DelPartition $1
|
||||||
|
parted -s $1 mklabel gpt
|
||||||
|
|
||||||
|
parted -s $1 mkpart primary ext4 0 100%
|
||||||
|
|
||||||
|
mkfs.ext4 $11
|
||||||
|
|
||||||
|
partprobe $1
|
||||||
|
|
||||||
|
# mount $11 $2
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#磁盘类型
|
#磁盘类型
|
||||||
@@ -151,7 +153,83 @@ GetPartitionSectors() {
|
|||||||
fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#检查没有使用的挂载点删除文件夹
|
||||||
|
AutoRemoveUnuseDir() {
|
||||||
|
DIRECTORY="/mnt/"
|
||||||
|
dir=$(ls -l $DIRECTORY | awk '/^d/ {print $NF}')
|
||||||
|
for i in $dir; do
|
||||||
|
|
||||||
|
path="$DIRECTORY$i"
|
||||||
|
mountStr=$(mountpoint $path)
|
||||||
|
notMountpoint="is not a mountpoint"
|
||||||
|
if [[ $mountStr =~ $notMountpoint ]]; then
|
||||||
|
if [ "$(ls -A $path)" = "" ]; then
|
||||||
|
rm -fr $path
|
||||||
|
else
|
||||||
|
echo "$path is not empty"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
#重载samba服务
|
#重载samba服务
|
||||||
ReloadSamba() {
|
ReloadSamba() {
|
||||||
/etc/init.d/smbd reload
|
/etc/init.d/smbd reload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1=sda1
|
||||||
|
# $2=volume{1}
|
||||||
|
do_mount() {
|
||||||
|
DEVBASE=$1
|
||||||
|
DEVICE="${DEVBASE}"
|
||||||
|
# See if this drive is already mounted, and if so where
|
||||||
|
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
||||||
|
|
||||||
|
if [ -n "${MOUNT_POINT}" ]; then
|
||||||
|
${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get info for this drive: $ID_FS_LABEL and $ID_FS_TYPE
|
||||||
|
eval $(blkid -o udev ${DEVICE} | grep -i -e "ID_FS_LABEL" -e "ID_FS_TYPE")
|
||||||
|
|
||||||
|
LABEL=$2
|
||||||
|
if grep -q " /media/${LABEL} " /etc/mtab; then
|
||||||
|
# Already in use, make a unique one
|
||||||
|
LABEL+="-${DEVBASE}"
|
||||||
|
fi
|
||||||
|
DEV_LABEL="${LABEL}"
|
||||||
|
|
||||||
|
# Use the device name in case the drive doesn't have label
|
||||||
|
if [ -z ${DEV_LABEL} ]; then
|
||||||
|
DEV_LABEL="${DEVBASE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MOUNT_POINT="/media/${DEV_LABEL}"
|
||||||
|
|
||||||
|
${log} "Mount point: ${MOUNT_POINT}"
|
||||||
|
|
||||||
|
mkdir -p ${MOUNT_POINT}
|
||||||
|
|
||||||
|
case ${ID_FS_TYPE} in
|
||||||
|
vfat)
|
||||||
|
mount -t vfat -o rw,relatime,users,gid=100,umask=000,shortname=mixed,utf8=1,flush ${DEVICE} ${MOUNT_POINT}
|
||||||
|
;;
|
||||||
|
ext[2-4])
|
||||||
|
mount -o noatime ${DEVICE} ${MOUNT_POINT} >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
exfat)
|
||||||
|
mount -t exfat ${DEVICE} ${MOUNT_POINT} >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
ntfs)
|
||||||
|
ntfs-3g ${DEVICE} ${MOUNT_POINT}
|
||||||
|
;;
|
||||||
|
iso9660)
|
||||||
|
mount -t iso9660 ${DEVICE} ${MOUNT_POINT}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
/bin/rmdir "${MOUNT_POINT}"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ show() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run_external_script() {
|
run_external_script() {
|
||||||
show 0 "run_external_script"
|
assist.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
@@ -99,13 +99,13 @@ update() {
|
|||||||
target_arch="386"
|
target_arch="386"
|
||||||
;;
|
;;
|
||||||
*armv5*)
|
*armv5*)
|
||||||
target_arch="armv5"
|
target_arch="arm-5"
|
||||||
;;
|
;;
|
||||||
*armv6*)
|
*armv6*)
|
||||||
target_arch="armv6"
|
target_arch="arm-6"
|
||||||
;;
|
;;
|
||||||
*armv7*)
|
*armv7*)
|
||||||
target_arch="armv7"
|
target_arch="arm-7"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
show 1 "Aborted, unsupported or unknown architecture: $unamem"
|
show 1 "Aborted, unsupported or unknown architecture: $unamem"
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# copy to /oasis/util/shell path
|
# copy to /casaOS/util/shell path
|
||||||
# chmod 755
|
# chmod 755
|
||||||
|
|
||||||
log="logger -t usb-mount.sh -s "
|
log="logger -t usb-mount.sh -s "
|
||||||
|
|
||||||
${log} "变量:$1 $2"
|
|
||||||
|
|
||||||
ACTION=$1
|
ACTION=$1
|
||||||
|
|
||||||
DEVBASE=$2
|
DEVBASE=$2
|
||||||
@@ -18,10 +16,10 @@ MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
|||||||
|
|
||||||
do_mount() {
|
do_mount() {
|
||||||
|
|
||||||
if [[ -n ${MOUNT_POINT} ]]; then
|
if [ -n "${MOUNT_POINT}" ]; then
|
||||||
${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
|
${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
|
||||||
exit 1
|
exit 1
|
||||||
fib
|
fi
|
||||||
|
|
||||||
# Get info for this drive: $ID_FS_LABEL and $ID_FS_TYPE
|
# Get info for this drive: $ID_FS_LABEL and $ID_FS_TYPE
|
||||||
eval $(blkid -o udev ${DEVICE} | grep -i -e "ID_FS_LABEL" -e "ID_FS_TYPE")
|
eval $(blkid -o udev ${DEVICE} | grep -i -e "ID_FS_LABEL" -e "ID_FS_TYPE")
|
||||||
@@ -33,7 +31,7 @@ do_mount() {
|
|||||||
# Figure out a mount point to use
|
# Figure out a mount point to use
|
||||||
# LABEL=${ID_FS_LABEL}
|
# LABEL=${ID_FS_LABEL}
|
||||||
LABEL=${DEVBASE}
|
LABEL=${DEVBASE}
|
||||||
if grep -q " /media/${LABEL} " /etc/mtab; then
|
if grep -q " /mnt/casa_${LABEL} " /etc/mtab; then
|
||||||
# Already in use, make a unique one
|
# Already in use, make a unique one
|
||||||
LABEL+="-${DEVBASE}"
|
LABEL+="-${DEVBASE}"
|
||||||
fi
|
fi
|
||||||
@@ -44,7 +42,7 @@ do_mount() {
|
|||||||
DEV_LABEL="${DEVBASE}"
|
DEV_LABEL="${DEVBASE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MOUNT_POINT="/media/${DEV_LABEL}"
|
MOUNT_POINT="/mnt/casa_${DEV_LABEL}"
|
||||||
|
|
||||||
${log} "Mount point: ${MOUNT_POINT}"
|
${log} "Mount point: ${MOUNT_POINT}"
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ Description=Mount USB Drive on %i
|
|||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
RemainAfterExit=true
|
RemainAfterExit=true
|
||||||
ExecStart=/oasis/util/shell/usb-mount.sh add %i
|
ExecStart=/casaOS/server/shell/usb-mount.sh add %i
|
||||||
ExecStop=/oasis/util/shell/usb-mount.sh remove %i
|
ExecStop=/casaOS/server/shell/usb-mount.sh remove %i
|
||||||
|
|||||||
BIN
snapshot-mobile.png
Normal file
BIN
snapshot-mobile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
snapshot.png
Normal file
BIN
snapshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
10
types/search.go
Normal file
10
types/search.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
const (
|
||||||
|
APPLICATION = iota
|
||||||
|
MEDIA
|
||||||
|
PICTURE
|
||||||
|
MUSIC
|
||||||
|
SEARCH
|
||||||
|
UNKNOWN
|
||||||
|
)
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
const CURRENTVERSION = "0.1.2"
|
const CURRENTVERSION = "0.2.3"
|
||||||
|
const BODY = "<li>Add detailed CPU and memory statistics.</li><li>Add the multi-language function and add Chinese translation.</li><li>Add the function to modify the search engine.</li><li>Add the function of modifying the WebUI port</li><li>fixed some bugs</li><li>Preprocessing usb automounting</li><li>Update update script</li>"
|
||||||
|
|||||||
BIN
web/favicon.ico
BIN
web/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
14
web/favicon.svg
Normal file
14
web/favicon.svg
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?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="Layer_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:#363636;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
|
||||||
|
@media ( prefers-color-scheme: dark ) {
|
||||||
|
.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: 863 B |
BIN
web/img/Account.1bc4a418.png
Normal file
BIN
web/img/Account.1bc4a418.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
72
web/img/Account.bde47fba.svg
Normal file
72
web/img/Account.bde47fba.svg
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 60C0 26.8629 26.8629 0 60 0V0C93.1371 0 120 26.8629 120 60V60C120 93.1371 93.1371 120 60 120V120C26.8629 120 0 93.1371 0 60V60Z" fill="url(#paint0_linear_582:2091)"/>
|
||||||
|
<g filter="url(#filter0_d_582:2091)">
|
||||||
|
<g filter="url(#filter1_iiiii_582:2091)">
|
||||||
|
<path d="M75.1248 42.125C75.1248 50.4783 68.3532 57.25 59.9999 57.25C51.6465 57.25 44.8749 50.4783 44.8749 42.125C44.8749 33.7717 51.6465 27 59.9999 27C68.3532 27 75.1248 33.7717 75.1248 42.125Z" fill="url(#paint1_linear_582:2091)"/>
|
||||||
|
<path d="M34.422 71.7327C41.316 66.1301 50.2453 62.75 59.9998 62.75C69.7544 62.75 78.6837 66.1301 85.5777 71.7327C89.5123 74.9302 89.5123 80.8198 85.5777 84.0174C78.6837 89.6199 69.7544 93 59.9998 93C50.2453 93 41.316 89.6199 34.422 84.0174C30.4874 80.8198 30.4874 74.9302 34.422 71.7327Z" fill="url(#paint2_linear_582:2091)"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_582:2091" x="4" y="8" width="112" height="112" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="6"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_582:2091"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_582:2091" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_iiiii_582:2091" x="27.4711" y="23" width="63.0576" height="72" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="2" dy="2"/>
|
||||||
|
<feGaussianBlur stdDeviation="3"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.495833 0 0 0 0 0.879 0 0 0 0 1 0 0 0 0.4 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_582:2091"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-4" dy="-4"/>
|
||||||
|
<feGaussianBlur stdDeviation="3"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.0205888 0 0 0 0 0.00944442 0 0 0 0 0.566667 0 0 0 0.2 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect1_innerShadow_582:2091" result="effect2_innerShadow_582:2091"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="1" dy="1"/>
|
||||||
|
<feGaussianBlur stdDeviation="1"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.816667 0 0 0 0 0.945 0 0 0 0 1 0 0 0 0.2 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect2_innerShadow_582:2091" result="effect3_innerShadow_582:2091"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-2" dy="-2"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.00608333 0 0 0 0 0 0 0 0 0 0.304167 0 0 0 0.2 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect3_innerShadow_582:2091" result="effect4_innerShadow_582:2091"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-1" dy="-1"/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.075 0 0 0 0 0.778 0 0 0 0 1 0 0 0 0.2 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect4_innerShadow_582:2091" result="effect5_innerShadow_582:2091"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient id="paint0_linear_582:2091" x1="60" y1="0" x2="60" y2="120" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#5A9CFF"/>
|
||||||
|
<stop offset="0.87897" stop-color="#2A23D5"/>
|
||||||
|
<stop offset="1" stop-color="#4A3CEC"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_582:2091" x1="60" y1="40" x2="59.9998" y2="93" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.0350902" stop-color="white"/>
|
||||||
|
<stop offset="0.525594" stop-color="#B0D4FF"/>
|
||||||
|
<stop offset="0.837131" stop-color="#DEEDFF"/>
|
||||||
|
<stop offset="1" stop-color="#FEFEFF"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint2_linear_582:2091" x1="60" y1="40" x2="59.9998" y2="93" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.0350902" stop-color="white"/>
|
||||||
|
<stop offset="0.525594" stop-color="#B0D4FF"/>
|
||||||
|
<stop offset="0.837131" stop-color="#DEEDFF"/>
|
||||||
|
<stop offset="1" stop-color="#FEFEFF"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user