mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 13:04:42 +00:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
752134942a | ||
|
|
faf683a02c | ||
|
|
f99f49dd7e | ||
|
|
b0dc30277b | ||
|
|
d91fef0a19 | ||
|
|
6bb044ab04 | ||
|
|
78479f9604 | ||
|
|
8fe893847f | ||
|
|
f506d6ce49 | ||
|
|
5d7c5ba120 | ||
|
|
eedffd7c19 | ||
|
|
0885c1386d | ||
|
|
0297fe67af | ||
|
|
3f53e6f33b | ||
|
|
94d0efdb12 | ||
|
|
1e821d1c10 | ||
|
|
2c80b53ee8 | ||
|
|
c33af66c6e | ||
|
|
9d47874ae3 | ||
|
|
c7b7a30210 | ||
|
|
fde665cd4d | ||
|
|
eaf2341a2a | ||
|
|
d4bed3e5c7 | ||
|
|
fcb2b3f5a5 | ||
|
|
60349c941a | ||
|
|
11bc70a710 | ||
|
|
665766019f | ||
|
|
57cef9624c | ||
|
|
6bd41ad016 | ||
|
|
05425d638f | ||
|
|
bd5a2e35d4 | ||
|
|
123e7e8758 | ||
|
|
1ec3e2e9fb | ||
|
|
0719c3cc0c | ||
|
|
0a4ceb7c4c | ||
|
|
655f59f00a | ||
|
|
5289f471d6 | ||
|
|
59597befb6 | ||
|
|
df2477a12f | ||
|
|
b709abe682 | ||
|
|
d0f3dc806e | ||
|
|
92d085acf9 | ||
|
|
20dbae21c8 | ||
|
|
9258cb4b9e | ||
|
|
d9794851f9 | ||
|
|
1fcb530ff2 | ||
|
|
364d411438 | ||
|
|
0dacc5db12 | ||
|
|
fcbff194d2 | ||
|
|
04e93b0e3c | ||
|
|
2eff7fa8bc | ||
|
|
dd0645ee0f | ||
|
|
c93aa6286e | ||
|
|
bf7b32309f | ||
|
|
cd779448ce | ||
|
|
c3b2c1d599 | ||
|
|
b7949e100f | ||
|
|
80d24570d6 | ||
|
|
539b72a388 | ||
|
|
a7d15a896e | ||
|
|
9796c5aad7 | ||
|
|
892cd99eb3 | ||
|
|
02cb4cd392 | ||
|
|
9213f9e379 | ||
|
|
4473056d5c | ||
|
|
07e96511cd | ||
|
|
ce1dc52bc2 | ||
|
|
d890b16644 | ||
|
|
5737936318 | ||
|
|
33acfababd | ||
|
|
28c1a52171 | ||
|
|
892eef424c | ||
|
|
f3c73ba79b | ||
|
|
c6928c333d | ||
|
|
63c6c2cebb | ||
|
|
6cba025679 | ||
|
|
d25b93c972 | ||
|
|
b14861703c | ||
|
|
32604225ce | ||
|
|
f623b29c38 | ||
|
|
94ae6ee8ec | ||
|
|
5115bf72e1 | ||
|
|
e1a928cd78 | ||
|
|
3977519c43 | ||
|
|
2f87834ac9 | ||
|
|
53335012d8 | ||
|
|
9d6302f7e3 | ||
|
|
20950e2a60 | ||
|
|
0e0e507f8f | ||
|
|
46e14617b6 | ||
|
|
903c73fafb | ||
|
|
42a56df4a5 | ||
|
|
493dc5c032 | ||
|
|
9a73bc2a18 | ||
|
|
55a9acd9f6 | ||
|
|
d060968b7a | ||
|
|
88a7f53130 | ||
|
|
26e5b18a5d | ||
|
|
011ace96f6 |
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Questions, Ideas, Discussions
|
||||||
|
url: https://github.com/IceWhaleTech/CasaOS/discussions
|
||||||
|
about: Ask questions, propose ideas, or discuss anything related to CasaOS
|
||||||
4
.github/workflows/demo.yml
vendored
4
.github/workflows/demo.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Get old instance and snapshot name, create new instance name
|
- name: Get old instance and snapshot name, create new instance name
|
||||||
run: |
|
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_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "CasaOS-Demo-Snapshot-1652856810' | 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 "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
|
echo "NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
--instance-snapshot-name ${{ env.OLD_INSTANCE_SNAPSHOT_NAME }} \
|
--instance-snapshot-name ${{ env.OLD_INSTANCE_SNAPSHOT_NAME }} \
|
||||||
--instance-names ${{ env.NEW_INSTANCE_NAME }} \
|
--instance-names ${{ env.NEW_INSTANCE_NAME }} \
|
||||||
--availability-zone us-west-2a \
|
--availability-zone us-west-2a \
|
||||||
--bundle-id large_2_0
|
--bundle-id medium_2_0
|
||||||
|
|
||||||
- name: Wait for new instance running
|
- name: Wait for new instance running
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -29,7 +29,10 @@ gen
|
|||||||
/out/
|
/out/
|
||||||
/db/
|
/db/
|
||||||
/docs/
|
/docs/
|
||||||
|
/web/
|
||||||
/conf/conf.ini
|
/conf/conf.ini
|
||||||
|
/conf/conf.json
|
||||||
__debug_bin
|
__debug_bin
|
||||||
main
|
main
|
||||||
CasaOS
|
CasaOS
|
||||||
|
github.com
|
||||||
|
|||||||
441
CHANGELOG.md
Normal file
441
CHANGELOG.md
Normal file
@@ -0,0 +1,441 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
## [0.3.3-pre] - 2022-07-01(UTC)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [System]Add interface call log
|
||||||
|
- Adding Developing file ([#311](https://github.com/IceWhaleTech/CasaOS/pull/311))
|
||||||
|
- [App] add new tips for app section.
|
||||||
|
- [System] UI Configurable function modules: support turning off the search bar and recommended apps module in the settings.
|
||||||
|
- [System] Custom wallpapers: two new preset wallpapers, support for custom uploads, support for setting images from Files as wallpapers, Also support right click on dashboard to change wallpaper.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- [App] Cache app store index and category data
|
||||||
|
- [System] casaos master program adapted to FHS standards
|
||||||
|
- [App] Update casaos icons.
|
||||||
|
- [System] Update translation.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- [System] Remove upnp function module
|
||||||
|
- [System] Remove ddns function module
|
||||||
|
- [System] Remove search function module
|
||||||
|
- [System] Remove zerotier function module
|
||||||
|
- [System] Remove task function module
|
||||||
|
- [System] Remove file share function module
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Disk] Fixed hard drive won't hibernate problem ([#202](https://github.com/IceWhaleTech/CasaOS/issues/202))
|
||||||
|
- [File] Fixed the backspace key that causes the folder to rewind ([#252](https://github.com/IceWhaleTech/CasaOS/issues/252))
|
||||||
|
- [App] Fixed app logo is not loading when imported. ([#320](https://github.com/IceWhaleTech/CasaOS/issues/320))
|
||||||
|
|
||||||
|
## [0.3.2.1] - 2022-06-16(UTC)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- [System] Adjusted the display style.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [System] Fixed the issue of widgets displaying wrongly on mobile devices.
|
||||||
|
- [App] Fix the problem of application opening failure on non-80 ports ([#283](https://github.com/IceWhaleTech/CasaOS/issues/283) [#280](https://github.com/IceWhaleTech/CasaOS/issues/280))
|
||||||
|
- [System] Modify port failure problem ([#282](https://github.com/IceWhaleTech/CasaOS/issues/282))
|
||||||
|
- [App]Modify environment variables disappearing problem([#284](https://github.com/IceWhaleTech/CasaOS/issues/284))
|
||||||
|
- [System]Fix no update alert([#278](https://github.com/IceWhaleTech/CasaOS/issues/278))
|
||||||
|
- [System] Fixed some bugs of application cpu usage and memory staging([#272](https://github.com/IceWhaleTech/CasaOS/issues/272))
|
||||||
|
- [App] Fixed plex and HA network mode error issues ([#299](https://github.com/IceWhaleTech/CasaOS/issues/299))
|
||||||
|
- [App] Fix application terminal not working ([#266](https://github.com/IceWhaleTech/CasaOS/issues/266))
|
||||||
|
|
||||||
|
## [0.3.2] - 2022-06-10
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [Files] Files can now be selected multiple files and downloaded, deleted, moved, etc.
|
||||||
|
- [Apps] Support to modify the application opening address.([#204](https://github.com/IceWhaleTech/CasaOS/issues/204))
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- [Apps] Hide the display of non-essential environment variables in the application.([#196](https://github.com/IceWhaleTech/CasaOS/issues/196))
|
||||||
|
- [System] Network, disk, cpu, memory, etc. information is modified to be pushed via socket.
|
||||||
|
- [System] Optimize opening speed.([#214](https://github.com/IceWhaleTech/CasaOS/issues/214))
|
||||||
|
- [Language] Update language pack [zarevskaya](https://github.com/zarevskaya) [patrickhilker](https://github.com/patrickhilker)
|
||||||
|
- [System] Interface path adjustment
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- [Files] Remove the online preview function of PDF files
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [System] Fixed the problem that sync data cannot submit the device ID ([#68](https://github.com/IceWhaleTech/CasaOS/issues/68))
|
||||||
|
- [Files] Fixed the code editor center alignment display problem.([#210](https://github.com/IceWhaleTech/CasaOS/issues/210))
|
||||||
|
- [Files] Fixed the problem of wrong name when downloading files.([#240](https://github.com/IceWhaleTech/CasaOS/issues/240))
|
||||||
|
- [System] Fixed the network display as a negative number problem.([#224](https://github.com/IceWhaleTech/CasaOS/issues/224))
|
||||||
|
- [System] Fixed the problem of wireless network card traffic display.([#222](https://github.com/IceWhaleTech/CasaOS/issues/222))
|
||||||
|
|
||||||
|
|
||||||
|
## [0.3.1.1] - 2022-05-17
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the data loss problem when importing local applications
|
||||||
|
|
||||||
|
## [0.3.1] - 2022-05-16
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- CasaConnect and file add image thumbnail function
|
||||||
|
- Import of docker applications
|
||||||
|
- List support custom sorting function
|
||||||
|
- CasaConnect gives priority to LAN connections
|
||||||
|
- USB auto-mount switch (Raspberry Pi is off by default)
|
||||||
|
- Application custom installation supports Docker Compose configuration import in YAML format
|
||||||
|
- You will see the new version changelog from the next version
|
||||||
|
- Added live preview for icons in custom installed applications
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Application data is no longer saved to the database
|
||||||
|
- Optimize app store speed issues
|
||||||
|
- Optimize the way WebUI is filled in
|
||||||
|
- Image preview has been completely upgraded and now supports switching between all images in the same folder, as well as dragging, zooming, rotating and resetting.
|
||||||
|
- Added color levels to the CPU and RAM charts
|
||||||
|
- Optimized the display of the Connect friends list right-click menu
|
||||||
|
- Change the initial display directory to /DATA
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Historical Application Data
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the problem that some Docker CLI commands failed to import
|
||||||
|
- Fix the problem that the application is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as application name
|
||||||
|
- Fix Pi-hole installation failure
|
||||||
|
- Fixed the issue that the app could not be updated using WatchTower
|
||||||
|
- Fixed the problem that the task status was lost after closing Files when there was an upload task
|
||||||
|
|
||||||
|
## [0.3.0] - 2022-04-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add CasaConnect function, now you can share private files peer-to-peer with your friends.
|
||||||
|
- Add a widget for network traffic monitoring.
|
||||||
|
- 12 new popular apps added to App Center
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated the sidebar of Files.
|
||||||
|
- Updated the initial directory of Files to the Root directory.
|
||||||
|
- Armbian 22.02 armhf/arm64/amd64 platform tests passed [@igorpecovnik ](https://github.com/igorpecovnik)
|
||||||
|
- Elementary OS 6.1 Jólnir amd64 platform tests passed [@alvarosamudio ](https://github.com/alvarosamudio)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix an issue in Files where the backspace button would trigger a return to the previous level of the directory when creating a folder.
|
||||||
|
- Fix the display problem of application list in CPU widget.
|
||||||
|
- Fix the problem that the ipv6 of the application cannot be opened
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Interfaces related to "zerotier"
|
||||||
|
|
||||||
|
## [0.2.10] - 2022-03-10
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added CasaOS own file manager, now you can browse, upload, download files from the system, even edit code online, preview photos and videos through it. It will appear in the first position of Apps.
|
||||||
|
- Added CPU core count display and memory capacity display.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Optimized the rendering performance of the home page.
|
||||||
|
- Optimized the internationalization display of the time widget.
|
||||||
|
- Show the icon of the stopped application as gray.
|
||||||
|
- Unify the animation of the drop-down menu.
|
||||||
|
- Optimize the display of the application drop-down menu.
|
||||||
|
- Replaced the default font to optimize the display.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the problem of failed to create storage space
|
||||||
|
|
||||||
|
## [0.2.9] - 2022-02-18
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add a simple notification function
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Custom installation of new parameters(Capabilities,Hostname,Privileged)
|
||||||
|
- Update front-end translation [@SemVer](https://github.com/zarevskaya) [@koboldMaki](https://github.com/koboldMaki) [@sgastol](https://github.com/sgastol) [@delki8](https://github.com/delki8)
|
||||||
|
|
||||||
|
- Modify the default location and name of the usb mount
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the problem of being indexed by search engines
|
||||||
|
- Fix some style display issues
|
||||||
|
- Solve hard drive can't be formatted, can't finish adding storage
|
||||||
|
|
||||||
|
## [0.2.8] - 2022-01-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add USB disk device display
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Update translation [@baptiste313](https://github.com/baptiste313) [@thueske](https://github.com/thueske)
|
||||||
|
- Compatible with more types of drives
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the language initialization bug
|
||||||
|
- Fix the problem that the login page could not be displayed
|
||||||
|
- Fix missing translated content
|
||||||
|
|
||||||
|
## [0.2.7] - 2022.01.26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Apply multilingual support
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix an injectable execution bug
|
||||||
|
|
||||||
|
## [0.2.6] - 2022.01.26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add a bug report panel.
|
||||||
|
- App Store apps start supporting multiple languages
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix a disk that cannot be formatted under certain circumstances
|
||||||
|
|
||||||
|
## [0.2.5] - 2022.01.24
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Storage Manager
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Update Disk widget
|
||||||
|
- Update language files [@ImOstrovskiy](https://github.com/ImOstrovskiy) [@baptiste313](https://github.com/baptiste313)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- File synchronization issues
|
||||||
|
- Fix the app store classification problem
|
||||||
|
|
||||||
|
## [0.2.4] - 2021.12.30
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Brand new App Store
|
||||||
|
- Optimize request method
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix Sync panel width display error.
|
||||||
|
- Fix App panel width display error.
|
||||||
|
|
||||||
|
## [0.2.3] - 2021.12.11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add detailed CPU and memory statistics.
|
||||||
|
- Add the multi-language function and add Chinese translation.
|
||||||
|
- Add the function to modify the search engine.
|
||||||
|
- Add the function of modifying the WebUI port
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Update update script
|
||||||
|
- Preprocessing usb automounting
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Volume path problem when customizing the installation of applications
|
||||||
|
- Fix Cpu and Ram usage display error
|
||||||
|
- Fix translation errors
|
||||||
|
- Fixed an error when importing and exporting appfile.
|
||||||
|
|
||||||
|
## [0.2.2] - 2021.12.02
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- UI adjustment
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the problem of data display error when manually installing apps
|
||||||
|
- Fix some spelling problems
|
||||||
|
- Fix the bug of synchronization module
|
||||||
|
|
||||||
|
## [0.2.1] - 2021.11.25
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix Sync display error
|
||||||
|
- Fix Sync Downoad url error
|
||||||
|
- Fix Smart Block display error
|
||||||
|
- Fix widgets settings dispaly error
|
||||||
|
- Fix application installation path error
|
||||||
|
|
||||||
|
## [0.2.0] - 2021.11.25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add sync function
|
||||||
|
|
||||||
|
|
||||||
|
## [0.1.11] - 2021.11.10
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Adaptation of cell phone terminals
|
||||||
|
- Optimize user experience
|
||||||
|
- Replaced the default background
|
||||||
|
- Optimized the display performance and fixed some bugs
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Resolve application installation path errors
|
||||||
|
|
||||||
|
## [0.1.10] - 2021.11.04
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add application terminal
|
||||||
|
- Add application logs
|
||||||
|
- Add system logs
|
||||||
|
- Add App Store for installation
|
||||||
|
|
||||||
|
## [0.1.9] - 2021.11.01 [YANKED]
|
||||||
|
|
||||||
|
## [0.1.8] - 2021.10.27
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add system terminal
|
||||||
|
- Add the ability to modify the user name and password
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Experience optimization
|
||||||
|
- Improve single user management function
|
||||||
|
- Fixed Disk widget display error
|
||||||
|
- Fixed Username display error after change
|
||||||
|
- Adaptation for mobile access
|
||||||
|
|
||||||
|
## [0.1.7] - 2021.10.22
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add user authentication module, Login page and initialization page.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix the problem that the application could not start after the system restarted.
|
||||||
|
- Home storage space data display exception
|
||||||
|
- Script override causes application loss after installation
|
||||||
|
- Fix docker network error
|
||||||
|
|
||||||
|
## [0.1.6] - 2021.10.19
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add app icon auto-fill via docker image name.
|
||||||
|
- Add a file selector for app install.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Modify import reminder.
|
||||||
|
- Optimize the application installation process
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed an issue with the app were it would disappear when the app was modified.
|
||||||
|
- Fixed device selector default dir to /dev
|
||||||
|
|
||||||
|
## [0.1.5] - 2021.10.15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add CPU RAM Status with widget
|
||||||
|
- Add Disk Info with widget
|
||||||
|
- Realize automatic loading of widgets
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Enhance the Docker cli import experience and automatically fill in the folders that need to be mounted
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove Weather widget.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- AppFile upload does not pass verification
|
||||||
|
- The setting menu of the app is displayed abnormally when the browser window is too narrow
|
||||||
|
- The port is occupied and the program cannot start
|
||||||
|
- Fix display bugs when windows size less than 1024px
|
||||||
|
|
||||||
|
## [0.1.4] - 2021.09.30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Import and export of application configuration files
|
||||||
|
- Automatic parsing of docker commands
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Improve the program release process
|
||||||
|
- Application installation process UX/UI optimization
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Authentication failure during the operation, resulting in the need to re-login
|
||||||
|
|
||||||
|
## [0.1.3] - 2021.09.29 [YANKED]
|
||||||
|
|
||||||
|
## [0.1.2] - 2021.09.28
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Application modification and new creation failure issues
|
||||||
|
|
||||||
|
## [0.1.1] - 2021.09.27
|
||||||
|
|
||||||
|
## [0.1.0] - 2021.09.26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Application Center
|
||||||
33
DEVELOPING.md
Normal file
33
DEVELOPING.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# CasaOS Development
|
||||||
|
Here we will describe the steps required to setup a development environment with CasaOS.
|
||||||
|
|
||||||
|
- [Setting up development environment](#setting-up-development-environment)
|
||||||
|
- [Pre-requisites](#pre-requisites)
|
||||||
|
- [1. Fork the Repo](#1.-fork-the-repo)
|
||||||
|
- [2. Clone the repo down](#2.-clone-the-repo-down)
|
||||||
|
- [3. Install dependencies](#3.-install-dependencies)
|
||||||
|
|
||||||
|
|
||||||
|
## Setting up a development environment
|
||||||
|
In this section we will walk you through the general process of setting up your development environment to get started.
|
||||||
|
|
||||||
|
### Pre-requisites
|
||||||
|
The following must be installed in order to get started. The details of how to install them is outside the scope of this doc, but generally they should be able to be installed with your systems package manager (apt, yum, brew, choco, etc).
|
||||||
|
- Go > v1.17.0
|
||||||
|
- yarn
|
||||||
|
- node.js
|
||||||
|
|
||||||
|
### 1. Fork the Repo
|
||||||
|
[Fork the repo](https://docs.github.com/en/get-started/quickstart/fork-a-repo) onto your own GitHub account for developing.
|
||||||
|
|
||||||
|
### 2. Clone the repo down
|
||||||
|
1. Navigate into your go workspace (check with `go env GOPATH`).
|
||||||
|
2. Navigate to the appropriate path for github. It should look something like this: `<path from GOPATH>/github.com/<GitHub Username>/`. If it doesn't exist create it.
|
||||||
|
3. Clone down the repo with the following: `git clone --recurse-submodules --remote-submodules https://github.com/<your GitHub Username>/CasaOS.git`
|
||||||
|
|
||||||
|
### 3. Install dependencies
|
||||||
|
1. `cd UI`
|
||||||
|
2. `yarn install`
|
||||||
|
3. `yarn build`
|
||||||
|
4. `cd ..`
|
||||||
|
5. `go get`
|
||||||
@@ -44,6 +44,9 @@ curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | bash
|
|||||||
### System Compatibility
|
### System Compatibility
|
||||||
|
|
||||||
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
||||||
|
- Armbian 22.02 armhf/arm64/amd64 (✅ Recommend, Tested)
|
||||||
|
- Elementary OS 6.1 Jólnir amd64 (✅ Recommend, Tested)
|
||||||
|
- Deepin 20.4 amd64 (⚠️ Not Fully Tested Yet)
|
||||||
- Raspberry Pi Lite OS aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
- Raspberry Pi Lite OS aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
||||||
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
||||||
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
||||||
@@ -83,4 +86,4 @@ So, we set out to build this open source project to develop CasaOS with our own
|
|||||||
- Ober Zhang
|
- Ober Zhang
|
||||||
- Zyaire Ann
|
- Zyaire Ann
|
||||||
- John Guan
|
- John Guan
|
||||||
- Right here, waiting for YOU!
|
- Right here, waiting for YOU!
|
||||||
|
|||||||
2
UI
2
UI
Submodule UI updated: 8146d1f4cb...7af1bf549d
41
alpha.md
Normal file
41
alpha.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-27 11:37:26
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-30 14:16:31
|
||||||
|
* @FilePath: /CasaOS/alpha.md
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# alpha Test Description
|
||||||
|
|
||||||
|
## :warning: Warning
|
||||||
|
|
||||||
|
There is a risk of data loss in non-release versions, so please be careful to back up your data.
|
||||||
|
|
||||||
|
## Install/Update
|
||||||
|
|
||||||
|
``` curl -fsSL https://get.casaos.io | bash -v v0.3.3-alpha ```
|
||||||
|
|
||||||
|
## Check change log
|
||||||
|
|
||||||
|
[CHANGELOG](https://github.com/IceWhaleTech/CasaOS/blob/main/CHANGELOG.md)
|
||||||
|
|
||||||
|
## Check Design drawings
|
||||||
|
|
||||||
|
[Design drawings](https://www.figma.com/file/pvlGobvuWEvbCb3GLqXfim/CasaOS-V0.3.3)
|
||||||
|
|
||||||
|
## Feedback questions
|
||||||
|
|
||||||
|
Go [here]() to give feedback on your question, note that try to match the picture or video
|
||||||
|
|
||||||
|
|
||||||
|
## Retest after update
|
||||||
|
|
||||||
|
Wait for the fix to appear and update and retest, and follow up on the issue
|
||||||
|
|
||||||
|
## Thanks
|
||||||
|
|
||||||
|
Thank you for your great support, we will return your support from time to time.
|
||||||
40
conf/conf.conf
Normal file
40
conf/conf.conf
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[app]
|
||||||
|
PAGE_SIZE = 10
|
||||||
|
RuntimeRootPath = runtime/
|
||||||
|
LogPath = ./CasaOS/logs/server/
|
||||||
|
LogSaveName = log
|
||||||
|
LogFileExt = log
|
||||||
|
DateStrFormat = 20060102
|
||||||
|
DateTimeFormat = 2006-01-02 15:04:05
|
||||||
|
TimeFormat = 15:04:05
|
||||||
|
DateFormat = 2006-01-02
|
||||||
|
DBPath = ./CasaOS/server/db
|
||||||
|
ShellPath = ./CasaOS/server/shell
|
||||||
|
UserDataPath = ./CasaOS/conf
|
||||||
|
TempPath = ./CasaOS/temp
|
||||||
|
|
||||||
|
[server]
|
||||||
|
HttpPort = 8089
|
||||||
|
UDPPort = 54216
|
||||||
|
RunMode = release
|
||||||
|
;ServerApi = https://api.casaos.io/casaos-api
|
||||||
|
ServerApi = http://127.0.0.1:8091
|
||||||
|
Handshake = socket.casaos.io
|
||||||
|
Token = af268e4f-9f3a-408a-b59b-cf1a4f7f88c8
|
||||||
|
USBAutoMount =
|
||||||
|
SocketPort = 58313
|
||||||
|
|
||||||
|
[system]
|
||||||
|
ConfigStr = {"auto_update":false,"background":"","background_type":"","search_engine":"https://duckduckgo.com/?q=","search_switch":false,"shortcuts_switch":false,"widgets_switch":false,"lang":"en_us"}
|
||||||
|
WidgetList = [{"name":"clock","show":true},{"name":"cpu","show":true},{"name":"disks","show":true},{"name":"network","show":true}]
|
||||||
|
|
||||||
|
[file]
|
||||||
|
ShareDir =
|
||||||
|
DownloadDir = ./CasaOS/DATA/Downloads
|
||||||
|
|
||||||
|
[user]
|
||||||
|
Description = nothing
|
||||||
|
UserName = casaos
|
||||||
|
Initialized = true
|
||||||
|
PWD = 123456
|
||||||
|
|
||||||
32
conf/conf.conf.sample
Normal file
32
conf/conf.conf.sample
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[app]
|
||||||
|
PAGE_SIZE = 10
|
||||||
|
RuntimeRootPath = runtime/
|
||||||
|
LogPath = /var/log/casaos/
|
||||||
|
LogSaveName = log
|
||||||
|
LogFileExt = log
|
||||||
|
DateStrFormat = 20060102
|
||||||
|
DateTimeFormat = 2006-01-02 15:04:05
|
||||||
|
TimeFormat = 15:04:05
|
||||||
|
DateFormat = 2006-01-02
|
||||||
|
DBPath = /var/lib/casaos
|
||||||
|
ShellPath = /usr/share/casaos/shell
|
||||||
|
UserDataPath = /var/lib/casaos/conf
|
||||||
|
TempPath = /var/lib/casaos/temp
|
||||||
|
|
||||||
|
[server]
|
||||||
|
HttpPort = 80
|
||||||
|
UDPPort =
|
||||||
|
RunMode = release
|
||||||
|
ServerApi = https://api.casaos.io/casaos-api
|
||||||
|
Handshake = socket.casaos.io
|
||||||
|
Token =
|
||||||
|
USBAutoMount =
|
||||||
|
|
||||||
|
|
||||||
|
[system]
|
||||||
|
WidgetList =
|
||||||
|
|
||||||
|
|
||||||
|
[file]
|
||||||
|
ShareDir =
|
||||||
|
DownloadDir =
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
[app]
|
|
||||||
PAGE_SIZE = 10
|
|
||||||
RuntimeRootPath = runtime/
|
|
||||||
LogSavePath = /casaOS/logs/server/
|
|
||||||
LogSaveName = log
|
|
||||||
LogFileExt = log
|
|
||||||
DateStrFormat = 20060102
|
|
||||||
DateTimeFormat = 2006-01-02 15:04:05
|
|
||||||
TimeFormat = 15:04:05
|
|
||||||
DateFormat = 2006-01-02
|
|
||||||
ProjectPath = /casaOS/server
|
|
||||||
|
|
||||||
|
|
||||||
[server]
|
|
||||||
HttpPort = 8089
|
|
||||||
RunMode = release
|
|
||||||
ServerApi = https://api.casaos.zimaboard.com
|
|
||||||
|
|
||||||
[user]
|
|
||||||
UserName = admin
|
|
||||||
PWD = zimaboard
|
|
||||||
Email = user@gmail.com
|
|
||||||
Description = description
|
|
||||||
Initialized = false
|
|
||||||
Token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVyZXJlIiwicGFzc3dvcmQiOiJhZHNmZGYiLCJleHAiOjE2MjQwMDU0ODEsImlzcyI6Imdpbi1ibG9nIn0.JNsCccZuFCwlSMLJg62iOIB2xymk_k7xGa11xhZ07bc
|
|
||||||
|
|
||||||
[zerotier]
|
|
||||||
UserName = user
|
|
||||||
PWD = pwd
|
|
||||||
Token = yBKYyavr2RdFAIVN7iTpzlsB1o6CqTgm
|
|
||||||
|
|
||||||
[redis]
|
|
||||||
Host = 127.0.0.1:6379
|
|
||||||
Password =
|
|
||||||
MaxIdle = 30
|
|
||||||
MaxActive = 30
|
|
||||||
IdleTimeout = 200
|
|
||||||
|
|
||||||
[system]
|
|
||||||
ConfigStr =
|
|
||||||
WidgetList =
|
|
||||||
|
|
||||||
25
go.mod
25
go.mod
@@ -3,38 +3,50 @@ module github.com/IceWhaleTech/CasaOS
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
||||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||||
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/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
|
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
|
||||||
|
github.com/ambelovsky/go-structs v1.1.0 // indirect
|
||||||
|
github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109
|
||||||
|
github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 // indirect
|
||||||
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.7
|
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/disintegration/imaging v1.6.2
|
||||||
|
github.com/docker/distribution v2.8.0+incompatible // 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
|
||||||
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
|
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
|
||||||
github.com/gin-contrib/gzip v0.0.2 // indirect
|
github.com/gin-contrib/gzip v0.0.2
|
||||||
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/spec v0.20.4 // indirect
|
github.com/go-openapi/spec v0.20.4 // 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/v4 v4.4.1
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/gomodule/redigo v1.8.5
|
github.com/gomodule/redigo v1.8.5
|
||||||
github.com/google/go-github/v36 v36.0.0
|
github.com/google/go-github/v36 v36.0.0
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/googollee/go-socket.io v1.6.2
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/jinzhu/copier v0.3.2
|
github.com/jinzhu/copier v0.3.2
|
||||||
github.com/json-iterator/go v1.1.11 // indirect
|
github.com/json-iterator/go v1.1.11 // indirect
|
||||||
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/lucas-clemente/quic-go v0.25.0
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.11 // indirect
|
||||||
|
github.com/mholt/archiver/v3 v3.5.1
|
||||||
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/image-spec 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/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@@ -49,10 +61,10 @@ require (
|
|||||||
github.com/swaggo/gin-swagger v1.3.0
|
github.com/swaggo/gin-swagger v1.3.0
|
||||||
github.com/swaggo/swag v1.7.3
|
github.com/swaggo/swag v1.7.3
|
||||||
github.com/tidwall/gjson v1.10.2
|
github.com/tidwall/gjson v1.10.2
|
||||||
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
|
||||||
|
go.uber.org/zap v1.10.0
|
||||||
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-20211020060615-d418f374d309 // indirect
|
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||||
@@ -66,7 +78,8 @@ require (
|
|||||||
google.golang.org/grpc v1.41.0 // indirect
|
google.golang.org/grpc v1.41.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
gorm.io/driver/sqlite v1.1.5
|
gorm.io/driver/sqlite v1.2.6
|
||||||
gorm.io/gorm v1.21.15
|
gorm.io/gorm v1.22.5
|
||||||
)
|
)
|
||||||
|
|||||||
228
go.sum
228
go.sum
@@ -1,7 +1,9 @@
|
|||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||||
@@ -32,7 +34,12 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
|||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
|
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||||
|
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||||
|
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||||
|
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
@@ -47,8 +54,11 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935
|
|||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
|
||||||
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
@@ -75,8 +85,6 @@ github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5
|
|||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/goquery v1.7.0 h1:O5SP3b9JWqMSVMG69zMfj577zwkSNpxrFf7ybS74eiw=
|
|
||||||
github.com/PuerkitoBio/goquery v1.7.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
@@ -92,8 +100,15 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
github.com/ambelovsky/go-structs v1.1.0 h1:LXj4/mHnYw0qhXQhOo96+ULGQ88H8qMcZd5SHef8boY=
|
||||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/ambelovsky/go-structs v1.1.0/go.mod h1:zN3RBXQvxgjjq/Q/WZS7p5AEK+qC9mNg7ycnvoQ63Ak=
|
||||||
|
github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109 h1:Tp8GVfUOEmJftBqi4+/aXTwJzm24POo6wIHeuTqaT+Y=
|
||||||
|
github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109/go.mod h1:MUREokfMKREm1fOm2babarrkYdk/dGHWY+ITC3qHHPQ=
|
||||||
|
github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 h1:suVCm9PiIhz7ftTbWQNe7u2YjVfr8AEuUiNWKWApdMM=
|
||||||
|
github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19/go.mod h1:o0+8DH+3X+FEOgSdNud0+8jJAsjtR9H3hF+O10Zcj/c=
|
||||||
|
github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
|
||||||
|
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
@@ -110,8 +125,10 @@ github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
|
|||||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||||
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||||
@@ -120,6 +137,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
|||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||||
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
||||||
|
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||||
|
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
@@ -233,6 +252,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
@@ -256,11 +276,14 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l
|
|||||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
|
github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY=
|
||||||
|
github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
@@ -275,6 +298,21 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
|||||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
|
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
||||||
|
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
|
||||||
|
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||||
|
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
|
||||||
|
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
|
||||||
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b h1:NgNuLvW/gAFKU30ULWW0gtkCt56JfB7FrZ2zyo0wT8I=
|
||||||
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||||
|
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf h1:/w4QxepU4AHh3AuO6/g8y/YIIHH5+aKP3Bj8sg5cqhU=
|
||||||
|
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8=
|
||||||
|
github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e h1:IxIbA7VbCNrwumIYjDoMOdf4KOSkMC6NJE4s8oRbE7E=
|
||||||
|
github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU=
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
@@ -289,11 +327,14 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
|||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b h1:r13MvtFTtnvxtuKK7z0ZSQ2EfMmTzWDHwfDvGCoqUQE=
|
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b h1:r13MvtFTtnvxtuKK7z0ZSQ2EfMmTzWDHwfDvGCoqUQE=
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b/go.mod h1:EfR6AU78zUiZ36oVS5YrmTzc2um3zDXWPx4L4st++jo=
|
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b/go.mod h1:EfR6AU78zUiZ36oVS5YrmTzc2um3zDXWPx4L4st++jo=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
|
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
@@ -311,6 +352,11 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/
|
|||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
|
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
|
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
|
github.com/go-errors/errors v1.1.1 h1:ljK/pL5ltg3qoN+OtN6yCv9HWSfMwxSx90GJCZQxYNg=
|
||||||
|
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
@@ -360,11 +406,14 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn
|
|||||||
github.com/go-playground/validator/v10 v10.6.1 h1:W6TRDXt4WcWp4c4nf/G+6BkGdhiIo0k417gfr+V6u4I=
|
github.com/go-playground/validator/v10 v10.6.1 h1:W6TRDXt4WcWp4c4nf/G+6BkGdhiIo0k417gfr+V6u4I=
|
||||||
github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk=
|
github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||||
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 h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
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=
|
||||||
@@ -377,8 +426,11 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP
|
|||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
|
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
|
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d h1:C/hKUcHT483btRbeGkrRjJz+Zbcj8audldIi9tRJDCc=
|
||||||
|
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@@ -387,6 +439,7 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er
|
|||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||||
@@ -394,6 +447,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -411,6 +466,9 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
|||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
|
||||||
|
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/gomodule/redigo v1.8.4/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||||
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
|
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
|
||||||
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
@@ -428,6 +486,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
||||||
github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk=
|
github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk=
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
@@ -450,9 +510,13 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||||
|
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||||
|
github.com/googollee/go-socket.io v1.6.2 h1:olKLLHJtHz1IkL/OrTyNriZZvVQYEORNkJAqsOwPask=
|
||||||
|
github.com/googollee/go-socket.io v1.6.2/go.mod h1:0vGP8/dXR9SZUMMD4+xxaGo/lohOw3YWMh2WRiWeKxg=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
@@ -467,6 +531,7 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb
|
|||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
@@ -486,12 +551,15 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
|
|||||||
github.com/imdario/mergo v0.3.12/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/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
|
github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
|
||||||
github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
|
github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
|
|
||||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
|
||||||
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
@@ -513,10 +581,15 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
|||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
|
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
||||||
|
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@@ -526,6 +599,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
|||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -533,8 +607,12 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
|
github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3mP4CLgibc=
|
||||||
|
github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg=
|
||||||
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@@ -542,6 +620,14 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
|||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||||
|
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||||
|
github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
||||||
|
github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco=
|
||||||
|
github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
||||||
|
github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk=
|
||||||
|
github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8=
|
||||||
|
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaIYMoiBsdwTNmNGkwUUM=
|
||||||
|
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
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=
|
||||||
@@ -551,13 +637,18 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
|
|||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
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.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.11 h1:gt+cp9c0XGqe9S/wAHTL3n/7MqY+siPWgWJgqdsFrzQ=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.11/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
|
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||||
|
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||||
@@ -583,8 +674,14 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||||
|
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
|
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
|
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||||
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
@@ -594,11 +691,18 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
|||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
|
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||||
|
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||||
|
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||||
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||||
|
github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
|
||||||
|
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
@@ -606,8 +710,9 @@ github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.
|
|||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
|
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||||
|
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v0.1.1/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-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
@@ -628,11 +733,14 @@ 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/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
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/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=
|
||||||
|
github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM=
|
||||||
|
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@@ -644,6 +752,7 @@ github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prY
|
|||||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 h1:h9WYaTCQJ7hap8C5vQniEum2YZbc+iRad/ROafTjy10=
|
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 h1:h9WYaTCQJ7hap8C5vQniEum2YZbc+iRad/ROafTjy10=
|
||||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109/go.mod h1:U7VCLF6LMHzOFD/6Kww2MTQuwaNeEA1U1dOxFyZBoBE=
|
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109/go.mod h1:U7VCLF6LMHzOFD/6Kww2MTQuwaNeEA1U1dOxFyZBoBE=
|
||||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
@@ -655,12 +764,14 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
|||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
@@ -679,15 +790,39 @@ github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfm
|
|||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
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/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
|
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||||
|
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
|
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||||
|
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||||
|
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||||
|
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||||
|
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||||
|
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||||
|
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||||
|
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||||
|
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
|
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||||
|
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||||
|
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||||
|
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||||
|
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||||
|
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
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/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||||
|
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||||
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=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
@@ -704,6 +839,8 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s
|
|||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||||
|
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
@@ -740,6 +877,7 @@ github.com/swaggo/swag v1.7.3/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3k
|
|||||||
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/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||||
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.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
|
github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
|
||||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
@@ -747,8 +885,6 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
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=
|
||||||
@@ -768,11 +904,16 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
|
|||||||
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
||||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||||
|
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
|
github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I=
|
||||||
|
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
|
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||||
@@ -784,12 +925,15 @@ github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr
|
|||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
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/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=
|
||||||
@@ -799,6 +943,7 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||||
|
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
@@ -808,18 +953,26 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
|||||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||||
|
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@@ -838,6 +991,9 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
|||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@@ -859,17 +1015,19 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
|
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
|
||||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
@@ -890,10 +1048,12 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
@@ -906,16 +1066,20 @@ 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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/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 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
|
||||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
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-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/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=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -931,12 +1095,14 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -980,6 +1146,7 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -995,6 +1162,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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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=
|
||||||
@@ -1032,7 +1200,9 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@@ -1079,8 +1249,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-20201224043029-2b0845dc783e/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.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
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/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=
|
||||||
@@ -1089,6 +1261,9 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
@@ -1106,6 +1281,8 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
|||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
@@ -1115,6 +1292,10 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6
|
|||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||||
|
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
@@ -1150,6 +1331,9 @@ google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6D
|
|||||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 h1:5Tbluzus3QxoAJx4IefGt1W0HQZW4nuMrVk684jI74Q=
|
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 h1:5Tbluzus3QxoAJx4IefGt1W0HQZW4nuMrVk684jI74Q=
|
||||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
|
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
|
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||||
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
@@ -1203,11 +1387,13 @@ gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/R
|
|||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@@ -1215,6 +1401,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
@@ -1223,15 +1410,18 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/sqlite v1.1.5 h1:JU8G59VyKu1x1RMQgjefQnkZjDe9wHc1kARDZPu5dZs=
|
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
||||||
gorm.io/driver/sqlite v1.1.5/go.mod h1:NpaYMcVKEh6vLJ47VP6T7Weieu4H1Drs3dGD/K6GrGc=
|
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
||||||
gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk=
|
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||||
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU=
|
||||||
|
gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||||
|
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||||
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
@@ -1273,3 +1463,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
|||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||||
|
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||||
|
|||||||
93
main.go
93
main.go
@@ -6,10 +6,13 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model/notify"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/cache"
|
"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"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
||||||
"github.com/IceWhaleTech/CasaOS/route"
|
"github.com/IceWhaleTech/CasaOS/route"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
|
||||||
@@ -20,19 +23,35 @@ import (
|
|||||||
var sqliteDB *gorm.DB
|
var sqliteDB *gorm.DB
|
||||||
|
|
||||||
var configFlag = flag.String("c", "", "config address")
|
var configFlag = flag.String("c", "", "config address")
|
||||||
|
var dbFlag = flag.String("db", "", "db path")
|
||||||
var showUserInfo = flag.Bool("show-user-info", false, "show user info")
|
var showUserInfo = flag.Bool("show-user-info", false, "show user info")
|
||||||
|
var resetUser = flag.Bool("ru", false, "reset user")
|
||||||
|
var user = flag.String("user", "", "user name")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
config.InitSetup(*configFlag)
|
config.InitSetup(*configFlag)
|
||||||
config.UpdateSetup()
|
config.UpdateSetup()
|
||||||
loger2.LogSetup()
|
loger.LogInit()
|
||||||
sqliteDB = sqlite.GetDb(config.AppInfo.ProjectPath)
|
if len(*dbFlag) == 0 {
|
||||||
|
*dbFlag = config.AppInfo.DBPath + "/db"
|
||||||
|
}
|
||||||
|
sqliteDB = sqlite.GetDb(*dbFlag)
|
||||||
//gredis.GetRedisConn(config.RedisInfo),
|
//gredis.GetRedisConn(config.RedisInfo),
|
||||||
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
|
service.MyService = service.NewService(sqliteDB)
|
||||||
service.Cache = cache.Init()
|
service.Cache = cache.Init()
|
||||||
|
|
||||||
|
service.GetToken()
|
||||||
|
service.UDPAddressMap = make(map[string]string)
|
||||||
|
//go service.SocketConnect()
|
||||||
|
service.CancelList = make(map[string]string)
|
||||||
|
service.InternalInspection = make(map[string][]string)
|
||||||
|
service.NewVersionApp = make(map[string]string)
|
||||||
route.InitFunction()
|
route.InitFunction()
|
||||||
|
|
||||||
|
// go service.LoopFriend()
|
||||||
|
// go service.MyService.App().CheckNewImage()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @title casaOS API
|
// @title casaOS API
|
||||||
@@ -47,27 +66,77 @@ func init() {
|
|||||||
// @name Authorization
|
// @name Authorization
|
||||||
// @BasePath /v1
|
// @BasePath /v1
|
||||||
func main() {
|
func main() {
|
||||||
|
service.NotifyMsg = make(chan notify.Message, 10)
|
||||||
if *showUserInfo {
|
if *showUserInfo {
|
||||||
fmt.Println("CasaOS User Info")
|
fmt.Println("CasaOS User Info")
|
||||||
fmt.Println("UserName:" + config.UserInfo.UserName)
|
fmt.Println("UserName:" + config.UserInfo.UserName)
|
||||||
fmt.Println("Password:" + config.UserInfo.PWD)
|
fmt.Println("Password:" + config.UserInfo.PWD)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
fmt.Println("Reset User", *resetUser)
|
||||||
|
if *resetUser {
|
||||||
|
|
||||||
|
if user == nil || len(*user) == 0 {
|
||||||
|
fmt.Println("user is empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userData := service.MyService.User().GetUserAllInfoByName(*user)
|
||||||
|
if userData.Id == 0 {
|
||||||
|
fmt.Println("user not exist")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
password := random.RandomString(6, false)
|
||||||
|
userData.Password = encryption.GetMD5ByStr(password)
|
||||||
|
service.MyService.User().UpdateUserPassword(userData)
|
||||||
|
fmt.Println("User reset successful")
|
||||||
|
fmt.Println("UserName:" + userData.UserName)
|
||||||
|
fmt.Println("Password:" + password)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
service.UDPService()
|
||||||
|
service.SendIPToServer()
|
||||||
|
}()
|
||||||
|
go route.SocketInit(service.NotifyMsg)
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
//service.NotifyMsg <- strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
//model.Setup()
|
//model.Setup()
|
||||||
//gredis.Setup()
|
//gredis.Setup()
|
||||||
r := route.InitRouter()
|
r := route.InitRouter()
|
||||||
//service.SyncTask(sqliteDB)
|
//service.SyncTask(sqliteDB)
|
||||||
cron2 := cron.New() //创建一个cron实例
|
cron2 := cron.New()
|
||||||
//执行定时任务(每5秒执行一次)
|
//every day execution
|
||||||
err := cron2.AddFunc("0 0 0 1/1 * *", func() {
|
err := cron2.AddFunc("0 0/5 * * * *", func() {
|
||||||
|
//service.PushIpInfo(*&config.ServerInfo.Token)
|
||||||
//service.UpdataDDNSList(mysqldb)
|
//service.UpdataDDNSList(mysqldb)
|
||||||
//service.SyncTask(sqliteDB)
|
//service.SyncTask(sqliteDB)
|
||||||
|
|
||||||
|
service.SendIPToServer()
|
||||||
|
|
||||||
|
service.LoopFriend()
|
||||||
|
//service.MyService.App().CheckNewImage()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
err = cron2.AddFunc("0/5 * * * * *", func() {
|
||||||
|
if service.ClientCount > 0 {
|
||||||
|
//route.SendNetINfoBySocket()
|
||||||
|
//route.SendCPUBySocket()
|
||||||
|
//route.SendMemBySocket()
|
||||||
|
// route.SendDiskBySocket()
|
||||||
|
//route.SendUSBBySocket()
|
||||||
|
route.SendAllHardwareStatusBySocket()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//启动/关闭
|
|
||||||
cron2.Start()
|
cron2.Start()
|
||||||
defer cron2.Stop()
|
defer cron2.Stop()
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
@@ -77,6 +146,10 @@ func main() {
|
|||||||
WriteTimeout: 60 * time.Second,
|
WriteTimeout: 60 * time.Second,
|
||||||
MaxHeaderBytes: 1 << 20,
|
MaxHeaderBytes: 1 << 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ListenAndServe()
|
s.ListenAndServe()
|
||||||
|
|
||||||
|
// if err := r.Run(fmt.Sprintf(":%v", config.ServerInfo.HttpPort)); err != nil {
|
||||||
|
// fmt.Println("failed run app: ", err)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-10-08 10:29:08
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-21 15:10:03
|
||||||
|
* @FilePath: /CasaOS/middleware/gin.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Cors() gin.HandlerFunc {
|
func Cors() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
method := c.Request.Method
|
method := c.Request.Method
|
||||||
//origin := c.Request.Header.Get("Origin") //请求头部
|
|
||||||
//if origin != "" {
|
|
||||||
//接收客户端发送的origin (重要!)
|
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
c.Header("Access-Control-Allow-Origin", "*")
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
//服务器支持的所有跨域请求的方法
|
|
||||||
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,Language")
|
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")
|
||||||
|
//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
|
||||||
//设置缓存时间
|
//设置缓存时间
|
||||||
c.Header("Access-Control-Max-Age", "172800")
|
c.Header("Access-Control-Max-Age", "172800")
|
||||||
//允许客户端传递校验信息比如 cookie (重要)
|
|
||||||
c.Header("Access-Control-Allow-Credentials", "true")
|
c.Header("Access-Control-Allow-Credentials", "true")
|
||||||
c.Set("content-type", "application/json")
|
c.Set("content-type", "application/json")
|
||||||
//}
|
//}
|
||||||
@@ -42,3 +50,9 @@ func Cors() gin.HandlerFunc {
|
|||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func WriteLog() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("body", c.Request.Body), zap.Any("method", c.Request.Method))
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
27
model/app-analyse.go
Normal file
27
model/app-analyse.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-03-18 11:40:55
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-05-13 14:48:01
|
||||||
|
* @FilePath: /CasaOS/model/app-analyse.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type AppAnalyse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UUId string `json:"uuid"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConnectionStatus struct {
|
||||||
|
From string `json:"from"`
|
||||||
|
To string `json:"to"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
UUId string `json:"uuid"`
|
||||||
|
Event string `json:"event"`
|
||||||
|
}
|
||||||
13
model/app.go
13
model/app.go
@@ -6,6 +6,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServerAppListCollection struct {
|
||||||
|
List []ServerAppList `json:"list"`
|
||||||
|
Recommend []ServerAppList `json:"recommend"`
|
||||||
|
Community []ServerAppList `json:"community"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
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"`
|
||||||
@@ -15,6 +22,7 @@ type ServerAppList struct {
|
|||||||
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"`
|
||||||
|
CategoryId int `json:"category_id"`
|
||||||
CategoryFont string `json:"category_font"`
|
CategoryFont string `json:"category_font"`
|
||||||
PortMap string `json:"port_map"`
|
PortMap string `json:"port_map"`
|
||||||
ImageVersion string `json:"image_version"`
|
ImageVersion string `json:"image_version"`
|
||||||
@@ -38,7 +46,12 @@ type ServerAppList struct {
|
|||||||
Plugins Strings `json:"plugins"`
|
Plugins Strings `json:"plugins"`
|
||||||
Origin string `json:"origin"`
|
Origin string `json:"origin"`
|
||||||
Type int `json:"type"`
|
Type int `json:"type"`
|
||||||
|
QueryCount int `json:"query_count"`
|
||||||
Developer string `json:"developer"`
|
Developer string `json:"developer"`
|
||||||
|
HostName string `json:"host_name"`
|
||||||
|
Privileged bool `json:"privileged"`
|
||||||
|
CapAdd Strings `json:"cap_add"`
|
||||||
|
Cmd Strings `json:"cmd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ports struct {
|
type Ports struct {
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author: link a624669980@163.com
|
||||||
|
* @Date: 2022-05-16 17:37:08
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-22 17:45:53
|
||||||
|
* @FilePath: /CasaOS/model/category.go
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
|
||||||
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
type ServerCategoryList struct {
|
type ServerCategoryList struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Item []CategoryList `json:"item"`
|
||||||
|
}
|
||||||
|
type CategoryList struct {
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
//CreatedAt time.Time `json:"created_at"`
|
//CreatedAt time.Time `json:"created_at"`
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type LSBLKModel struct {
|
|||||||
Format string `json:"format"`
|
Format string `json:"format"`
|
||||||
Health string `json:"health"`
|
Health string `json:"health"`
|
||||||
HotPlug bool `json:"hotplug"`
|
HotPlug bool `json:"hotplug"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
FSUsed string `json:"fsused"`
|
FSUsed string `json:"fsused"`
|
||||||
Temperature int `json:"temperature"`
|
Temperature int `json:"temperature"`
|
||||||
Tran string `json:"tran"`
|
Tran string `json:"tran"`
|
||||||
@@ -47,6 +48,15 @@ type Drive struct {
|
|||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DriveUSB struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Used uint64 `json:"use"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
Mount bool `json:"mount"` //是否完全挂载
|
||||||
|
Avail uint64 `json:"avail"` //可用空间
|
||||||
|
}
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
MountPoint string `json:"mountpoint"`
|
MountPoint string `json:"mountpoint"`
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-12-08 18:10:25
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-14 17:20:36
|
||||||
|
* @FilePath: /CasaOS/model/docker.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
type DockerStatsModel struct {
|
type DockerStatsModel struct {
|
||||||
|
|||||||
33
model/file.go
Normal file
33
model/file.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-20 16:27:12
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-09 18:18:46
|
||||||
|
* @FilePath: /CasaOS/model/file.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type FileOperate struct {
|
||||||
|
Type string `json:"type" binding:"required"`
|
||||||
|
Item []FileItem `json:"item" binding:"required"`
|
||||||
|
TotalSize int64 `json:"total_size"`
|
||||||
|
ProcessedSize int64 `json:"processed_size"`
|
||||||
|
To string `json:"to" binding:"required"`
|
||||||
|
Style string `json:"style"`
|
||||||
|
Finished bool `json:"finished"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileItem struct {
|
||||||
|
From string `json:"from" binding:"required"`
|
||||||
|
Finished bool `json:"finished"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
ProcessedSize int64 `json:"processed_size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileUpdate struct {
|
||||||
|
FilePath string `json:"path" binding:"required"`
|
||||||
|
FileContent string `json:"content" binding:"required"`
|
||||||
|
}
|
||||||
6
model/heart.go
Normal file
6
model/heart.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type CasaOSHeart struct {
|
||||||
|
UuId string `json:"uuid"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
@@ -104,6 +104,7 @@ func (p *PathArray) Scan(input interface{}) error {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
type CustomizationPostData struct {
|
type CustomizationPostData struct {
|
||||||
|
CustomId string `json:"custom_id"`
|
||||||
Origin string `json:"origin"`
|
Origin string `json:"origin"`
|
||||||
NetworkModel string `json:"network_model"`
|
NetworkModel string `json:"network_model"`
|
||||||
Index string `json:"index"`
|
Index string `json:"index"`
|
||||||
@@ -114,12 +115,18 @@ type CustomizationPostData struct {
|
|||||||
Volumes PathArray `json:"volumes"`
|
Volumes PathArray `json:"volumes"`
|
||||||
Devices PathArray `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"`
|
||||||
Memory int64 `json:"memory"`
|
Memory int64 `json:"memory"`
|
||||||
Restart string `json:"restart"`
|
Restart string `json:"restart"`
|
||||||
EnableUPNP bool `json:"enable_upnp"`
|
EnableUPNP bool `json:"enable_upnp"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Position bool `json:"position"`
|
Position bool `json:"position"`
|
||||||
|
HostName string `json:"host_name"`
|
||||||
|
Privileged bool `json:"privileged"`
|
||||||
|
CapAdd []string `json:"cap_add"`
|
||||||
|
Cmd []string `json:"cmd"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Host string `json:"host"`
|
||||||
}
|
}
|
||||||
|
|||||||
28
model/net.go
28
model/net.go
@@ -1,19 +1,17 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type IOCountersStat struct {
|
type IOCountersStat struct {
|
||||||
Name string `json:"name"` // interface name
|
Name string `json:"name"` // interface name
|
||||||
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
|
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
|
||||||
BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
|
BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
|
||||||
PacketsSent uint64 `json:"packetsSent"` // number of packets sent
|
PacketsSent uint64 `json:"packetsSent"` // number of packets sent
|
||||||
PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
|
PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
|
||||||
Errin uint64 `json:"errin"` // total number of errors while receiving
|
Errin uint64 `json:"errin"` // total number of errors while receiving
|
||||||
Errout uint64 `json:"errout"` // total number of errors while sending
|
Errout uint64 `json:"errout"` // total number of errors while sending
|
||||||
Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
|
Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
|
||||||
Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
|
Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
|
||||||
Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
|
Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
|
||||||
Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
|
Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
DateTime time.Time `json:"date_time"`
|
Time int64 `json:"time"`
|
||||||
}
|
}
|
||||||
|
|||||||
6
model/notify.go
Normal file
6
model/notify.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type NotifyMssage struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
21
model/notify/application.go
Normal file
21
model/notify/application.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-27 15:01:58
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-05-31 14:51:21
|
||||||
|
* @FilePath: /CasaOS/model/notify/application.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
type Application struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Finished bool `json:"finished"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
}
|
||||||
22
model/notify/file.go
Normal file
22
model/notify/file.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-26 14:21:57
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-02 11:14:15
|
||||||
|
* @FilePath: /CasaOS/model/notify/file.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
Finished bool `json:"finished"`
|
||||||
|
ProcessedSize int64 `json:"processed_size"`
|
||||||
|
ProcessingPath string `json:"processing_path"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TotalSize int64 `json:"total_size"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
To string `json:"to"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
20
model/notify/message.go
Normal file
20
model/notify/message.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-26 14:39:22
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-05-26 19:08:52
|
||||||
|
* @FilePath: /CasaOS/model/notify/message.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
f "github.com/ambelovsky/gosf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Msg f.Message `json:"msg"`
|
||||||
|
}
|
||||||
16
model/notify/person.go
Normal file
16
model/notify/person.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-27 18:42:42
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-05-27 18:43:08
|
||||||
|
* @FilePath: /CasaOS/model/notify/person.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
ShareId string `json:"share_id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
18
model/notify/result.go
Normal file
18
model/notify/result.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-26 14:21:11
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-05-27 11:15:59
|
||||||
|
* @FilePath: /CasaOS/model/notify/result.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package notify
|
||||||
|
|
||||||
|
// Notify struct for Notify
|
||||||
|
type NotifyModel struct {
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
State string `json:"state"`
|
||||||
|
}
|
||||||
54
model/person.go
Normal file
54
model/person.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type PersionModel struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Ips []string `json:"ips"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//记录链接状态
|
||||||
|
type ConnectState struct {
|
||||||
|
From string `json:"from"`
|
||||||
|
To string `json:"to"`
|
||||||
|
Type string `json:"type"` //current state 1:ready 2:ok
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UUId string `json:"uuid"` //对接标识
|
||||||
|
}
|
||||||
|
type MessageModel struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
UUId string `json:"uuid"`
|
||||||
|
From string `json:"from"`
|
||||||
|
To string `json:"to"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TranFileModel struct {
|
||||||
|
Hash string `json:"hash"` //Verify current fragment integrity
|
||||||
|
Length int `json:"length"`
|
||||||
|
Index int `json:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//需要获取文件详情
|
||||||
|
type FileDetailModel struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回文件详情
|
||||||
|
type FileSummaryModel struct {
|
||||||
|
Hash string `json:"hash"` //Verify file
|
||||||
|
Name string `json:"name"`
|
||||||
|
BlockSize int `json:"block_size"`
|
||||||
|
Length int `json:"length"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriendsModel struct {
|
||||||
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
|
NickName string `json:"nick_name"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
ShareId string `json:"share_id"`
|
||||||
|
}
|
||||||
1
model/receive/app.go
Normal file
1
model/receive/app.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package receive
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-13 18:15:46
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-16 17:50:56
|
||||||
|
* @FilePath: /CasaOS/model/sys_common.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
@@ -16,26 +26,37 @@ type UserModel struct {
|
|||||||
Email string
|
Email string
|
||||||
Description string
|
Description string
|
||||||
Initialized bool
|
Initialized bool
|
||||||
|
Avatar string
|
||||||
|
NickName string
|
||||||
|
Public string
|
||||||
}
|
}
|
||||||
|
|
||||||
//服务配置
|
//服务配置
|
||||||
type ServerModel struct {
|
type ServerModel struct {
|
||||||
HttpPort string
|
HttpPort string
|
||||||
RunMode string
|
RunMode string
|
||||||
ServerApi string
|
ServerApi string
|
||||||
LockAccount bool
|
LockAccount bool
|
||||||
|
Handshake string
|
||||||
|
Token string
|
||||||
|
UDPPort string
|
||||||
|
USBAutoMount string
|
||||||
|
SocketPort string
|
||||||
}
|
}
|
||||||
|
|
||||||
//服务配置
|
//服务配置
|
||||||
type APPModel struct {
|
type APPModel struct {
|
||||||
LogSavePath string
|
LogPath string
|
||||||
LogSaveName string
|
LogSaveName string
|
||||||
LogFileExt string
|
LogFileExt string
|
||||||
DateStrFormat string
|
DateStrFormat string
|
||||||
DateTimeFormat string
|
DateTimeFormat string
|
||||||
|
UserDataPath string
|
||||||
TimeFormat string
|
TimeFormat string
|
||||||
DateFormat string
|
DateFormat string
|
||||||
ProjectPath string
|
DBPath string
|
||||||
|
ShellPath string
|
||||||
|
TempPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
//公共返回模型
|
//公共返回模型
|
||||||
@@ -45,13 +66,6 @@ type Result struct {
|
|||||||
Data interface{} `json:"data" example:"返回结果"`
|
Data interface{} `json:"data" example:"返回结果"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//zeritier相关
|
|
||||||
type ZeroTierModel struct {
|
|
||||||
UserName string
|
|
||||||
PWD string
|
|
||||||
Token string
|
|
||||||
}
|
|
||||||
|
|
||||||
//redis配置文件
|
//redis配置文件
|
||||||
type RedisModel struct {
|
type RedisModel struct {
|
||||||
Host string
|
Host string
|
||||||
@@ -67,8 +81,14 @@ type SystemConfig struct {
|
|||||||
ConfigPath string `json:"config_path"`
|
ConfigPath string `json:"config_path"`
|
||||||
SyncPort string `json:"sync_port"`
|
SyncPort string `json:"sync_port"`
|
||||||
SyncKey string `json:"sync_key"`
|
SyncKey string `json:"sync_key"`
|
||||||
|
Analyse string `json:"analyse"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CasaOSGlobalVariables struct {
|
type CasaOSGlobalVariables struct {
|
||||||
AppChange bool
|
AppChange bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FileSetting struct {
|
||||||
|
ShareDir []string `json:"share_dir" delim:"|"`
|
||||||
|
DownloadDir string `json:"download_dir"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package model
|
|
||||||
17
model/system_model/verify_information.go
Normal file
17
model/system_model/verify_information.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-15 11:30:47
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-23 18:40:40
|
||||||
|
* @FilePath: /CasaOS/model/system_model/verify_information.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package system_model
|
||||||
|
|
||||||
|
type VerifyInformation struct {
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
ExpiresAt int64 `json:"expires_at"`
|
||||||
|
}
|
||||||
9
model/user.go
Normal file
9
model/user.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type UserInfo struct {
|
||||||
|
NickName string `json:"nick_name"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
ShareId string `json:"share_id"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
Version int `json:"version,omitempty"`
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import "time"
|
|||||||
|
|
||||||
type Version struct {
|
type Version struct {
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
ChangLog string `json:"chang_log"`
|
ChangeLog string `json:"change_log"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type ZeroTierUpData struct {
|
|
||||||
Config ZeroTierConfig `json:"config"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ZeroTierConfig struct {
|
|
||||||
Private bool `json:"private"`
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,12 @@ package model
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"` //File name or document name
|
||||||
Path string `json:"path"`
|
Path string `json:"path"` //Full path to file or folder
|
||||||
IsDir bool `json:"is_dir"`
|
IsDir bool `json:"is_dir"` //Is it a folder
|
||||||
Date time.Time `json:"date"`
|
Date time.Time `json:"date"`
|
||||||
|
Size int64 `json:"size"` //File Size
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Label string `json:"label,omitempty"`
|
||||||
|
Write bool `json:"write"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-09-30 18:18:14
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-21 11:09:30
|
||||||
|
* @FilePath: /CasaOS/pkg/config/config.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package config
|
package config
|
||||||
|
|
||||||
const (
|
const (
|
||||||
USERCONFIGURL = "conf/conf.ini"
|
USERCONFIGURL = "/etc/casaos.conf"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-13 18:15:46
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-21 16:01:26
|
||||||
|
* @FilePath: /CasaOS/pkg/config/init.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -22,11 +32,7 @@ var UserInfo = &model.UserModel{}
|
|||||||
//用户相关
|
//用户相关
|
||||||
var AppInfo = &model.APPModel{}
|
var AppInfo = &model.APPModel{}
|
||||||
|
|
||||||
//redis相关配置
|
//var RedisInfo = &model.RedisModel{}
|
||||||
var RedisInfo = &model.RedisModel{}
|
|
||||||
|
|
||||||
//zerotier相关
|
|
||||||
var ZeroTierInfo = &model.ZeroTierModel{}
|
|
||||||
|
|
||||||
//server相关
|
//server相关
|
||||||
var ServerInfo = &model.ServerModel{}
|
var ServerInfo = &model.ServerModel{}
|
||||||
@@ -35,6 +41,8 @@ var SystemConfigInfo = &model.SystemConfig{}
|
|||||||
|
|
||||||
var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
|
var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
|
||||||
|
|
||||||
|
var FileSettingInfo = &model.FileSetting{}
|
||||||
|
|
||||||
var Cfg *ini.File
|
var Cfg *ini.File
|
||||||
|
|
||||||
//初始化设置,获取系统的部分信息。
|
//初始化设置,获取系统的部分信息。
|
||||||
@@ -44,6 +52,9 @@ func InitSetup(config string) {
|
|||||||
if len(config) > 0 {
|
if len(config) > 0 {
|
||||||
configDir = config
|
configDir = config
|
||||||
}
|
}
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
configDir = "./conf/conf.conf"
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
//读取文件
|
//读取文件
|
||||||
Cfg, err = ini.Load(configDir)
|
Cfg, err = ini.Load(configDir)
|
||||||
@@ -54,11 +65,31 @@ func InitSetup(config string) {
|
|||||||
|
|
||||||
mapTo("user", UserInfo)
|
mapTo("user", UserInfo)
|
||||||
mapTo("app", AppInfo)
|
mapTo("app", AppInfo)
|
||||||
mapTo("zerotier", ZeroTierInfo)
|
//mapTo("redis", RedisInfo)
|
||||||
mapTo("redis", RedisInfo)
|
|
||||||
mapTo("server", ServerInfo)
|
mapTo("server", ServerInfo)
|
||||||
mapTo("system", SystemConfigInfo)
|
mapTo("system", SystemConfigInfo)
|
||||||
|
mapTo("file", FileSettingInfo)
|
||||||
SystemConfigInfo.ConfigPath = configDir
|
SystemConfigInfo.ConfigPath = configDir
|
||||||
|
if len(AppInfo.DBPath) == 0 {
|
||||||
|
AppInfo.DBPath = "/var/lib/casaos"
|
||||||
|
Cfg.SaveTo(configDir)
|
||||||
|
}
|
||||||
|
if len(AppInfo.LogPath) == 0 {
|
||||||
|
AppInfo.LogPath = "/var/log/casaos/"
|
||||||
|
Cfg.SaveTo(configDir)
|
||||||
|
}
|
||||||
|
if len(AppInfo.ShellPath) == 0 {
|
||||||
|
AppInfo.ShellPath = "/usr/share/casaos/shell"
|
||||||
|
Cfg.SaveTo(configDir)
|
||||||
|
}
|
||||||
|
if len(AppInfo.UserDataPath) == 0 {
|
||||||
|
AppInfo.UserDataPath = "/var/lib/casaos/conf"
|
||||||
|
Cfg.SaveTo(configDir)
|
||||||
|
}
|
||||||
|
if len(AppInfo.TempPath) == 0 {
|
||||||
|
AppInfo.TempPath = "/var/lib/casaos/temp"
|
||||||
|
Cfg.SaveTo(configDir)
|
||||||
|
}
|
||||||
// AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd()
|
// AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
import (
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
)
|
||||||
|
|
||||||
//检查目录是否存在
|
//检查目录是否存在
|
||||||
func mkdirDATAAll() {
|
func mkdirDATAAll() {
|
||||||
dirArray := [7]string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"}
|
sysType := runtime.GOOS
|
||||||
|
var dirArray []string
|
||||||
|
if sysType == "linux" {
|
||||||
|
dirArray = []string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sysType == "windows" {
|
||||||
|
dirArray = []string{"C:\\CasaOS\\DATA\\AppData", "C:\\CasaOS\\DATA\\Documents", "C:\\CasaOS\\DATA\\Downloads", "C:\\CasaOS\\DATA\\Gallery", "C:\\CasaOS\\DATA\\Media/Movies", "C:\\CasaOS\\DATA\\Media\\TV Shows", "C:\\CasaOS\\DATA\\Media\\Music"}
|
||||||
|
}
|
||||||
|
if sysType == "darwin" {
|
||||||
|
dirArray = []string{"./CasaOS/DATA/AppData", "./CasaOS/DATA/Documents", "./CasaOS/DATA/Downloads", "./CasaOS/DATA/Gallery", "./CasaOS/DATA/Media/Movies", "./CasaOS/DATA/Media/TV Shows", "./CasaOS/DATA/Media/Music"}
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range dirArray {
|
for _, v := range dirArray {
|
||||||
file.IsNotExistMkDir(v)
|
file.IsNotExistMkDir(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSetup() {
|
func UpdateSetup() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
func GetGithubClient() *github.Client {
|
func GetGithubClient() *github.Client {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ts := oauth2.StaticTokenSource(
|
ts := oauth2.StaticTokenSource(
|
||||||
&oauth2.Token{AccessToken: "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"},
|
&oauth2.Token{AccessToken: ""},
|
||||||
)
|
)
|
||||||
tc := oauth2.NewClient(ctx, ts)
|
tc := oauth2.NewClient(ctx, ts)
|
||||||
client := github.NewClient(tc)
|
client := github.NewClient(tc)
|
||||||
|
|||||||
51
pkg/quic_helper/config.go
Normal file
51
pkg/quic_helper/config.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package quic_helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/lucas-clemente/quic-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setup a bare-bones TLS config for the server
|
||||||
|
func GetGenerateTLSConfig(token string) *tls.Config {
|
||||||
|
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
template := x509.Certificate{SerialNumber: big.NewInt(1)}
|
||||||
|
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||||||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||||
|
|
||||||
|
tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{tlsCert},
|
||||||
|
NextProtos: []string{token},
|
||||||
|
SessionTicketsDisabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func GetClientTlsConfig(otherToken string) *tls.Config {
|
||||||
|
return &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
NextProtos: []string{otherToken},
|
||||||
|
SessionTicketsDisabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetQUICConfig() *quic.Config {
|
||||||
|
return &quic.Config{
|
||||||
|
ConnectionIDLength: 4,
|
||||||
|
KeepAlive: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-13 18:15:46
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-22 18:50:44
|
||||||
|
* @FilePath: /CasaOS/pkg/sqlite/db.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package sqlite
|
package sqlite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
"go.uber.org/zap"
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var gdb *gorm.DB
|
var gdb *gorm.DB
|
||||||
|
|
||||||
func GetDb(projectPath string) *gorm.DB {
|
func GetDb(dbPath string) *gorm.DB {
|
||||||
if gdb != nil {
|
if gdb != nil {
|
||||||
return gdb
|
return gdb
|
||||||
}
|
}
|
||||||
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
|
// Refer https://github.com/go-sql-driver/mysql#dsn-data-source-name
|
||||||
//dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", m.User, m.PWD, m.IP, m.Port, m.DBName)
|
//dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", m.User, m.PWD, m.IP, m.Port, m.DBName)
|
||||||
//db, err := gorm.Open(mysql2.Open(dsn), &gorm.Config{})
|
//db, err := gorm.Open(mysql2.Open(dsn), &gorm.Config{})
|
||||||
file.IsNotExistMkDir(projectPath + "/db/")
|
file.IsNotExistMkDir(dbPath)
|
||||||
db, err := gorm.Open(sqlite.Open(projectPath+"/db/casaOS.db"), &gorm.Config{})
|
db, err := gorm.Open(sqlite.Open(dbPath+"/casaOS.db"), &gorm.Config{})
|
||||||
c, _ := db.DB()
|
c, _ := db.DB()
|
||||||
c.SetMaxIdleConns(10)
|
c.SetMaxIdleConns(10)
|
||||||
c.SetMaxOpenConns(100)
|
c.SetMaxOpenConns(100)
|
||||||
c.SetConnMaxIdleTime(time.Second * 1000)
|
c.SetConnMaxIdleTime(time.Second * 1000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("连接数据失败!")
|
loger.Error("sqlite connect error", zap.Any("db connect error", err))
|
||||||
panic("数据库连接失败")
|
panic("sqlite connect error")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
gdb = db
|
gdb = db
|
||||||
err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{})
|
err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{}, model2.PersonDownRecordDBModel{}, model2.UserDBModel{})
|
||||||
|
db.Exec("DROP TABLE IF EXISTS o_application")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("检查和创建数据库出错", err)
|
loger.Error("check or create db error", zap.Any("error", err))
|
||||||
}
|
}
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetCtrlUrl(host, device string) string {
|
|
||||||
request := ctrlUrlRequest(host, device)
|
|
||||||
response, _ := http.DefaultClient.Do(request)
|
|
||||||
resultBody, _ := ioutil.ReadAll(response.Body)
|
|
||||||
defer response.Body.Close()
|
|
||||||
if response.StatusCode == 200 {
|
|
||||||
return resolve(string(resultBody))
|
|
||||||
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func ctrlUrlRequest(host string, deviceDescUrl string) *http.Request {
|
|
||||||
//请求头
|
|
||||||
header := http.Header{}
|
|
||||||
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
|
||||||
header.Set("User-Agent", "preston")
|
|
||||||
header.Set("Host", host)
|
|
||||||
header.Set("Connection", "keep-alive")
|
|
||||||
request, _ := http.NewRequest("GET", "http://"+host+deviceDescUrl, nil)
|
|
||||||
request.Header = header
|
|
||||||
return request
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolve(resultStr string) string {
|
|
||||||
inputReader := strings.NewReader(resultStr)
|
|
||||||
|
|
||||||
// 从文件读取,如可以如下:
|
|
||||||
// content, err := ioutil.ReadFile("studygolang.xml")
|
|
||||||
// decoder := xml.NewDecoder(bytes.NewBuffer(content))
|
|
||||||
|
|
||||||
lastLabel := ""
|
|
||||||
|
|
||||||
ISUpnpServer := false
|
|
||||||
|
|
||||||
IScontrolURL := false
|
|
||||||
var controlURL string //`controlURL`
|
|
||||||
// var eventSubURL string //`eventSubURL`
|
|
||||||
// var SCPDURL string //`SCPDURL`
|
|
||||||
|
|
||||||
decoder := xml.NewDecoder(inputReader)
|
|
||||||
for t, err := decoder.Token(); err == nil && !IScontrolURL; t, err = decoder.Token() {
|
|
||||||
switch token := t.(type) {
|
|
||||||
// 处理元素开始(标签)
|
|
||||||
case xml.StartElement:
|
|
||||||
if ISUpnpServer {
|
|
||||||
name := token.Name.Local
|
|
||||||
lastLabel = name
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理元素结束(标签)
|
|
||||||
case xml.EndElement:
|
|
||||||
// log.Println("结束标记:", token.Name.Local)
|
|
||||||
// 处理字符数据(这里就是元素的文本)
|
|
||||||
case xml.CharData:
|
|
||||||
//得到url后其他标记就不处理了
|
|
||||||
content := string([]byte(token))
|
|
||||||
//找到提供端口映射的服务
|
|
||||||
if content == "urn:schemas-upnp-org:service:WANIPConnection:1" {
|
|
||||||
ISUpnpServer = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if ISUpnpServer {
|
|
||||||
switch lastLabel {
|
|
||||||
case "controlURL":
|
|
||||||
controlURL = content
|
|
||||||
IScontrolURL = true
|
|
||||||
case "eventSubURL":
|
|
||||||
// eventSubURL = content
|
|
||||||
case "SCPDURL":
|
|
||||||
// SCPDURL = content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return controlURL
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetCtrlUrl(t *testing.T) {
|
|
||||||
upnp, err := Gateway()
|
|
||||||
if err == nil {
|
|
||||||
upnp.CtrlUrl = GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
|
||||||
upnp.LocalHost = ip_helper2.GetLoclIp()
|
|
||||||
upnp.AddPortMapping(8090, 8090, "TCP")
|
|
||||||
//upnp.DelPortMapping(9999, "TCP")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Gateway() (*Upnp, error) {
|
|
||||||
result, error := send()
|
|
||||||
if result == "" || error != nil {
|
|
||||||
return nil, error
|
|
||||||
}
|
|
||||||
upnp := resolvesss(result)
|
|
||||||
return upnp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func send() (string, error) {
|
|
||||||
var str = "M-SEARCH * HTTP/1.1\r\n" +
|
|
||||||
"HOST: 239.255.255.250:1900\r\n" +
|
|
||||||
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
|
|
||||||
"MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n"
|
|
||||||
var conn *net.UDPConn
|
|
||||||
remoteAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("组播地址格式不正确")
|
|
||||||
}
|
|
||||||
localAddr, err := net.ResolveUDPAddr("udp", ip_helper2.GetLoclIp()+":")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("本地ip地址格式不正确")
|
|
||||||
}
|
|
||||||
conn, err = net.ListenUDP("udp", localAddr)
|
|
||||||
defer conn.Close()
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("监听udp出错")
|
|
||||||
}
|
|
||||||
_, err = conn.WriteToUDP([]byte(str), remoteAddr)
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("发送msg到组播地址出错")
|
|
||||||
}
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
n, _, err := conn.ReadFromUDP(buf)
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("从组播地址接搜消息出错")
|
|
||||||
}
|
|
||||||
result := string(buf[:n])
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolvesss(result string) *Upnp {
|
|
||||||
var upnp = &Upnp{}
|
|
||||||
lines := strings.Split(result, "\r\n")
|
|
||||||
for _, line := range lines {
|
|
||||||
//按照第一个冒号分为两个字符串
|
|
||||||
nameValues := strings.SplitAfterN(line, ":", 2)
|
|
||||||
if len(nameValues) < 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch strings.ToUpper(strings.Trim(strings.Split(nameValues[0], ":")[0], " ")) {
|
|
||||||
case "ST":
|
|
||||||
//fmt.Println(nameValues[1])
|
|
||||||
case "CACHE-CONTROL":
|
|
||||||
//fmt.Println(nameValues[1])
|
|
||||||
case "LOCATION":
|
|
||||||
urls := strings.Split(strings.Split(nameValues[1], "//")[1], "/")
|
|
||||||
upnp.GatewayHost = (urls[0])
|
|
||||||
upnp.DeviceDescUrl = ("/" + urls[1])
|
|
||||||
case "SERVER":
|
|
||||||
upnp.GatewayName = (nameValues[1])
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return upnp
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestGateway(t *testing.T) {
|
|
||||||
|
|
||||||
Gateway()
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
//
|
|
||||||
////添加一个端口映射
|
|
||||||
func (n *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) {
|
|
||||||
defer func() {
|
|
||||||
if errTemp := recover(); errTemp != nil {
|
|
||||||
loger2.NewOLoger().Error("upnp模块报错了", errTemp)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if isSuccess := addSend(localPort, remotePort, protocol, n.GatewayHost, n.CtrlUrl, n.LocalHost); isSuccess {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return errors.New("添加一个端口映射失败")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addSend(localPort, remotePort int, protocol, host, ctrUrl, localHost string) bool {
|
|
||||||
request := addRequest(localPort, remotePort, protocol, host, ctrUrl, localHost)
|
|
||||||
response, _ := http.DefaultClient.Do(request)
|
|
||||||
defer response.Body.Close()
|
|
||||||
//resultBody, _ := ioutil.ReadAll(response.Body)
|
|
||||||
//fmt.Println(string(resultBody))
|
|
||||||
return response.StatusCode == 200
|
|
||||||
}
|
|
||||||
|
|
||||||
type Node struct {
|
|
||||||
Name string
|
|
||||||
Content string
|
|
||||||
Attr map[string]string
|
|
||||||
Child []Node
|
|
||||||
}
|
|
||||||
|
|
||||||
func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl, localHost string) *http.Request {
|
|
||||||
//请求头
|
|
||||||
header := http.Header{}
|
|
||||||
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
|
||||||
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`)
|
|
||||||
header.Set("Content-Type", "text/xml")
|
|
||||||
header.Set("Connection", "Close")
|
|
||||||
header.Set("Content-Length", "")
|
|
||||||
//请求体
|
|
||||||
body := Node{Name: "SOAP-ENV:Envelope",
|
|
||||||
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
|
|
||||||
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
|
|
||||||
childOne := Node{Name: `SOAP-ENV:Body`}
|
|
||||||
childTwo := Node{Name: `m:AddPortMapping`,
|
|
||||||
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
|
|
||||||
|
|
||||||
childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
|
|
||||||
childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)}
|
|
||||||
childList3 := Node{Name: "NewProtocol", Content: protocol}
|
|
||||||
childList4 := Node{Name: "NewEnabled", Content: "1"}
|
|
||||||
childList5 := Node{Name: "NewInternalClient", Content: localHost}
|
|
||||||
childList6 := Node{Name: "NewLeaseDuration", Content: "0"}
|
|
||||||
childList7 := Node{Name: "NewPortMappingDescription", Content: "Oasis"}
|
|
||||||
childList8 := Node{Name: "NewRemoteHost"}
|
|
||||||
childTwo.AddChild(childList1)
|
|
||||||
childTwo.AddChild(childList2)
|
|
||||||
childTwo.AddChild(childList3)
|
|
||||||
childTwo.AddChild(childList4)
|
|
||||||
childTwo.AddChild(childList5)
|
|
||||||
childTwo.AddChild(childList6)
|
|
||||||
childTwo.AddChild(childList7)
|
|
||||||
childTwo.AddChild(childList8)
|
|
||||||
|
|
||||||
childOne.AddChild(childTwo)
|
|
||||||
body.AddChild(childOne)
|
|
||||||
bodyStr := body.BuildXML()
|
|
||||||
//请求
|
|
||||||
request, _ := http.NewRequest("POST", "http://"+gatewayHost+ctlUrl,
|
|
||||||
strings.NewReader(bodyStr))
|
|
||||||
request.Header = header
|
|
||||||
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
|
|
||||||
return request
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) AddChild(node Node) {
|
|
||||||
n.Child = append(n.Child, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) BuildXML() string {
|
|
||||||
buf := bytes.NewBufferString("<")
|
|
||||||
buf.WriteString(n.Name)
|
|
||||||
for key, value := range n.Attr {
|
|
||||||
buf.WriteString(" ")
|
|
||||||
buf.WriteString(key + "=" + value)
|
|
||||||
}
|
|
||||||
buf.WriteString(">" + n.Content)
|
|
||||||
|
|
||||||
for _, node := range n.Child {
|
|
||||||
buf.WriteString(node.BuildXML())
|
|
||||||
}
|
|
||||||
buf.WriteString("</" + n.Name + ">")
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Upnp) DelPortMapping(remotePort int, protocol string) bool {
|
|
||||||
isSuccess := delSendSend(remotePort, protocol, n.GatewayHost, n.CtrlUrl)
|
|
||||||
if isSuccess {
|
|
||||||
//this.MappingPort.delMapping(remotePort, protocol)
|
|
||||||
//fmt.Println("删除了一个端口映射: remote:", remotePort)
|
|
||||||
}
|
|
||||||
return isSuccess
|
|
||||||
}
|
|
||||||
|
|
||||||
func delSendSend(remotePort int, protocol, host, ctlUrl string) bool {
|
|
||||||
delrequest := delbuildRequest(remotePort, protocol, host, ctlUrl)
|
|
||||||
response, _ := http.DefaultClient.Do(delrequest)
|
|
||||||
//resultBody, _ := ioutil.ReadAll(response.Body)
|
|
||||||
defer response.Body.Close()
|
|
||||||
|
|
||||||
return response.StatusCode == 200
|
|
||||||
}
|
|
||||||
|
|
||||||
func delbuildRequest(remotePort int, protocol, host, ctlUrl string) *http.Request {
|
|
||||||
//请求头
|
|
||||||
header := http.Header{}
|
|
||||||
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
|
|
||||||
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`)
|
|
||||||
header.Set("Content-Type", "text/xml")
|
|
||||||
header.Set("Connection", "Close")
|
|
||||||
header.Set("Content-Length", "")
|
|
||||||
//请求体
|
|
||||||
body := Node{Name: "SOAP-ENV:Envelope",
|
|
||||||
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
|
|
||||||
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
|
|
||||||
childOne := Node{Name: `SOAP-ENV:Body`}
|
|
||||||
childTwo := Node{Name: `m:DeletePortMapping`,
|
|
||||||
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
|
|
||||||
childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
|
|
||||||
childList2 := Node{Name: "NewProtocol", Content: protocol}
|
|
||||||
childList3 := Node{Name: "NewRemoteHost"}
|
|
||||||
childTwo.AddChild(childList1)
|
|
||||||
childTwo.AddChild(childList2)
|
|
||||||
childTwo.AddChild(childList3)
|
|
||||||
childOne.AddChild(childTwo)
|
|
||||||
body.AddChild(childOne)
|
|
||||||
bodyStr := body.BuildXML()
|
|
||||||
|
|
||||||
//请求
|
|
||||||
request, _ := http.NewRequest("POST", "http://"+host+ctlUrl,
|
|
||||||
strings.NewReader(bodyStr))
|
|
||||||
request.Header = header
|
|
||||||
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
|
|
||||||
return request
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestAddPortMapping(t *testing.T) {
|
|
||||||
//AddPortMapping(6666,6666,"TCP","192.168.2.1:5000",)
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/prestonTao/upnp"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Upnp struct {
|
|
||||||
LocalHost string `json:"local_host"`
|
|
||||||
GatewayName string `json:"gateway_name"` //网关名称
|
|
||||||
GatewayHost string `json:"gateway_host"` //网关ip和端口
|
|
||||||
DeviceDescUrl string `json:"device_desc_url"` //设备描述url
|
|
||||||
CtrlUrl string `json:"ctrl_url"` //控制请求url
|
|
||||||
}
|
|
||||||
|
|
||||||
func Testaaa() {
|
|
||||||
upnpMan := new(upnp.Upnp)
|
|
||||||
err := upnpMan.SearchGateway()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
} else {
|
|
||||||
fmt.Println("local ip address: ", upnpMan.LocalHost)
|
|
||||||
fmt.Println("gateway ip address: ", upnpMan.Gateway.Host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package upnp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTestaaa(t *testing.T) {
|
|
||||||
(Testaaa())
|
|
||||||
}
|
|
||||||
@@ -101,7 +101,6 @@ func ExecSmartCTLByPath(path string) []byte {
|
|||||||
output, err := exec.CommandContext(ctx, "smartctl", "-a", path, "-j").Output()
|
output, err := exec.CommandContext(ctx, "smartctl", "-a", path, "-j").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("smartctl", err)
|
fmt.Println("smartctl", err)
|
||||||
fmt.Println("output", string(output))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
|
|||||||
127
pkg/utils/common_err/e.go
Normal file
127
pkg/utils/common_err/e.go
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package common_err
|
||||||
|
|
||||||
|
const (
|
||||||
|
SUCCESS = 200
|
||||||
|
ERROR = 500
|
||||||
|
INVALID_PARAMS = 400
|
||||||
|
ERROR_AUTH_TOKEN = 401
|
||||||
|
|
||||||
|
//user
|
||||||
|
PWD_INVALID = 10001
|
||||||
|
PWD_IS_EMPTY = 10002
|
||||||
|
PWD_INVALID_OLD = 10003
|
||||||
|
ACCOUNT_LOCK = 10004
|
||||||
|
PWD_IS_TOO_SIMPLE = 10005
|
||||||
|
USER_NOT_EXIST = 10006
|
||||||
|
USER_EXIST = 10007
|
||||||
|
KEY_NOT_EXIST = 10008
|
||||||
|
NOT_IMAGE = 10009
|
||||||
|
IMAGE_TOO_LARGE = 10010
|
||||||
|
INSUFFICIENT_PERMISSIONS = 10011
|
||||||
|
|
||||||
|
//system
|
||||||
|
DIR_ALREADY_EXISTS = 20001
|
||||||
|
FILE_ALREADY_EXISTS = 20002
|
||||||
|
FILE_OR_DIR_EXISTS = 20003
|
||||||
|
PORT_IS_OCCUPIED = 20004
|
||||||
|
COMMAND_ERROR_INVALID_OPERATION = 20005
|
||||||
|
VERIFICATION_FAILURE = 20006
|
||||||
|
|
||||||
|
//disk
|
||||||
|
NAME_NOT_AVAILABLE = 40001
|
||||||
|
DISK_NEEDS_FORMAT = 40002
|
||||||
|
DISK_BUSYING = 40003
|
||||||
|
REMOVE_MOUNT_POINT_ERROR = 40004
|
||||||
|
FORMAT_ERROR = 40005
|
||||||
|
|
||||||
|
//app
|
||||||
|
UNINSTALL_APP_ERROR = 50001
|
||||||
|
PULL_IMAGE_ERROR = 50002
|
||||||
|
DEVICE_NOT_EXIST = 50003
|
||||||
|
ERROR_APP_NAME_EXIST = 50004
|
||||||
|
|
||||||
|
//file
|
||||||
|
FILE_DOES_NOT_EXIST = 60001
|
||||||
|
FILE_READ_ERROR = 60002
|
||||||
|
FILE_DELETE_ERROR = 60003
|
||||||
|
DIR_NOT_EXISTS = 60004
|
||||||
|
SOURCE_DES_SAME = 60005
|
||||||
|
|
||||||
|
//shortcuts
|
||||||
|
SHORTCUTS_URL_ERROR = 70001
|
||||||
|
|
||||||
|
//person
|
||||||
|
PERSON_REMOTE_ERROR = 80001
|
||||||
|
PERSON_DOWN_NOT_EXIST = 80002
|
||||||
|
PERSON_EXIST_DOWNLOAD = 80003
|
||||||
|
PERSON_NOT_EXIST_USER = 80004
|
||||||
|
PERSON_EXIST_FRIEND = 80005
|
||||||
|
PERSON_MYSELF = 80006
|
||||||
|
)
|
||||||
|
|
||||||
|
var MsgFlags = map[int]string{
|
||||||
|
SUCCESS: "ok",
|
||||||
|
ERROR: "fail",
|
||||||
|
INVALID_PARAMS: "Parameters Error",
|
||||||
|
ERROR_AUTH_TOKEN: "Error auth token",
|
||||||
|
|
||||||
|
//user
|
||||||
|
PWD_INVALID: "Invalid password",
|
||||||
|
PWD_IS_EMPTY: "Password is empty",
|
||||||
|
PWD_INVALID_OLD: "Invalid old password",
|
||||||
|
ACCOUNT_LOCK: "Account is locked",
|
||||||
|
PWD_IS_TOO_SIMPLE: "Password is too simple",
|
||||||
|
USER_NOT_EXIST: "User does not exist",
|
||||||
|
USER_EXIST: "User already exists",
|
||||||
|
KEY_NOT_EXIST: "Key does not exist",
|
||||||
|
IMAGE_TOO_LARGE: "Image is too large",
|
||||||
|
NOT_IMAGE: "Not an image",
|
||||||
|
INSUFFICIENT_PERMISSIONS: "Insufficient permissions",
|
||||||
|
|
||||||
|
//system
|
||||||
|
DIR_ALREADY_EXISTS: "Folder already exists",
|
||||||
|
FILE_ALREADY_EXISTS: "File already exists",
|
||||||
|
FILE_OR_DIR_EXISTS: "File or folder already exists",
|
||||||
|
PORT_IS_OCCUPIED: "Port is occupied",
|
||||||
|
VERIFICATION_FAILURE: "Verification failure",
|
||||||
|
|
||||||
|
//app
|
||||||
|
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
||||||
|
PULL_IMAGE_ERROR: "Error pulling image",
|
||||||
|
DEVICE_NOT_EXIST: "Device does not exist",
|
||||||
|
ERROR_APP_NAME_EXIST: "App name already exists",
|
||||||
|
|
||||||
|
//disk
|
||||||
|
NAME_NOT_AVAILABLE: "Name not available",
|
||||||
|
DISK_NEEDS_FORMAT: "Drive needs to be formatted",
|
||||||
|
REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point",
|
||||||
|
DISK_BUSYING: "Drive is busy",
|
||||||
|
FORMAT_ERROR: "Formatting failed, please check if the directory is occupied",
|
||||||
|
|
||||||
|
//
|
||||||
|
SOURCE_DES_SAME: "Source and destination cannot be the same.",
|
||||||
|
FILE_DOES_NOT_EXIST: "File does not exist",
|
||||||
|
|
||||||
|
DIR_NOT_EXISTS: "Directory does not exist",
|
||||||
|
|
||||||
|
FILE_READ_ERROR: "File read error",
|
||||||
|
FILE_DELETE_ERROR: "Delete error",
|
||||||
|
SHORTCUTS_URL_ERROR: "URL error",
|
||||||
|
|
||||||
|
PERSON_REMOTE_ERROR: "Remote connection error",
|
||||||
|
PERSON_DOWN_NOT_EXIST: "Download record does not exist",
|
||||||
|
PERSON_EXIST_DOWNLOAD: "The same download task exists",
|
||||||
|
PERSON_EXIST_FRIEND: "Friend already exist",
|
||||||
|
PERSON_NOT_EXIST_USER: "User does not exist",
|
||||||
|
PERSON_MYSELF: "You can not add yourself",
|
||||||
|
COMMAND_ERROR_INVALID_OPERATION: "invalid operation",
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取错误信息
|
||||||
|
func GetMsg(code int) string {
|
||||||
|
msg, ok := MsgFlags[code]
|
||||||
|
if ok {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
return MsgFlags[ERROR]
|
||||||
|
}
|
||||||
22
pkg/utils/encryption/md5_helper.go
Normal file
22
pkg/utils/encryption/md5_helper.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-14 14:33:25
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-14 14:33:49
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/encryption/md5_helper.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package encryption
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetMD5ByStr(str string) string {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(str))
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
81
pkg/utils/file/block.go
Normal file
81
pkg/utils/file/block.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get info of block
|
||||||
|
func GetBlockInfo(fileSize int64) (blockSize int, length int) {
|
||||||
|
switch {
|
||||||
|
case fileSize <= 1<<28: //256M
|
||||||
|
blockSize = 1 << 17 //128kb
|
||||||
|
case fileSize <= 1<<29: //512M
|
||||||
|
blockSize = 1 << 18 //256kb
|
||||||
|
case fileSize <= 1<<30: //1G
|
||||||
|
blockSize = 1 << 19 //512kb
|
||||||
|
case fileSize <= 1<<31: //2G
|
||||||
|
blockSize = 1 << 20 //(mb)
|
||||||
|
case fileSize <= 1<<32: //4G
|
||||||
|
blockSize = 1 << 21 //2mb
|
||||||
|
case fileSize <= 1<<33: //8G
|
||||||
|
blockSize = 1 << 22 //4mb
|
||||||
|
case fileSize <= 1<<34: //16g
|
||||||
|
blockSize = 1 << 23 //8mb
|
||||||
|
default:
|
||||||
|
blockSize = 1 << 24 //16mb
|
||||||
|
}
|
||||||
|
temp := float64(fileSize) / float64(blockSize)
|
||||||
|
length = int(math.Ceil(temp))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the hash of the data
|
||||||
|
func GetHashByContent(data []byte) string {
|
||||||
|
sum := md5.Sum(data)
|
||||||
|
return hex.EncodeToString(sum[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the hash of the data
|
||||||
|
func GetHashByPath(path string) string {
|
||||||
|
pFile, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer pFile.Close()
|
||||||
|
md5h := md5.New()
|
||||||
|
io.Copy(md5h, pFile)
|
||||||
|
return hex.EncodeToString(md5h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Comparison data hash
|
||||||
|
func ComparisonHash(data []byte, hash string) bool {
|
||||||
|
sum := md5.Sum(data)
|
||||||
|
return hex.EncodeToString(sum[:]) == hash
|
||||||
|
}
|
||||||
|
|
||||||
|
//get prefix byte length
|
||||||
|
func PrefixLength(byteLength int) []byte {
|
||||||
|
lengthByte := []byte{'0', '0', '0', '0', '0', '0'}
|
||||||
|
bSize := strconv.Itoa(byteLength)
|
||||||
|
cha := 6 - len(bSize)
|
||||||
|
for i := len(bSize); i > 0; i-- {
|
||||||
|
lengthByte[cha+i-1] = bSize[i-1]
|
||||||
|
}
|
||||||
|
return lengthByte
|
||||||
|
}
|
||||||
|
|
||||||
|
//get data byte length
|
||||||
|
func DataLength(length int) []byte {
|
||||||
|
lengthByte := []byte{'0', '0', '0', '0', '0', '0', '0', '0'}
|
||||||
|
bSize := strconv.Itoa(length)
|
||||||
|
cha := 8 - len(bSize)
|
||||||
|
for i := len(bSize); i > 0; i-- {
|
||||||
|
lengthByte[cha+i-1] = bSize[i-1]
|
||||||
|
}
|
||||||
|
return lengthByte
|
||||||
|
}
|
||||||
@@ -1,11 +1,21 @@
|
|||||||
package file
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
path2 "path"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mholt/archiver/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetSize get the file size
|
// GetSize get the file size
|
||||||
@@ -35,7 +45,7 @@ func CheckPermission(src string) bool {
|
|||||||
|
|
||||||
// IsNotExistMkDir create a directory if it does not exist
|
// IsNotExistMkDir create a directory if it does not exist
|
||||||
func IsNotExistMkDir(src string) error {
|
func IsNotExistMkDir(src string) error {
|
||||||
if notExist := CheckNotExist(src); notExist == true {
|
if notExist := CheckNotExist(src); notExist {
|
||||||
if err := MkDir(src); err != nil {
|
if err := MkDir(src); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -136,6 +146,21 @@ func CreateFile(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateFileAndWriteContent(path string, content string) error {
|
||||||
|
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
write := bufio.NewWriter(file)
|
||||||
|
|
||||||
|
write.WriteString(content)
|
||||||
|
|
||||||
|
write.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// IsNotExistMkDir create a directory if it does not exist
|
// IsNotExistMkDir create a directory if it does not exist
|
||||||
func IsNotExistCreateFile(src string) error {
|
func IsNotExistCreateFile(src string) error {
|
||||||
if notExist := CheckNotExist(src); notExist == true {
|
if notExist := CheckNotExist(src); notExist == true {
|
||||||
@@ -159,3 +184,343 @@ func ReadFullFile(path string) []byte {
|
|||||||
}
|
}
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// File copies a single file from src to dst
|
||||||
|
func CopyFile(src, dst, style string) error {
|
||||||
|
var err error
|
||||||
|
var srcfd *os.File
|
||||||
|
var dstfd *os.File
|
||||||
|
var srcinfo os.FileInfo
|
||||||
|
|
||||||
|
lastPath := src[strings.LastIndex(src, "/")+1:]
|
||||||
|
|
||||||
|
if !strings.HasSuffix(dst, "/") {
|
||||||
|
dst += "/"
|
||||||
|
}
|
||||||
|
dst += lastPath
|
||||||
|
if Exists(dst) {
|
||||||
|
if style == "skip" {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
os.Remove(dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcfd, err = os.Open(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer srcfd.Close()
|
||||||
|
|
||||||
|
if dstfd, err = os.Create(dst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer dstfd.Close()
|
||||||
|
|
||||||
|
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if srcinfo, err = os.Stat(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.Chmod(dst, srcinfo.Mode())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @param {*} src
|
||||||
|
* @param {*} dst
|
||||||
|
* @param {string} style
|
||||||
|
* @return {*}
|
||||||
|
* @method:
|
||||||
|
* @router:
|
||||||
|
*/
|
||||||
|
func CopySingleFile(src, dst, style string) error {
|
||||||
|
var err error
|
||||||
|
var srcfd *os.File
|
||||||
|
var dstfd *os.File
|
||||||
|
var srcinfo os.FileInfo
|
||||||
|
|
||||||
|
if Exists(dst) {
|
||||||
|
if style == "skip" {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
os.Remove(dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcfd, err = os.Open(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer srcfd.Close()
|
||||||
|
|
||||||
|
if dstfd, err = os.Create(dst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer dstfd.Close()
|
||||||
|
|
||||||
|
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if srcinfo, err = os.Stat(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.Chmod(dst, srcinfo.Mode())
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check for duplicate file names
|
||||||
|
func GetNoDuplicateFileName(fullPath string) string {
|
||||||
|
path, fileName := filepath.Split(fullPath)
|
||||||
|
fileSuffix := path2.Ext(fileName)
|
||||||
|
filenameOnly := strings.TrimSuffix(fileName, fileSuffix)
|
||||||
|
for i := 0; Exists(fullPath); i++ {
|
||||||
|
fullPath = path2.Join(path, filenameOnly+"("+strconv.Itoa(i+1)+")"+fileSuffix)
|
||||||
|
}
|
||||||
|
return fullPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dir copies a whole directory recursively
|
||||||
|
func CopyDir(src string, dst string, style string) error {
|
||||||
|
var err error
|
||||||
|
var fds []os.FileInfo
|
||||||
|
var srcinfo os.FileInfo
|
||||||
|
|
||||||
|
if srcinfo, err = os.Stat(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !srcinfo.IsDir() {
|
||||||
|
if err = CopyFile(src, dst, style); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
//dstPath := dst
|
||||||
|
lastPath := src[strings.LastIndex(src, "/")+1:]
|
||||||
|
dst += "/" + lastPath
|
||||||
|
// for i := 0; Exists(dst); i++ {
|
||||||
|
// dst = dstPath + "/" + lastPath + strconv.Itoa(i+1)
|
||||||
|
// }
|
||||||
|
if Exists(dst) {
|
||||||
|
if style == "skip" {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
os.Remove(dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if fds, err = ioutil.ReadDir(src); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, fd := range fds {
|
||||||
|
srcfp := path.Join(src, fd.Name())
|
||||||
|
dstfp := dst //path.Join(dst, fd.Name())
|
||||||
|
|
||||||
|
if fd.IsDir() {
|
||||||
|
if err = CopyDir(srcfp, dstfp, style); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err = CopyFile(srcfp, dstfp, style); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteToPath(data []byte, path, name string) error {
|
||||||
|
fullPath := path
|
||||||
|
if strings.HasSuffix(path, "/") {
|
||||||
|
fullPath += name
|
||||||
|
} else {
|
||||||
|
fullPath += "/" + name
|
||||||
|
}
|
||||||
|
IsNotExistCreateFile(fullPath)
|
||||||
|
file, err := os.OpenFile(fullPath,
|
||||||
|
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
|
||||||
|
0666,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = file.Write(data)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//最终拼接
|
||||||
|
func SpliceFiles(dir, path string, length int, startPoint int) error {
|
||||||
|
|
||||||
|
fullPath := path
|
||||||
|
|
||||||
|
IsNotExistCreateFile(fullPath)
|
||||||
|
|
||||||
|
file, _ := os.OpenFile(fullPath,
|
||||||
|
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
|
||||||
|
0666,
|
||||||
|
)
|
||||||
|
defer file.Close()
|
||||||
|
bufferedWriter := bufio.NewWriter(file)
|
||||||
|
for i := 0; i < length+startPoint; i++ {
|
||||||
|
data, err := ioutil.ReadFile(dir + "/" + strconv.Itoa(i+startPoint))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = bufferedWriter.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferedWriter.Flush()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) {
|
||||||
|
|
||||||
|
switch t {
|
||||||
|
case "zip", "":
|
||||||
|
return ".zip", archiver.NewZip(), nil
|
||||||
|
case "tar":
|
||||||
|
return ".tar", archiver.NewTar(), nil
|
||||||
|
case "targz":
|
||||||
|
return ".tar.gz", archiver.NewTarGz(), nil
|
||||||
|
case "tarbz2":
|
||||||
|
return ".tar.bz2", archiver.NewTarBz2(), nil
|
||||||
|
case "tarxz":
|
||||||
|
return ".tar.xz", archiver.NewTarXz(), nil
|
||||||
|
case "tarlz4":
|
||||||
|
return ".tar.lz4", archiver.NewTarLz4(), nil
|
||||||
|
case "tarsz":
|
||||||
|
return ".tar.sz", archiver.NewTarSz(), nil
|
||||||
|
default:
|
||||||
|
return "", nil, errors.New("format not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func AddFile(ar archiver.Writer, path, commonPath string) error {
|
||||||
|
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !info.IsDir() && !info.Mode().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if path != commonPath {
|
||||||
|
filename := info.Name()
|
||||||
|
err = ar.Write(archiver.File{
|
||||||
|
FileInfo: archiver.FileInfo{
|
||||||
|
FileInfo: info,
|
||||||
|
CustomName: filename,
|
||||||
|
},
|
||||||
|
ReadCloser: file,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
names, err := file.Readdirnames(0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
|
err = AddFile(ar, filepath.Join(path, name), commonPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to archive %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func CommonPrefix(sep byte, paths ...string) string {
|
||||||
|
// Handle special cases.
|
||||||
|
switch len(paths) {
|
||||||
|
case 0:
|
||||||
|
return ""
|
||||||
|
case 1:
|
||||||
|
return path.Clean(paths[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, we treat string as []byte, not []rune as is often
|
||||||
|
// done in Go. (And sep as byte, not rune). This is because
|
||||||
|
// most/all supported OS' treat paths as string of non-zero
|
||||||
|
// bytes. A filename may be displayed as a sequence of Unicode
|
||||||
|
// runes (typically encoded as UTF-8) but paths are
|
||||||
|
// not required to be valid UTF-8 or in any normalized form
|
||||||
|
// (e.g. "é" (U+00C9) and "é" (U+0065,U+0301) are different
|
||||||
|
// file names.
|
||||||
|
c := []byte(path.Clean(paths[0]))
|
||||||
|
|
||||||
|
// We add a trailing sep to handle the case where the
|
||||||
|
// common prefix directory is included in the path list
|
||||||
|
// (e.g. /home/user1, /home/user1/foo, /home/user1/bar).
|
||||||
|
// path.Clean will have cleaned off trailing / separators with
|
||||||
|
// the exception of the root directory, "/" (in which case we
|
||||||
|
// make it "//", but this will get fixed up to "/" bellow).
|
||||||
|
c = append(c, sep)
|
||||||
|
|
||||||
|
// Ignore the first path since it's already in c
|
||||||
|
for _, v := range paths[1:] {
|
||||||
|
// Clean up each path before testing it
|
||||||
|
v = path.Clean(v) + string(sep)
|
||||||
|
|
||||||
|
// Find the first non-common byte and truncate c
|
||||||
|
if len(v) < len(c) {
|
||||||
|
c = c[:len(v)]
|
||||||
|
}
|
||||||
|
for i := 0; i < len(c); i++ {
|
||||||
|
if v[i] != c[i] {
|
||||||
|
c = c[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing non-separator characters and the final separator
|
||||||
|
for i := len(c) - 1; i >= 0; i-- {
|
||||||
|
if c[i] == sep {
|
||||||
|
c = c[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileOrDirSize(path string) (int64, error) {
|
||||||
|
fileInfo, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if fileInfo.IsDir() {
|
||||||
|
return DirSizeB(path + "/")
|
||||||
|
}
|
||||||
|
return fileInfo.Size(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//getFileSize get file size by path(B)
|
||||||
|
func DirSizeB(path string) (int64, error) {
|
||||||
|
var size int64
|
||||||
|
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
|
||||||
|
if !info.IsDir() {
|
||||||
|
size += info.Size()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return size, err
|
||||||
|
}
|
||||||
|
|||||||
261
pkg/utils/file/image.go
Normal file
261
pkg/utils/file/image.go
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/disintegration/imaging"
|
||||||
|
"github.com/dsoprea/go-exif/v3"
|
||||||
|
exifcommon "github.com/dsoprea/go-exif/v3/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetImage(path string, width, height int) ([]byte, error) {
|
||||||
|
if thumbnail, err := GetThumbnailByOwnerPhotos(path); err == nil {
|
||||||
|
return thumbnail, nil
|
||||||
|
} else {
|
||||||
|
return GetThumbnailByWebPhoto(path, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func GetThumbnailByOwnerPhotos(path string) ([]byte, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buff := &bytes.Buffer{}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
offset := 0
|
||||||
|
offsets := []int{12, 30}
|
||||||
|
|
||||||
|
head := make([]byte, 0xffff)
|
||||||
|
|
||||||
|
r := io.TeeReader(file, buff)
|
||||||
|
_, err = r.Read(head)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, offset = range offsets {
|
||||||
|
if _, err = exif.ParseExifHeader(head[offset:]); err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
im, err := exifcommon.NewIfdMappingWithStandard()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, index, err := exif.Collect(im, exif.NewTagIndex(), head[offset:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ifd := index.RootIfd.NextIfd()
|
||||||
|
if ifd == nil {
|
||||||
|
return nil, exif.ErrNoThumbnail
|
||||||
|
}
|
||||||
|
thumbnail, err := ifd.Thumbnail()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return thumbnail, nil
|
||||||
|
}
|
||||||
|
func GetThumbnailByWebPhoto(path string, width, height int) ([]byte, error) {
|
||||||
|
src, err := imaging.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
img := imaging.Resize(src, width, 0, imaging.Lanczos)
|
||||||
|
|
||||||
|
f, err := imaging.FormatFromFilename(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
imaging.Encode(&buf, img, f)
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ImageExtArray() []string {
|
||||||
|
|
||||||
|
ext := []string{
|
||||||
|
"ase",
|
||||||
|
"art",
|
||||||
|
"bmp",
|
||||||
|
"blp",
|
||||||
|
"cd5",
|
||||||
|
"cit",
|
||||||
|
"cpt",
|
||||||
|
"cr2",
|
||||||
|
"cut",
|
||||||
|
"dds",
|
||||||
|
"dib",
|
||||||
|
"djvu",
|
||||||
|
"egt",
|
||||||
|
"exif",
|
||||||
|
"gif",
|
||||||
|
"gpl",
|
||||||
|
"grf",
|
||||||
|
"icns",
|
||||||
|
"ico",
|
||||||
|
"iff",
|
||||||
|
"jng",
|
||||||
|
"jpeg",
|
||||||
|
"jpg",
|
||||||
|
"jfif",
|
||||||
|
"jp2",
|
||||||
|
"jps",
|
||||||
|
"lbm",
|
||||||
|
"max",
|
||||||
|
"miff",
|
||||||
|
"mng",
|
||||||
|
"msp",
|
||||||
|
"nitf",
|
||||||
|
"ota",
|
||||||
|
"pbm",
|
||||||
|
"pc1",
|
||||||
|
"pc2",
|
||||||
|
"pc3",
|
||||||
|
"pcf",
|
||||||
|
"pcx",
|
||||||
|
"pdn",
|
||||||
|
"pgm",
|
||||||
|
"PI1",
|
||||||
|
"PI2",
|
||||||
|
"PI3",
|
||||||
|
"pict",
|
||||||
|
"pct",
|
||||||
|
"pnm",
|
||||||
|
"pns",
|
||||||
|
"ppm",
|
||||||
|
"psb",
|
||||||
|
"psd",
|
||||||
|
"pdd",
|
||||||
|
"psp",
|
||||||
|
"px",
|
||||||
|
"pxm",
|
||||||
|
"pxr",
|
||||||
|
"qfx",
|
||||||
|
"raw",
|
||||||
|
"rle",
|
||||||
|
"sct",
|
||||||
|
"sgi",
|
||||||
|
"rgb",
|
||||||
|
"int",
|
||||||
|
"bw",
|
||||||
|
"tga",
|
||||||
|
"tiff",
|
||||||
|
"tif",
|
||||||
|
"vtf",
|
||||||
|
"xbm",
|
||||||
|
"xcf",
|
||||||
|
"xpm",
|
||||||
|
"3dv",
|
||||||
|
"amf",
|
||||||
|
"ai",
|
||||||
|
"awg",
|
||||||
|
"cgm",
|
||||||
|
"cdr",
|
||||||
|
"cmx",
|
||||||
|
"dxf",
|
||||||
|
"e2d",
|
||||||
|
"egt",
|
||||||
|
"eps",
|
||||||
|
"fs",
|
||||||
|
"gbr",
|
||||||
|
"odg",
|
||||||
|
"svg",
|
||||||
|
"stl",
|
||||||
|
"vrml",
|
||||||
|
"x3d",
|
||||||
|
"sxd",
|
||||||
|
"v2d",
|
||||||
|
"vnd",
|
||||||
|
"wmf",
|
||||||
|
"emf",
|
||||||
|
"art",
|
||||||
|
"xar",
|
||||||
|
"png",
|
||||||
|
"webp",
|
||||||
|
"jxr",
|
||||||
|
"hdp",
|
||||||
|
"wdp",
|
||||||
|
"cur",
|
||||||
|
"ecw",
|
||||||
|
"iff",
|
||||||
|
"lbm",
|
||||||
|
"liff",
|
||||||
|
"nrrd",
|
||||||
|
"pam",
|
||||||
|
"pcx",
|
||||||
|
"pgf",
|
||||||
|
"sgi",
|
||||||
|
"rgb",
|
||||||
|
"rgba",
|
||||||
|
"bw",
|
||||||
|
"int",
|
||||||
|
"inta",
|
||||||
|
"sid",
|
||||||
|
"ras",
|
||||||
|
"sun",
|
||||||
|
"tga",
|
||||||
|
}
|
||||||
|
|
||||||
|
return ext
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:get a image's ext
|
||||||
|
* @param {string} path "file path"
|
||||||
|
* @return {string} ext "file ext"
|
||||||
|
* @return {error} err "error info"
|
||||||
|
*/
|
||||||
|
func GetImageExt(p string) (string, error) {
|
||||||
|
file, err := os.Open(p)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
buff := make([]byte, 512)
|
||||||
|
|
||||||
|
_, err = file.Read(buff)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
filetype := http.DetectContentType(buff)
|
||||||
|
|
||||||
|
ext := ImageExtArray()
|
||||||
|
|
||||||
|
for i := 0; i < len(ext); i++ {
|
||||||
|
if strings.Contains(ext[i], filetype[6:]) {
|
||||||
|
return ext[i], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("invalid image type")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetImageExtByName(p string) (string, error) {
|
||||||
|
|
||||||
|
extArr := ImageExtArray()
|
||||||
|
ext := filepath.Ext(p)
|
||||||
|
for i := 0; i < len(extArr); i++ {
|
||||||
|
if strings.Contains(ext, extArr[i]) {
|
||||||
|
return extArr[i], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", errors.New("invalid image type")
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package httper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -16,12 +16,48 @@ import (
|
|||||||
//url:请求地址
|
//url:请求地址
|
||||||
//response:请求返回的内容
|
//response:请求返回的内容
|
||||||
func Get(url string, head map[string]string) (response string) {
|
func Get(url string, head map[string]string) (response string) {
|
||||||
client := http.Client{Timeout: 30 * time.Second}
|
client := &http.Client{Timeout: 30 * time.Second}
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
req.BasicAuth()
|
|
||||||
for k, v := range head {
|
for k, v := range head {
|
||||||
req.Header.Add(k, v)
|
req.Header.Add(k, v)
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
//需要错误日志的处理
|
||||||
|
//loger.Error(error)
|
||||||
|
return ""
|
||||||
|
//panic(error)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var buffer [512]byte
|
||||||
|
result := bytes.NewBuffer(nil)
|
||||||
|
for {
|
||||||
|
n, err := resp.Body.Read(buffer[0:])
|
||||||
|
result.Write(buffer[0:n])
|
||||||
|
if err != nil && err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
//loger.Error(err)
|
||||||
|
return ""
|
||||||
|
// panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = result.String()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送GET请求
|
||||||
|
//url:请求地址
|
||||||
|
//response:请求返回的内容
|
||||||
|
func PersonGet(url string) (response string) {
|
||||||
|
client := &http.Client{Timeout: 5 * time.Second}
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -67,7 +103,8 @@ func Post(url string, data []byte, contentType string, head map[string]string) (
|
|||||||
client := &http.Client{Timeout: 5 * time.Second}
|
client := &http.Client{Timeout: 5 * time.Second}
|
||||||
resp, error := client.Do(req)
|
resp, error := client.Do(req)
|
||||||
if error != nil {
|
if error != nil {
|
||||||
panic(error)
|
fmt.Println(error)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
@@ -76,88 +113,6 @@ func Post(url string, data []byte, contentType string, head map[string]string) (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//发送POST请求
|
|
||||||
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
|
||||||
//content:请求放回的内容
|
|
||||||
func ZeroTierPost(url string, data map[string]string, head map[string]string, cookies []*http.Cookie) (content string, code int) {
|
|
||||||
b, _ := json.Marshal(data)
|
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewReader(b))
|
|
||||||
for _, cookie := range cookies {
|
|
||||||
req.AddCookie(cookie)
|
|
||||||
}
|
|
||||||
for k, v := range head {
|
|
||||||
req.Header.Add(k, v)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{Timeout: 20 * time.Second}
|
|
||||||
resp, error := client.Do(req)
|
|
||||||
|
|
||||||
if error != nil {
|
|
||||||
panic(error)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
code = resp.StatusCode
|
|
||||||
result, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
content = string(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送POST请求
|
|
||||||
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
|
||||||
//content:请求放回的内容
|
|
||||||
func ZeroTierPostJson(url string, data string, head map[string]string) (content string, code int) {
|
|
||||||
var postData *bytes.Buffer
|
|
||||||
|
|
||||||
jsonStr := []byte(data)
|
|
||||||
postData = bytes.NewBuffer(jsonStr)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", url, postData)
|
|
||||||
for k, v := range head {
|
|
||||||
req.Header.Add(k, v)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{Timeout: 20 * time.Second}
|
|
||||||
resp, error := client.Do(req)
|
|
||||||
|
|
||||||
if error != nil {
|
|
||||||
panic(error)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
result, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
content = string(result)
|
|
||||||
code = resp.StatusCode
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ZeroTierDelete(url string, head map[string]string) (content string, code int) {
|
|
||||||
|
|
||||||
req, err := http.NewRequest("DELETE", url, nil)
|
|
||||||
for k, v := range head {
|
|
||||||
req.Header.Add(k, v)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{Timeout: 20 * time.Second}
|
|
||||||
resp, error := client.Do(req)
|
|
||||||
|
|
||||||
if error != nil {
|
|
||||||
panic(error)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
result, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
content = string(result)
|
|
||||||
code = resp.StatusCode
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送POST请求
|
//发送POST请求
|
||||||
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
//url:请求地址,data:POST请求提交的数据,contentType:请求体格式,如:application/json
|
||||||
//content:请求放回的内容
|
//content:请求放回的内容
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package utils
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package ip_helper
|
package ip_helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsIPv4(address string) bool {
|
func IsIPv4(address string) bool {
|
||||||
@@ -39,3 +40,35 @@ func GetLoclIp() string {
|
|||||||
}
|
}
|
||||||
return "127.0.0.1"
|
return "127.0.0.1"
|
||||||
}
|
}
|
||||||
|
func GetDeviceAllIP(port string) []string {
|
||||||
|
var address []string
|
||||||
|
addrs, err := net.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
for _, a := range addrs {
|
||||||
|
if ipNet, ok := a.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
|
||||||
|
if ipNet.IP.To16() != nil {
|
||||||
|
address = append(address, ipNet.IP.String()+":"+port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
|
||||||
|
func HasLocalIP(ip net.IP) bool {
|
||||||
|
if ip.IsLoopback() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
ip.String()
|
||||||
|
|
||||||
|
ip4 := ip.To4()
|
||||||
|
if ip4 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip4[0] == 10 || // 10.0.0.0/8
|
||||||
|
(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || // 172.16.0.0/12
|
||||||
|
(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
|
||||||
|
(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ip_helper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,3 +21,7 @@ func TestGetExternalIPV6(t *testing.T) {
|
|||||||
func TestGetLoclIp(t *testing.T) {
|
func TestGetLoclIp(t *testing.T) {
|
||||||
fmt.Println(GetLoclIp())
|
fmt.Println(GetLoclIp())
|
||||||
}
|
}
|
||||||
|
func TestHasLocalIP(t *testing.T) {
|
||||||
|
fmt.Println("dddd")
|
||||||
|
fmt.Println(HasLocalIP(net.ParseIP("192.168.2.10")))
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-09-30 18:18:14
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-24 10:02:46
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/jwt/jwt.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package jwt
|
package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
jwt "github.com/golang-jwt/jwt"
|
jwt "github.com/golang-jwt/jwt/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// type Claims struct {
|
||||||
|
// UserName string `json:"username"`
|
||||||
|
// PassWord string `json:"password"`
|
||||||
|
// Id int `json:"id"`
|
||||||
|
// jwt.RegisteredClaims
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var jwtSecret []byte
|
||||||
|
|
||||||
|
// //创建token
|
||||||
|
// func GenerateToken(username, password string, id int, issuer string, t time.Duration) (string, error) {
|
||||||
|
// clims := Claims{
|
||||||
|
// username,
|
||||||
|
// password,
|
||||||
|
// id,
|
||||||
|
// jwt.RegisteredClaims{
|
||||||
|
// ExpiresAt: jwt.NewNumericDate(time.Now().Add(t)),
|
||||||
|
// IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
// NotBefore: jwt.NewNumericDate(time.Now()),
|
||||||
|
// Issuer: issuer,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
// tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, clims)
|
||||||
|
// token, err := tokenClaims.SignedString(jwtSecret)
|
||||||
|
// return token, err
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //解析token
|
||||||
|
// func ParseToken(token string) (*Claims, error) {
|
||||||
|
// tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// return jwtSecret, nil
|
||||||
|
// })
|
||||||
|
// if tokenClaims != nil {
|
||||||
|
// if clims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
|
||||||
|
// return clims, nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
//****************** soon to be removed ******************
|
||||||
|
|
||||||
type Claims struct {
|
type Claims struct {
|
||||||
UserName string `json:"username"`
|
UserName string `json:"username"`
|
||||||
PassWord string `json:"password"`
|
PassWord string `json:"password"`
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-17 14:01:25
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-24 10:13:52
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/jwt/jwt_helper.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package jwt
|
package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,36 +15,87 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
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"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc {
|
// func JWT() gin.HandlerFunc {
|
||||||
|
// return func(c *gin.Context) {
|
||||||
|
// var code int
|
||||||
|
// code = common_err.SUCCESS
|
||||||
|
// token := c.GetHeader("Authorization")
|
||||||
|
// if len(token) == 0 {
|
||||||
|
// token = c.Query("token")
|
||||||
|
// }
|
||||||
|
// if token == "" {
|
||||||
|
// code = common_err.INVALID_PARAMS
|
||||||
|
// }
|
||||||
|
|
||||||
|
// claims, err := ParseToken(token)
|
||||||
|
// //_, err := ParseToken(token)
|
||||||
|
// if err != nil {
|
||||||
|
// code = common_err.ERROR_AUTH_TOKEN
|
||||||
|
// } else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) {
|
||||||
|
// code = common_err.ERROR_AUTH_TOKEN
|
||||||
|
// }
|
||||||
|
// if code != common_err.SUCCESS {
|
||||||
|
// c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
|
// c.Abort()
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// c.Request.Header.Add("user_id", strconv.Itoa(claims.Id))
|
||||||
|
// c.Next()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //get AccessToken
|
||||||
|
// func GetAccessToken(username, pwd string, id int) string {
|
||||||
|
// token, err := GenerateToken(username, pwd, id, "casaos", 3*time.Hour*time.Duration(1))
|
||||||
|
// if err == nil {
|
||||||
|
// return token
|
||||||
|
// } else {
|
||||||
|
// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func GetRefreshToken(username, pwd string, id int) string {
|
||||||
|
// token, err := GenerateToken(username, pwd, id, "fresh", 7*24*time.Hour*time.Duration(1))
|
||||||
|
// if err == nil {
|
||||||
|
// return token
|
||||||
|
// } else {
|
||||||
|
// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//*************** soon to be removed *****************
|
||||||
|
|
||||||
|
func JWT() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
var code int
|
var code int
|
||||||
code = oasis_err2.SUCCESS
|
code = common_err.SUCCESS
|
||||||
token := c.GetHeader("Authorization")
|
token := c.GetHeader("Authorization")
|
||||||
if len(token) == 0 {
|
if len(token) == 0 {
|
||||||
token = c.Query("token")
|
token = c.Query("token")
|
||||||
}
|
}
|
||||||
if token == "" {
|
if token == "" {
|
||||||
code = oasis_err2.INVALID_PARAMS
|
code = common_err.INVALID_PARAMS
|
||||||
}
|
|
||||||
if swagHandler == nil {
|
|
||||||
//claims, err := ParseToken(token)
|
|
||||||
_, err := ParseToken(token)
|
|
||||||
if err != nil {
|
|
||||||
code = oasis_err2.ERROR_AUTH_TOKEN
|
|
||||||
|
|
||||||
}
|
|
||||||
//else if time.Now().Unix() > claims.ExpiresAt {
|
|
||||||
// code = oasis_err2.ERROR_AUTH_TOKEN
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if code != oasis_err2.SUCCESS {
|
//claims, err := ParseToken(token)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
|
_, err := ParseToken(token)
|
||||||
|
if err != nil {
|
||||||
|
code = common_err.ERROR_AUTH_TOKEN
|
||||||
|
|
||||||
|
}
|
||||||
|
//else if time.Now().Unix() > claims.ExpiresAt {
|
||||||
|
// code = oasis_err2.ERROR_AUTH_TOKEN
|
||||||
|
//}
|
||||||
|
|
||||||
|
if code != common_err.SUCCESS {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,109 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-02 15:09:38
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-27 15:47:49
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/loger/log.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package loger
|
package loger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//定义一个int的别名
|
var loggers *zap.Logger
|
||||||
type Level int
|
|
||||||
|
|
||||||
type OLog interface {
|
func getFileLogWriter() (writeSyncer zapcore.WriteSyncer) {
|
||||||
Debug(v ...interface{})
|
// 使用 lumberjack 实现 log rotate
|
||||||
Info(v ...interface{})
|
lumberJackLogger := &lumberjack.Logger{
|
||||||
Warn(v ...interface{})
|
Filename: filepath.Join(config.AppInfo.LogPath, fmt.Sprintf("%s.%s",
|
||||||
Error(v ...interface{})
|
config.AppInfo.LogSaveName,
|
||||||
Fatal(v ...interface{})
|
config.AppInfo.LogFileExt,
|
||||||
Path() string
|
)),
|
||||||
}
|
MaxSize: 10,
|
||||||
|
MaxBackups: 60,
|
||||||
type oLog struct {
|
MaxAge: 1,
|
||||||
}
|
Compress: true,
|
||||||
|
|
||||||
var (
|
|
||||||
F *os.File
|
|
||||||
DefaultPrefix = ""
|
|
||||||
DefaultCallerDepth = 2
|
|
||||||
logger *log.Logger
|
|
||||||
logPrefix = ""
|
|
||||||
levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
|
|
||||||
)
|
|
||||||
|
|
||||||
//iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
|
|
||||||
const (
|
|
||||||
DEBUG Level = iota
|
|
||||||
INFO
|
|
||||||
WARN
|
|
||||||
ERROR
|
|
||||||
FATAL
|
|
||||||
)
|
|
||||||
|
|
||||||
//日志初始化
|
|
||||||
func LogSetup() {
|
|
||||||
var err error
|
|
||||||
filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
|
|
||||||
fileName := fmt.Sprintf("%s.%s",
|
|
||||||
config.AppInfo.LogSaveName,
|
|
||||||
config.AppInfo.LogFileExt,
|
|
||||||
)
|
|
||||||
F, err = file2.MustOpen(fileName, filePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("logging.Setup err: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger = log.New(F, DefaultPrefix, log.LstdFlags)
|
return zapcore.AddSync(lumberJackLogger)
|
||||||
|
|
||||||
}
|
}
|
||||||
func (o *oLog) Path() string {
|
|
||||||
filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
|
func LogInit() {
|
||||||
fileName := fmt.Sprintf("%s.%s",
|
encoderConfig := zap.NewProductionEncoderConfig()
|
||||||
config.AppInfo.LogSaveName,
|
encoderConfig.EncodeTime = zapcore.EpochTimeEncoder
|
||||||
config.AppInfo.LogFileExt,
|
encoder := zapcore.NewJSONEncoder(encoderConfig)
|
||||||
|
fileWriteSyncer := getFileLogWriter()
|
||||||
|
core := zapcore.NewTee(
|
||||||
|
zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.InfoLevel),
|
||||||
|
zapcore.NewCore(encoder, fileWriteSyncer, zapcore.InfoLevel),
|
||||||
)
|
)
|
||||||
return filePath + fileName
|
loggers = zap.New(core)
|
||||||
}
|
|
||||||
func (o *oLog) Debug(v ...interface{}) {
|
|
||||||
setPrefix(DEBUG)
|
|
||||||
logger.Println(v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *oLog) Info(v ...interface{}) {
|
func Info(message string, fields ...zap.Field) {
|
||||||
setPrefix(INFO)
|
callerFields := getCallerInfoForLog()
|
||||||
logger.Println(v)
|
fields = append(fields, callerFields...)
|
||||||
|
loggers.Info(message, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *oLog) Warn(v ...interface{}) {
|
func Debug(message string, fields ...zap.Field) {
|
||||||
setPrefix(WARN)
|
callerFields := getCallerInfoForLog()
|
||||||
logger.Println(v)
|
fields = append(fields, callerFields...)
|
||||||
|
loggers.Debug(message, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *oLog) Error(v ...interface{}) {
|
func Error(message string, fields ...zap.Field) {
|
||||||
setPrefix(ERROR)
|
callerFields := getCallerInfoForLog()
|
||||||
logger.Println(v)
|
fields = append(fields, callerFields...)
|
||||||
|
loggers.Error(message, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *oLog) Fatal(v ...interface{}) {
|
func Warn(message string, fields ...zap.Field) {
|
||||||
setPrefix(FATAL)
|
callerFields := getCallerInfoForLog()
|
||||||
logger.Println(v)
|
fields = append(fields, callerFields...)
|
||||||
|
loggers.Warn(message, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPrefix(level Level) {
|
func getCallerInfoForLog() (callerFields []zap.Field) {
|
||||||
_, file, line, ok := runtime.Caller(DefaultCallerDepth)
|
|
||||||
if ok {
|
pc, file, line, ok := runtime.Caller(2) // 回溯两层,拿到写日志的调用方的函数信息
|
||||||
logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
|
if !ok {
|
||||||
} else {
|
return
|
||||||
logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
|
|
||||||
}
|
}
|
||||||
|
funcName := runtime.FuncForPC(pc).Name()
|
||||||
|
funcName = path.Base(funcName) //Base函数返回路径的最后一个元素,只保留函数名
|
||||||
|
|
||||||
logger.SetPrefix(logPrefix)
|
callerFields = append(callerFields, zap.String("func", funcName), zap.String("file", file), zap.Int("line", line))
|
||||||
}
|
return
|
||||||
|
|
||||||
func NewOLoger() OLog {
|
|
||||||
return &oLog{}
|
|
||||||
}
|
}
|
||||||
|
|||||||
109
pkg/utils/loger/log_old.go
Normal file
109
pkg/utils/loger/log_old.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package loger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
//定义一个int的别名
|
||||||
|
type Level int
|
||||||
|
|
||||||
|
type OLog interface {
|
||||||
|
Debug(v ...interface{})
|
||||||
|
Info(v ...interface{})
|
||||||
|
Warn(v ...interface{})
|
||||||
|
Error(v ...interface{})
|
||||||
|
Fatal(v ...interface{})
|
||||||
|
Path() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type oLog struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
F *os.File
|
||||||
|
DefaultPrefix = ""
|
||||||
|
DefaultCallerDepth = 2
|
||||||
|
logger *log.Logger
|
||||||
|
logPrefix = ""
|
||||||
|
levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
|
||||||
|
)
|
||||||
|
|
||||||
|
//iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
|
||||||
|
const (
|
||||||
|
DEBUG Level = iota
|
||||||
|
INFO
|
||||||
|
WARN
|
||||||
|
ERROR
|
||||||
|
FATAL
|
||||||
|
)
|
||||||
|
|
||||||
|
//日志初始化
|
||||||
|
func LogSetupOld() {
|
||||||
|
var err error
|
||||||
|
filePath := fmt.Sprintf("%s", config.AppInfo.LogPath)
|
||||||
|
fileName := fmt.Sprintf("%s.%s",
|
||||||
|
config.AppInfo.LogSaveName,
|
||||||
|
config.AppInfo.LogFileExt,
|
||||||
|
)
|
||||||
|
F, err = file2.MustOpen(fileName, filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("logging.Setup err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger = log.New(F, DefaultPrefix, log.LstdFlags)
|
||||||
|
|
||||||
|
}
|
||||||
|
func (o *oLog) Path() string {
|
||||||
|
filePath := fmt.Sprintf("%s", config.AppInfo.LogPath)
|
||||||
|
fileName := fmt.Sprintf("%s.%s",
|
||||||
|
config.AppInfo.LogSaveName,
|
||||||
|
config.AppInfo.LogFileExt,
|
||||||
|
)
|
||||||
|
return filePath + fileName
|
||||||
|
}
|
||||||
|
func (o *oLog) Debug(v ...interface{}) {
|
||||||
|
setPrefix(DEBUG)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oLog) Info(v ...interface{}) {
|
||||||
|
setPrefix(INFO)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oLog) Warn(v ...interface{}) {
|
||||||
|
setPrefix(WARN)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oLog) Error(v ...interface{}) {
|
||||||
|
setPrefix(ERROR)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oLog) Fatal(v ...interface{}) {
|
||||||
|
setPrefix(FATAL)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setPrefix(level Level) {
|
||||||
|
_, file, line, ok := runtime.Caller(DefaultCallerDepth)
|
||||||
|
if ok {
|
||||||
|
logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
|
||||||
|
} else {
|
||||||
|
logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.SetPrefix(logPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOLoger() OLog {
|
||||||
|
return &oLog{}
|
||||||
|
}
|
||||||
30
pkg/utils/network_detection.go
Normal file
30
pkg/utils/network_detection.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong a624669980@163.com
|
||||||
|
* @Date: 2022-05-08 14:58:46
|
||||||
|
* @LastEditors: LinkLeong a624669980@163.com
|
||||||
|
* @LastEditTime: 2022-05-09 13:42:26
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/network_detection.go
|
||||||
|
* @Description:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import natType "github.com/Curtis-Milo/nat-type-identifier-go"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @param {chanstring} data
|
||||||
|
* @param {string} url
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
func GetNetWorkTypeDetection(data chan string, url string) {
|
||||||
|
// fmt.Println("url:", url)
|
||||||
|
// httper.Get(url, nil)
|
||||||
|
// aaa <- url
|
||||||
|
result, err := natType.GetDeterminedNatType(true, 5, url)
|
||||||
|
if err == nil {
|
||||||
|
data <- result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
pkg/utils/network_detection_test.go
Normal file
29
pkg/utils/network_detection_test.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong a624669980@163.com
|
||||||
|
* @Date: 2022-05-08 15:07:31
|
||||||
|
* @LastEditors: LinkLeong a624669980@163.com
|
||||||
|
* @LastEditTime: 2022-05-09 11:43:30
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/network_detection_test.go
|
||||||
|
* @Description:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetResultTest(t *testing.T) {
|
||||||
|
list := []string{"https://www.google.com", "https://www.bing.com", "https://www.baidu.com"}
|
||||||
|
data := make(chan string)
|
||||||
|
//data <- "init"
|
||||||
|
for _, v := range list {
|
||||||
|
go GetNetWorkTypeDetection(data, v)
|
||||||
|
}
|
||||||
|
result := <-data
|
||||||
|
close(data)
|
||||||
|
fmt.Println(result)
|
||||||
|
}
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package oasis_err
|
|
||||||
|
|
||||||
const (
|
|
||||||
SUCCESS = 200
|
|
||||||
ERROR = 500
|
|
||||||
INVALID_PARAMS = 400
|
|
||||||
ERROR_AUTH_TOKEN = 401
|
|
||||||
|
|
||||||
//user
|
|
||||||
PWD_INVALID = 10001
|
|
||||||
PWD_IS_EMPTY = 10002
|
|
||||||
|
|
||||||
PWD_INVALID_OLD = 10003
|
|
||||||
ACCOUNT_LOCK = 10004
|
|
||||||
//system
|
|
||||||
DIR_ALREADY_EXISTS = 20001
|
|
||||||
FILE_ALREADY_EXISTS = 20002
|
|
||||||
FILE_OR_DIR_EXISTS = 20003
|
|
||||||
PORT_IS_OCCUPIED = 20004
|
|
||||||
|
|
||||||
//zerotier
|
|
||||||
GET_TOKEN_ERROR = 30001
|
|
||||||
|
|
||||||
//disk
|
|
||||||
NAME_NOT_AVAILABLE = 40001
|
|
||||||
DISK_NEEDS_FORMAT = 40002
|
|
||||||
DISK_BUSYING = 40003
|
|
||||||
REMOVE_MOUNT_POINT_ERROR = 40004
|
|
||||||
FORMAT_ERROR = 40005
|
|
||||||
|
|
||||||
//app
|
|
||||||
UNINSTALL_APP_ERROR = 50001
|
|
||||||
PULL_IMAGE_ERROR = 50002
|
|
||||||
DEVICE_NOT_EXIST = 50003
|
|
||||||
|
|
||||||
//file
|
|
||||||
FILE_DOES_NOT_EXIST = 60001
|
|
||||||
FILE_READ_ERROR = 60002
|
|
||||||
|
|
||||||
//shortcuts
|
|
||||||
SHORTCUTS_URL_ERROR = 70001
|
|
||||||
)
|
|
||||||
|
|
||||||
var MsgFlags = map[int]string{
|
|
||||||
SUCCESS: "ok",
|
|
||||||
ERROR: "fail",
|
|
||||||
INVALID_PARAMS: "Parameters Error",
|
|
||||||
ERROR_AUTH_TOKEN: "Error auth token",
|
|
||||||
|
|
||||||
//user
|
|
||||||
PWD_INVALID: "Invalid password",
|
|
||||||
PWD_IS_EMPTY: "Password is empty",
|
|
||||||
PWD_INVALID_OLD: "Invalid old password",
|
|
||||||
ACCOUNT_LOCK: "Account is locked",
|
|
||||||
|
|
||||||
//system
|
|
||||||
DIR_ALREADY_EXISTS: "Folder already exists",
|
|
||||||
FILE_ALREADY_EXISTS: "File already exists",
|
|
||||||
FILE_OR_DIR_EXISTS: "File or folder already exists",
|
|
||||||
PORT_IS_OCCUPIED: "Port is occupied",
|
|
||||||
|
|
||||||
//zerotier
|
|
||||||
GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available",
|
|
||||||
|
|
||||||
//app
|
|
||||||
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
|
||||||
PULL_IMAGE_ERROR: "Error pulling image",
|
|
||||||
DEVICE_NOT_EXIST: "Device does not exist",
|
|
||||||
|
|
||||||
//disk
|
|
||||||
NAME_NOT_AVAILABLE: "Name not available",
|
|
||||||
DISK_NEEDS_FORMAT: "Drive needs to be formatted",
|
|
||||||
REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point",
|
|
||||||
DISK_BUSYING: "Drive is busy",
|
|
||||||
FORMAT_ERROR: "Formatting failed, please check if the directory is occupied",
|
|
||||||
|
|
||||||
//
|
|
||||||
FILE_DOES_NOT_EXIST: "File does not exist",
|
|
||||||
|
|
||||||
FILE_READ_ERROR: "File read error",
|
|
||||||
SHORTCUTS_URL_ERROR: "URL error",
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取错误信息
|
|
||||||
func GetMsg(code int) string {
|
|
||||||
msg, ok := MsgFlags[code]
|
|
||||||
if ok {
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
return MsgFlags[ERROR]
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package sort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
|
|
||||||
// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
|
|
||||||
type devSorter struct {
|
|
||||||
dev []model.Devices
|
|
||||||
less []lessFuncDev
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort接口方法之一(Less)
|
|
||||||
type lessFuncDev func(p1, p2 *model.Devices) bool
|
|
||||||
|
|
||||||
// Sort 函数有两个作用
|
|
||||||
// 第一, 将参数(实际的数据集)赋值给ms对象
|
|
||||||
// 第二, 调用内置sort函数进行排序操作
|
|
||||||
func (ms *devSorter) Sort(dev []model.Devices) {
|
|
||||||
ms.dev = dev
|
|
||||||
sort.Sort(ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
|
|
||||||
// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
|
|
||||||
// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
|
|
||||||
// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
|
|
||||||
// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
|
|
||||||
func DevSort(less ...lessFuncDev) *devSorter {
|
|
||||||
return &devSorter{
|
|
||||||
less: less,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len 为sort接口方法之一
|
|
||||||
func (ms *devSorter) Len() int {
|
|
||||||
return len(ms.dev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap 为sort接口方法之一
|
|
||||||
func (ms *devSorter) Swap(i, j int) {
|
|
||||||
ms.dev[i], ms.dev[j] = ms.dev[j], ms.dev[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less 为sort接口方法之一
|
|
||||||
func (ms *devSorter) Less(i, j int) bool {
|
|
||||||
temp := ms.dev
|
|
||||||
p, q := &temp[i], &temp[j]
|
|
||||||
// Try all but the last comparison.
|
|
||||||
var k int
|
|
||||||
// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
|
|
||||||
// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
|
|
||||||
for k = 0; k < len(ms.less)-1; k++ {
|
|
||||||
// 提取比较函数, 将函数赋值到新的变量中以便调用
|
|
||||||
less := ms.less[k]
|
|
||||||
switch {
|
|
||||||
case less(p, q):
|
|
||||||
// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
// 如果 p > q, 返回值为false, 则调到下一个case中处理
|
|
||||||
return true
|
|
||||||
case less(q, p):
|
|
||||||
// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
|
|
||||||
// 直接返回最后一次的比较结果数据即可
|
|
||||||
return ms.less[k](p, q)
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package sort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
|
|
||||||
// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
|
|
||||||
type evnSorter struct {
|
|
||||||
evn []model.Envs
|
|
||||||
less []lessFuncEnv
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort接口方法之一(Less)
|
|
||||||
type lessFuncEnv func(p1, p2 *model.Envs) bool
|
|
||||||
|
|
||||||
// Sort 函数有两个作用
|
|
||||||
// 第一, 将参数(实际的数据集)赋值给ms对象
|
|
||||||
// 第二, 调用内置sort函数进行排序操作
|
|
||||||
func (ms *evnSorter) Sort(env []model.Envs) {
|
|
||||||
ms.evn = env
|
|
||||||
sort.Sort(ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
|
|
||||||
// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
|
|
||||||
// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
|
|
||||||
// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
|
|
||||||
// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
|
|
||||||
func EnvSort(less ...lessFuncEnv) *evnSorter {
|
|
||||||
return &evnSorter{
|
|
||||||
less: less,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len 为sort接口方法之一
|
|
||||||
func (ms *evnSorter) Len() int {
|
|
||||||
return len(ms.evn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap 为sort接口方法之一
|
|
||||||
func (ms *evnSorter) Swap(i, j int) {
|
|
||||||
ms.evn[i], ms.evn[j] = ms.evn[j], ms.evn[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less 为sort接口方法之一
|
|
||||||
func (ms *evnSorter) Less(i, j int) bool {
|
|
||||||
temp := ms.evn
|
|
||||||
p, q := &temp[i], &temp[j]
|
|
||||||
// Try all but the last comparison.
|
|
||||||
var k int
|
|
||||||
// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
|
|
||||||
// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
|
|
||||||
for k = 0; k < len(ms.less)-1; k++ {
|
|
||||||
// 提取比较函数, 将函数赋值到新的变量中以便调用
|
|
||||||
less := ms.less[k]
|
|
||||||
switch {
|
|
||||||
case less(p, q):
|
|
||||||
// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
// 如果 p > q, 返回值为false, 则调到下一个case中处理
|
|
||||||
return true
|
|
||||||
case less(q, p):
|
|
||||||
// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
|
|
||||||
// 直接返回最后一次的比较结果数据即可
|
|
||||||
return ms.less[k](p, q)
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package sort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
|
|
||||||
// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
|
|
||||||
type multiSorter struct {
|
|
||||||
ports []model.Ports
|
|
||||||
less []lessFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort接口方法之一(Less)
|
|
||||||
type lessFunc func(p1, p2 *model.Ports) bool
|
|
||||||
|
|
||||||
// Sort 函数有两个作用
|
|
||||||
// 第一, 将参数(实际的数据集)赋值给ms对象
|
|
||||||
// 第二, 调用内置sort函数进行排序操作
|
|
||||||
func (ms *multiSorter) Sort(ports []model.Ports) {
|
|
||||||
ms.ports = ports
|
|
||||||
sort.Sort(ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
|
|
||||||
// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
|
|
||||||
// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
|
|
||||||
// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
|
|
||||||
// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
|
|
||||||
func PortsSort(less ...lessFunc) *multiSorter {
|
|
||||||
return &multiSorter{
|
|
||||||
less: less,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len 为sort接口方法之一
|
|
||||||
func (ms *multiSorter) Len() int {
|
|
||||||
return len(ms.ports)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap 为sort接口方法之一
|
|
||||||
func (ms *multiSorter) Swap(i, j int) {
|
|
||||||
ms.ports[i], ms.ports[j] = ms.ports[j], ms.ports[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less 为sort接口方法之一
|
|
||||||
func (ms *multiSorter) Less(i, j int) bool {
|
|
||||||
port := ms.ports
|
|
||||||
p, q := &port[i], &port[j]
|
|
||||||
// Try all but the last comparison.
|
|
||||||
var k int
|
|
||||||
// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
|
|
||||||
// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
|
|
||||||
for k = 0; k < len(ms.less)-1; k++ {
|
|
||||||
// 提取比较函数, 将函数赋值到新的变量中以便调用
|
|
||||||
less := ms.less[k]
|
|
||||||
switch {
|
|
||||||
case less(p, q):
|
|
||||||
// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
// 如果 p > q, 返回值为false, 则调到下一个case中处理
|
|
||||||
return true
|
|
||||||
case less(q, p):
|
|
||||||
// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
|
|
||||||
// 直接返回最后一次的比较结果数据即可
|
|
||||||
return ms.less[k](p, q)
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package sort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
|
|
||||||
// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
|
|
||||||
type volSorter struct {
|
|
||||||
vol []model.Volume
|
|
||||||
less []lessFuncVol
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort接口方法之一(Less)
|
|
||||||
type lessFuncVol func(p1, p2 *model.Volume) bool
|
|
||||||
|
|
||||||
// Sort 函数有两个作用
|
|
||||||
// 第一, 将参数(实际的数据集)赋值给ms对象
|
|
||||||
// 第二, 调用内置sort函数进行排序操作
|
|
||||||
func (ms *volSorter) Sort(vol []model.Volume) {
|
|
||||||
ms.vol = vol
|
|
||||||
sort.Sort(ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
|
|
||||||
// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
|
|
||||||
// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
|
|
||||||
// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
|
|
||||||
// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
|
|
||||||
func VolSort(less ...lessFuncVol) *volSorter {
|
|
||||||
return &volSorter{
|
|
||||||
less: less,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len 为sort接口方法之一
|
|
||||||
func (ms *volSorter) Len() int {
|
|
||||||
return len(ms.vol)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap 为sort接口方法之一
|
|
||||||
func (ms *volSorter) Swap(i, j int) {
|
|
||||||
ms.vol[i], ms.vol[j] = ms.vol[j], ms.vol[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less 为sort接口方法之一
|
|
||||||
func (ms *volSorter) Less(i, j int) bool {
|
|
||||||
temp := ms.vol
|
|
||||||
p, q := &temp[i], &temp[j]
|
|
||||||
// Try all but the last comparison.
|
|
||||||
var k int
|
|
||||||
// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
|
|
||||||
// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
|
|
||||||
for k = 0; k < len(ms.less)-1; k++ {
|
|
||||||
// 提取比较函数, 将函数赋值到新的变量中以便调用
|
|
||||||
less := ms.less[k]
|
|
||||||
switch {
|
|
||||||
case less(p, q):
|
|
||||||
// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
// 如果 p > q, 返回值为false, 则调到下一个case中处理
|
|
||||||
return true
|
|
||||||
case less(q, p):
|
|
||||||
// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
|
|
||||||
// 直接返回最后一次的比较结果数据即可
|
|
||||||
return ms.less[k](p, q)
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-13 18:15:46
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-29 14:29:34
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/version/version.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package version
|
package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
json2 "encoding/json"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsNeedUpdate() (bool, model.Version) {
|
func IsNeedUpdate(version model.Version) (bool, model.Version) {
|
||||||
var version model.Version
|
|
||||||
v := httper.OasisGet(config.ServerInfo.ServerApi + "/v1/sys/version")
|
|
||||||
data := gjson.Get(v, "data")
|
|
||||||
json2.Unmarshal([]byte(data.String()), &version)
|
|
||||||
|
|
||||||
v1 := strings.Split(version.Version, ".")
|
v1 := strings.Split(version.Version, ".")
|
||||||
|
|
||||||
v2 := strings.Split(types.CURRENTVERSION, ".")
|
v2 := strings.Split(types.CURRENTVERSION, ".")
|
||||||
|
|
||||||
for len(v1) < len(v2) {
|
for len(v1) < len(v2) {
|
||||||
@@ -30,29 +33,15 @@ func IsNeedUpdate() (bool, model.Version) {
|
|||||||
for i := 0; i < len(v1); i++ {
|
for i := 0; i < len(v1); i++ {
|
||||||
a, _ := strconv.Atoi(v1[i])
|
a, _ := strconv.Atoi(v1[i])
|
||||||
b, _ := strconv.Atoi(v2[i])
|
b, _ := strconv.Atoi(v2[i])
|
||||||
|
if i == 0 && a > b {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if a > b {
|
if a > b {
|
||||||
return true, version
|
return true, version
|
||||||
}
|
}
|
||||||
|
if a < b {
|
||||||
|
return false, 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,47 +0,0 @@
|
|||||||
package zerotier
|
|
||||||
|
|
||||||
import (
|
|
||||||
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PostData(url, token string, data string) interface{} {
|
|
||||||
|
|
||||||
body, code := httper2.ZeroTierPostJson(url, data, GetHead(token))
|
|
||||||
|
|
||||||
if code != http.StatusOK {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := gjson.Parse(body)
|
|
||||||
return result.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetData(url, token string) interface{} {
|
|
||||||
|
|
||||||
body, code := httper2.ZeroTierGet(url, GetHead(token))
|
|
||||||
|
|
||||||
if code != http.StatusOK {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := gjson.Parse(body)
|
|
||||||
return result.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeleteMember(url, token string) interface{} {
|
|
||||||
|
|
||||||
body, code := httper2.ZeroTierDelete(url, GetHead(token))
|
|
||||||
|
|
||||||
if code != http.StatusOK {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := gjson.Parse(body)
|
|
||||||
return result.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetHead(token string) map[string]string {
|
|
||||||
var head = make(map[string]string)
|
|
||||||
head["Authorization"] = "Bearer " + token
|
|
||||||
head["Content-Type"] = "application/json"
|
|
||||||
return head
|
|
||||||
}
|
|
||||||
15
route/doc.go
15
route/doc.go
@@ -1,15 +0,0 @@
|
|||||||
//go:build doc
|
|
||||||
// +build doc
|
|
||||||
|
|
||||||
package route
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/IceWhaleTech/CasaOS/docs"
|
|
||||||
ginSwagger "github.com/swaggo/gin-swagger"
|
|
||||||
swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
|
|
||||||
swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
|
|
||||||
}
|
|
||||||
202
route/init.go
202
route/init.go
@@ -1,17 +1,20 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/model/system_app"
|
"github.com/IceWhaleTech/CasaOS/model/system_app"
|
||||||
"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"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||||
@@ -22,9 +25,14 @@ import (
|
|||||||
|
|
||||||
func InitFunction() {
|
func InitFunction() {
|
||||||
go checkSystemApp()
|
go checkSystemApp()
|
||||||
Update2_3()
|
ShellInit()
|
||||||
CheckSerialDiskMount()
|
CheckSerialDiskMount()
|
||||||
|
|
||||||
|
CheckToken2_11()
|
||||||
|
ImportApplications()
|
||||||
|
ChangeAPIUrl()
|
||||||
|
|
||||||
|
MoveUserToDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncIsExistence = false
|
var syncIsExistence = false
|
||||||
@@ -35,7 +43,7 @@ func installSyncthing(appId string) {
|
|||||||
m := model.CustomizationPostData{}
|
m := model.CustomizationPostData{}
|
||||||
var dockerImage string
|
var dockerImage string
|
||||||
var dockerImageVersion string
|
var dockerImageVersion string
|
||||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system")
|
appInfo = service.MyService.Casa().GetServerAppInfo(appId, "system", "us_en")
|
||||||
dockerImage = appInfo.Image
|
dockerImage = appInfo.Image
|
||||||
dockerImageVersion = appInfo.ImageVersion
|
dockerImageVersion = appInfo.ImageVersion
|
||||||
|
|
||||||
@@ -74,14 +82,12 @@ func installSyncthing(appId string) {
|
|||||||
appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
|
appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
|
||||||
}
|
}
|
||||||
|
|
||||||
appInfo.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
|
appInfo.MaxMemory = service.MyService.System().GetMemInfo()["total"].(uint64) >> 20
|
||||||
|
|
||||||
id := uuid.NewV4().String()
|
id := uuid.NewV4().String()
|
||||||
|
|
||||||
installLog := model2.AppNotify{}
|
|
||||||
|
|
||||||
// step:下载镜像
|
// step:下载镜像
|
||||||
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
|
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//pull image error
|
//pull image error
|
||||||
fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
|
fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
|
||||||
@@ -99,8 +105,10 @@ func installSyncthing(appId string) {
|
|||||||
m.Ports = appInfo.Ports
|
m.Ports = appInfo.Ports
|
||||||
m.Restart = "always"
|
m.Restart = "always"
|
||||||
m.Volumes = appInfo.Volumes
|
m.Volumes = appInfo.Volumes
|
||||||
|
m.NetworkModel = appInfo.NetworkModel
|
||||||
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
|
m.Label = id
|
||||||
|
m.CustomId = id
|
||||||
|
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("container create error", err)
|
fmt.Println("container create error", err)
|
||||||
// create container error
|
// create container error
|
||||||
@@ -108,83 +116,45 @@ func installSyncthing(appId string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//step:start container
|
//step:start container
|
||||||
err = service.MyService.Docker().DockerContainerStart(id)
|
err = service.MyService.Docker().DockerContainerStart(containerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//start container error
|
//start container error
|
||||||
return
|
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()
|
checkSystemApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the system application is installed
|
// check if the system application is installed
|
||||||
func checkSystemApp() {
|
func checkSystemApp() {
|
||||||
list := service.MyService.App().GetSystemAppList()
|
list := service.MyService.App().GetSystemAppList()
|
||||||
for _, v := range *list {
|
for _, v := range list {
|
||||||
if v.Image == "linuxserver/syncthing" {
|
info, err := service.MyService.Docker().DockerContainerInfo(v.ID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(info.Config.Image, "linuxserver/syncthing") {
|
||||||
if v.State != "running" {
|
if v.State != "running" {
|
||||||
//step:start container
|
//step:start container
|
||||||
service.MyService.Docker().DockerContainerStart(v.CustomId)
|
service.MyService.Docker().DockerContainerStart(v.ID)
|
||||||
}
|
}
|
||||||
syncIsExistence = true
|
syncIsExistence = true
|
||||||
if config.SystemConfigInfo.SyncPort != v.Port {
|
if config.SystemConfigInfo.SyncPort != v.Labels["web"] {
|
||||||
config.SystemConfigInfo.SyncPort = v.Port
|
config.SystemConfigInfo.SyncPort = v.Labels["web"]
|
||||||
}
|
}
|
||||||
var paths []model.PathMap
|
|
||||||
json.Unmarshal([]byte(v.Volumes), &paths)
|
|
||||||
path := ""
|
path := ""
|
||||||
for _, i := range paths {
|
for _, i := range info.Mounts {
|
||||||
if i.ContainerPath == "/config" {
|
if i.Destination == "/config" {
|
||||||
path = docker.GetDir(v.CustomId, i.Path) + "/config.xml"
|
path = i.Source
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
if file.CheckNotExist(path) {
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content := file.ReadFullFile(path)
|
content := file.ReadFullFile(filepath.Join(path, "config.xml"))
|
||||||
syncConfig := &system_app.SyncConfig{}
|
syncConfig := &system_app.SyncConfig{}
|
||||||
xml.Unmarshal(content, &syncConfig)
|
xml.Unmarshal(content, &syncConfig)
|
||||||
config.SystemConfigInfo.SyncKey = syncConfig.Key
|
config.SystemConfigInfo.SyncKey = syncConfig.Key
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !syncIsExistence {
|
if !syncIsExistence {
|
||||||
@@ -195,18 +165,18 @@ func CheckSerialDiskMount() {
|
|||||||
// check mount point
|
// check mount point
|
||||||
dbList := service.MyService.Disk().GetSerialAll()
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
mountPoint := make(map[string]string, len(dbList))
|
mountPoint := make(map[string]string, len(dbList))
|
||||||
//remount
|
//remount
|
||||||
for _, v := range dbList {
|
for _, v := range dbList {
|
||||||
mountPoint[v.Path] = v.MountPoint
|
mountPoint[v.UUID] = v.MountPoint
|
||||||
}
|
}
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
command.ExecEnabledSMART(v.Path)
|
command.ExecEnabledSMART(v.Path)
|
||||||
if v.Children != nil {
|
if v.Children != nil {
|
||||||
for _, h := range v.Children {
|
for _, h := range v.Children {
|
||||||
if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
|
if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
|
||||||
if m, ok := mountPoint[h.Path]; ok {
|
if m, ok := mountPoint[h.UUID]; ok {
|
||||||
//mount point check
|
//mount point check
|
||||||
volume := m
|
volume := m
|
||||||
if !file.CheckNotExist(m) {
|
if !file.CheckNotExist(m) {
|
||||||
@@ -217,7 +187,8 @@ func CheckSerialDiskMount() {
|
|||||||
service.MyService.Disk().MountDisk(h.Path, volume)
|
service.MyService.Disk().MountDisk(h.Path, volume)
|
||||||
if volume != m {
|
if volume != m {
|
||||||
ms := model2.SerialDisk{}
|
ms := model2.SerialDisk{}
|
||||||
ms.Serial = v.Serial
|
ms.UUID = v.UUID
|
||||||
|
ms.MountPoint = volume
|
||||||
service.MyService.Disk().UpdateMountPoint(ms)
|
service.MyService.Disk().UpdateMountPoint(ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,9 +198,98 @@ func CheckSerialDiskMount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AutoRemoveUnuseDir")
|
command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;AutoRemoveUnuseDir")
|
||||||
|
}
|
||||||
|
func ShellInit() {
|
||||||
|
command.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/assist.sh | bash")
|
||||||
|
if !file.CheckNotExist("/casaOS") {
|
||||||
|
command.OnlyExec("source /casaOS/server/shell/update.sh ;")
|
||||||
|
command.OnlyExec("source " + config.AppInfo.ShellPath + "/delete-old-service.sh ;")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func Update2_3() {
|
func CheckToken2_11() {
|
||||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
|
if len(config.ServerInfo.Token) == 0 {
|
||||||
|
token := uuid.NewV4().String
|
||||||
|
config.ServerInfo.Token = token()
|
||||||
|
config.Cfg.Section("server").Key("Token").SetValue(token())
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
sysType := runtime.GOOS
|
||||||
|
if len(config.FileSettingInfo.DownloadDir) == 0 {
|
||||||
|
downloadPath := "/DATA/Downloads"
|
||||||
|
if sysType == "windows" {
|
||||||
|
downloadPath = "C:\\CasaOS\\DATA\\Downloads"
|
||||||
|
}
|
||||||
|
if sysType == "darwin" {
|
||||||
|
downloadPath = "./CasaOS/DATA/Downloads"
|
||||||
|
}
|
||||||
|
config.Cfg.Section("file").Key("DownloadDir").SetValue(downloadPath)
|
||||||
|
config.FileSettingInfo.DownloadDir = downloadPath
|
||||||
|
file.IsNotExistMkDir(config.FileSettingInfo.DownloadDir)
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(config.UserInfo.Description) == 0 {
|
||||||
|
config.Cfg.Section("user").Key("Description").SetValue("nothing")
|
||||||
|
config.UserInfo.Description = "nothing"
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
if len(config.ServerInfo.Handshake) == 0 {
|
||||||
|
config.Cfg.Section("server").Key("Handshake").SetValue("socket.casaos.io")
|
||||||
|
config.ServerInfo.Handshake = "socket.casaos.io"
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") {
|
||||||
|
service.MyService.System().UpdateUSBAutoMount("False")
|
||||||
|
service.MyService.System().ExecUSBAutoMountShell("False")
|
||||||
|
}
|
||||||
|
|
||||||
|
// str := []string{}
|
||||||
|
// str = append(str, "ddd")
|
||||||
|
// str = append(str, "aaa")
|
||||||
|
// ddd := strings.Join(str, "|")
|
||||||
|
// config.Cfg.Section("file").Key("ShareDir").SetValue(ddd)
|
||||||
|
|
||||||
|
// config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ImportApplications() {
|
||||||
|
service.MyService.App().ImportApplications(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0.3.1
|
||||||
|
func ChangeAPIUrl() {
|
||||||
|
|
||||||
|
newAPIUrl := "https://api.casaos.io/casaos-api"
|
||||||
|
if config.ServerInfo.ServerApi == "https://api.casaos.zimaboard.com" {
|
||||||
|
config.ServerInfo.ServerApi = newAPIUrl
|
||||||
|
config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//0.3.3
|
||||||
|
//Transferring user data to the database
|
||||||
|
func MoveUserToDB() {
|
||||||
|
|
||||||
|
if len(config.UserInfo.UserName) > 0 && service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 {
|
||||||
|
user := model2.UserDBModel{}
|
||||||
|
user.UserName = config.UserInfo.UserName
|
||||||
|
user.Email = config.UserInfo.Email
|
||||||
|
user.NickName = config.UserInfo.NickName
|
||||||
|
user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD)
|
||||||
|
user.Role = "admin"
|
||||||
|
user = service.MyService.User().CreateUser(user)
|
||||||
|
if user.Id > 0 {
|
||||||
|
userPath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
|
||||||
|
file.MkDir(userPath)
|
||||||
|
os.Rename("/casaOS/server/conf/app_order.json", userPath+"/app_order.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
285
route/periodical.go
Normal file
285
route/periodical.go
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-01 15:11:36
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-07-01 15:16:00
|
||||||
|
* @FilePath: /CasaOS/route/periodical.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-27 15:55:36
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-29 16:47:19
|
||||||
|
* @FilePath: /CasaOS/route/periodical.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SendNetINfoBySocket() {
|
||||||
|
netList := service.MyService.System().GetNetInfo()
|
||||||
|
newNet := []model.IOCountersStat{}
|
||||||
|
nets := service.MyService.System().GetNet(true)
|
||||||
|
for _, n := range netList {
|
||||||
|
for _, netCardName := range nets {
|
||||||
|
if n.Name == netCardName {
|
||||||
|
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||||
|
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
|
||||||
|
item.Time = time.Now().Unix()
|
||||||
|
newNet = append(newNet, item)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service.MyService.Notify().SendNetInfoBySocket(newNet)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendCPUBySocket() {
|
||||||
|
cpu := service.MyService.System().GetCpuPercent()
|
||||||
|
num := service.MyService.System().GetCpuCoreNum()
|
||||||
|
cpuData := make(map[string]interface{})
|
||||||
|
cpuData["percent"] = cpu
|
||||||
|
cpuData["num"] = num
|
||||||
|
service.MyService.Notify().SendCPUInfoBySocket(cpuData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendMemBySocket() {
|
||||||
|
service.MyService.Notify().SendMemInfoBySocket(service.MyService.System().GetMemInfo())
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendDiskBySocket() {
|
||||||
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
|
|
||||||
|
summary := model.Summary{}
|
||||||
|
healthy := true
|
||||||
|
findSystem := 0
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
|
|
||||||
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
|
|
||||||
|
if len(list[i].Children[j].Children) > 0 {
|
||||||
|
for _, v := range list[i].Children[j].Children {
|
||||||
|
if v.MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if findSystem == 1 {
|
||||||
|
findSystem += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") {
|
||||||
|
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||||
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
|
healthy = true
|
||||||
|
} else {
|
||||||
|
healthy = temp.SmartStatus.Passed
|
||||||
|
}
|
||||||
|
|
||||||
|
//list[i].Temperature = temp.Temperature.Current
|
||||||
|
|
||||||
|
if len(list[i].Children) > 0 {
|
||||||
|
for _, v := range list[i].Children {
|
||||||
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary.Health = healthy
|
||||||
|
service.MyService.Notify().SendDiskInfoBySocket(summary)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendUSBBySocket() {
|
||||||
|
usbList := service.MyService.Disk().LSBLK(false)
|
||||||
|
usb := []model.DriveUSB{}
|
||||||
|
for _, v := range usbList {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
mountTemp := true
|
||||||
|
if len(v.Children) == 0 {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
||||||
|
temp.Used += used
|
||||||
|
} else {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp.Mount = mountTemp
|
||||||
|
usb = append(usb, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service.MyService.Notify().SendUSBInfoBySocket(usb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendAllHardwareStatusBySocket() {
|
||||||
|
|
||||||
|
netList := service.MyService.System().GetNetInfo()
|
||||||
|
newNet := []model.IOCountersStat{}
|
||||||
|
nets := service.MyService.System().GetNet(true)
|
||||||
|
for _, n := range netList {
|
||||||
|
for _, netCardName := range nets {
|
||||||
|
if n.Name == netCardName {
|
||||||
|
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||||
|
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
|
||||||
|
item.Time = time.Now().Unix()
|
||||||
|
newNet = append(newNet, item)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpu := service.MyService.System().GetCpuPercent()
|
||||||
|
num := service.MyService.System().GetCpuCoreNum()
|
||||||
|
cpuData := make(map[string]interface{})
|
||||||
|
cpuData["percent"] = cpu
|
||||||
|
cpuData["num"] = num
|
||||||
|
|
||||||
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
|
|
||||||
|
summary := model.Summary{}
|
||||||
|
healthy := true
|
||||||
|
findSystem := 0
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
|
|
||||||
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
|
|
||||||
|
if len(list[i].Children[j].Children) > 0 {
|
||||||
|
for _, v := range list[i].Children[j].Children {
|
||||||
|
if v.MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if findSystem == 1 {
|
||||||
|
findSystem += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") {
|
||||||
|
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||||
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
|
healthy = true
|
||||||
|
} else {
|
||||||
|
healthy = temp.SmartStatus.Passed
|
||||||
|
}
|
||||||
|
if len(list[i].Children) > 0 {
|
||||||
|
for _, v := range list[i].Children {
|
||||||
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary.Health = healthy
|
||||||
|
|
||||||
|
usbList := service.MyService.Disk().LSBLK(false)
|
||||||
|
usb := []model.DriveUSB{}
|
||||||
|
for _, v := range usbList {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
mountTemp := true
|
||||||
|
if len(v.Children) == 0 {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
||||||
|
temp.Used += used
|
||||||
|
} else {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp.Mount = mountTemp
|
||||||
|
usb = append(usb, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memInfo := service.MyService.System().GetMemInfo()
|
||||||
|
|
||||||
|
service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memInfo, cpuData, newNet)
|
||||||
|
|
||||||
|
}
|
||||||
243
route/route.go
243
route/route.go
@@ -8,138 +8,85 @@ import (
|
|||||||
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-contrib/gzip"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var swagHandler gin.HandlerFunc
|
|
||||||
var OnlineDemo bool = false
|
var OnlineDemo bool = false
|
||||||
|
|
||||||
func InitRouter() *gin.Engine {
|
func InitRouter() *gin.Engine {
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
r.Use(middleware.Cors())
|
|
||||||
gin.SetMode(config.ServerInfo.RunMode)
|
|
||||||
|
|
||||||
|
r.Use(middleware.Cors())
|
||||||
|
r.Use(middleware.WriteLog())
|
||||||
|
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||||
|
gin.SetMode(config.ServerInfo.RunMode)
|
||||||
r.StaticFS("/ui", http.FS(web.Static))
|
r.StaticFS("/ui", http.FS(web.Static))
|
||||||
r.GET("/", WebUIHome)
|
r.GET("/", WebUIHome)
|
||||||
|
// r.StaticFS("/assets", http.Dir("./static/assets"))
|
||||||
|
// r.StaticFile("/favicon.ico", "./static/favicon.ico")
|
||||||
//r.GET("/", func(c *gin.Context) {
|
//r.GET("/", func(c *gin.Context) {
|
||||||
// c.Redirect(http.StatusMovedPermanently, "ui/")
|
// c.Redirect(http.StatusMovedPermanently, "ui/")
|
||||||
//})
|
//})
|
||||||
if swagHandler != nil {
|
|
||||||
r.GET("/swagger/*any", swagHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.POST("/v1/user/login", v1.Login)
|
r.POST("/v1/user/register/:key", v1.PostUserRegister)
|
||||||
|
r.POST("/v1/user/login", v1.PostUserLogin) //
|
||||||
|
r.GET("/v1/user/all/name", v1.GetUserAllUserName)
|
||||||
|
|
||||||
|
r.GET("/v1/sys/init/check", v1.GetSystemInitCheck)
|
||||||
r.GET("/v1/guide/check", v1.GetGuideCheck)
|
r.GET("/v1/guide/check", v1.GetGuideCheck)
|
||||||
|
|
||||||
r.GET("/v1/debug", v1.GetSystemConfigDebug)
|
r.GET("/v1/debug", v1.GetSystemConfigDebug)
|
||||||
//set user
|
|
||||||
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
|
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
|
||||||
//get user info
|
r.GET("/v1/user/info/:id", v1.GetUserInfo)
|
||||||
r.GET("/v1/user/info", v1.UserInfo)
|
r.GET("/v1/user/avatar/:id", v1.GetUserAvatar)
|
||||||
|
r.GET("/v1/user/image", v1.GetUserImage)
|
||||||
|
|
||||||
|
//get user info
|
||||||
|
r.GET("/v1/person/shareid", v1.GetPersonShareId)
|
||||||
|
r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort)
|
||||||
|
//r.POST("/v1/user/refresh/token", v1.PostUserRefreshToken)
|
||||||
v1Group := r.Group("/v1")
|
v1Group := r.Group("/v1")
|
||||||
|
|
||||||
v1Group.Use(jwt2.JWT(swagHandler))
|
v1Group.Use(jwt2.JWT())
|
||||||
{
|
{
|
||||||
v1UserGroup := v1Group.Group("/user")
|
v1UserGroup := v1Group.Group("/user")
|
||||||
v1UserGroup.Use()
|
v1UserGroup.Use()
|
||||||
{
|
{
|
||||||
|
|
||||||
//chang head
|
//****************** New version needs to be modified start ******************
|
||||||
v1UserGroup.POST("/changhead", v1.Up_Load_Head)
|
|
||||||
//chang user name
|
//chang user name
|
||||||
v1UserGroup.PUT("/changusername", v1.Chang_User_Name)
|
v1UserGroup.PUT("/username", v1.PutUserName)
|
||||||
//chang pwd
|
v1UserGroup.PUT("/password", v1.PutUserPwd)
|
||||||
v1UserGroup.PUT("/changuserpwd", v1.Chang_User_Pwd)
|
v1UserGroup.PUT("/nick", v1.PutUserNick)
|
||||||
//edit user info
|
v1UserGroup.PUT("/desc", v1.PutUserDesc)
|
||||||
v1UserGroup.POST("/changuserinfo", v1.Chang_User_Info)
|
v1UserGroup.GET("/info", v1.GetUserInfoByUserName)
|
||||||
|
v1UserGroup.GET("/custom/:id/:key", v1.GetUserCustomConf)
|
||||||
|
v1UserGroup.POST("/custom/:id/:key", v1.PostUserCustomConf)
|
||||||
|
v1UserGroup.DELETE("/custom/:id/:key", v1.DeleteUserCustomConf)
|
||||||
|
v1UserGroup.POST("/upload/image/:id/:key", v1.PostUserUploadImage)
|
||||||
|
v1UserGroup.POST("/file/image/:id/:key", v1.PostUserFileImage)
|
||||||
|
v1UserGroup.DELETE("/image/:id", v1.DeleteUserImage)
|
||||||
|
//****************** New version needs to be modified end ******************
|
||||||
|
|
||||||
}
|
//****************** soon to be removed start ******************
|
||||||
|
v1UserGroup.POST("/person/info", v1.PostUserPersonInfo)
|
||||||
|
v1UserGroup.GET("/shareid", v1.GetUserShareID)
|
||||||
|
//****************** soon to be removed end ******************
|
||||||
|
|
||||||
v1ZiMaGroup := v1Group.Group("/zima")
|
//v1UserGroup.GET("/info", v1.GetUserInfo)
|
||||||
v1ZiMaGroup.Use()
|
|
||||||
{
|
|
||||||
//获取cpu信息
|
|
||||||
v1ZiMaGroup.GET("/getcpuinfo", v1.CupInfo)
|
|
||||||
//获取内存信息
|
|
||||||
v1ZiMaGroup.GET("/getmeminfo", v1.MemInfo)
|
|
||||||
//获取硬盘信息
|
|
||||||
v1ZiMaGroup.GET("/getdiskinfo", v1.DiskInfo)
|
|
||||||
|
|
||||||
//获取网络信息
|
v1UserGroup.PUT("/avatar", v1.PutUserAvatar)
|
||||||
v1ZiMaGroup.GET("/getnetinfo", v1.NetInfo)
|
v1UserGroup.GET("/avatar", v1.GetUserAvatar)
|
||||||
|
v1UserGroup.DELETE("/delete/:id", v1.DeleteUser)
|
||||||
|
|
||||||
//获取系统信息
|
|
||||||
v1ZiMaGroup.GET("/sysinfo", v1.SysInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
v1ZeroTierGroup := v1Group.Group("/zerotier")
|
|
||||||
v1ZeroTierGroup.Use()
|
|
||||||
{
|
|
||||||
//获取zerotier token
|
|
||||||
v1ZeroTierGroup.POST("/login", v1.ZeroTierGetToken)
|
|
||||||
//注册zerotier
|
|
||||||
v1ZeroTierGroup.POST("/register", v1.ZeroTierRegister)
|
|
||||||
//是否需要登录
|
|
||||||
v1ZeroTierGroup.GET("/islogin", v1.ZeroTierIsNeedLogin)
|
|
||||||
//获取网络列表
|
|
||||||
v1ZeroTierGroup.GET("/list", v1.ZeroTierGetNetworkList)
|
|
||||||
//加入网络
|
|
||||||
v1ZeroTierGroup.POST("/join/:id", v1.ZeroTierJoinNetwork)
|
|
||||||
//离开网络
|
|
||||||
v1ZeroTierGroup.POST("/leave/:id", v1.ZeroTierLeaveNetwork)
|
|
||||||
//详情
|
|
||||||
v1ZeroTierGroup.GET("/info/:id", v1.ZeroTierGetNetworkGetInfo)
|
|
||||||
////网络状态
|
|
||||||
//v1ZeroTierGroup.GET("/status", v1.ZeroTierGetNetworkGetStatus)
|
|
||||||
//修改网络类型
|
|
||||||
//v1ZeroTierGroup.PUT("/type/:id", v1.ZeroTierEditType)
|
|
||||||
//修改网络类型
|
|
||||||
//v1ZeroTierGroup.PUT("/name/:id", v1.ZeroTierEditName)
|
|
||||||
//修改v6 assign
|
|
||||||
//v1ZeroTierGroup.PUT("/v6assign/:id", v1.ZeroTierEditV6Assign)
|
|
||||||
//修改 broadcast
|
|
||||||
//v1ZeroTierGroup.PUT("/broadcast/:id", v1.ZeroTierEditBroadcast)
|
|
||||||
//create new network
|
|
||||||
v1ZeroTierGroup.POST("/create", v1.ZeroTierCreateNetwork)
|
|
||||||
//获取用户列表
|
|
||||||
v1ZeroTierGroup.GET("/member/:id", v1.ZeroTierMemberList)
|
|
||||||
//修改用户信息
|
|
||||||
//v1ZeroTierGroup.PUT("/members/:id/auth/:mId", v1.ZeroTierMemberAuth)
|
|
||||||
//修改网络用户name
|
|
||||||
//v1ZeroTierGroup.PUT("/members/:id/name/:mId", v1.ZeroTierMemberName)
|
|
||||||
v1ZeroTierGroup.DELETE("/members/:id/del/:mId", v1.ZeroTierMemberDelete)
|
|
||||||
v1ZeroTierGroup.DELETE("/network/:id/del", v1.ZeroTierDeleteNetwork)
|
|
||||||
//修改网络用户bridge功能
|
|
||||||
//v1ZeroTierGroup.PUT("/members/:id/bridge/:mId", v1.ZeroTierMemberBridge)
|
|
||||||
v1ZeroTierGroup.PUT("/edit/:id", v1.ZeroTierEdit)
|
|
||||||
v1ZeroTierGroup.GET("/joined/list", v1.ZeroTierJoinedList)
|
|
||||||
v1ZeroTierGroup.PUT("/member/:id/edit/:mId", v1.ZeroTierMemberEdit)
|
|
||||||
|
|
||||||
}
|
|
||||||
v1DDNSGroup := v1Group.Group("/ddns")
|
|
||||||
v1DDNSGroup.Use()
|
|
||||||
{
|
|
||||||
//获取ddns列表
|
|
||||||
v1DDNSGroup.GET("/getlist", v1.DDNSGetDomainList)
|
|
||||||
//测试连接性
|
|
||||||
v1DDNSGroup.GET("/ping/:api_host", v1.DDNSPing)
|
|
||||||
//获取ip
|
|
||||||
v1DDNSGroup.GET("/ip", v1.DDNSGetIP)
|
|
||||||
//设置ddns
|
|
||||||
v1DDNSGroup.POST("/set", v1.DDNSAddConfig)
|
|
||||||
//获取ddns
|
|
||||||
v1DDNSGroup.GET("/list", v1.DDNSConfigList)
|
|
||||||
//获取ddns
|
|
||||||
v1DDNSGroup.DELETE("/delete/:id", v1.DDNSDelete)
|
|
||||||
}
|
}
|
||||||
v1AppGroup := v1Group.Group("/app")
|
v1AppGroup := v1Group.Group("/app")
|
||||||
v1AppGroup.Use()
|
v1AppGroup.Use()
|
||||||
{
|
{
|
||||||
//获取我的已安装的列表
|
//获取我的已安装的列表
|
||||||
v1AppGroup.GET("/mylist", v1.MyAppList)
|
v1AppGroup.GET("/my/list", v1.MyAppList)
|
||||||
//
|
//
|
||||||
v1AppGroup.GET("/usage", v1.AppUsageList)
|
v1AppGroup.GET("/usage", v1.AppUsageList)
|
||||||
//app详情
|
//app详情
|
||||||
@@ -150,12 +97,10 @@ func InitRouter() *gin.Engine {
|
|||||||
v1AppGroup.GET("/port", v1.GetPort)
|
v1AppGroup.GET("/port", v1.GetPort)
|
||||||
//检查端口
|
//检查端口
|
||||||
v1AppGroup.GET("/check/:port", v1.PortCheck)
|
v1AppGroup.GET("/check/:port", v1.PortCheck)
|
||||||
//分类
|
|
||||||
v1AppGroup.GET("/category", v1.CategoryList)
|
v1AppGroup.GET("/category", v1.CategoryList)
|
||||||
//容器相关
|
|
||||||
v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
|
v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
|
||||||
//准备安装
|
|
||||||
//v1AppGroup.GET("/ready/:id", v1.ReadyInstall)
|
|
||||||
//app容器详情
|
//app容器详情
|
||||||
v1AppGroup.GET("/info/:id", v1.ContainerInfo)
|
v1AppGroup.GET("/info/:id", v1.ContainerInfo)
|
||||||
//app容器日志
|
//app容器日志
|
||||||
@@ -163,11 +108,9 @@ func InitRouter() *gin.Engine {
|
|||||||
//暂停或启动容器
|
//暂停或启动容器
|
||||||
v1AppGroup.PUT("/state/:id", v1.ChangAppState)
|
v1AppGroup.PUT("/state/:id", v1.ChangAppState)
|
||||||
//安装app
|
//安装app
|
||||||
v1AppGroup.POST("/install/:id", v1.InstallApp)
|
v1AppGroup.POST("/install", v1.InstallApp)
|
||||||
//卸载app
|
//卸载app
|
||||||
v1AppGroup.DELETE("/uninstall/:id", v1.UnInstallApp)
|
v1AppGroup.DELETE("/uninstall/:id", v1.UnInstallApp)
|
||||||
//获取安装进度
|
|
||||||
v1AppGroup.GET("/speed/:id", v1.GetInstallSpeed)
|
|
||||||
//获取进度
|
//获取进度
|
||||||
v1AppGroup.GET("/state/:id", v1.GetContainerState)
|
v1AppGroup.GET("/state/:id", v1.GetContainerState)
|
||||||
//更新容器配置
|
//更新容器配置
|
||||||
@@ -176,42 +119,52 @@ func InitRouter() *gin.Engine {
|
|||||||
v1AppGroup.GET("/update/:id/info", v1.ContainerUpdateInfo)
|
v1AppGroup.GET("/update/:id/info", v1.ContainerUpdateInfo)
|
||||||
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.PUT("/update/:id", v1.PutAppUpdate)
|
||||||
v1AppGroup.POST("/share", v1.ShareAppFile)
|
v1AppGroup.POST("/share", v1.ShareAppFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
v1SysGroup := v1Group.Group("/sys")
|
v1SysGroup := v1Group.Group("/sys")
|
||||||
v1SysGroup.Use()
|
v1SysGroup.Use()
|
||||||
{
|
{
|
||||||
//获取检查版本是否需要升级
|
v1SysGroup.GET("/version/check", v1.GetSystemCheckVersion)
|
||||||
v1SysGroup.GET("/check", v1.CheckVersion)
|
v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo)
|
||||||
v1SysGroup.POST("/update", v1.SystemUpdate)
|
v1SysGroup.POST("/update", v1.SystemUpdate)
|
||||||
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.POST("/config", v1.PostSetSystemConfig)
|
||||||
v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
|
v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
|
||||||
v1SysGroup.POST("/config", v1.PostSetSystemConfig)
|
|
||||||
v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
|
v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
|
||||||
v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
|
v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
|
||||||
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
||||||
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||||
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
|
v1SysGroup.POST("/stop", v1.PostKillCasaOS)
|
||||||
v1SysGroup.GET("/info", v1.Info)
|
v1SysGroup.GET("/utilization", v1.GetSystemUtilization)
|
||||||
|
v1SysGroup.PUT("/usb/:status", v1.PutSystemUSBAutoMount)
|
||||||
|
v1SysGroup.GET("/usb/status", v1.GetSystemUSBAutoMount)
|
||||||
|
v1SysGroup.GET("/cpu", v1.GetSystemCupInfo)
|
||||||
|
v1SysGroup.GET("/mem", v1.GetSystemMemInfo)
|
||||||
|
v1SysGroup.GET("/disk", v1.GetSystemDiskInfo)
|
||||||
|
v1SysGroup.GET("/network", v1.GetSystemNetInfo)
|
||||||
}
|
}
|
||||||
v1FileGroup := v1Group.Group("/file")
|
v1FileGroup := v1Group.Group("/file")
|
||||||
v1FileGroup.Use()
|
v1FileGroup.Use()
|
||||||
{
|
{
|
||||||
//修改文件名称/目录名称
|
|
||||||
v1FileGroup.PUT("/rename", v1.RenamePath)
|
v1FileGroup.PUT("/rename", v1.RenamePath)
|
||||||
v1FileGroup.GET("/read", v1.GetFilerContent)
|
v1FileGroup.GET("/read", v1.GetFilerContent)
|
||||||
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||||
v1FileGroup.GET("/catalog", v1.DirPath)
|
v1FileGroup.GET("/upload", v1.GetFileUpload)
|
||||||
//创建目录
|
v1FileGroup.GET("/dirpath", v1.DirPath)
|
||||||
|
//create folder
|
||||||
v1FileGroup.POST("/mkdir", v1.MkdirAll)
|
v1FileGroup.POST("/mkdir", v1.MkdirAll)
|
||||||
v1FileGroup.POST("/create", v1.PostCreateFile)
|
v1FileGroup.POST("/create", v1.PostCreateFile)
|
||||||
|
|
||||||
v1FileGroup.GET("/download", v1.GetDownloadFile)
|
v1FileGroup.GET("/download", v1.GetDownloadFile)
|
||||||
v1FileGroup.PUT("/move", v1.PutFileMove)
|
v1FileGroup.GET("/download/*path", v1.GetDownloadSingleFile)
|
||||||
|
v1FileGroup.POST("/operate", v1.PostOperateFileOrDir)
|
||||||
|
v1FileGroup.DELETE("/delete", v1.DeleteFile)
|
||||||
|
v1FileGroup.PUT("/update", v1.PutFileContent)
|
||||||
|
v1FileGroup.GET("/image", v1.GetFileImage)
|
||||||
|
v1FileGroup.DELETE("/operate/:id", v1.DeleteOperateFileOrDir)
|
||||||
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
||||||
}
|
}
|
||||||
v1DiskGroup := v1Group.Group("/disk")
|
v1DiskGroup := v1Group.Group("/disk")
|
||||||
@@ -225,10 +178,10 @@ func InitRouter() *gin.Engine {
|
|||||||
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
||||||
|
|
||||||
//format storage
|
//format storage
|
||||||
v1DiskGroup.POST("/format", v1.FormatDisk)
|
v1DiskGroup.POST("/format", v1.PostDiskFormat)
|
||||||
|
|
||||||
// add storage
|
// add storage
|
||||||
v1DiskGroup.POST("/storage", v1.AddPartition)
|
v1DiskGroup.POST("/storage", v1.PostDiskAddPartition)
|
||||||
|
|
||||||
//mount SATA disk
|
//mount SATA disk
|
||||||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||||
@@ -241,48 +194,36 @@ func InitRouter() *gin.Engine {
|
|||||||
|
|
||||||
//删除分区
|
//删除分区
|
||||||
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
||||||
|
v1DiskGroup.GET("/usb", v1.GetUSBList)
|
||||||
|
|
||||||
}
|
}
|
||||||
v1ShareGroup := v1Group.Group("/share")
|
v1PersonGroup := v1Group.Group("/person")
|
||||||
v1ShareGroup.Use()
|
v1PersonGroup.Use()
|
||||||
{
|
{
|
||||||
v1ShareGroup.POST("/add", v1.PostShareDirAdd)
|
v1PersonGroup.GET("/detection", v1.GetPersonDetection)
|
||||||
v1ShareGroup.DELETE("/del/:id", v1.DeleteShareDirDel)
|
v1PersonGroup.GET("/users", v1.GetPersonFriend)
|
||||||
v1ShareGroup.GET("/list", v1.GetShareDirList)
|
v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend)
|
||||||
v1ShareGroup.GET("/info/:id", v1.GetShareDirInfo)
|
v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend)
|
||||||
v1ShareGroup.PUT("/update/:id", v1.PutShareDirEdit)
|
v1PersonGroup.GET("/directory", v1.GetPersonDirectory)
|
||||||
}
|
v1PersonGroup.GET("/file", v1.GetPersonFile)
|
||||||
v1TaskGroup := v1Group.Group("/task")
|
v1PersonGroup.GET("/refile/:uuid", v1.GetPersonReFile)
|
||||||
v1TaskGroup.Use()
|
v1PersonGroup.PUT("/remarks/:shareid", v1.PutPersonRemarks)
|
||||||
{
|
v1PersonGroup.GET("/list", v1.GetPersonDownloadList)
|
||||||
v1TaskGroup.GET("/list", v1.GetTaskList)
|
v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersonDownloadFile)
|
||||||
v1TaskGroup.PUT("/update", v1.PutTaskUpdate)
|
|
||||||
v1TaskGroup.POST("/add", v1.PostTaskAdd)
|
v1PersonGroup.POST("/share", v1.PostPersonShare)
|
||||||
v1TaskGroup.PUT("/completion/:id", v1.PutTaskMarkerCompletion)
|
v1PersonGroup.POST("/file/:shareid", v1.PostPersonFile)
|
||||||
|
v1PersonGroup.GET("/share", v1.GetPersonShare)
|
||||||
|
v1PersonGroup.POST("/down/dir", v1.PostPersonDownDir)
|
||||||
|
v1PersonGroup.GET("/down/dir", v1.GetPersonDownDir)
|
||||||
|
v1PersonGroup.PUT("/block/:shareid", v1.PutPersonBlock)
|
||||||
|
v1PersonGroup.GET("/public", v1.GetPersonPublic)
|
||||||
|
v1PersonGroup.PUT("/friend/:shareid", v1.PutPersonAgreeFriend)
|
||||||
|
v1PersonGroup.PUT("/write/:shareid", v1.PutPersonWrite)
|
||||||
|
v1PersonGroup.GET("/image/thumbnail/:shareid", v1.GetPersonImageThumbnail)
|
||||||
|
|
||||||
}
|
|
||||||
v1ShortcutsGroup := v1Group.Group("/shortcuts")
|
|
||||||
v1ShortcutsGroup.Use()
|
|
||||||
{
|
|
||||||
v1ShortcutsGroup.GET("/list", v1.GetShortcutsList)
|
|
||||||
v1ShortcutsGroup.POST("/add", v1.PostShortcutsAdd)
|
|
||||||
v1ShortcutsGroup.PUT("/edit", v1.PutShortcutsEdit)
|
|
||||||
v1ShortcutsGroup.DELETE("/del/:id", v1.DeleteShortcutsDelete)
|
|
||||||
}
|
|
||||||
v1NotifyGroup := v1Group.Group("/notify")
|
|
||||||
v1NotifyGroup.Use()
|
|
||||||
{
|
|
||||||
v1NotifyGroup.GET("/ws", v1.NotifyWS)
|
|
||||||
v1NotifyGroup.PUT("/read/:id", v1.PutNotifyRead)
|
|
||||||
}
|
|
||||||
v1SearchGroup := v1Group.Group("/search")
|
|
||||||
v1SearchGroup.Use()
|
|
||||||
{
|
|
||||||
v1SearchGroup.GET("/search", v1.GetSearchList)
|
|
||||||
}
|
}
|
||||||
v1Group.GET("/sync/config", v1.GetSyncConfig)
|
v1Group.GET("/sync/config", v1.GetSyncConfig)
|
||||||
v1Group.Any("/syncthing/*url", v1.SyncToSyncthing)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
60
route/socket.go
Normal file
60
route/socket.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-05-23 17:18:56
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-09 21:48:10
|
||||||
|
* @FilePath: /CasaOS/route/socket.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model/notify"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
f "github.com/ambelovsky/gosf"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SocketInit(msg chan notify.Message) {
|
||||||
|
|
||||||
|
// set socket port
|
||||||
|
socketPort := 0
|
||||||
|
if len(config.ServerInfo.SocketPort) == 0 {
|
||||||
|
socketPort, _ = port.GetAvailablePort("tcp")
|
||||||
|
config.ServerInfo.SocketPort = strconv.Itoa(socketPort)
|
||||||
|
config.Cfg.Section("server").Key("SocketPort").SetValue(strconv.Itoa(socketPort))
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
} else {
|
||||||
|
socketPort, _ = strconv.Atoi(config.ServerInfo.SocketPort)
|
||||||
|
if !port.IsPortAvailable(socketPort, "tcp") {
|
||||||
|
socketPort, _ := port.GetAvailablePort("tcp")
|
||||||
|
config.ServerInfo.SocketPort = strconv.Itoa(socketPort)
|
||||||
|
config.Cfg.Section("server").Key("SocketPort").SetValue(strconv.Itoa(socketPort))
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.OnConnect(func(c *f.Client, request *f.Request) {
|
||||||
|
service.ClientCount += 1
|
||||||
|
})
|
||||||
|
f.OnDisconnect(func(c *f.Client, request *f.Request) {
|
||||||
|
service.ClientCount -= 1
|
||||||
|
})
|
||||||
|
go func(msg chan notify.Message) {
|
||||||
|
for v := range msg {
|
||||||
|
f.Broadcast("", v.Path, &v.Msg)
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
}(msg)
|
||||||
|
|
||||||
|
f.Startup(map[string]interface{}{
|
||||||
|
"port": socketPort})
|
||||||
|
|
||||||
|
}
|
||||||
13
route/ui.go
13
route/ui.go
@@ -1,9 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-06-23 17:27:43
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-23 17:27:48
|
||||||
|
* @FilePath: /CasaOS/route/ui.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/web"
|
"github.com/IceWhaleTech/CasaOS/web"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"html/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func WebUIHome(c *gin.Context) {
|
func WebUIHome(c *gin.Context) {
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
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/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -35,7 +36,11 @@ func AppList(c *gin.Context) {
|
|||||||
t := c.DefaultQuery("type", "rank")
|
t := c.DefaultQuery("type", "rank")
|
||||||
categoryId := c.DefaultQuery("category_id", "0")
|
categoryId := c.DefaultQuery("category_id", "0")
|
||||||
key := c.DefaultQuery("key", "")
|
key := c.DefaultQuery("key", "")
|
||||||
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
if len(index) == 0 || len(size) == 0 || len(t) == 0 || len(categoryId) == 0 {
|
||||||
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
collection := service.MyService.Casa().GetServerList(index, size, t, categoryId, key)
|
||||||
// for i := 0; i < len(recommend); i++ {
|
// for i := 0; i < len(recommend); i++ {
|
||||||
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||||
// if ct != nil {
|
// if ct != nil {
|
||||||
@@ -55,11 +60,11 @@ func AppList(c *gin.Context) {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
data := make(map[string]interface{}, 3)
|
data := make(map[string]interface{}, 3)
|
||||||
data["recommend"] = recommend
|
data["recommend"] = collection.Recommend
|
||||||
data["list"] = list
|
data["list"] = collection.List
|
||||||
data["community"] = community
|
data["community"] = collection.Community
|
||||||
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取一个可用端口
|
// @Summary 获取一个可用端口
|
||||||
@@ -78,7 +83,7 @@ func GetPort(c *gin.Context) {
|
|||||||
p, _ = port2.GetAvailablePort(t)
|
p, _ = port2.GetAvailablePort(t)
|
||||||
ok = !port2.IsPortAvailable(p, t)
|
ok = !port2.IsPortAvailable(p, t)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: p})
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 检查端口是否可用
|
// @Summary 检查端口是否可用
|
||||||
@@ -93,7 +98,7 @@ func GetPort(c *gin.Context) {
|
|||||||
func PortCheck(c *gin.Context) {
|
func PortCheck(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Param("port"))
|
p, _ := strconv.Atoi(c.Param("port"))
|
||||||
t := c.DefaultQuery("type", "tcp")
|
t := c.DefaultQuery("type", "tcp")
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: port2.IsPortAvailable(p, t)})
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port2.IsPortAvailable(p, t)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 我的应用列表
|
// @Summary 我的应用列表
|
||||||
@@ -105,13 +110,17 @@ func PortCheck(c *gin.Context) {
|
|||||||
// @Param size query int false "size"
|
// @Param size query int false "size"
|
||||||
// @Param position query bool false "是否是首页应用"
|
// @Param position query bool false "是否是首页应用"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /app/mylist [get]
|
// @Router /app/my/list [get]
|
||||||
func MyAppList(c *gin.Context) {
|
func MyAppList(c *gin.Context) {
|
||||||
index, _ := strconv.Atoi(c.DefaultQuery("index", "1"))
|
index, _ := strconv.Atoi(c.DefaultQuery("index", "1"))
|
||||||
size, _ := strconv.Atoi(c.DefaultQuery("size", "0"))
|
size, _ := strconv.Atoi(c.DefaultQuery("size", "0"))
|
||||||
position, _ := strconv.ParseBool(c.DefaultQuery("position", "true"))
|
position, _ := strconv.ParseBool(c.DefaultQuery("position", "true"))
|
||||||
list := service.MyService.App().GetMyList(index, size, position)
|
list, unTranslation := service.MyService.App().GetMyList(index, size, position)
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
data := make(map[string]interface{}, 2)
|
||||||
|
data["list"] = list
|
||||||
|
data["local"] = unTranslation
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary my app hardware usage list
|
// @Summary my app hardware usage list
|
||||||
@@ -123,7 +132,7 @@ func MyAppList(c *gin.Context) {
|
|||||||
// @Router /app/usage [get]
|
// @Router /app/usage [get]
|
||||||
func AppUsageList(c *gin.Context) {
|
func AppUsageList(c *gin.Context) {
|
||||||
list := service.MyService.App().GetHardwareUsage()
|
list := service.MyService.App().GetHardwareUsage()
|
||||||
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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 应用详情
|
// @Summary 应用详情
|
||||||
@@ -137,7 +146,8 @@ func AppUsageList(c *gin.Context) {
|
|||||||
func AppInfo(c *gin.Context) {
|
func AppInfo(c *gin.Context) {
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
info := service.MyService.OAPI().GetServerAppInfo(id, "")
|
language := c.GetHeader("Language")
|
||||||
|
info := service.MyService.Casa().GetServerAppInfo(id, "", language)
|
||||||
if info.NetworkModel != "host" {
|
if info.NetworkModel != "host" {
|
||||||
for i := 0; i < len(info.Ports); i++ {
|
for i := 0; i < len(info.Ports); i++ {
|
||||||
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
||||||
@@ -202,9 +212,9 @@ func AppInfo(c *gin.Context) {
|
|||||||
// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
|
// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
|
||||||
// sort.DevSort(devOrder).Sort(info.Devices)
|
// sort.DevSort(devOrder).Sort(info.Devices)
|
||||||
|
|
||||||
info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
|
info.MaxMemory = (service.MyService.System().GetMemInfo()["total"]).(uint64) >> 20
|
||||||
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取远程分类列表
|
// @Summary 获取远程分类列表
|
||||||
@@ -215,16 +225,16 @@ func AppInfo(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /app/category [get]
|
// @Router /app/category [get]
|
||||||
func CategoryList(c *gin.Context) {
|
func CategoryList(c *gin.Context) {
|
||||||
list := service.MyService.OAPI().GetServerCategoryList()
|
list := service.MyService.Casa().GetServerCategoryList()
|
||||||
var count uint = 0
|
var count uint = 0
|
||||||
for _, category := range list {
|
for _, category := range list {
|
||||||
count += category.Count
|
count += category.Count
|
||||||
}
|
}
|
||||||
|
|
||||||
rear := append([]model.ServerCategoryList{}, list[0:]...)
|
rear := append([]model.CategoryList{}, list[0:]...)
|
||||||
list = append(list[:0], model.ServerCategoryList{Count: count, Name: "All", Font: "apps"})
|
list = append(list[:0], model.CategoryList{Count: count, Name: "All", Font: "apps"})
|
||||||
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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 分享该应用配置
|
// @Summary 分享该应用配置
|
||||||
@@ -236,17 +246,6 @@ func CategoryList(c *gin.Context) {
|
|||||||
// @Router /app/share [post]
|
// @Router /app/share [post]
|
||||||
func ShareAppFile(c *gin.Context) {
|
func ShareAppFile(c *gin.Context) {
|
||||||
str, _ := ioutil.ReadAll(c.Request.Body)
|
str, _ := ioutil.ReadAll(c.Request.Body)
|
||||||
content := service.MyService.OAPI().ShareAppFile(str)
|
content := service.MyService.Casa().ShareAppFile(str)
|
||||||
c.JSON(http.StatusOK, json.RawMessage(content))
|
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() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
174
route/v1/ddns.go
174
route/v1/ddns.go
@@ -1,174 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
|
||||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/forease/gotld"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 获取可以设置的ddns列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags ddns
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/getlist [get]
|
|
||||||
func DDNSGetDomainList(c *gin.Context) {
|
|
||||||
|
|
||||||
host, domain, tld := gotld.GetSubdomain("bbb.aaa.liru-05.com.cn", 3)
|
|
||||||
fmt.Println(strings.Replace(host, "."+domain, "", 1))
|
|
||||||
fmt.Println(domain)
|
|
||||||
fmt.Println(tld)
|
|
||||||
|
|
||||||
data := make(map[string]interface{}, 2)
|
|
||||||
t, api := service.MyService.DDNS().GetType("godaddy")
|
|
||||||
data["godaddy"] = &model.GoDaddyModel{Type: t, ApiHost: api}
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: data,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 添加新的ddns(按给定模型返回内容)
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags ddns
|
|
||||||
// @Param type formData string true "类型"
|
|
||||||
// @Param host formData string true "host"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/set [post]
|
|
||||||
func DDNSAddConfig(c *gin.Context) {
|
|
||||||
t, _ := strconv.Atoi(c.PostForm("type"))
|
|
||||||
host := c.PostForm("host")
|
|
||||||
_, domain, _ := gotld.GetSubdomain("host", 3)
|
|
||||||
sub := strings.ReplaceAll(host, "."+domain, "")
|
|
||||||
|
|
||||||
if service.MyService.DDNS().IsExis(t, domain, sub) {
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.ERROR,
|
|
||||||
Message: "Repeat add",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var m model2.DDNSUpdateDBModel
|
|
||||||
c.Bind(&m)
|
|
||||||
if err := service.MyService.DDNS().SaveConfig(m); err != nil {
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.ERROR,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.ERROR),
|
|
||||||
Data: err.Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取ip,仅做展示使用
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags ddns
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/ip [get]
|
|
||||||
func DDNSGetIP(c *gin.Context) {
|
|
||||||
ipv4, ipv6 := service.MyService.DDNS().GetExternalIP()
|
|
||||||
var ipjson = make(map[string]string, 2)
|
|
||||||
ipjson["ipv4"] = ipv4
|
|
||||||
ipjson["ipv6"] = ipv6
|
|
||||||
c.JSON(http.StatusOK, &model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: ipjson,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 测试网址是否可以ping通
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags ddns
|
|
||||||
// @Param api_host path int true "api地址"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/ping/{api_host} [get]
|
|
||||||
func DDNSPing(c *gin.Context) {
|
|
||||||
url := c.Param("api_host")
|
|
||||||
url = strings.ReplaceAll(url, "https://", "")
|
|
||||||
url = strings.ReplaceAll(url, "http://", "")
|
|
||||||
cmd := exec.Command("ping", url, "-c", "1", "-W", "5")
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, &model.Result{
|
|
||||||
Success: oasis_err2.ERROR,
|
|
||||||
Message: err.Error(),
|
|
||||||
Data: false,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, &model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取已设置的列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags ddns
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/list [get]
|
|
||||||
func DDNSConfigList(c *gin.Context) {
|
|
||||||
j := service.MyService.DDNS().GetConfigList()
|
|
||||||
ip4 := ip_helper2.GetExternalIPV4()
|
|
||||||
ip6 := ip_helper2.GetExternalIPV6()
|
|
||||||
for i := 0; i < len(*j); i++ {
|
|
||||||
(*j)[i].IPV6 = ip6
|
|
||||||
(*j)[i].IPV4 = ip4
|
|
||||||
cmd := exec.Command("ping", (*j)[i].Host+"."+(*j)[i].Domain, "-c", "1", "-W", "3")
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
(*j)[i].State = false
|
|
||||||
} else {
|
|
||||||
(*j)[i].State = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: j})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 删除ddns
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags ddns
|
|
||||||
// @Param id path int true "ID"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /ddns/delete/{id} [delete]
|
|
||||||
func DDNSDelete(c *gin.Context) {
|
|
||||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isok := service.MyService.DDNS().DeleteConfig(uint(id))
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: isok})
|
|
||||||
}
|
|
||||||
212
route/v1/disk.go
212
route/v1/disk.go
@@ -1,6 +1,7 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -9,8 +10,8 @@ import (
|
|||||||
|
|
||||||
"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/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"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/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -27,7 +28,7 @@ var diskMap = make(map[string]string)
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/list [get]
|
// @Router /disk/list [get]
|
||||||
func GetDiskList(c *gin.Context) {
|
func GetDiskList(c *gin.Context) {
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK(false)
|
||||||
dbList := service.MyService.Disk().GetSerialAll()
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
part := make(map[string]int64, len(dbList))
|
part := make(map[string]int64, len(dbList))
|
||||||
for _, v := range dbList {
|
for _, v := range dbList {
|
||||||
@@ -53,28 +54,56 @@ func GetDiskList(c *gin.Context) {
|
|||||||
|
|
||||||
if len(list[i].Children) > 0 && findSystem == 0 {
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
for j := 0; j < len(list[i].Children); j++ {
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
if list[i].Children[j].MountPoint == "/" {
|
if len(list[i].Children[j].Children) > 0 {
|
||||||
stor := model.Storage{}
|
for _, v := range list[i].Children[j].Children {
|
||||||
stor.Name = "System"
|
if v.MountPoint == "/" {
|
||||||
stor.MountPoint = list[i].Children[j].MountPoint
|
stor := model.Storage{}
|
||||||
stor.Size = list[i].Children[j].FSSize
|
stor.Name = "System"
|
||||||
stor.Avail = list[i].Children[j].FSAvail
|
stor.MountPoint = v.MountPoint
|
||||||
stor.Path = list[i].Children[j].Path
|
stor.Size = v.FSSize
|
||||||
stor.Type = list[i].Children[j].FsType
|
stor.Avail = v.FSAvail
|
||||||
stor.DriveName = "System"
|
stor.Path = v.Path
|
||||||
disk.Model = "System"
|
stor.Type = v.FsType
|
||||||
if strings.Contains(list[i].Children[j].SubSystems, "mmc") {
|
stor.DriveName = "System"
|
||||||
disk.DiskType = "MMC"
|
disk.Model = "System"
|
||||||
} else if strings.Contains(list[i].Children[j].SubSystems, "usb") {
|
if strings.Contains(v.SubSystems, "mmc") {
|
||||||
disk.DiskType = "USB"
|
disk.DiskType = "MMC"
|
||||||
}
|
} else if strings.Contains(v.SubSystems, "usb") {
|
||||||
disk.Health = "true"
|
disk.DiskType = "USB"
|
||||||
|
}
|
||||||
|
disk.Health = "true"
|
||||||
|
|
||||||
disks = append(disks, disk)
|
disks = append(disks, disk)
|
||||||
storage = append(storage, stor)
|
storage = append(storage, stor)
|
||||||
findSystem = 1
|
findSystem = 1
|
||||||
break
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
stor := model.Storage{}
|
||||||
|
stor.Name = "System"
|
||||||
|
stor.MountPoint = list[i].Children[j].MountPoint
|
||||||
|
stor.Size = list[i].Children[j].FSSize
|
||||||
|
stor.Avail = list[i].Children[j].FSAvail
|
||||||
|
stor.Path = list[i].Children[j].Path
|
||||||
|
stor.Type = list[i].Children[j].FsType
|
||||||
|
stor.DriveName = "System"
|
||||||
|
disk.Model = "System"
|
||||||
|
if strings.Contains(list[i].Children[j].SubSystems, "mmc") {
|
||||||
|
disk.DiskType = "MMC"
|
||||||
|
} else if strings.Contains(list[i].Children[j].SubSystems, "usb") {
|
||||||
|
disk.DiskType = "USB"
|
||||||
|
}
|
||||||
|
disk.Health = "true"
|
||||||
|
|
||||||
|
disks = append(disks, disk)
|
||||||
|
storage = append(storage, stor)
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if findSystem == 1 {
|
if findSystem == 1 {
|
||||||
@@ -82,10 +111,10 @@ func GetDiskList(c *gin.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if list[i].Tran == "sata" {
|
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") {
|
||||||
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
continue
|
temp.SmartStatus.Passed = true
|
||||||
}
|
}
|
||||||
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
|
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
|
||||||
stor := model.Storage{}
|
stor := model.Storage{}
|
||||||
@@ -125,7 +154,7 @@ func GetDiskList(c *gin.Context) {
|
|||||||
data["storage"] = storage
|
data["storage"] = storage
|
||||||
data["avail"] = avail
|
data["avail"] = avail
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get disk list
|
// @Summary get disk list
|
||||||
@@ -137,12 +166,12 @@ func GetDiskList(c *gin.Context) {
|
|||||||
// @Router /disk/lists [get]
|
// @Router /disk/lists [get]
|
||||||
func GetPlugInDisks(c *gin.Context) {
|
func GetPlugInDisks(c *gin.Context) {
|
||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
var result []*disk.UsageStat
|
var result []*disk.UsageStat
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
result = append(result, service.MyService.Disk().GetDiskInfoByPath(item.Path))
|
result = append(result, service.MyService.Disk().GetDiskInfoByPath(item.Path))
|
||||||
}
|
}
|
||||||
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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary disk detail
|
// @Summary disk detail
|
||||||
@@ -156,10 +185,10 @@ func GetPlugInDisks(c *gin.Context) {
|
|||||||
func GetDiskInfo(c *gin.Context) {
|
func GetDiskInfo(c *gin.Context) {
|
||||||
path := c.Query("path")
|
path := c.Query("path")
|
||||||
if len(path) == 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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
}
|
}
|
||||||
m := service.MyService.Disk().GetDiskInfo(path)
|
m := service.MyService.Disk().GetDiskInfo(path)
|
||||||
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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary format storage
|
// @Summary format storage
|
||||||
@@ -172,37 +201,37 @@ func GetDiskInfo(c *gin.Context) {
|
|||||||
// @Param volume formData string true "mount point"
|
// @Param volume formData string true "mount point"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/format [post]
|
// @Router /disk/format [post]
|
||||||
func FormatDisk(c *gin.Context) {
|
func PostDiskFormat(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
t := "ext4"
|
t := "ext4"
|
||||||
pwd := c.PostForm("pwd")
|
pwd := c.PostForm("pwd")
|
||||||
volume := c.PostForm("volume")
|
volume := c.PostForm("volume")
|
||||||
|
|
||||||
if pwd != config.UserInfo.PWD {
|
if pwd != config.UserInfo.PWD {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.PWD_INVALID, Message: oasis_err.GetMsg(oasis_err.PWD_INVALID)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := diskMap[path]; ok {
|
if _, ok := diskMap[path]; ok {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
diskMap[path] = "busying"
|
diskMap[path] = "busying"
|
||||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||||
format := service.MyService.Disk().FormatDisk(path, t)
|
format := service.MyService.Disk().FormatDisk(path, t)
|
||||||
if len(format) == 0 {
|
if len(format) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.FORMAT_ERROR, Message: oasis_err.GetMsg(oasis_err.FORMAT_ERROR)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
||||||
delete(diskMap, path)
|
delete(diskMap, path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.Disk().MountDisk(path, volume)
|
service.MyService.Disk().MountDisk(path, volume)
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
delete(diskMap, path)
|
delete(diskMap, 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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取支持的格式
|
// @Summary 获取支持的格式
|
||||||
@@ -214,7 +243,7 @@ func FormatDisk(c *gin.Context) {
|
|||||||
// @Router /disk/type [get]
|
// @Router /disk/type [get]
|
||||||
func FormatDiskType(c *gin.Context) {
|
func FormatDiskType(c *gin.Context) {
|
||||||
var strArr = [4]string{"fat32", "ntfs", "ext4", "exfat"}
|
var strArr = [4]string{"fat32", "ntfs", "ext4", "exfat"}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: strArr})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: strArr})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,12 +259,12 @@ func RemovePartition(c *gin.Context) {
|
|||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
|
|
||||||
if len(path) == 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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
}
|
}
|
||||||
var p = path[:len(path)-1]
|
var p = path[:len(path)-1]
|
||||||
var n = path[len(path)-1:]
|
var n = path[len(path)-1:]
|
||||||
service.MyService.Disk().DelPartition(p, n)
|
service.MyService.Disk().DelPartition(p, n)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary add storage
|
// @Summary add storage
|
||||||
@@ -249,55 +278,69 @@ func RemovePartition(c *gin.Context) {
|
|||||||
// @Param format formData bool true "need format(true)"
|
// @Param format formData bool true "need format(true)"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/storage [post]
|
// @Router /disk/storage [post]
|
||||||
func AddPartition(c *gin.Context) {
|
func PostDiskAddPartition(c *gin.Context) {
|
||||||
|
|
||||||
name := c.PostForm("name")
|
name := c.PostForm("name")
|
||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
serial := c.PostForm("serial")
|
|
||||||
format, _ := strconv.ParseBool(c.PostForm("format"))
|
format, _ := strconv.ParseBool(c.PostForm("format"))
|
||||||
if len(name) == 0 || len(path) == 0 || len(serial) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
if len(name) == 0 || len(path) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := diskMap[serial]; ok {
|
if _, ok := diskMap[path]; ok {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.CheckNotExist("/DATA/" + name) {
|
if !file.CheckNotExist("/DATA/" + name) {
|
||||||
// /mnt/name exist
|
// /mnt/name exist
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.NAME_NOT_AVAILABLE, Message: oasis_err.GetMsg(oasis_err.NAME_NOT_AVAILABLE)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
diskMap[serial] = "busying"
|
diskMap[path] = "busying"
|
||||||
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
||||||
if !format {
|
if !format {
|
||||||
if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") {
|
if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_NEEDS_FORMAT, Message: oasis_err.GetMsg(oasis_err.DISK_NEEDS_FORMAT)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
||||||
delete(diskMap, serial)
|
delete(diskMap, path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
service.MyService.Disk().AddPartition(path)
|
service.MyService.Disk().AddPartition(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatBool := true
|
||||||
|
for formatBool {
|
||||||
|
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
fmt.Println(currentDisk.Children)
|
||||||
|
if len(currentDisk.Children) > 0 {
|
||||||
|
formatBool = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
if len(currentDisk.Children) != 1 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mountPath := "/DATA/" + name
|
mountPath := "/DATA/" + name
|
||||||
|
|
||||||
service.MyService.Disk().MountDisk(path, mountPath)
|
|
||||||
|
|
||||||
m := model2.SerialDisk{}
|
m := model2.SerialDisk{}
|
||||||
m.MountPoint = mountPath
|
m.MountPoint = mountPath
|
||||||
m.Path = path + "1"
|
m.Path = currentDisk.Children[0].Path
|
||||||
m.Serial = serial
|
m.UUID = currentDisk.Children[0].UUID
|
||||||
m.State = 0
|
m.State = 0
|
||||||
m.CreatedAt = time.Now().Unix()
|
m.CreatedAt = time.Now().Unix()
|
||||||
service.MyService.Disk().SaveMountPoint(m)
|
service.MyService.Disk().SaveMountPoint(m)
|
||||||
|
|
||||||
//mount dir
|
//mount dir
|
||||||
service.MyService.Disk().MountDisk(path+"1", mountPath)
|
service.MyService.Disk().MountDisk(currentDisk.Children[0].Path, mountPath)
|
||||||
|
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
|
|
||||||
delete(diskMap, serial)
|
delete(diskMap, 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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary add mount point
|
// @Summary add mount point
|
||||||
@@ -334,10 +377,10 @@ func PostMountDisk(c *gin.Context) {
|
|||||||
m := model2.SerialDisk{}
|
m := model2.SerialDisk{}
|
||||||
m.MountPoint = mountPath
|
m.MountPoint = mountPath
|
||||||
m.Path = path
|
m.Path = path
|
||||||
m.Serial = serial
|
m.UUID = serial
|
||||||
m.State = 0
|
m.State = 0
|
||||||
//service.MyService.Disk().SaveMountPoint(m)
|
//service.MyService.Disk().SaveMountPoint(m)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary remove mount point
|
// @Summary remove mount point
|
||||||
@@ -357,16 +400,16 @@ func PostDiskUmount(c *gin.Context) {
|
|||||||
pwd := c.PostForm("pwd")
|
pwd := c.PostForm("pwd")
|
||||||
|
|
||||||
if len(path) == 0 || len(mountPoint) == 0 {
|
if len(path) == 0 || len(mountPoint) == 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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if pwd != config.UserInfo.PWD {
|
if pwd != config.UserInfo.PWD {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.PWD_INVALID, Message: oasis_err.GetMsg(oasis_err.PWD_INVALID)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := diskMap[path]; ok {
|
if _, ok := diskMap[path]; ok {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +417,7 @@ func PostDiskUmount(c *gin.Context) {
|
|||||||
//delete data
|
//delete data
|
||||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary confirm delete disk
|
// @Summary confirm delete disk
|
||||||
@@ -388,7 +431,7 @@ func PostDiskUmount(c *gin.Context) {
|
|||||||
func DeleteDisk(c *gin.Context) {
|
func DeleteDisk(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
service.MyService.Disk().DeleteMount(id)
|
service.MyService.Disk().DeleteMount(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary check mount point
|
// @Summary check mount point
|
||||||
@@ -401,7 +444,7 @@ func DeleteDisk(c *gin.Context) {
|
|||||||
func GetDiskCheck(c *gin.Context) {
|
func GetDiskCheck(c *gin.Context) {
|
||||||
|
|
||||||
dbList := service.MyService.Disk().GetSerialAll()
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
|
|
||||||
mapList := make(map[string]string)
|
mapList := make(map[string]string)
|
||||||
|
|
||||||
@@ -410,12 +453,47 @@ func GetDiskCheck(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dbList {
|
for _, v := range dbList {
|
||||||
if _, ok := mapList[v.Serial]; !ok {
|
if _, ok := mapList[v.UUID]; !ok {
|
||||||
//disk undefind
|
//disk undefind
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.ERROR, Message: oasis_err.GetMsg(oasis_err.ERROR), Data: "disk undefind"})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: "disk undefind"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary check mount point
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags disk
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /disk/usb [get]
|
||||||
|
func GetUSBList(c *gin.Context) {
|
||||||
|
list := service.MyService.Disk().LSBLK(false)
|
||||||
|
data := []model.DriveUSB{}
|
||||||
|
for _, v := range list {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
mountTemp := true
|
||||||
|
if len(v.Children) == 0 {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
} else {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp.Mount = mountTemp
|
||||||
|
data = append(data, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
620
route/v1/file.go
620
route/v1/file.go
@@ -6,17 +6,24 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
url2 "net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
oasis_err2 "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"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func downloadReadFile(c *gin.Context) {
|
func downloadReadFile(c *gin.Context) {
|
||||||
@@ -45,24 +52,6 @@ func downloadReadFile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadWriteFile(c *gin.Context) {
|
|
||||||
//写文件
|
|
||||||
var filename = "./output1.csv"
|
|
||||||
|
|
||||||
file, err := os.Create(filename) //创建文件
|
|
||||||
if err != nil {
|
|
||||||
c.String(400, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
buf := bufio.NewWriter(file) //创建新的 Writer 对象
|
|
||||||
buf.WriteString("test")
|
|
||||||
buf.Flush()
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
//返回文件流
|
|
||||||
c.File(filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 读取文件
|
// @Summary 读取文件
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -75,15 +64,15 @@ func GetFilerContent(c *gin.Context) {
|
|||||||
filePath := c.Query("path")
|
filePath := c.Query("path")
|
||||||
if len(filePath) == 0 {
|
if len(filePath) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.Exists(filePath) {
|
if !file.Exists(filePath) {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.FILE_DOES_NOT_EXIST,
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -91,8 +80,8 @@ func GetFilerContent(c *gin.Context) {
|
|||||||
info, err := ioutil.ReadFile(filePath)
|
info, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.FILE_READ_ERROR,
|
Success: common_err.FILE_READ_ERROR,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.FILE_READ_ERROR),
|
Message: common_err.GetMsg(common_err.FILE_READ_ERROR),
|
||||||
Data: err.Error(),
|
Data: err.Error(),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -101,8 +90,8 @@ func GetFilerContent(c *gin.Context) {
|
|||||||
|
|
||||||
//返回结果
|
//返回结果
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: result,
|
Data: result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -111,15 +100,15 @@ func GetLocalFile(c *gin.Context) {
|
|||||||
path := c.Query("path")
|
path := c.Query("path")
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.Exists(path) {
|
if !file.Exists(path) {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.FILE_DOES_NOT_EXIST,
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -127,45 +116,111 @@ func GetLocalFile(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 下载文件
|
// @Summary download
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path query string true "路径"
|
// @Param t query string false "Compression format" Enums(zip,tar,targz)
|
||||||
|
// @Param files query string true "file list eg: filename1,filename2,filename3 "
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/download [get]
|
// @Router /file/download [get]
|
||||||
func GetDownloadFile(c *gin.Context) {
|
func GetDownloadFile(c *gin.Context) {
|
||||||
filePath := c.Query("path")
|
|
||||||
if len(filePath) == 0 {
|
t := c.Query("t")
|
||||||
|
|
||||||
|
files := c.Query("files")
|
||||||
|
|
||||||
|
if len(files) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err2.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.Exists(filePath) {
|
list := strings.Split(files, ",")
|
||||||
c.JSON(http.StatusOK, model.Result{
|
for _, v := range list {
|
||||||
Success: oasis_err2.FILE_DOES_NOT_EXIST,
|
if !file.Exists(v) {
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
|
c.JSON(http.StatusOK, model.Result{
|
||||||
})
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
return
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//打开文件
|
|
||||||
fileTmp, _ := os.Open(filePath)
|
|
||||||
defer fileTmp.Close()
|
|
||||||
//获取文件的名称
|
|
||||||
fileName := path.Base(filePath)
|
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
c.Header("Content-Type", "application/octet-stream")
|
||||||
c.Header("Content-Disposition", "attachment; filename="+fileName)
|
|
||||||
c.Header("Content-Transfer-Encoding", "binary")
|
c.Header("Content-Transfer-Encoding", "binary")
|
||||||
c.Header("Cache-Control", "no-cache")
|
c.Header("Cache-Control", "no-cache")
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
// handles only single files not folders and multiple files
|
||||||
c.Header("Content-Disposition", "attachment; filename="+fileName)
|
if len(list) == 1 {
|
||||||
c.Header("Content-Transfer-Encoding", "binary")
|
|
||||||
|
|
||||||
|
filePath := list[0]
|
||||||
|
info, err := os.Stat(filePath)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{
|
||||||
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
|
||||||
|
//打开文件
|
||||||
|
fileTmp, _ := os.Open(filePath)
|
||||||
|
defer fileTmp.Close()
|
||||||
|
|
||||||
|
//获取文件的名称
|
||||||
|
fileName := path.Base(filePath)
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||||
|
c.File(filePath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension, ar, err := file.GetCompressionAlgorithm(t)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{
|
||||||
|
Success: common_err.INVALID_PARAMS,
|
||||||
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ar.Create(c.Writer)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{
|
||||||
|
Success: common_err.ERROR,
|
||||||
|
Message: common_err.GetMsg(common_err.ERROR),
|
||||||
|
Data: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer ar.Close()
|
||||||
|
commonDir := file.CommonPrefix(filepath.Separator, list...)
|
||||||
|
|
||||||
|
currentPath := filepath.Base(commonDir)
|
||||||
|
|
||||||
|
name := "_" + currentPath
|
||||||
|
name += extension
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||||
|
for _, fname := range list {
|
||||||
|
err = file.AddFile(ar, fname, commonDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to archive %s: %v", fname, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDownloadSingleFile(c *gin.Context) {
|
||||||
|
filePath := c.Param("path")
|
||||||
|
fileTmp, _ := os.Open(filePath)
|
||||||
|
defer fileTmp.Close()
|
||||||
|
|
||||||
|
fileName := path.Base(filePath)
|
||||||
|
//c.Header("Content-Disposition", "inline")
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||||
c.File(filePath)
|
c.File(filePath)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取目录列表
|
// @Summary 获取目录列表
|
||||||
@@ -177,145 +232,426 @@ func GetDownloadFile(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/dirpath [get]
|
// @Router /file/dirpath [get]
|
||||||
func DirPath(c *gin.Context) {
|
func DirPath(c *gin.Context) {
|
||||||
path := c.DefaultQuery("path", "/")
|
path := c.DefaultQuery("path", "")
|
||||||
info := service.MyService.ZiMa().GetDirPath(path)
|
info := service.MyService.System().GetDirPath(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
if path == "/DATA/AppData" {
|
||||||
|
list := service.MyService.Docker().DockerContainerList()
|
||||||
|
apps := make(map[string]string, len(list))
|
||||||
|
for _, v := range list {
|
||||||
|
apps[strings.ReplaceAll(v.Names[0], "/", "")] = strings.ReplaceAll(v.Names[0], "/", "")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(info); i++ {
|
||||||
|
if v, ok := apps[info[i].Name]; ok {
|
||||||
|
info[i].Label = v
|
||||||
|
info[i].Type = "application"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if path == "/DATA" {
|
||||||
|
disk := make(map[string]string)
|
||||||
|
lsblk := service.MyService.Disk().LSBLK(true)
|
||||||
|
for _, v := range lsblk {
|
||||||
|
if len(v.Children) > 0 {
|
||||||
|
t := v.Tran
|
||||||
|
for _, c := range v.Children {
|
||||||
|
if len(c.Children) > 0 {
|
||||||
|
for _, gc := range c.Children {
|
||||||
|
if len(gc.MountPoint) > 0 {
|
||||||
|
disk[gc.MountPoint] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(c.MountPoint) > 0 {
|
||||||
|
disk[c.MountPoint] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < len(info); i++ {
|
||||||
|
if v, ok := disk[info[i].Path]; ok {
|
||||||
|
info[i].Type = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hide the files or folders in operation
|
||||||
|
fileQueue := make(map[string]string)
|
||||||
|
if len(service.OpStrArr) > 0 {
|
||||||
|
for _, v := range service.OpStrArr {
|
||||||
|
v, ok := service.FileQueue.Load(v)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
vt := v.(model.FileOperate)
|
||||||
|
for _, i := range vt.Item {
|
||||||
|
lastPath := i.From[strings.LastIndex(i.From, "/")+1:]
|
||||||
|
fileQueue[vt.To+"/"+lastPath] = i.From
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathList := []model.Path{}
|
||||||
|
for i := 0; i < len(info); i++ {
|
||||||
|
if _, ok := fileQueue[info[i].Path]; !ok {
|
||||||
|
pathList = append(pathList, info[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: pathList})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 重命名目录或文件
|
// @Summary rename file or dir
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param oldpath formData string true "旧的路径"
|
// @Param oldpath body string true "path of old"
|
||||||
// @Param newpath formData string true "新路径"
|
// @Param newpath body string true "path of new"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/rename [put]
|
// @Router /file/rename [put]
|
||||||
func RenamePath(c *gin.Context) {
|
func RenamePath(c *gin.Context) {
|
||||||
op := c.PostForm("oldpath")
|
json := make(map[string]string)
|
||||||
np := c.PostForm("newpath")
|
c.BindJSON(&json)
|
||||||
|
op := json["oldpath"]
|
||||||
|
np := json["newpath"]
|
||||||
if len(op) == 0 || len(np) == 0 {
|
if len(op) == 0 || len(np) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.ZiMa().RenameFile(op, np)
|
success, err := service.MyService.System().RenameFile(op, np)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 创建文件夹
|
// @Summary create folder
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept application/json
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string false "路径"
|
// @Param path body string true "path of folder"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/mkdir [post]
|
// @Router /file/mkdir [post]
|
||||||
func MkdirAll(c *gin.Context) {
|
func MkdirAll(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
path := json["path"]
|
||||||
var code int
|
var code int
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code, _ = service.MyService.ZiMa().MkdirAll(path)
|
// decodedPath, err := url.QueryUnescape(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
code, _ = service.MyService.System().MkdirAll(path)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 创建文件
|
// @Summary create file
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept application/json
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string false "路径"
|
// @Param path body string true "path of folder (path need to url encode)"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/create [post]
|
// @Router /file/create [post]
|
||||||
func PostCreateFile(c *gin.Context) {
|
func PostCreateFile(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
path := json["path"]
|
||||||
var code int
|
var code int
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code, _ = service.MyService.ZiMa().CreateFile(path)
|
// decodedPath, err := url.QueryUnescape(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
code, _ = service.MyService.System().CreateFile(path)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 上传文件
|
// @Summary upload file
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param path formData string false "file path"
|
||||||
|
// @Param file formData file true "file"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /file/upload [get]
|
||||||
|
func GetFileUpload(c *gin.Context) {
|
||||||
|
|
||||||
|
relative := c.Query("relativePath")
|
||||||
|
fileName := c.Query("filename")
|
||||||
|
chunkNumber := c.Query("chunkNumber")
|
||||||
|
totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0"))
|
||||||
|
path := c.Query("path")
|
||||||
|
dirPath := ""
|
||||||
|
hash := file.GetHashByContent([]byte(fileName))
|
||||||
|
tempDir := config.AppInfo.TempPath + "/" + hash + strconv.Itoa(totalChunks) + "/"
|
||||||
|
if fileName != relative {
|
||||||
|
dirPath = strings.TrimSuffix(relative, fileName)
|
||||||
|
tempDir += dirPath
|
||||||
|
file.MkDir(path + "/" + dirPath)
|
||||||
|
}
|
||||||
|
tempDir += chunkNumber
|
||||||
|
if !file.CheckNotExist(tempDir) {
|
||||||
|
c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary upload file
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string false "路径"
|
// @Param path formData string false "file path"
|
||||||
|
// @Param file formData file true "file"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/mkdir [post]
|
// @Router /file/upload [post]
|
||||||
func PostFileUpload(c *gin.Context) {
|
func PostFileUpload(c *gin.Context) {
|
||||||
file, _, _ := c.Request.FormFile("file")
|
f, _, _ := c.Request.FormFile("file")
|
||||||
//file.Read()
|
relative := c.PostForm("relativePath")
|
||||||
path := c.Query("path")
|
fileName := c.PostForm("filename")
|
||||||
//上传文件
|
totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0"))
|
||||||
out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
|
chunkNumber := c.PostForm("chunkNumber")
|
||||||
defer out.Close()
|
dirPath := ""
|
||||||
io.Copy(out, file)
|
path := c.PostForm("path")
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutFileMove(c *gin.Context) {
|
hash := file.GetHashByContent([]byte(fileName))
|
||||||
from := "/Users/liangjianli/go/CasaOS"
|
|
||||||
to := "/Users/liangjianli/go/CasaOS/test"
|
|
||||||
//t := 1 //是否覆盖
|
|
||||||
|
|
||||||
//方法体
|
if len(path) == 0 {
|
||||||
stopCh := make(chan int)
|
c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
f, err := os.Stat(from)
|
return
|
||||||
if err != nil {
|
|
||||||
//未拿到文件信息
|
|
||||||
fmt.Println("stat", err)
|
|
||||||
}
|
}
|
||||||
//未创建新的文件夹
|
tempDir := config.AppInfo.TempPath + "/" + hash + strconv.Itoa(totalChunks) + "/"
|
||||||
if f.IsDir() {
|
|
||||||
//from 是文件夹,定义to也是文件夹
|
if fileName != relative {
|
||||||
if list, err := ioutil.ReadDir(from); err == nil {
|
dirPath = strings.TrimSuffix(relative, fileName)
|
||||||
for _, v := range list {
|
tempDir += dirPath
|
||||||
time.Sleep(time.Second)
|
file.MkDir(path + "/" + dirPath)
|
||||||
if err = Copy(stopCh, filepath.Join(from, v.Name()), filepath.Join(to, v.Name())); err != nil {
|
}
|
||||||
fmt.Printf("copy %s ,err %d", v.Name(), err)
|
|
||||||
}
|
path += "/" + relative
|
||||||
}
|
|
||||||
|
if !file.CheckNotExist(tempDir + chunkNumber) {
|
||||||
|
file.RMDir(tempDir + chunkNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalChunks > 1 {
|
||||||
|
file.IsNotExistMkDir(tempDir)
|
||||||
|
|
||||||
|
out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
defer out.Close()
|
||||||
|
_, err := io.Copy(out, f)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p := filepath.Dir(to)
|
out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
if _, err = os.Stat(p); err != nil {
|
defer out.Close()
|
||||||
if err = os.MkdirAll(p, 0777); err != nil {
|
_, err := io.Copy(out, f)
|
||||||
fmt.Println("mkdir", err)
|
if err != nil {
|
||||||
|
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileNum, err := ioutil.ReadDir(tempDir)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if totalChunks == len(fileNum) {
|
||||||
|
file.SpliceFiles(tempDir, path, totalChunks, 1)
|
||||||
|
file.RMDir(tempDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary copy or move file
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param body body model.FileOperate true "type:move,copy"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /file/operate [post]
|
||||||
|
func PostOperateFileOrDir(c *gin.Context) {
|
||||||
|
|
||||||
|
list := model.FileOperate{}
|
||||||
|
c.BindJSON(&list)
|
||||||
|
|
||||||
|
if len(list.Item) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var total int64 = 0
|
||||||
|
for i := 0; i < len(list.Item); i++ {
|
||||||
|
|
||||||
|
size, err := file.GetFileOrDirSize(list.Item[i].From)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list.Item[i].Size = size
|
||||||
|
total += size
|
||||||
|
}
|
||||||
|
|
||||||
|
list.TotalSize = total
|
||||||
|
list.ProcessedSize = 0
|
||||||
|
|
||||||
|
uid := uuid.NewV4().String()
|
||||||
|
service.FileQueue.Store(uid, list)
|
||||||
|
service.OpStrArr = append(service.OpStrArr, uid)
|
||||||
|
|
||||||
|
if len(service.OpStrArr) == 1 {
|
||||||
|
go service.ExecOpFile()
|
||||||
|
go service.CheckFileStatus()
|
||||||
|
|
||||||
|
go service.MyService.Notify().SendFileOperateNotify(false)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary delete file
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param body body string true "paths eg ["/a/b/c","/d/e/f"]"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /file/delete [delete]
|
||||||
|
func DeleteFile(c *gin.Context) {
|
||||||
|
|
||||||
|
paths := []string{}
|
||||||
|
c.BindJSON(&paths)
|
||||||
|
if len(paths) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// path := c.Query("path")
|
||||||
|
|
||||||
|
// paths := strings.Split(path, ",")
|
||||||
|
|
||||||
|
for _, v := range paths {
|
||||||
|
err := os.RemoveAll(v)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary update file
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param path body string true "path"
|
||||||
|
// @Param content body string true "content"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /file/update [put]
|
||||||
|
func PutFileContent(c *gin.Context) {
|
||||||
|
|
||||||
|
fi := model.FileUpdate{}
|
||||||
|
c.BindJSON(&fi)
|
||||||
|
|
||||||
|
// path := c.PostForm("path")
|
||||||
|
// content := c.PostForm("content")
|
||||||
|
if !file.Exists(fi.FilePath) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//err := os.Remove(path)
|
||||||
|
err := os.RemoveAll(fi.FilePath)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = file.CreateFileAndWriteContent(fi.FilePath, fi.FileContent)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary image thumbnail/original image
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param path query string true "path"
|
||||||
|
// @Param type query string false "original,thumbnail" Enums(original,thumbnail)
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /file/image [get]
|
||||||
|
func GetFileImage(c *gin.Context) {
|
||||||
|
t := c.Query("type")
|
||||||
|
path := c.Query("path")
|
||||||
|
if !file.Exists(path) {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if t == "thumbnail" {
|
||||||
|
f, err := file.GetImage(path, 100, 0)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Writer.WriteString(string(f))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
data, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Writer.WriteString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteOperateFileOrDir(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
if id == "0" {
|
||||||
|
service.FileQueue = sync.Map{}
|
||||||
|
service.OpStrArr = []string{}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
service.FileQueue.Delete(id)
|
||||||
|
tempList := []string{}
|
||||||
|
for _, v := range service.OpStrArr {
|
||||||
|
if v != id {
|
||||||
|
tempList = append(tempList, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
service.OpStrArr = tempList
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(from)
|
go service.MyService.Notify().SendFileOperateNotify(true)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
if err != nil {
|
|
||||||
fmt.Println("open file error ", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
out, err := os.Create(to)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("create to file err", err)
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
io.Copy(out, file)
|
|
||||||
time.Sleep(time.Second * 4)
|
|
||||||
close(stopCh)
|
|
||||||
}
|
|
||||||
func Copy(stop chan int, from, to string) error {
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
fmt.Println(from)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
json2 "encoding/json"
|
"fmt"
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"net/http"
|
||||||
"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/IceWhaleTech/CasaOS/types"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var upGrader = websocket.Upgrader{
|
var upGrader = websocket.Upgrader{
|
||||||
@@ -33,24 +31,17 @@ func NotifyWS(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
|
service.WebSocketConns = append(service.WebSocketConns, ws)
|
||||||
|
|
||||||
|
if !service.SocketRun {
|
||||||
|
service.SocketRun = true
|
||||||
|
service.SendMeg()
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
mt, message, err := ws.ReadMessage()
|
mt, message, err := ws.ReadMessage()
|
||||||
if err != nil {
|
fmt.Println(mt, message, err)
|
||||||
break
|
|
||||||
}
|
|
||||||
if string(message) != "notify" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
list := service.MyService.Notify().GetList()
|
|
||||||
json, _ := json2.Marshal(list)
|
|
||||||
err = ws.WriteMessage(mt, json)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 标记notify已读
|
// @Summary 标记notify已读
|
||||||
@@ -62,9 +53,10 @@ func NotifyWS(c *gin.Context) {
|
|||||||
// @Router /notify/read/{id} [put]
|
// @Router /notify/read/{id} [put]
|
||||||
func PutNotifyRead(c *gin.Context) {
|
func PutNotifyRead(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
if len(id) == 0 {
|
// if len(id) == 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
|
// return
|
||||||
}
|
// }
|
||||||
|
fmt.Println(id)
|
||||||
service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
|
service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
|
||||||
}
|
}
|
||||||
804
route/v1/person.go
Normal file
804
route/v1/person.go
Normal file
@@ -0,0 +1,804 @@
|
|||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/gob"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
natType "github.com/Curtis-Milo/nat-type-identifier-go"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Summary Retry the file that failed to download
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param uui path string true "download uuid"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/refile/{uuid} [get]
|
||||||
|
func GetPersonReFile(c *gin.Context) {
|
||||||
|
|
||||||
|
uid := c.Param("uuid")
|
||||||
|
_, err := uuid.FromString(uid)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
task := service.MyService.Download().GetDownloadById(uid)
|
||||||
|
if reflect.DeepEqual(task, model2.PersonDownloadDBModel{}) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
token := task.From
|
||||||
|
if _, ok := service.UDPAddressMap[token]; !ok {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = task.Path
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONDOWNLOAD
|
||||||
|
m.UUId = uid
|
||||||
|
go service.Dial(m, false)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary download file
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param share_id query string true "opponent share_id"
|
||||||
|
// @Param path query string true "file path"
|
||||||
|
// @Param file_name query string true "file name"
|
||||||
|
// @Param local_path query string true "local_path"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/file [get]
|
||||||
|
func GetPersonFile(c *gin.Context) {
|
||||||
|
|
||||||
|
path := c.Query("path")
|
||||||
|
localPath := c.Query("local_path")
|
||||||
|
token := c.Query("share_id")
|
||||||
|
fileName := c.Query("file_name")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if len(path) == 0 || err != nil || len(localPath) == 0 || len(fileName) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if file.CheckNotExist(localPath) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := service.UDPAddressMap[token]; !ok {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := service.UDPAddressMap[token]; !ok {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// task id
|
||||||
|
uuid := uuid.NewV4().String()
|
||||||
|
|
||||||
|
task := model2.PersonDownloadDBModel{}
|
||||||
|
task.UUID = uuid
|
||||||
|
task.Name = fileName
|
||||||
|
task.Length = 0
|
||||||
|
task.From = token
|
||||||
|
task.Path = path
|
||||||
|
task.Size = 0
|
||||||
|
task.State = types.DOWNLOADAWAIT
|
||||||
|
task.Created = time.Now().Unix()
|
||||||
|
task.Type = types.PERSONFILEDOWNLOAD
|
||||||
|
task.LocalPath = localPath
|
||||||
|
if service.MyService.Download().GetDownloadListByPath(task) > 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.MyService.Download().AddDownloadTask(task)
|
||||||
|
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = path
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONDOWNLOAD
|
||||||
|
m.UUId = uuid
|
||||||
|
go service.Dial(m, false)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary delete download file records
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param uuid path string true "download uuid"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/file/{uuid} [delete]
|
||||||
|
func DeletePersonDownloadFile(c *gin.Context) {
|
||||||
|
|
||||||
|
id := c.Param("uuid")
|
||||||
|
_, err := uuid.FromString(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
task := service.MyService.Download().GetDownloadById(id)
|
||||||
|
if task.State == types.DOWNLOADING {
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = ""
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = task.From
|
||||||
|
m.Type = types.PERSONCANCEL
|
||||||
|
m.UUId = task.UUID
|
||||||
|
service.CancelList[task.UUID] = task.UUID
|
||||||
|
service.Dial(m, false)
|
||||||
|
}
|
||||||
|
service.MyService.Download().DelDownload(id)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get file download list
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param state query int false "wait:0,downloading:1,pause:2,finish:3,error:4,finished:5" Enums(0,1,2,3,4,5)
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {object} []model2.PersonDownloadDBModel
|
||||||
|
// @Router /person/list [get]
|
||||||
|
func GetPersonDownloadList(c *gin.Context) {
|
||||||
|
state := c.DefaultQuery("state", "")
|
||||||
|
list := service.MyService.Download().GetDownloadListByState(state, types.PERSONFILEDOWNLOAD)
|
||||||
|
//if it is downloading, it need to add 'already'
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if list[i].State == types.DOWNLOADING {
|
||||||
|
tempDir := config.AppInfo.TempPath + "/" + list[i].UUID
|
||||||
|
files, err := ioutil.ReadDir(tempDir)
|
||||||
|
if err == nil {
|
||||||
|
list[i].Already = len(files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list[i].Duration = time.Now().Unix() - list[i].Created
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit friend's remarks
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param remarks formData string true "remarks name"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/remarks/{shareid} [put]
|
||||||
|
func PutPersonRemarks(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
mark := c.PostForm("remarks")
|
||||||
|
if err != nil || len(mark) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
friend := model2.FriendModel{}
|
||||||
|
friend.Token = token
|
||||||
|
friend.Mark = mark
|
||||||
|
service.MyService.Friend().EditFriendMark(friend)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit friend's
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param write formData bool true "write"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/write/{shareid} [put]
|
||||||
|
func PutPersonWrite(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
write, _ := strconv.ParseBool(c.PostForm("write"))
|
||||||
|
friend := model2.FriendModel{}
|
||||||
|
friend.Token = token
|
||||||
|
friend.Write = write
|
||||||
|
service.MyService.Friend().EditFriendMark(friend)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary image thumbnail
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param write formData bool true "write"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/image/thumbnail/{shareid} [get]
|
||||||
|
func GetPersonImageThumbnail(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
path := c.Query("path")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if err != nil || len(path) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uuid := uuid.NewV4().String()
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = path
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONIMAGETHUMBNAIL
|
||||||
|
m.UUId = uuid
|
||||||
|
|
||||||
|
img, err := service.Dial(m, false)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// var buf bytes.Buffer
|
||||||
|
//err = gob.NewEncoder(&buf).Encode(img.Data)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = gob.NewEncoder(&buf).Encode(img.Data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string))
|
||||||
|
c.Writer.WriteString(string(imageBuffer))
|
||||||
|
// c.String(http.StatusOK, "data:image/"+filesuffix+";base64,"+img.Data.(string))
|
||||||
|
//c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: img.Data.(string)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get my friend list
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {object} []model2.FriendModel
|
||||||
|
// @Router /person/users [get]
|
||||||
|
func GetPersonFriend(c *gin.Context) {
|
||||||
|
list := service.MyService.Friend().GetFriendList()
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 {
|
||||||
|
list[i].OnLine = true
|
||||||
|
if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
|
||||||
|
list[i].LocalIP = strings.Split(v, ":")[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary network type detection
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/detection [get]
|
||||||
|
func GetPersonDetection(c *gin.Context) {
|
||||||
|
// - Blocked
|
||||||
|
// - Open Internet
|
||||||
|
// - Full Cone
|
||||||
|
// - Symmetric UDP Firewall
|
||||||
|
// - Restric NAT
|
||||||
|
// - Restric Port NAT
|
||||||
|
// - Symmetric NAT
|
||||||
|
|
||||||
|
result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com")
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//result := service.MyService.Person().GetPersionNetWorkTypeDetection()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary add friend
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/user/{shareids} [post]
|
||||||
|
func PostAddPersonFriend(c *gin.Context) {
|
||||||
|
token := c.Param("shareids")
|
||||||
|
tokenList := strings.Split(token, ",")
|
||||||
|
|
||||||
|
for _, v := range tokenList {
|
||||||
|
_, err := uuid.FromString(v)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v == config.ServerInfo.Token {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_MYSELF, Message: common_err.GetMsg(common_err.PERSON_MYSELF)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
udb := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: v})
|
||||||
|
if !reflect.DeepEqual(udb, model2.FriendModel{Token: v}) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_FRIEND, Message: common_err.GetMsg(common_err.PERSON_EXIST_FRIEND)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user := service.MyService.Casa().GetUserInfoByShareId(v)
|
||||||
|
if reflect.DeepEqual(user, model.UserInfo{}) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_NOT_EXIST_USER, Message: common_err.GetMsg(common_err.PERSON_NOT_EXIST_USER)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
message := model.MessageModel{}
|
||||||
|
message.Type = types.PERSONCONNECTION
|
||||||
|
message.Data = v
|
||||||
|
message.From = config.ServerInfo.Token
|
||||||
|
message.To = v
|
||||||
|
message.UUId = uuid.NewV4().String()
|
||||||
|
|
||||||
|
go service.Dial(message, true)
|
||||||
|
|
||||||
|
msg := model.MessageModel{}
|
||||||
|
msg.Type = types.PERSONGETIP
|
||||||
|
msg.Data = ""
|
||||||
|
msg.From = config.ServerInfo.Token
|
||||||
|
msg.To = v
|
||||||
|
msg.UUId = uuid.NewV4().String()
|
||||||
|
|
||||||
|
service.Dial(msg, true)
|
||||||
|
|
||||||
|
friend := model2.FriendModel{}
|
||||||
|
friend.Token = v
|
||||||
|
friend.Avatar = user.Avatar
|
||||||
|
friend.Block = false
|
||||||
|
friend.State = types.FRIENDSTATEWAIT
|
||||||
|
friend.NickName = user.NickName
|
||||||
|
friend.Profile = user.Desc
|
||||||
|
friend.Version = user.Version
|
||||||
|
service.MyService.Friend().AddFriend(friend)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get a list of directories
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param share_id query string true "Opponent share_id"
|
||||||
|
// @Param path query string true "dir path"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {object} []model.Path
|
||||||
|
// @Router /person/directory [get]
|
||||||
|
func GetPersonDirectory(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
token := c.Query("share_id")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if len(path) == 0 || err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := service.UDPAddressMap[token]; !ok {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uuid := uuid.NewV4().String()
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = path
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONDIRECTORY
|
||||||
|
m.UUId = uuid
|
||||||
|
result, err := service.Dial(m, false)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dataModel := []model.Path{}
|
||||||
|
if uuid == m.UUId {
|
||||||
|
dataModelByte, _ := json.Marshal(result.Data)
|
||||||
|
err := json.Unmarshal(dataModelByte, &dataModel)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: dataModel})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Modify the download storage directory
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param path formData string true "path"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/down/dir [post]
|
||||||
|
func PostPersonDownDir(c *gin.Context) {
|
||||||
|
|
||||||
|
downPath := c.PostForm("path")
|
||||||
|
|
||||||
|
if len(downPath) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if file.CheckNotExist(downPath) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config.Cfg.Section("file").Key("DownloadDir").SetValue(downPath)
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
config.FileSettingInfo.DownloadDir = downPath
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get the download storage directory
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/down/dir [get]
|
||||||
|
func GetPersonDownDir(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.DownloadDir})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Modify the shared directory
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param share formData string true "share"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/share [post]
|
||||||
|
func PostPersonShare(c *gin.Context) {
|
||||||
|
|
||||||
|
share := c.PostForm("share")
|
||||||
|
|
||||||
|
if len(share) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var list []string
|
||||||
|
json.Unmarshal([]byte(share), &list)
|
||||||
|
|
||||||
|
if len(list) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range list {
|
||||||
|
if !file.Exists(v) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Cfg.Section("file").Key("ShareDir").SetValue(strings.Join(list, "|"))
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
config.FileSettingInfo.ShareDir = list
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get the shared directory
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/share [get]
|
||||||
|
func GetPersonShare(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.ShareDir})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get the shareid
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/shareid [get]
|
||||||
|
func GetPersonShareId(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Modify disabled status
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Param block formData bool false "Disable or not,Default:false "
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/block/{shareid} [put]
|
||||||
|
func PutPersonBlock(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
block, _ := strconv.ParseBool(c.PostForm("block"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
friend := model2.FriendModel{}
|
||||||
|
friend.Token = token
|
||||||
|
friend.Block = block
|
||||||
|
service.MyService.Friend().EditFriendBlock(friend)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Delete my friend
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/user/{shareid} [delete]
|
||||||
|
func DeletePersonFriend(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
friend := model2.FriendModel{}
|
||||||
|
friend.Token = token
|
||||||
|
|
||||||
|
service.MyService.Friend().DeleteFriend(friend)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get public person
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/public [get]
|
||||||
|
func GetPersonPublic(c *gin.Context) {
|
||||||
|
list := service.MyService.Casa().GetPersonPublic()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary upload file to friend
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param path formData string true "Destination path"
|
||||||
|
// @Param local_path formData string true "Full path of the file to be uploaded"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/file/{shareid} [post]
|
||||||
|
func PostPersonFile(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
path := c.PostForm("path")
|
||||||
|
localPath := c.PostForm("local_path")
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !file.Exists(localPath) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uuid := uuid.NewV4().String()
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = path
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONUPLOAD
|
||||||
|
m.UUId = uuid
|
||||||
|
go service.UDPSendData(m, localPath)
|
||||||
|
|
||||||
|
f, _ := os.Stat(localPath)
|
||||||
|
|
||||||
|
task := model2.PersonDownloadDBModel{}
|
||||||
|
task.UUID = uuid
|
||||||
|
task.Name = f.Name()
|
||||||
|
task.Length = 0
|
||||||
|
task.From = token
|
||||||
|
task.Path = path
|
||||||
|
task.Size = f.Size()
|
||||||
|
task.State = types.DOWNLOADFINISHED
|
||||||
|
task.Created = time.Now().Unix()
|
||||||
|
task.Type = types.PERSONFILEUPLOAD
|
||||||
|
task.LocalPath = localPath
|
||||||
|
if service.MyService.Download().GetDownloadListByPath(task) > 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.MyService.Download().AddDownloadTask(task)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary agree add friend
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags person
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /person/friend/{shareid} [put]
|
||||||
|
func PutPersonAgreeFriend(c *gin.Context) {
|
||||||
|
token := c.Param("shareid")
|
||||||
|
_, err := uuid.FromString(token)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: token})
|
||||||
|
|
||||||
|
if user.State != types.FRIENDSTATEREQUEST {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.COMMAND_ERROR_INVALID_OPERATION, Message: common_err.GetMsg(common_err.COMMAND_ERROR_INVALID_OPERATION)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.MyService.Friend().AgreeFrined(user.Token)
|
||||||
|
|
||||||
|
uuid := uuid.NewV4().String()
|
||||||
|
m := model.MessageModel{}
|
||||||
|
m.Data = ""
|
||||||
|
m.From = config.ServerInfo.Token
|
||||||
|
m.To = token
|
||||||
|
m.Type = types.PERSONAGREEFRIEND
|
||||||
|
m.UUId = uuid
|
||||||
|
go service.Dial(m, true)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// // @Summary upload file
|
||||||
|
// // @Produce application/json
|
||||||
|
// // @Accept multipart/form-data
|
||||||
|
// // @Tags person
|
||||||
|
// // @Security ApiKeyAuth
|
||||||
|
// // @Param path formData string false "file path"
|
||||||
|
// // @Param file formData file true "file"
|
||||||
|
// // @Success 200 {string} string "ok"
|
||||||
|
// // @Router /person/upload/{shareid} [get]
|
||||||
|
// func GetPersonFileUpload(c *gin.Context) {
|
||||||
|
|
||||||
|
// token := c.Param("shareid")
|
||||||
|
// _, err := uuid.FromString(token)
|
||||||
|
// path := c.Query("path")
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// relative := c.Query("relativePath")
|
||||||
|
// fileName := c.Query("filename")
|
||||||
|
// chunkNumber := c.Query("chunkNumber")
|
||||||
|
// totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0"))
|
||||||
|
// dirPath := ""
|
||||||
|
// hash := file.GetHashByContent([]byte(fileName))
|
||||||
|
// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/"
|
||||||
|
// if fileName != relative {
|
||||||
|
// dirPath = strings.TrimSuffix(relative, fileName)
|
||||||
|
// tempDir += dirPath
|
||||||
|
// file.MkDir(path + "/" + dirPath)
|
||||||
|
// }
|
||||||
|
// tempDir += chunkNumber
|
||||||
|
// if !file.CheckNotExist(tempDir) {
|
||||||
|
// c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // @Summary upload file
|
||||||
|
// // @Produce application/json
|
||||||
|
// // @Accept multipart/form-data
|
||||||
|
// // @Tags person
|
||||||
|
// // @Security ApiKeyAuth
|
||||||
|
// // @Param path formData string false "file path"
|
||||||
|
// // @Param file formData file true "file"
|
||||||
|
// // @Success 200 {string} string "ok"
|
||||||
|
// // @Router /person/upload [post]
|
||||||
|
// func PostPersonFileUpload(c *gin.Context) {
|
||||||
|
// token := c.Param("shareid")
|
||||||
|
// _, err := uuid.FromString(token)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// f, _, _ := c.Request.FormFile("file")
|
||||||
|
// relative := c.PostForm("relativePath")
|
||||||
|
// fileName := c.PostForm("filename")
|
||||||
|
// totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0"))
|
||||||
|
// chunkNumber := c.PostForm("chunkNumber")
|
||||||
|
// dirPath := ""
|
||||||
|
// path := c.PostForm("path")
|
||||||
|
|
||||||
|
// hash := file.GetHashByContent([]byte(fileName))
|
||||||
|
|
||||||
|
// if len(path) == 0 {
|
||||||
|
// c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/"
|
||||||
|
|
||||||
|
// if fileName != relative {
|
||||||
|
// dirPath = strings.TrimSuffix(relative, fileName)
|
||||||
|
// tempDir += dirPath
|
||||||
|
// file.MkDir(path + "/" + dirPath)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// path += "/" + relative
|
||||||
|
|
||||||
|
// if !file.CheckNotExist(tempDir + chunkNumber) {
|
||||||
|
// file.RMDir(tempDir + chunkNumber)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if totalChunks > 1 {
|
||||||
|
// file.IsNotExistMkDir(tempDir)
|
||||||
|
|
||||||
|
// out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
// defer out.Close()
|
||||||
|
// _, err := io.Copy(out, f)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
// defer out.Close()
|
||||||
|
// _, err := io.Copy(out, f)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fileNum, err := ioutil.ReadDir(tempDir)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if totalChunks == len(fileNum) {
|
||||||
|
// file.RMDir(tempDir)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
// }
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
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})
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 获取列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags share
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /share/list [get]
|
|
||||||
func GetShareDirList(c *gin.Context) {
|
|
||||||
list := service.MyService.ShareDirectory().List(true)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 添加文件共享
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags share
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param path formData string true "要分享的文件路径"
|
|
||||||
// @Param name formData string true "名称"
|
|
||||||
// @Param comment formData string true "描述"
|
|
||||||
// @Param read_only formData bool false "是否只读"
|
|
||||||
// @Param writeable formData bool false "是否可写"
|
|
||||||
// @Param browseable formData bool false "是否可浏览"
|
|
||||||
// @Param user formData string false "用户"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /share/add [post]
|
|
||||||
func PostShareDirAdd(c *gin.Context) {
|
|
||||||
|
|
||||||
name := c.PostForm("name")
|
|
||||||
comment := c.PostForm("comment")
|
|
||||||
path := c.PostForm("path")
|
|
||||||
readOnly, _ := strconv.ParseBool(c.DefaultPostForm("read_only", "false"))
|
|
||||||
writeable, _ := strconv.ParseBool(c.DefaultPostForm("writeable", "true"))
|
|
||||||
browse, _ := strconv.ParseBool(c.DefaultPostForm("browseable", "true"))
|
|
||||||
user := c.PostForm("user")
|
|
||||||
|
|
||||||
if len(name) == 0 || len(comment) == 0 || len(path) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var m model2.ShareDirDBModel
|
|
||||||
m.Name = name
|
|
||||||
m.Comment = comment
|
|
||||||
m.Path = path
|
|
||||||
m.ReadOnly = readOnly
|
|
||||||
m.Writeable = writeable
|
|
||||||
m.Browseable = browse
|
|
||||||
m.ValidUsers = user
|
|
||||||
|
|
||||||
service.MyService.ShareDirectory().Add(&m)
|
|
||||||
service.MyService.ShareDirectory().UpConfig()
|
|
||||||
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 share
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /share/del/{id} [delete]
|
|
||||||
func DeleteShareDirDel(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
service.MyService.ShareDirectory().Delete(id)
|
|
||||||
service.MyService.ShareDirectory().UpConfig()
|
|
||||||
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 share
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /share/info/{id} [get]
|
|
||||||
func GetShareDirInfo(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
info := service.MyService.ShareDirectory().Info(id)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 更新分享详情
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags share
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "id"
|
|
||||||
// @Param path formData string true "要分享的文件路径"
|
|
||||||
// @Param name formData string true "名称"
|
|
||||||
// @Param comment formData string true "描述"
|
|
||||||
// @Param read_only formData bool false "是否只读"
|
|
||||||
// @Param writeable formData bool false "是否可写"
|
|
||||||
// @Param browseable formData bool false "是否可浏览"
|
|
||||||
// @Param user formData string false "用户"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /share/update/{id} [put]
|
|
||||||
func PutShareDirEdit(c *gin.Context) {
|
|
||||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
||||||
|
|
||||||
if err != nil || id == 0 {
|
|
||||||
//todo 报错出去
|
|
||||||
}
|
|
||||||
|
|
||||||
name := c.PostForm("name")
|
|
||||||
comment := c.PostForm("comment")
|
|
||||||
path := c.PostForm("path")
|
|
||||||
readOnly, _ := strconv.ParseBool(c.DefaultPostForm("read_only", "false"))
|
|
||||||
writeable, _ := strconv.ParseBool(c.DefaultPostForm("writeable", "true"))
|
|
||||||
browse, _ := strconv.ParseBool(c.DefaultPostForm("browseable", "true"))
|
|
||||||
user := c.PostForm("user")
|
|
||||||
|
|
||||||
if len(name) == 0 || len(comment) == 0 || len(path) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var m model2.ShareDirDBModel
|
|
||||||
m.Id = uint(id)
|
|
||||||
m.Name = name
|
|
||||||
m.Comment = comment
|
|
||||||
m.Path = path
|
|
||||||
m.ReadOnly = readOnly
|
|
||||||
m.Writeable = writeable
|
|
||||||
m.Browseable = browse
|
|
||||||
m.ValidUsers = user
|
|
||||||
service.MyService.ShareDirectory().Update(&m)
|
|
||||||
service.MyService.ShareDirectory().UpConfig()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-09-30 18:18:14
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-15 14:30:05
|
||||||
|
* @FilePath: /CasaOS/route/v1/shortcuts.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"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/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Summary 获取短链列表
|
// @Summary 获取短链列表
|
||||||
@@ -21,7 +32,7 @@ import (
|
|||||||
// @Router /shortcuts/list [get]
|
// @Router /shortcuts/list [get]
|
||||||
func GetShortcutsList(c *gin.Context) {
|
func GetShortcutsList(c *gin.Context) {
|
||||||
list := service.MyService.Shortcuts().GetList()
|
list := service.MyService.Shortcuts().GetList()
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 添加shortcuts
|
// @Summary 添加shortcuts
|
||||||
@@ -38,17 +49,17 @@ func PostShortcutsAdd(c *gin.Context) {
|
|||||||
|
|
||||||
c.BindJSON(&m)
|
c.BindJSON(&m)
|
||||||
if len(m.Url) == 0 || len(m.Title) == 0 {
|
if len(m.Url) == 0 || len(m.Title) == 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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u, err := url.Parse(m.Url)
|
u, err := url.Parse(m.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SHORTCUTS_URL_ERROR, Message: oasis_err.GetMsg(oasis_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
||||||
service.MyService.Shortcuts().AddData(m)
|
service.MyService.Shortcuts().AddData(m)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +74,8 @@ func DeleteShortcutsDelete(c *gin.Context) {
|
|||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
service.MyService.Shortcuts().DeleteData(id)
|
service.MyService.Shortcuts().DeleteData(id)
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(http.StatusOK, model.Result{
|
||||||
Success: oasis_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: "",
|
Data: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -82,15 +93,15 @@ func PutShortcutsEdit(c *gin.Context) {
|
|||||||
var m model2.ShortcutsDBModel
|
var m model2.ShortcutsDBModel
|
||||||
c.BindJSON(&m)
|
c.BindJSON(&m)
|
||||||
if len(m.Url) == 0 || len(m.Title) == 0 {
|
if len(m.Url) == 0 || len(m.Title) == 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: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u, err := url.Parse(m.Url)
|
u, err := url.Parse(m.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SHORTCUTS_URL_ERROR, Message: oasis_err.GetMsg(oasis_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
||||||
service.MyService.Shortcuts().EditData(m)
|
service.MyService.Shortcuts().EditData(m)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: ""})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2021-11-08 18:02:02
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-06-21 19:13:59
|
||||||
|
* @FilePath: /CasaOS/route/v1/sync.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
|
||||||
"net/url"
|
|
||||||
"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/oasis_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/gin-gonic/gin"
|
"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) {
|
func GetSyncConfig(c *gin.Context) {
|
||||||
data := make(map[string]string)
|
data := make(map[string]string)
|
||||||
data["key"] = config.SystemConfigInfo.SyncKey
|
data["key"] = config.SystemConfigInfo.SyncKey
|
||||||
data["port"] = config.SystemConfigInfo.SyncPort
|
data["port"] = config.SystemConfigInfo.SyncPort
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,25 +13,27 @@ import (
|
|||||||
|
|
||||||
"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/common_err"
|
||||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
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"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Summary 系统信息
|
// @Summary check version
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags sys
|
// @Tags sys
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/chackversion [get]
|
// @Router /sys/version/check [get]
|
||||||
func CheckVersion(c *gin.Context) {
|
func GetSystemCheckVersion(c *gin.Context) {
|
||||||
need, version := version.IsNeedUpdate()
|
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
|
||||||
if need {
|
if need {
|
||||||
installLog := model2.AppNotify{}
|
installLog := model2.AppNotify{}
|
||||||
installLog.State = 0
|
installLog.State = 0
|
||||||
@@ -42,12 +44,11 @@ func CheckVersion(c *gin.Context) {
|
|||||||
installLog.Name = "CasaOS System"
|
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{}, 3)
|
||||||
data["is_need"] = need
|
data["is_need"] = need
|
||||||
data["version"] = version
|
data["version"] = version
|
||||||
data["current_version"] = types.CURRENTVERSION
|
data["current_version"] = types.CURRENTVERSION
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 系统信息
|
// @Summary 系统信息
|
||||||
@@ -58,16 +59,16 @@ 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) {
|
||||||
need, version := version.IsNeedUpdate()
|
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
|
||||||
if need {
|
if need {
|
||||||
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: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
//系统配置
|
//Get system config
|
||||||
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: json.RawMessage(config.SystemConfigInfo.ConfigStr)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get logs
|
// @Summary get logs
|
||||||
@@ -79,7 +80,7 @@ func GetSystemConfig(c *gin.Context) {
|
|||||||
// @Router /sys/error/logs [get]
|
// @Router /sys/error/logs [get]
|
||||||
func GetCasaOSErrorLogs(c *gin.Context) {
|
func GetCasaOSErrorLogs(c *gin.Context) {
|
||||||
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 修改配置文件
|
// @Summary 修改配置文件
|
||||||
@@ -97,8 +98,8 @@ func PostSetSystemConfig(c *gin.Context) {
|
|||||||
service.MyService.System().UpSystemConfig(string(buf[0:n]), "")
|
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: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: json.RawMessage(config.SystemConfigInfo.ConfigStr),
|
Data: json.RawMessage(config.SystemConfigInfo.ConfigStr),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -107,15 +108,15 @@ func PostSetSystemConfig(c *gin.Context) {
|
|||||||
func GetSystemConfigDebug(c *gin.Context) {
|
func GetSystemConfigDebug(c *gin.Context) {
|
||||||
|
|
||||||
array := service.MyService.System().GetSystemConfigDebug()
|
array := service.MyService.System().GetSystemConfigDebug()
|
||||||
disk := service.MyService.ZiMa().GetDiskInfo()
|
disk := service.MyService.System().GetDiskInfo()
|
||||||
sys := service.MyService.ZiMa().GetSysInfo()
|
sys := service.MyService.System().GetSysInfo()
|
||||||
//todo 准备sync需要显示的数据(镜像,容器)
|
//todo 准备sync需要显示的数据(镜像,容器)
|
||||||
var systemAppStatus string
|
var systemAppStatus string
|
||||||
images := service.MyService.Docker().IsExistImage("linuxserver/syncthing")
|
images := service.MyService.Docker().IsExistImage("linuxserver/syncthing")
|
||||||
systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
|
systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
|
||||||
|
|
||||||
list := service.MyService.App().GetSystemAppList()
|
list := service.MyService.App().GetSystemAppList()
|
||||||
for _, v := range *list {
|
for _, v := range list {
|
||||||
systemAppStatus += v.Image + ",\n\t"
|
systemAppStatus += v.Image + ",\n\t"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,15 +135,12 @@ func GetSystemConfigDebug(c *gin.Context) {
|
|||||||
|
|
||||||
// array = append(array, fmt.Sprintf("disk,total:%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: bugContent})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
|
||||||
}
|
|
||||||
func Sys(c *gin.Context) {
|
|
||||||
service.DockerPull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//widget配置
|
//widget配置
|
||||||
func GetWidgetConfig(c *gin.Context) {
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(config.SystemConfigInfo.WidgetList)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 修改组件配置文件
|
// @Summary 修改组件配置文件
|
||||||
@@ -155,13 +153,11 @@ func GetWidgetConfig(c *gin.Context) {
|
|||||||
func PostSetWidgetConfig(c *gin.Context) {
|
func PostSetWidgetConfig(c *gin.Context) {
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
n, _ := c.Request.Body.Read(buf)
|
n, _ := c.Request.Body.Read(buf)
|
||||||
fmt.Println("错误", strconv.Itoa(n))
|
|
||||||
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
|
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
|
||||||
fmt.Println("错误1", string(buf[0:n]))
|
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: json.RawMessage(config.SystemConfigInfo.WidgetList),
|
Data: json.RawMessage(config.SystemConfigInfo.WidgetList),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -176,8 +172,8 @@ func PostSetWidgetConfig(c *gin.Context) {
|
|||||||
func GetCasaOSPort(c *gin.Context) {
|
func GetCasaOSPort(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: config.ServerInfo.HttpPort,
|
Data: config.ServerInfo.HttpPort,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -187,15 +183,18 @@ func GetCasaOSPort(c *gin.Context) {
|
|||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags sys
|
// @Tags sys
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param port formData string true "port"
|
// @Param port json string true "port"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/port [put]
|
// @Router /sys/port [put]
|
||||||
func PutCasaOSPort(c *gin.Context) {
|
func PutCasaOSPort(c *gin.Context) {
|
||||||
port, err := strconv.Atoi(c.PostForm("port"))
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
portStr := json["port"]
|
||||||
|
port, err := strconv.Atoi(portStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.ERROR,
|
Success: common_err.ERROR,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -205,16 +204,16 @@ func PutCasaOSPort(c *gin.Context) {
|
|||||||
if !isAvailable {
|
if !isAvailable {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.PORT_IS_OCCUPIED,
|
Success: common_err.PORT_IS_OCCUPIED,
|
||||||
Message: oasis_err.GetMsg(oasis_err.PORT_IS_OCCUPIED),
|
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.System().UpSystemPort(strconv.Itoa(port))
|
service.MyService.System().UpSystemPort(strconv.Itoa(port))
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,18 +223,23 @@ func PutCasaOSPort(c *gin.Context) {
|
|||||||
// @Tags sys
|
// @Tags sys
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /guide/check [get]
|
// @Router /sys/init/check [get]
|
||||||
func GetGuideCheck(c *gin.Context) {
|
func GetSystemInitCheck(c *gin.Context) {
|
||||||
initUser := false
|
data := make(map[string]interface{}, 2)
|
||||||
if !config.UserInfo.Initialized {
|
|
||||||
initUser = true
|
if service.MyService.User().GetUserCount() > 0 {
|
||||||
|
data["initialized"] = true
|
||||||
|
data["key"] = ""
|
||||||
|
} else {
|
||||||
|
key := uuid.NewV4().String()
|
||||||
|
service.UserRegisterHash[key] = key
|
||||||
|
data["key"] = key
|
||||||
|
data["initialized"] = false
|
||||||
}
|
}
|
||||||
data := make(map[string]interface{}, 1)
|
|
||||||
data["need_init_user"] = initUser
|
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(http.StatusOK,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: oasis_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: oasis_err.GetMsg(oasis_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: data,
|
Data: data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -246,22 +250,86 @@ func GetGuideCheck(c *gin.Context) {
|
|||||||
// @Tags sys
|
// @Tags sys
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/kill [post]
|
// @Router /sys/restart [post]
|
||||||
func PostKillCasaOS(c *gin.Context) {
|
func PostKillCasaOS(c *gin.Context) {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary system info
|
// @Summary Turn off usb auto-mount
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags sys
|
// @Tags sys
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/info [get]
|
// @Router /sys/usb/off [put]
|
||||||
func Info(c *gin.Context) {
|
func PutSystemUSBAutoMount(c *gin.Context) {
|
||||||
var data = make(map[string]interface{}, 5)
|
status := c.Param("status")
|
||||||
|
if status == "on" {
|
||||||
|
service.MyService.System().UpdateUSBAutoMount("True")
|
||||||
|
service.MyService.System().ExecUSBAutoMountShell("True")
|
||||||
|
} else {
|
||||||
|
service.MyService.System().UpdateUSBAutoMount("False")
|
||||||
|
service.MyService.System().ExecUSBAutoMountShell("False")
|
||||||
|
}
|
||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Turn off usb auto-mount
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/usb [get]
|
||||||
|
func GetSystemUSBAutoMount(c *gin.Context) {
|
||||||
|
state := "True"
|
||||||
|
if config.ServerInfo.USBAutoMount == "False" {
|
||||||
|
state = "False"
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get system hardware info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/hardware/info [get]
|
||||||
|
func GetSystemHardwareInfo(c *gin.Context) {
|
||||||
|
|
||||||
|
data := make(map[string]string, 1)
|
||||||
|
data["drive_model"] = service.MyService.System().GetDeviceTree()
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary system utilization
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/utilization [get]
|
||||||
|
func GetSystemUtilization(c *gin.Context) {
|
||||||
|
var data = make(map[string]interface{}, 6)
|
||||||
|
|
||||||
|
list := service.MyService.Disk().LSBLK(true)
|
||||||
|
|
||||||
summary := model.Summary{}
|
summary := model.Summary{}
|
||||||
healthy := true
|
healthy := true
|
||||||
@@ -269,38 +337,59 @@ func Info(c *gin.Context) {
|
|||||||
|
|
||||||
for i := 0; i < len(list); i++ {
|
for i := 0; i < len(list); i++ {
|
||||||
if len(list[i].Children) > 0 && findSystem == 0 {
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
|
|
||||||
for j := 0; j < len(list[i].Children); j++ {
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
if list[i].Children[j].MountPoint == "/" {
|
|
||||||
s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
|
if len(list[i].Children[j].Children) > 0 {
|
||||||
a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
|
for _, v := range list[i].Children[j].Children {
|
||||||
u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
|
if v.MountPoint == "/" {
|
||||||
summary.Size += s
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
summary.Avail += a
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
summary.Used += u
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
findSystem = 1
|
loger.Info("disk info", zap.Any("/ total:", s))
|
||||||
break
|
loger.Info("disk path", zap.Any("path", v.Path))
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
|
||||||
|
loger.Info("disk info", zap.Any("/ total:", s))
|
||||||
|
loger.Info("disk path", zap.Any("path", list[i].Path))
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if findSystem == 1 {
|
if findSystem == 1 {
|
||||||
findSystem += 1
|
findSystem += 1
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if list[i].Tran == "sata" {
|
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") {
|
||||||
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
continue
|
healthy = true
|
||||||
}
|
} else {
|
||||||
|
healthy = temp.SmartStatus.Passed
|
||||||
//list[i].Temperature = temp.Temperature.Current
|
|
||||||
if !temp.SmartStatus.Passed {
|
|
||||||
healthy = false
|
|
||||||
}
|
}
|
||||||
if len(list[i].Children) > 0 {
|
if len(list[i].Children) > 0 {
|
||||||
for _, v := range list[i].Children {
|
for _, v := range list[i].Children {
|
||||||
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
loger.Info("disk info", zap.Any("/ total:", s))
|
||||||
|
loger.Info("disk path", zap.Any("path", list[i].Path))
|
||||||
summary.Size += s
|
summary.Size += s
|
||||||
summary.Avail += a
|
summary.Avail += a
|
||||||
summary.Used += u
|
summary.Used += u
|
||||||
@@ -312,24 +401,51 @@ func Info(c *gin.Context) {
|
|||||||
|
|
||||||
summary.Health = healthy
|
summary.Health = healthy
|
||||||
data["disk"] = summary
|
data["disk"] = summary
|
||||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
usbList := service.MyService.Disk().LSBLK(false)
|
||||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
usb := []model.DriveUSB{}
|
||||||
|
for _, v := range usbList {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
mountTemp := true
|
||||||
|
if len(v.Children) == 0 {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
||||||
|
temp.Used += used
|
||||||
|
} else {
|
||||||
|
mountTemp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp.Mount = mountTemp
|
||||||
|
usb = append(usb, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data["usb"] = usb
|
||||||
|
cpu := service.MyService.System().GetCpuPercent()
|
||||||
|
num := service.MyService.System().GetCpuCoreNum()
|
||||||
cpuData := make(map[string]interface{})
|
cpuData := make(map[string]interface{})
|
||||||
cpuData["percent"] = cpu
|
cpuData["percent"] = cpu
|
||||||
cpuData["num"] = num
|
cpuData["num"] = num
|
||||||
data["cpu"] = cpuData
|
data["cpu"] = cpuData
|
||||||
data["mem"] = service.MyService.ZiMa().GetMemInfo()
|
data["mem"] = service.MyService.System().GetMemInfo()
|
||||||
|
|
||||||
//拼装网络信息
|
//拼装网络信息
|
||||||
netList := service.MyService.ZiMa().GetNetInfo()
|
netList := service.MyService.System().GetNetInfo()
|
||||||
newNet := []model.IOCountersStat{}
|
newNet := []model.IOCountersStat{}
|
||||||
nets := service.MyService.ZiMa().GetNet(true)
|
nets := service.MyService.System().GetNet(true)
|
||||||
for _, n := range netList {
|
for _, n := range netList {
|
||||||
for _, netCardName := range nets {
|
for _, netCardName := range nets {
|
||||||
if n.Name == netCardName {
|
if n.Name == netCardName {
|
||||||
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||||
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
|
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
|
||||||
item.DateTime = time.Now()
|
item.Time = time.Now().Unix()
|
||||||
newNet = append(newNet, item)
|
newNet = append(newNet, item)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -338,5 +454,112 @@ func Info(c *gin.Context) {
|
|||||||
|
|
||||||
data["net"] = newNet
|
data["net"] = newNet
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get notification port
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/socket/port [get]
|
||||||
|
func GetSystemSocketPort(c *gin.Context) {
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: config.ServerInfo.SocketPort,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get cpu info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/cpu [get]
|
||||||
|
func GetSystemCupInfo(c *gin.Context) {
|
||||||
|
cpu := service.MyService.System().GetCpuPercent()
|
||||||
|
num := service.MyService.System().GetCpuCoreNum()
|
||||||
|
data := make(map[string]interface{})
|
||||||
|
data["percent"] = cpu
|
||||||
|
data["num"] = num
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get mem info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/mem [get]
|
||||||
|
func GetSystemMemInfo(c *gin.Context) {
|
||||||
|
mem := service.MyService.System().GetMemInfo()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get disk info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/disk [get]
|
||||||
|
func GetSystemDiskInfo(c *gin.Context) {
|
||||||
|
disk := service.MyService.System().GetDiskInfo()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get Net info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags sys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /sys/net [get]
|
||||||
|
func GetSystemNetInfo(c *gin.Context) {
|
||||||
|
netList := service.MyService.System().GetNetInfo()
|
||||||
|
newNet := []model.IOCountersStat{}
|
||||||
|
for _, n := range netList {
|
||||||
|
for _, netCardName := range service.MyService.System().GetNet(true) {
|
||||||
|
if n.Name == netCardName {
|
||||||
|
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||||
|
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
|
||||||
|
item.Time = time.Now().Unix()
|
||||||
|
newNet = append(newNet, item)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
|
||||||
|
}
|
||||||
|
|
||||||
|
//********************************************* Soon to be removed ***********************************************
|
||||||
|
// @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 := true
|
||||||
|
if service.MyService.User().GetUserCount() > 0 {
|
||||||
|
initUser = false
|
||||||
|
}
|
||||||
|
data := make(map[string]interface{}, 1)
|
||||||
|
data["need_init_user"] = initUser
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: data,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 获取task列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags task
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /task/list [get]
|
|
||||||
func GetTaskList(c *gin.Context) {
|
|
||||||
//list := service.MyService.Task().List(true)
|
|
||||||
list := service.MyService.Task().GetServerTasks()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutTaskUpdate(c *gin.Context) {
|
|
||||||
service.MyService.Task().SyncTaskService()
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 标记task已完成
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags task
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /task/completion/{id} [put]
|
|
||||||
func PutTaskMarkerCompletion(c *gin.Context) {
|
|
||||||
id, _ := strconv.Atoi(c.Param("id"))
|
|
||||||
if id == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var m model2.TaskDBModel
|
|
||||||
m.Id = uint(id)
|
|
||||||
m.State = types.TASK_STATE_COMPLETED
|
|
||||||
service.MyService.Task().Update(&m)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostTaskAdd(c *gin.Context) {
|
|
||||||
var m model2.TaskDBModel
|
|
||||||
c.BindJSON(&m)
|
|
||||||
service.MyService.Task().Add(&m)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
886
route/v1/user.go
886
route/v1/user.go
@@ -1,24 +1,704 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
json2 "encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
url2 "net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"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"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var user_service service.UserService
|
// @Summary register user
|
||||||
|
// @Router /user/register/ [post]
|
||||||
|
func PostUserRegister(c *gin.Context) {
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
username := json["user_name"]
|
||||||
|
pwd := json["password"]
|
||||||
|
key := c.Param("key")
|
||||||
|
if _, ok := service.UserRegisterHash[key]; !ok {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(username) == 0 || len(pwd) == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(pwd) < 6 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.PWD_IS_TOO_SIMPLE, Message: common_err.GetMsg(common_err.PWD_IS_TOO_SIMPLE)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oldUser := service.MyService.User().GetUserInfoByUserName(username)
|
||||||
|
if oldUser.Id > 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user := model2.UserDBModel{}
|
||||||
|
user.UserName = username
|
||||||
|
user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD)
|
||||||
|
user.Role = "admin"
|
||||||
|
|
||||||
|
user = service.MyService.User().CreateUser(user)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
|
||||||
|
delete(service.UserRegisterHash, key)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
|
||||||
func init() {
|
|
||||||
user_service = service.NewUserService()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary login
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Param user_name query string true "User name"
|
||||||
|
// @Param pwd query string true "password"
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/login [post]
|
||||||
|
func PostUserLogin(c *gin.Context) {
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
|
||||||
|
username := json["username"]
|
||||||
|
pwd := json["pwd"]
|
||||||
|
//check params is empty
|
||||||
|
if len(username) == 0 || len(pwd) == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.ERROR,
|
||||||
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserAllInfoByName(username)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if user.Password != encryption.GetMD5ByStr(pwd) {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.Password = ""
|
||||||
|
// token := system_model.VerifyInformation{}
|
||||||
|
// token.AccessToken = jwt.GetAccessToken(user.UserName, user.Password, user.Id)
|
||||||
|
// token.RefreshToken = jwt.GetRefreshToken(user.UserName, user.Password, user.Id)
|
||||||
|
// token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
||||||
|
// data := make(map[string]interface{}, 2)
|
||||||
|
// data["token"] = token
|
||||||
|
// data["user"] = user
|
||||||
|
data := make(map[string]interface{}, 3)
|
||||||
|
data["token"] = jwt.GetToken(username, pwd)
|
||||||
|
data["version"] = types.CURRENTVERSION
|
||||||
|
data["user"] = user
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit user head
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Tags user
|
||||||
|
// @Param file formData file true "用户头像"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/avatar [put]
|
||||||
|
func PutUserAvatar(c *gin.Context) {
|
||||||
|
id := c.GetHeader("user_id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, err := c.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(user.Avatar) > 0 {
|
||||||
|
os.RemoveAll(config.AppInfo.UserDataPath + "/" + id + "/" + user.Avatar)
|
||||||
|
}
|
||||||
|
ext := filepath.Ext(f.Filename)
|
||||||
|
avatarPath := config.AppInfo.UserDataPath + "/" + id + "/avatar" + ext
|
||||||
|
c.SaveUploadedFile(f, avatarPath)
|
||||||
|
user.Avatar = avatarPath
|
||||||
|
service.MyService.User().UpdateUser(user)
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: get user avatar by user id
|
||||||
|
* @param {query} id string user id
|
||||||
|
* @method: GET
|
||||||
|
*/
|
||||||
|
func GetUserAvatar(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
|
path := "default.png"
|
||||||
|
if user.Id > 0 {
|
||||||
|
path = user.Avatar
|
||||||
|
}
|
||||||
|
c.File(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit user name
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Param old_name query string true "Old user name"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/name/:id [put]
|
||||||
|
func PutUserName(c *gin.Context) {
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
//userName := json["user_name"]
|
||||||
|
username := json["username"]
|
||||||
|
id := json["user_id"]
|
||||||
|
if len(username) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.UserName = username
|
||||||
|
service.MyService.User().UpdateUser(user)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit user password
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/password/:id [put]
|
||||||
|
func PutUserPwd(c *gin.Context) {
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
oldPwd := json["old_pwd"]
|
||||||
|
pwd := json["pwd"]
|
||||||
|
id := json["user_id"]
|
||||||
|
if len(oldPwd) == 0 || len(pwd) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserAllInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if user.Password != encryption.GetMD5ByStr(oldPwd) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.Password = encryption.GetMD5ByStr(pwd)
|
||||||
|
service.MyService.User().UpdateUserPassword(user)
|
||||||
|
user.Password = ""
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit user nick
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Param nick_name query string false "nick name"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/nick [put]
|
||||||
|
func PutUserNick(c *gin.Context) {
|
||||||
|
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
nickName := json["nick_name"]
|
||||||
|
id := json["user_id"]
|
||||||
|
if len(nickName) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.NickName = nickName
|
||||||
|
service.MyService.User().UpdateUser(user)
|
||||||
|
//TODO:person remove together
|
||||||
|
go service.MyService.Casa().PushUserInfo()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary edit user description
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Tags user
|
||||||
|
// @Param description formData string false "Description"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/desc [put]
|
||||||
|
func PutUserDesc(c *gin.Context) {
|
||||||
|
// id := c.GetHeader("user_id")
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
id := json["user_id"]
|
||||||
|
desc := json["description"]
|
||||||
|
if len(desc) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.Description = desc
|
||||||
|
|
||||||
|
service.MyService.User().UpdateUser(user)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Modify user person information (Initialization use)
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Tags user
|
||||||
|
// @Param nick_name formData string false "user nick name"
|
||||||
|
// @Param description formData string false "Description"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/person/info [post]
|
||||||
|
func PostUserPersonInfo(c *gin.Context) {
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
desc := json["description"]
|
||||||
|
nickName := json["nick_name"]
|
||||||
|
id := json["user_id"]
|
||||||
|
if len(desc) == 0 || len(nickName) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//user_service.SetUser("", "", "", "", desc, nickName)
|
||||||
|
user.NickName = nickName
|
||||||
|
user.Description = desc
|
||||||
|
service.MyService.User().UpdateUser(user)
|
||||||
|
go service.MyService.Casa().PushUserInfo()
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get user info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/info/:id [get]
|
||||||
|
func GetUserInfo(c *gin.Context) {
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
|
//*****
|
||||||
|
var u = make(map[string]string, 5)
|
||||||
|
u["user_name"] = user.UserName
|
||||||
|
u["head"] = user.Avatar
|
||||||
|
u["email"] = user.Email
|
||||||
|
u["description"] = user.NickName
|
||||||
|
u["nick_name"] = user.NickName
|
||||||
|
u["id"] = strconv.Itoa(user.Id)
|
||||||
|
|
||||||
|
//**
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: u,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary get user info
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/info [get]
|
||||||
|
func GetUserInfoByUserName(c *gin.Context) {
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
userName := json["user_name"]
|
||||||
|
if len(userName) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoByUserName(userName)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//**
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Get my shareId
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags user
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /user/shareid [get]
|
||||||
|
func GetUserShareID(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: get all user name
|
||||||
|
* @method:GET
|
||||||
|
* @router:/user/all/name
|
||||||
|
*/
|
||||||
|
func GetUserAllUserName(c *gin.Context) {
|
||||||
|
users := service.MyService.User().GetAllUserName()
|
||||||
|
names := []string{}
|
||||||
|
for _, v := range users {
|
||||||
|
names = append(names, v.UserName)
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: names,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:get custom file by user
|
||||||
|
* @param {path} name string "file name"
|
||||||
|
* @method: GET
|
||||||
|
* @router: /user/custom/:key
|
||||||
|
*/
|
||||||
|
func GetUserCustomConf(c *gin.Context) {
|
||||||
|
name := c.Param("key")
|
||||||
|
if len(name) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
// user := service.MyService.User().GetUserInfoByUserName(userName)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
|
||||||
|
data := file.ReadFullFile(filePath)
|
||||||
|
if !gjson.ValidBytes(data) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:create or update custom conf by user
|
||||||
|
* @param {path} name string "file name"
|
||||||
|
* @method:POST
|
||||||
|
* @router:/user/custom/:key
|
||||||
|
*/
|
||||||
|
func PostUserCustomConf(c *gin.Context) {
|
||||||
|
name := c.Param("key")
|
||||||
|
if len(name) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, _ := ioutil.ReadAll(c.Request.Body)
|
||||||
|
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
|
||||||
|
|
||||||
|
file.WriteToPath(data, filePath, name+".json")
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: delete user custom config
|
||||||
|
* @param {path} key string
|
||||||
|
* @method:delete
|
||||||
|
* @router:/user/custom/:key
|
||||||
|
*/
|
||||||
|
func DeleteUserCustomConf(c *gin.Context) {
|
||||||
|
name := c.Param("key")
|
||||||
|
if len(name) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK,
|
||||||
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + name + ".json"
|
||||||
|
os.Remove(filePath)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @param {path} id string "user id"
|
||||||
|
* @method:DELETE
|
||||||
|
* @router:/user/delete/:id
|
||||||
|
*/
|
||||||
|
func DeleteUser(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
service.MyService.User().DeleteUserById(id)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:update user image
|
||||||
|
* @method:POST
|
||||||
|
* @router:/user/file/image/:key
|
||||||
|
*/
|
||||||
|
func PostUserFileImage(c *gin.Context) {
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
json := make(map[string]string)
|
||||||
|
c.BindJSON(&json)
|
||||||
|
|
||||||
|
path := json["path"]
|
||||||
|
key := c.Param("key")
|
||||||
|
if len(path) == 0 || len(key) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !file.Exists(path) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := file.GetImageExt(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fstat, _ := os.Stat(path)
|
||||||
|
if fstat.Size() > 10<<20 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.IMAGE_TOO_LARGE, Message: common_err.GetMsg(common_err.IMAGE_TOO_LARGE)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ext := file.GetExt(path)
|
||||||
|
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
|
||||||
|
file.CopySingleFile(path, filePath, "overwrite")
|
||||||
|
|
||||||
|
data := make(map[string]string, 3)
|
||||||
|
data["path"] = filePath
|
||||||
|
data["file_name"] = key + ext
|
||||||
|
data["online_path"] = "/v1/user/image?path=" + filePath
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:create or update user's custom image
|
||||||
|
* @param {formData} file file "a file to be uploaded"
|
||||||
|
* @param {path} key string "file name"
|
||||||
|
* @method:POST
|
||||||
|
* @router:/user/upload/image/:key
|
||||||
|
*/
|
||||||
|
func PostUserUploadImage(c *gin.Context) {
|
||||||
|
//id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
f, err := c.FormFile("file")
|
||||||
|
key := c.Param("key")
|
||||||
|
if len(key) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = file.GetImageExtByName(f.Filename)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ext := filepath.Ext(f.Filename)
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
path := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
|
||||||
|
c.SaveUploadedFile(f, path)
|
||||||
|
data := make(map[string]string, 3)
|
||||||
|
data["path"] = path
|
||||||
|
data["file_name"] = key + ext
|
||||||
|
data["online_path"] = "/v1/user/image?path=" + path
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: get current user's image
|
||||||
|
* @method:GET
|
||||||
|
* @router:/user/image/:id
|
||||||
|
*/
|
||||||
|
func GetUserImage(c *gin.Context) {
|
||||||
|
filePath := c.Query("path")
|
||||||
|
if len(filePath) == 0 {
|
||||||
|
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !file.Exists(filePath) {
|
||||||
|
c.JSON(http.StatusNotFound, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.Contains(filePath, config.AppInfo.UserDataPath) {
|
||||||
|
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileTmp, _ := os.Open(filePath)
|
||||||
|
defer fileTmp.Close()
|
||||||
|
|
||||||
|
fileName := path.Base(filePath)
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||||
|
c.File(filePath)
|
||||||
|
}
|
||||||
|
func DeleteUserImage(c *gin.Context) {
|
||||||
|
// id := c.GetHeader("user_id")
|
||||||
|
id := c.Param("id")
|
||||||
|
path := c.Query("path")
|
||||||
|
if len(path) == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !file.Exists(path) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+strconv.Itoa(user.Id)) {
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os.Remove(path)
|
||||||
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
////refresh token
|
||||||
|
// func PostUserRefreshToken(c *gin.Context) {
|
||||||
|
// json := make(map[string]string)
|
||||||
|
// c.BindJSON(&json)
|
||||||
|
// refresh := json["refresh_token"]
|
||||||
|
// claims, err := jwt.ParseToken(refresh)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("refresh", true) {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// newToken := jwt.GetAccessToken(claims.UserName, claims.PassWord, claims.Id)
|
||||||
|
// if err != nil {
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// verifyInfo := system_model.VerifyInformation{}
|
||||||
|
// verifyInfo.AccessToken = newToken
|
||||||
|
// verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.UserName, claims.PassWord, claims.Id)
|
||||||
|
// verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
||||||
|
|
||||||
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo})
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
//******** soon to be removed ********
|
||||||
|
|
||||||
// @Summary 设置用户名和密码
|
// @Summary 设置用户名和密码
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
@@ -29,189 +709,27 @@ func init() {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/setusernamepwd [post]
|
// @Router /user/setusernamepwd [post]
|
||||||
func Set_Name_Pwd(c *gin.Context) {
|
func Set_Name_Pwd(c *gin.Context) {
|
||||||
//json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
//c.BindJSON(&json)
|
c.BindJSON(&json)
|
||||||
username := c.PostForm("username")
|
username := json["username"]
|
||||||
pwd := c.PostForm("pwd")
|
pwd := json["pwd"]
|
||||||
//老用户名是否存在即新用户名和密码的验证
|
if service.MyService.User().GetUserCount() > 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: common_err.ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//开始设置
|
user := model2.UserDBModel{}
|
||||||
err := user_service.SetUser(username, pwd, "", "", "")
|
user.UserName = username
|
||||||
if err != nil {
|
user.Password = encryption.GetMD5ByStr(pwd)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: fmt.Sprintf("%v", err)})
|
user.Role = "admin"
|
||||||
return
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 登录
|
user = service.MyService.User().CreateUser(user)
|
||||||
// @Produce application/json
|
if user.Id == 0 {
|
||||||
// @Accept multipart/form-data
|
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
||||||
// @Tags user
|
|
||||||
// @Param username formData string true "User name"
|
|
||||||
// @Param pwd formData string true "password"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/login [post]
|
|
||||||
func Login(c *gin.Context) {
|
|
||||||
username := c.PostForm("username")
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
//检查参数是否正确
|
|
||||||
if len(username) == 0 || len(pwd) == 0 {
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.ERROR,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
|
||||||
|
|
||||||
if config.UserInfo.UserName == username && config.UserInfo.PWD == pwd {
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
//if username == "admin" && pwd == "admin" {
|
|
||||||
|
|
||||||
data := make(map[string]string, 2)
|
|
||||||
data["token"] = jwt2.GetToken(username, pwd)
|
|
||||||
data["version"] = types.CURRENTVERSION
|
|
||||||
//user_service.SetUser("", "", token, "", "")
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: data,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.ERROR,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.ERROR),
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 修改头像
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags user
|
|
||||||
// @Param file formData file true "用户头像"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/changhead [post]
|
|
||||||
func Up_Load_Head(c *gin.Context) {
|
|
||||||
file, _, _ := c.Request.FormFile("file")
|
|
||||||
user_service.UpLoadFile(file, config.UserInfo.Head)
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: config.UserInfo.Head,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改用户名
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags user
|
|
||||||
// @Param username formData string true "User name"
|
|
||||||
// @Param oldname formData string true "Old user name"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/changusername [put]
|
|
||||||
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")
|
|
||||||
username := c.PostForm("username")
|
|
||||||
if len(username) == 0 || config.UserInfo.UserName != oldname {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user_service.SetUser(username, "", "", "", "")
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改密码
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags user
|
|
||||||
// @Param pwd formData string true "Password"
|
|
||||||
// @Param oldpwd formData string true "Old password"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/changuserpwd [put]
|
|
||||||
func Chang_User_Pwd(c *gin.Context) {
|
|
||||||
oldpwd := c.PostForm("oldpwd")
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
if config.UserInfo.PWD != oldpwd {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
user_service.SetUser("", pwd, "", "", "")
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改用户信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags user
|
|
||||||
// @Param username formData string false "User Name"
|
|
||||||
// @Param email formData string false "Email"
|
|
||||||
// @Param description formData string false "Description"
|
|
||||||
// @Param pwd formData string false "Password"
|
|
||||||
// @Param oldpwd formData string false "Old password"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/changuserinfo [post]
|
|
||||||
func Chang_User_Info(c *gin.Context) {
|
|
||||||
username := c.PostForm("username")
|
|
||||||
email := c.PostForm("email")
|
|
||||||
description := c.PostForm("description")
|
|
||||||
oldpwd := c.PostForm("oldpwd")
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
if len(pwd) > 0 && config.UserInfo.PWD != oldpwd {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_INVALID, Message: oasis_err2.GetMsg(oasis_err2.PWD_INVALID)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user_service.SetUser(username, pwd, "", email, description)
|
|
||||||
data := make(map[string]string, 2)
|
|
||||||
|
|
||||||
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 获取用户详情
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept mapplication/json
|
|
||||||
// @Tags user
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/info [get]
|
|
||||||
func UserInfo(c *gin.Context) {
|
|
||||||
var u = make(map[string]string, 2)
|
|
||||||
u["user_name"] = config.UserInfo.UserName
|
|
||||||
u["head"] = config.UserInfo.Head
|
|
||||||
u["email"] = config.UserInfo.Email
|
|
||||||
u["description"] = config.UserInfo.Description
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: oasis_err2.SUCCESS,
|
|
||||||
Message: oasis_err2.GetMsg(oasis_err2.SUCCESS),
|
|
||||||
Data: u,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,459 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
json2 "encoding/json"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 登录zerotier获取token
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Param username formData string true "User name"
|
|
||||||
// @Param pwd formData string true "password"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/login [post]
|
|
||||||
func ZeroTierGetToken(c *gin.Context) {
|
|
||||||
username := c.PostForm("username")
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
if len(username) == 0 || len(pwd) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
errInfo := service.MyService.ZeroTier().GetToken(username, pwd)
|
|
||||||
|
|
||||||
if len(errInfo) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.GET_TOKEN_ERROR)})
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 注册zerotier
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Param firstName formData string true "first name"
|
|
||||||
// @Param pwd formData string true "password"
|
|
||||||
// @Param email formData string true "email"
|
|
||||||
// @Param lastName formData string true "last name"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/register [post]
|
|
||||||
func ZeroTierRegister(c *gin.Context) {
|
|
||||||
firstName := c.PostForm("firstName")
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
email := c.PostForm("email")
|
|
||||||
lastName := c.PostForm("lastName")
|
|
||||||
if len(firstName) == 0 || len(pwd) == 0 || len(email) == 0 || len(lastName) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
errInfo := service.MyService.ZeroTier().ZeroTierRegister(email, lastName, firstName, pwd)
|
|
||||||
if len(errInfo) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: errInfo})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 是否需要登录zerotier
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "false:需要登录,true:不需要登录"
|
|
||||||
// @Router /zerotier/islogin [get]
|
|
||||||
func ZeroTierIsNeedLogin(c *gin.Context) {
|
|
||||||
if len(config.ZeroTierInfo.Token) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: false})
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: true})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取zerotier网络列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/list [get]
|
|
||||||
func ZeroTierGetNetworkList(c *gin.Context) {
|
|
||||||
jsonList, joined := service.MyService.ZeroTier().ZeroTierNetworkList(config.ZeroTierInfo.Token)
|
|
||||||
rdata := make(map[string]interface{})
|
|
||||||
rdata["network_list"] = jsonList
|
|
||||||
rdata["joined"] = joined
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: rdata})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取zerotier网络详情
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/info/{id} [get]
|
|
||||||
func ZeroTierGetNetworkGetInfo(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
if len(id) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info, joined := service.MyService.ZeroTier().ZeroTierGetInfo(config.ZeroTierInfo.Token, id)
|
|
||||||
rdata := make(map[string]interface{})
|
|
||||||
rdata["info"] = info
|
|
||||||
rdata["joined"] = joined
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: rdata})
|
|
||||||
}
|
|
||||||
|
|
||||||
//// @Summary 获取zerotier网络状态
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/status [get]
|
|
||||||
//func ZeroTierGetNetworkGetStatus(c *gin.Context) {
|
|
||||||
// status := service.MyService.ZeroTier().ZeroTierGetStatus(config.ZeroTierInfo.Token)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: status})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary 修改网络类型
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param type formData string true "Private true/false"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/type/{id} [put]
|
|
||||||
//func ZeroTierEditType(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// t := c.PostForm("type")
|
|
||||||
// if len(id) == 0 || len(t) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"private":` + t + `}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary 修改名称
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param name formData string true "需要过滤特殊字符串"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/name/{id} [put]
|
|
||||||
//func ZeroTierEditName(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// name := c.PostForm("name")
|
|
||||||
// if len(id) == 0 || len(name) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"name":"` + name + `"}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary V6Assign (注意三个属性需要一起传过来,不传的会被zerotier设置成false)
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param v6plan formData string false "true/false"
|
|
||||||
//// @Param rfc formData string false "true/false"
|
|
||||||
//// @Param auto formData string false "true/false"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/v6assign/{id} [put]
|
|
||||||
//func ZeroTierEditV6Assign(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// v6plan := c.PostForm("v6plan")
|
|
||||||
// rfc := c.PostForm("rfc")
|
|
||||||
// auto := c.PostForm("auto")
|
|
||||||
// if len(id) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// var spicing string
|
|
||||||
// if len(v6plan) > 0 {
|
|
||||||
// spicing = `"6plane":` + v6plan
|
|
||||||
// }
|
|
||||||
// if len(rfc) > 0 {
|
|
||||||
// if len(spicing) > 0 {
|
|
||||||
// spicing += ","
|
|
||||||
// }
|
|
||||||
// spicing += `"rfc4193":` + rfc
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if len(auto) > 0 {
|
|
||||||
// if len(spicing) > 0 {
|
|
||||||
// spicing += ","
|
|
||||||
// }
|
|
||||||
// spicing += `"zt":` + auto
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"v6AssignMode":{` + spicing + `}}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary Broadcast
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param broadcast formData string true "true/false"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/broadcast/{id} [put]
|
|
||||||
//func ZeroTierEditBroadcast(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// broadcast := c.PostForm("broadcast")
|
|
||||||
// if len(id) == 0 || len(broadcast) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"enableBroadcast":` + broadcast + `}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
// @Summary 网络列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/member/{id} [get]
|
|
||||||
func ZeroTierMemberList(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
if len(id) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info := service.MyService.ZeroTier().MemberList(config.ZeroTierInfo.Token, id)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary create new network
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/create [post]
|
|
||||||
func ZeroTierCreateNetwork(c *gin.Context) {
|
|
||||||
info := service.MyService.ZeroTier().CreateNetwork(config.ZeroTierInfo.Token)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
//// @Summary 通过/拒绝客户端
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param mId path string true "member_id"
|
|
||||||
//// @Param auth formData string true "true/false"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/member/{id}/auth/{mId} [put]
|
|
||||||
//func ZeroTierMemberAuth(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// mId := c.Param("mId")
|
|
||||||
// auth := c.PostForm("auth")
|
|
||||||
// if len(id) == 0 || len(mId) == 0 || len(auth) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"authorized":` + auth + `}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary 修改名字
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param mId path string true "member_id"
|
|
||||||
//// @Param name formData string true "name"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/member/{id}/name/{mId} [put]
|
|
||||||
//func ZeroTierMemberName(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// mId := c.Param("mId")
|
|
||||||
// name := c.PostForm("name")
|
|
||||||
// if len(id) == 0 || len(mId) == 0 || len(name) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"name":"` + name + `"}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// @Summary 修改桥接
|
|
||||||
//// @Produce application/json
|
|
||||||
//// @Accept application/json
|
|
||||||
//// @Tags zerotier
|
|
||||||
//// @Security ApiKeyAuth
|
|
||||||
//// @Param id path string true "network id"
|
|
||||||
//// @Param mId path string true "member_id"
|
|
||||||
//// @Param bridge formData string true "true/false"
|
|
||||||
//// @Success 200 {string} string "ok"
|
|
||||||
//// @Router /zerotier/member/{id}/bridge/{mId} [put]
|
|
||||||
//func ZeroTierMemberBridge(c *gin.Context) {
|
|
||||||
// id := c.Param("id")
|
|
||||||
// mId := c.Param("mId")
|
|
||||||
// bridge := c.PostForm("bridge")
|
|
||||||
// if len(id) == 0 || len(mId) == 0 || len(bridge) == 0 {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// postData := `{"config":{"activeBridge":` + bridge + `}}`
|
|
||||||
// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
//}
|
|
||||||
|
|
||||||
// @Summary 修改网络
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Param json formData string true "json数据"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/edit/{id} [put]
|
|
||||||
func ZeroTierEdit(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
json := c.PostForm("json")
|
|
||||||
if len(id) == 0 || len(json) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, json, id)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取已加入的网络
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/joined/list [get]
|
|
||||||
func ZeroTierJoinedList(c *gin.Context) {
|
|
||||||
info := service.MyService.ZeroTier().GetJoinNetworks()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: json2.RawMessage(info)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改网络用户信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Param mId path string true "mId"
|
|
||||||
// @Param json formData string true "json数据"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/member/{id}/edit/{mId} [put]
|
|
||||||
func ZeroTierMemberEdit(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
mId := c.Param("mId")
|
|
||||||
json := c.PostForm("json")
|
|
||||||
if len(id) == 0 || len(json) == 0 || len(mId) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, json, id, mId)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 删除网络中的用户
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Param mId path string true "member_id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/member/{id}/del/{mId} [delete]
|
|
||||||
func ZeroTierMemberDelete(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
mId := c.Param("mId")
|
|
||||||
if len(id) == 0 || len(mId) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info := service.MyService.ZeroTier().DeleteMember(config.ZeroTierInfo.Token, id, mId)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 删除网络
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/network/{id}/del [delete]
|
|
||||||
func ZeroTierDeleteNetwork(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
if len(id) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info := service.MyService.ZeroTier().DeleteNetwork(config.ZeroTierInfo.Token, id)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 加入网络
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/join/{id} [post]
|
|
||||||
func ZeroTierJoinNetwork(c *gin.Context) {
|
|
||||||
networkId := c.Param("id")
|
|
||||||
service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
|
|
||||||
if len(networkId) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取zerotier网络列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags zerotier
|
|
||||||
// @Param id path string true "network id"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zerotier/leave/{id} [post]
|
|
||||||
func ZeroTierLeaveNetwork(c *gin.Context) {
|
|
||||||
networkId := c.Param("id")
|
|
||||||
service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)
|
|
||||||
if len(networkId) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 获取cpu信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zima
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zima/getcpuinfo [get]
|
|
||||||
func CupInfo(c *gin.Context) {
|
|
||||||
//检查参数是否正确
|
|
||||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
|
||||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
|
||||||
data := make(map[string]interface{})
|
|
||||||
data["percent"] = cpu
|
|
||||||
data["num"] = num
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取内存信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zima
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zima/getmeminfo [get]
|
|
||||||
func MemInfo(c *gin.Context) {
|
|
||||||
|
|
||||||
//检查参数是否正确
|
|
||||||
mem := service.MyService.ZiMa().GetMemInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: mem})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取硬盘信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zima
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zima/getdiskinfo [get]
|
|
||||||
func DiskInfo(c *gin.Context) {
|
|
||||||
disk := service.MyService.ZiMa().GetDiskInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: disk})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取网络信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zima
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zima/getnetinfo [get]
|
|
||||||
func NetInfo(c *gin.Context) {
|
|
||||||
netList := service.MyService.ZiMa().GetNetInfo()
|
|
||||||
|
|
||||||
newNet := []model.IOCountersStat{}
|
|
||||||
for _, n := range netList {
|
|
||||||
for _, netCardName := range service.MyService.ZiMa().GetNet(true) {
|
|
||||||
if n.Name == netCardName {
|
|
||||||
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
|
||||||
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
|
|
||||||
item.DateTime = time.Now()
|
|
||||||
newNet = append(newNet, item)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: newNet})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取信息系统信息
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags zima
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /zima/sysinfo [get]
|
|
||||||
func SysInfo(c *gin.Context) {
|
|
||||||
info := service.MyService.ZiMa().GetSysInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
|
|
||||||
}
|
|
||||||
348
service/app.go
348
service/app.go
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -13,159 +14,263 @@ import (
|
|||||||
"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/command"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
"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"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
|
"go.uber.org/zap"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppService interface {
|
type AppService interface {
|
||||||
GetMyList(index, size int, position bool) *[]model2.MyAppList
|
GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList)
|
||||||
SaveContainer(m model2.AppListDBModel)
|
SaveContainer(m model2.AppListDBModel)
|
||||||
GetUninstallInfo(id string) model2.AppListDBModel
|
GetUninstallInfo(id string) model2.AppListDBModel
|
||||||
RemoveContainerById(id string)
|
DeleteApp(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(path string)
|
DelAppConfigDir(path string)
|
||||||
GetSystemAppList() *[]model2.MyAppList
|
GetSystemAppList() []types.Container
|
||||||
GetHardwareUsageSteam()
|
GetHardwareUsageSteam()
|
||||||
GetHardwareUsage() []model.DockerStatsModel
|
GetHardwareUsage() []model.DockerStatsModel
|
||||||
GetAppStats(id string) string
|
GetAppStats(id string) string
|
||||||
|
GetAllDBApps() []model2.AppListDBModel
|
||||||
|
ImportApplications(casaApp bool)
|
||||||
|
CheckNewImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
type appStruct struct {
|
type appStruct struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
log loger2.OLog
|
}
|
||||||
|
|
||||||
|
func (a *appStruct) CheckNewImage() {
|
||||||
|
list := MyService.Docker().DockerContainerList()
|
||||||
|
for _, v := range list {
|
||||||
|
inspect, err := MyService.Docker().DockerImageInfo(strings.Split(v.Image, ":")[0])
|
||||||
|
if err != nil {
|
||||||
|
NewVersionApp[v.ID] = inspect.ID
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if inspect.ID == v.ImageID {
|
||||||
|
delete(NewVersionApp, v.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
NewVersionApp[v.ID] = inspect.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
func (a *appStruct) ImportApplications(casaApp bool) {
|
||||||
|
if casaApp {
|
||||||
|
list := MyService.App().GetAllDBApps()
|
||||||
|
for _, app := range list {
|
||||||
|
info, err := MyService.Docker().DockerContainerInfo(app.CustomId)
|
||||||
|
if err != nil {
|
||||||
|
MyService.App().DeleteApp(app.CustomId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//info.NetworkSettings
|
||||||
|
info.Config.Labels["casaos"] = "casaos"
|
||||||
|
info.Config.Labels["web"] = app.PortMap
|
||||||
|
info.Config.Labels["icon"] = app.Icon
|
||||||
|
info.Config.Labels["desc"] = app.Description
|
||||||
|
info.Config.Labels["index"] = app.Index
|
||||||
|
info.Config.Labels["custom_id"] = app.CustomId
|
||||||
|
info.Name = app.Title
|
||||||
|
container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
MyService.App().DeleteApp(app.CustomId)
|
||||||
|
MyService.Docker().DockerContainerStop(app.CustomId)
|
||||||
|
MyService.Docker().DockerContainerRemove(app.CustomId, false)
|
||||||
|
MyService.Docker().DockerContainerStart(container_id)
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list := MyService.Docker().DockerContainerList()
|
||||||
|
for _, app := range list {
|
||||||
|
info, err := MyService.Docker().DockerContainerInfo(app.ID)
|
||||||
|
if err != nil || info.Config.Labels["casaos"] == "casaos" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
info.Config.Labels["casaos"] = "casaos"
|
||||||
|
info.Config.Labels["web"] = ""
|
||||||
|
info.Config.Labels["icon"] = ""
|
||||||
|
info.Config.Labels["desc"] = ""
|
||||||
|
info.Config.Labels["index"] = ""
|
||||||
|
info.Config.Labels["custom_id"] = uuid.NewV4().String()
|
||||||
|
|
||||||
|
_, err = MyService.Docker().DockerContainerCopyCreate(info)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allcontainer := MyService.Docker().DockerContainerList()
|
||||||
|
// for _, app := range allcontainer {
|
||||||
|
// info, err := MyService.Docker().DockerContainerInfo(app.ID)
|
||||||
|
// if err != nil {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// MyService.Docker().DockerContainerStop(app.ID)
|
||||||
|
// MyService.Docker().DockerContainerRemove(app.ID, false)
|
||||||
|
// //info.NetworkSettings
|
||||||
|
// info.Config.Labels["custom_id"] = uuid.NewV4().String()
|
||||||
|
// container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// MyService.Docker().DockerContainerStart(container_id)
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取我的应用列表
|
//获取我的应用列表
|
||||||
func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppList {
|
func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList) {
|
||||||
//获取docker应用
|
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
|
cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
|
loger.Error("Failed to init client", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
fts := filters.NewArgs()
|
// fts := filters.NewArgs()
|
||||||
fts.Add("label", "origin")
|
// fts.Add("label", "casaos=casaos")
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
//fts.Add("label", "casaos")
|
||||||
|
//fts.Add("casaos", "casaos")
|
||||||
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
//获取本地数据库应用
|
//获取本地数据库应用
|
||||||
|
|
||||||
var lm []model2.AppListDBModel
|
unTranslation := []model2.MyAppList{}
|
||||||
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{})
|
|
||||||
for _, dbModel := range lm {
|
|
||||||
if position {
|
|
||||||
if dbModel.Position {
|
|
||||||
lMap[dbModel.ContainerId] = dbModel
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lMap[dbModel.ContainerId] = dbModel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, container := range containers {
|
|
||||||
|
|
||||||
if lMap[container.ID] != nil && container.Labels["origin"] != "system" {
|
for _, m := range containers {
|
||||||
m := lMap[container.ID].(model2.AppListDBModel)
|
if m.Labels["casaos"] == "casaos" {
|
||||||
if len(m.Label) == 0 {
|
if m.Labels["origin"] == "system" {
|
||||||
m.Label = m.Title
|
continue
|
||||||
}
|
}
|
||||||
|
_, newVersion := NewVersionApp[m.ID]
|
||||||
// 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{
|
list = append(list, model2.MyAppList{
|
||||||
Name: m.Label,
|
Name: strings.ReplaceAll(m.Names[0], "/", ""),
|
||||||
Icon: m.Icon,
|
Icon: m.Labels["icon"],
|
||||||
State: container.State,
|
State: m.State,
|
||||||
CustomId: strings.ReplaceAll(container.Names[0], "/", ""),
|
CustomId: m.Labels["custom_id"],
|
||||||
Port: m.PortMap,
|
Id: m.ID,
|
||||||
Index: m.Index,
|
Port: m.Labels["web"],
|
||||||
//UpTime: tm,
|
Index: m.Labels["index"],
|
||||||
Image: m.Image,
|
//Order: m.Labels["order"],
|
||||||
Slogan: m.Slogan,
|
Image: m.Image,
|
||||||
|
NewVersion: newVersion,
|
||||||
|
Type: m.Labels["origin"],
|
||||||
|
//Slogan: m.Slogan,
|
||||||
//Rely: m.Rely,
|
//Rely: m.Rely,
|
||||||
|
Host: m.Labels["host"],
|
||||||
|
Protocol: m.Labels["protocol"],
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
unTranslation = append(unTranslation, model2.MyAppList{
|
||||||
|
Name: strings.ReplaceAll(m.Names[0], "/", ""),
|
||||||
|
Icon: "",
|
||||||
|
State: m.State,
|
||||||
|
CustomId: m.ID,
|
||||||
|
Id: m.ID,
|
||||||
|
Port: "",
|
||||||
|
NewVersion: false,
|
||||||
|
Host: "",
|
||||||
|
Protocol: "",
|
||||||
|
Image: m.Image,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &list
|
//lMap := make(map[string]interface{})
|
||||||
|
// for _, dbModel := range lm {
|
||||||
|
// if position {
|
||||||
|
// if dbModel.Position {
|
||||||
|
// lMap[dbModel.ContainerId] = dbModel
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// lMap[dbModel.ContainerId] = dbModel
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// for _, container := range containers {
|
||||||
|
|
||||||
|
// if lMap[container.ID] != nil && container.Labels["origin"] != "system" {
|
||||||
|
// 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,
|
||||||
|
// //Rely: m.Rely,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
return &list, &unTranslation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//system application list
|
//system application list
|
||||||
func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
|
func (a *appStruct) GetSystemAppList() []types.Container {
|
||||||
//获取docker应用
|
//获取docker应用
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
|
loger.Error("Failed to init client", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
fts := filters.NewArgs()
|
fts := filters.NewArgs()
|
||||||
fts.Add("label", "origin=system")
|
fts.Add("label", "origin=system")
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("获取docker容器失败", "app.sys", "line:123", err)
|
loger.Error("Failed to get container_list", zap.Any("err", 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
|
||||||
|
// }
|
||||||
|
|
||||||
|
return containers
|
||||||
|
|
||||||
|
}
|
||||||
|
func (a *appStruct) GetAllDBApps() []model2.AppListDBModel {
|
||||||
var lm []model2.AppListDBModel
|
var lm []model2.AppListDBModel
|
||||||
a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
|
a.db.Table(model2.CONTAINERTABLENAME).Select("custom_id,title,icon,container_id,label,slogan,image,port_map").Find(&lm)
|
||||||
|
return 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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取我的应用列表
|
//获取我的应用列表
|
||||||
@@ -173,13 +278,13 @@ func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
|||||||
//获取docker应用
|
//获取docker应用
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
|
loger.Error("Failed to init client", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
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 {
|
if err != nil {
|
||||||
a.log.Error("获取docker容器失败", "app.getcontainerinfo", "line:182", err)
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(containers) > 0 {
|
if len(containers) > 0 {
|
||||||
@@ -233,10 +338,10 @@ func (a *appStruct) UpdateApp(m model2.AppListDBModel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *appStruct) DelAppConfigDir(path string) {
|
func (a *appStruct) DelAppConfigDir(path string) {
|
||||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;DelAppConfigDir " + path)
|
command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;DelAppConfigDir " + path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appStruct) RemoveContainerById(id string) {
|
func (a *appStruct) DeleteApp(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{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,31 +397,33 @@ func (a *appStruct) GetHardwareUsageSteam() {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
var lm []model2.AppListDBModel
|
fts := filters.NewArgs()
|
||||||
a.db.Table(model2.CONTAINERTABLENAME).Select("label,title,icon,container_id").Where("origin != ?", "system").Find(&lm)
|
fts.Add("label", "casaos=casaos")
|
||||||
|
//fts.Add("status", "running")
|
||||||
|
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
if config.CasaOSGlobalVariables.AppChange {
|
if config.CasaOSGlobalVariables.AppChange {
|
||||||
lm = []model2.AppListDBModel{}
|
|
||||||
config.CasaOSGlobalVariables.AppChange = false
|
config.CasaOSGlobalVariables.AppChange = false
|
||||||
a.db.Table(model2.CONTAINERTABLENAME).Select("label,title,icon,container_id").Where("origin != ?", "system").Find(&lm)
|
|
||||||
dataApps := dataStats
|
|
||||||
dataStats.Range(func(key, value interface{}) bool {
|
dataStats.Range(func(key, value interface{}) bool {
|
||||||
dataStats.Delete(key)
|
dataStats.Delete(key)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
for _, v := range lm {
|
|
||||||
m, _ := dataApps.Load(v.ContainerId)
|
|
||||||
if m != nil {
|
|
||||||
dataStats.Store(v.ContainerId, m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||||
|
if err != nil {
|
||||||
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
|
}
|
||||||
|
var temp sync.Map
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, v := range lm {
|
for _, v := range containers {
|
||||||
|
if v.State != "running" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(v model2.AppListDBModel, i int) {
|
go func(v types.Container, i int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
stats, err := cli.ContainerStats(ctx, v.ContainerId, true)
|
stats, err := cli.ContainerStats(ctx, v.ID, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -325,32 +432,31 @@ func (a *appStruct) GetHardwareUsageSteam() {
|
|||||||
if err := decode.Decode(&data); err == io.EOF {
|
if err := decode.Decode(&data); err == io.EOF {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m, _ := dataStats.Load(v.ContainerId)
|
m, _ := dataStats.Load(v.ID)
|
||||||
dockerStats := model.DockerStatsModel{}
|
dockerStats := model.DockerStatsModel{}
|
||||||
if m != nil {
|
if m != nil {
|
||||||
dockerStats.Pre = m.(model.DockerStatsModel).Data
|
dockerStats.Pre = m.(model.DockerStatsModel).Data
|
||||||
}
|
}
|
||||||
dockerStats.Data = data
|
dockerStats.Data = data
|
||||||
dockerStats.Icon = v.Icon
|
dockerStats.Icon = v.Labels["icon"]
|
||||||
if len(v.Label) > 0 {
|
dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
|
||||||
dockerStats.Title = v.Label
|
|
||||||
} else {
|
temp.Store(v.ID, dockerStats)
|
||||||
dockerStats.Title = v.Title
|
|
||||||
}
|
|
||||||
dataStats.Store(v.ContainerId, dockerStats)
|
|
||||||
if i == 99 {
|
if i == 99 {
|
||||||
stats.Body.Close()
|
stats.Body.Close()
|
||||||
}
|
}
|
||||||
}(v, i)
|
}(v, i)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
dataStats = temp
|
||||||
isFinish = true
|
isFinish = true
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
}
|
}
|
||||||
isFinish = false
|
isFinish = false
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAppService(db *gorm.DB, logger loger2.OLog) AppService {
|
func NewAppService(db *gorm.DB) AppService {
|
||||||
return &appStruct{db: db, log: logger}
|
return &appStruct{db: db}
|
||||||
}
|
}
|
||||||
|
|||||||
9
service/app_test.go
Normal file
9
service/app_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetCasaOSCount(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user