From 33acfababda52913261e5560ea23ed2b47e17f42 Mon Sep 17 00:00:00 2001 From: link Date: Wed, 9 Mar 2022 16:37:03 +0800 Subject: [PATCH] new file manager 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. --- UI | 2 +- conf/conf.ini.sample | 1 + go.mod | 1 + go.sum | 137 +++++++- main.go | 4 +- model/app-analyse.go | 8 + model/person.go | 15 +- model/sys_common.go | 1 + model/zima.go | 2 + pkg/sqlite/db.go | 2 +- pkg/utils/file/block.go | 41 ++- pkg/utils/file/file.go | 99 +++++- route/init.go | 2 +- route/route.go | 20 +- route/v1/analyse.go | 38 +++ route/v1/app.go | 8 +- route/v1/docker.go | 2 +- route/v1/file.go | 136 +++++++- route/v1/persion.go | 48 +++ service/app.go | 6 + service/casa.go | 23 +- service/data_ handling.go | 1 + service/disk.go | 4 +- service/model/o_download.go | 24 ++ service/person.go | 632 ++++++++++++++++++++++-------------- service/service.go | 12 +- service/socket.go | 3 - service/udpconn.go | 168 ++++++++++ shell/helper.sh | 4 +- types/persion_download.go | 9 + types/system.go | 4 +- 31 files changed, 1162 insertions(+), 295 deletions(-) create mode 100644 model/app-analyse.go create mode 100644 route/v1/analyse.go create mode 100644 service/data_ handling.go create mode 100644 service/model/o_download.go create mode 100644 service/udpconn.go create mode 100644 types/persion_download.go diff --git a/UI b/UI index 106902c..ebaf4b2 160000 --- a/UI +++ b/UI @@ -1 +1 @@ -Subproject commit 106902c76a48d3502bb7365d49573023edabc4a2 +Subproject commit ebaf4b2fc6b4cf416fff197629dc0f8f02cf3b31 diff --git a/conf/conf.ini.sample b/conf/conf.ini.sample index 38a7a11..9479a6b 100644 --- a/conf/conf.ini.sample +++ b/conf/conf.ini.sample @@ -41,4 +41,5 @@ IdleTimeout = 200 [system] ConfigStr = WidgetList = +Analyse = diff --git a/go.mod b/go.mod index 885c9b4..4d293b4 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/json-iterator/go v1.1.11 // indirect github.com/klauspost/compress v1.13.6 // 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/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-sqlite3 v1.14.11 // indirect diff --git a/go.sum b/go.sum index bd62674..2043428 100644 --- a/go.sum +++ b/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-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.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.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= 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.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.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 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/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/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= @@ -94,6 +101,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF 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/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +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/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= @@ -110,8 +118,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.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/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/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/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= @@ -120,6 +130,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/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/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/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -233,6 +245,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-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-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/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= @@ -259,7 +272,6 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 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 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.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY= github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -291,11 +303,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/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/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/go.mod h1:EfR6AU78zUiZ36oVS5YrmTzc2um3zDXWPx4L4st++jo= 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/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/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= @@ -313,6 +328,8 @@ 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.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA= 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-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-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -362,6 +379,8 @@ 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/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= 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-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= @@ -389,6 +408,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-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 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.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -396,6 +416,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.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.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.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -430,6 +452,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.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 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/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= @@ -452,6 +476,8 @@ 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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 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.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= @@ -469,6 +495,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.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/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.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -488,11 +515,11 @@ 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/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/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= 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/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/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= 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= @@ -530,6 +557,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/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -537,8 +565,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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 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/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-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -546,6 +578,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/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 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-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -555,13 +595,12 @@ 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-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-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= -github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9/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.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +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/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= @@ -590,8 +629,12 @@ 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/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/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/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/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= @@ -601,11 +644,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.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.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-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.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.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-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -613,7 +663,6 @@ 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/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 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.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= @@ -637,6 +686,7 @@ 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.5 h1:OkT6bMHOQ1JQQO4ihjQ49sj0+wciDcjziSVTRn8VeTA= 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/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -653,6 +703,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/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.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.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -664,12 +715,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.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-20180801064454-c7de2306084e/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.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.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-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-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -688,15 +741,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 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/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/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/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 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/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= 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/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.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -713,6 +790,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/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 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/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -749,6 +828,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-20180916011248-d98352740cb2/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/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -780,6 +860,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb 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/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 v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -797,6 +879,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= @@ -806,6 +889,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/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.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.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -818,15 +902,20 @@ go.uber.org/atomic v1.3.2/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/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 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-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-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-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-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-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-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-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -845,6 +934,7 @@ 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/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/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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -872,11 +962,14 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r 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-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-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-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-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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -901,6 +994,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ 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-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-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -913,16 +1007,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-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-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-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-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-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-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/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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -938,12 +1036,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-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-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-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-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-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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -987,6 +1087,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-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-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-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1002,6 +1103,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-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-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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1039,7 +1141,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/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-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-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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1086,8 +1190,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-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-20201224043029-2b0845dc783e/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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1096,6 +1202,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/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-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.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1113,6 +1222,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.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1122,6 +1233,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/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-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-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1157,6 +1272,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/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 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.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1215,6 +1333,7 @@ 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.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/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/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= @@ -1230,12 +1349,8 @@ 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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 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.1.5/go.mod h1:NpaYMcVKEh6vLJ47VP6T7Weieu4H1Drs3dGD/K6GrGc= gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4= 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.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.22.3/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= @@ -1244,6 +1359,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 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/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1285,3 +1402,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/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 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= diff --git a/main.go b/main.go index 2d52867..17b1c99 100644 --- a/main.go +++ b/main.go @@ -32,10 +32,8 @@ func init() { //gredis.GetRedisConn(config.RedisInfo), service.MyService = service.NewService(sqliteDB, loger2.NewOLoger()) service.Cache = cache.Init() + //go service.UDPConnect([]string{}) //go service.SocketConnect() - //go service.TestTCP() - //go service.TestTCPOne() - go service.TestTCPTwo() route.InitFunction() } diff --git a/model/app-analyse.go b/model/app-analyse.go new file mode 100644 index 0000000..1a249ac --- /dev/null +++ b/model/app-analyse.go @@ -0,0 +1,8 @@ +package model + +type AppAnalyse struct { + Name string `json:"name"` + Type string `json:"type"` + UUId string `json:"uuid"` + Language string `json:"language"` +} diff --git a/model/person.go b/model/person.go index d9f5ad2..cf39af1 100644 --- a/model/person.go +++ b/model/person.go @@ -22,17 +22,26 @@ type MessageModel struct { 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 - Data []byte `json:"data"` - Index int `json:"index"` + 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"` Path string `json:"path"` BlockSize int `json:"block_size"` + Length int `json:"length"` + Size int64 `json:"size"` } diff --git a/model/sys_common.go b/model/sys_common.go index e4e496e..504dd80 100644 --- a/model/sys_common.go +++ b/model/sys_common.go @@ -69,6 +69,7 @@ type SystemConfig struct { ConfigPath string `json:"config_path"` SyncPort string `json:"sync_port"` SyncKey string `json:"sync_key"` + Analyse string `json:"analyse"` } type CasaOSGlobalVariables struct { diff --git a/model/zima.go b/model/zima.go index 656aa3d..dafaa43 100644 --- a/model/zima.go +++ b/model/zima.go @@ -8,4 +8,6 @@ type Path struct { IsDir bool `json:"is_dir"` Date time.Time `json:"date"` Size int64 `json:"size"` + Type string `json:"type,omitempty"` + Label string `json:"label,omitempty"` } diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index dcbaf10..565408d 100644 --- a/pkg/sqlite/db.go +++ b/pkg/sqlite/db.go @@ -31,7 +31,7 @@ func GetDb(projectPath string) *gorm.DB { return nil } gdb = db - err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}) + err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersionDownloadDBModel{}) if err != nil { fmt.Println("检查和创建数据库出错", err) } diff --git a/pkg/utils/file/block.go b/pkg/utils/file/block.go index 45f0b6e..bbe568c 100644 --- a/pkg/utils/file/block.go +++ b/pkg/utils/file/block.go @@ -3,11 +3,14 @@ package file import ( "crypto/md5" "encoding/hex" + "io" "math" + "os" + "strconv" ) // Get info of block -func GetBlockInfo(fileSize int) (blockSize int, length int) { +func GetBlockInfo(fileSize int64) (blockSize int, length int) { switch { case fileSize <= 1<<28: //256M blockSize = 1 << 17 //128kb @@ -32,13 +35,47 @@ func GetBlockInfo(fileSize int) (blockSize int, length int) { } //get the hash of the data -func GetHash(data []byte) string { +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'} + bSize := strconv.Itoa(byteLength) + cha := 4 - 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 +} diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index a298017..bf89988 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -1,12 +1,15 @@ package file import ( + "bufio" "fmt" "io" "io/ioutil" "mime/multipart" "os" "path" + "strconv" + "strings" ) // GetSize get the file size @@ -137,6 +140,21 @@ func CreateFile(path string) error { 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 func IsNotExistCreateFile(src string) error { if notExist := CheckNotExist(src); notExist == true { @@ -168,6 +186,27 @@ func CopyFile(src, dst string) error { var dstfd *os.File var srcinfo os.FileInfo + lastPath := src[strings.LastIndex(src, "/")+1:] + + if !strings.HasSuffix(dst, "/") { + dst += "/" + } + dstPath := dst + dst += lastPath + for i := 0; Exists(dst); i++ { + name := strings.Split(lastPath, ".") + nameIndex := 0 + if len(name) > 2 { + nameIndex = len(name) - 2 + } + name[nameIndex] = name[nameIndex] + strconv.Itoa(i+1) + dst = dstPath + for _, v := range name { + dst += v + "." + } + dst = strings.TrimSuffix(dst, ".") + } + if srcfd, err = os.Open(src); err != nil { return err } @@ -202,16 +241,21 @@ func CopyDir(src string, dst string) error { } 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 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 := path.Join(dst, fd.Name()) + dstfp := dst //path.Join(dst, fd.Name()) if fd.IsDir() { if err = CopyDir(srcfp, dstfp); err != nil { @@ -225,3 +269,54 @@ func CopyDir(src string, dst string) error { } 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) 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; i++ { + data, err := ioutil.ReadFile(path + strconv.Itoa(i)) + if err != nil { + return err + } + _, err = bufferedWriter.Write(data) + if err != nil { + return err + } + } + + bufferedWriter.Flush() + + return nil +} diff --git a/route/init.go b/route/init.go index 763c0cd..e18c0f6 100644 --- a/route/init.go +++ b/route/init.go @@ -37,7 +37,7 @@ func installSyncthing(appId string) { m := model.CustomizationPostData{} var dockerImage string var dockerImageVersion string - appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system", "us_en") + appInfo = service.MyService.Casa().GetServerAppInfo(appId, "system", "us_en") dockerImage = appInfo.Image dockerImageVersion = appInfo.ImageVersion diff --git a/route/route.go b/route/route.go index f9ae0e1..7172ca8 100644 --- a/route/route.go +++ b/route/route.go @@ -207,6 +207,7 @@ func InitRouter() *gin.Engine { v1FileGroup.PUT("/rename", v1.RenamePath) v1FileGroup.GET("/read", v1.GetFilerContent) v1FileGroup.POST("/upload", v1.PostFileUpload) + v1FileGroup.GET("/upload", v1.GetFileUpload) v1FileGroup.GET("/dirpath", v1.DirPath) //create folder v1FileGroup.POST("/mkdir", v1.MkdirAll) @@ -214,7 +215,9 @@ func InitRouter() *gin.Engine { v1FileGroup.GET("/download", v1.GetDownloadFile) v1FileGroup.POST("/operate", v1.PostOperateFileOrDir) - v1FileGroup.DELETE("delete", v1.DeleteFile) + v1FileGroup.DELETE("/delete", v1.DeleteFile) + v1FileGroup.PUT("/update", v1.PutFileContent) + //v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) } v1DiskGroup := v1Group.Group("/disk") @@ -287,7 +290,20 @@ func InitRouter() *gin.Engine { v1PersonGroup := v1Group.Group("/persion") v1PersonGroup.Use() { - v1PersonGroup.GET("/test", v1.PersonTest) + // v1PersonGroup.GET("/test", v1.PersonTest) + // v1PersonGroup.GET("/users", v1.Users) //用户列表 + // v1PersonGroup.POST("/user", v1.Users) //添加用户 + // v1PersonGroup.GET("/directory", v1.Users) //文件列表 + v1PersonGroup.GET("/download", v1.GetPersionFile) //下载文件 + // v1PersonGroup.PUT("/edit/:id", v1.EditUser) //修改好友 + v1PersonGroup.GET("/list", v1.GetPersionDownloadList) //下载列表(需要考虑试试下载速度) + // v1PersonGroup.PUT("/state/:id", v1.PutPersionCancelDownload) //修改下载状态(开始暂停删除) + + } + v1AnalyseGroup := v1Group.Group("/analyse") + v1AnalyseGroup.Use() + { + v1AnalyseGroup.POST("/app", v1.PostAppAnalyse) } v1Group.GET("/sync/config", v1.GetSyncConfig) v1Group.Any("/syncthing/*url", v1.SyncToSyncthing) diff --git a/route/v1/analyse.go b/route/v1/analyse.go new file mode 100644 index 0000000..e054b74 --- /dev/null +++ b/route/v1/analyse.go @@ -0,0 +1,38 @@ +package v1 + +import ( + "net/http" + + "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" +) + +// @Summary post app analyse +// @Produce application/json +// @Accept multipart/form-data +// @Tags analyse +// @Param name formData string true "app name" +// @Param type formData string true "action" Enums(open,delete) +// @Security ApiKeyAuth +// @Success 200 {string} string "ok" +// @Router /analyse/app [post] +func PostAppAnalyse(c *gin.Context) { + if config.SystemConfigInfo.Analyse == "False" { + c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) + return + } + name := c.PostForm("name") + t := c.PostForm("type") + language := c.GetHeader("Language") + + if len(name) == 0 || len(t) == 0 { + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)}) + return + } + + service.MyService.Casa().PushAppAnalyse(config.ServerInfo.Token, t, name, language) + c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) +} diff --git a/route/v1/app.go b/route/v1/app.go index 6103802..6b2425b 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -36,7 +36,7 @@ func AppList(c *gin.Context) { categoryId := c.DefaultQuery("category_id", "0") key := c.DefaultQuery("key", "") language := c.GetHeader("Language") - recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key, language) + recommend, list, community := service.MyService.Casa().GetServerList(index, size, t, categoryId, key, language) // for i := 0; i < len(recommend); i++ { // ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion) // if ct != nil { @@ -139,7 +139,7 @@ func AppInfo(c *gin.Context) { id := c.Param("id") language := c.GetHeader("Language") - info := service.MyService.OAPI().GetServerAppInfo(id, "", language) + info := service.MyService.Casa().GetServerAppInfo(id, "", language) if info.NetworkModel != "host" { for i := 0; i < len(info.Ports); i++ { if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) { @@ -217,7 +217,7 @@ func AppInfo(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /app/category [get] func CategoryList(c *gin.Context) { - list := service.MyService.OAPI().GetServerCategoryList() + list := service.MyService.Casa().GetServerCategoryList() var count uint = 0 for _, category := range list { count += category.Count @@ -238,7 +238,7 @@ func CategoryList(c *gin.Context) { // @Router /app/share [post] func ShareAppFile(c *gin.Context) { 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)) } diff --git a/route/v1/docker.go b/route/v1/docker.go index e0c49d6..7906cd2 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -176,7 +176,7 @@ func InstallApp(c *gin.Context) { dockerImageVersion = "latest" } if m.Origin != "custom" { - appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "", language) + appInfo = service.MyService.Casa().GetServerAppInfo(appId, "", language) } else { diff --git a/route/v1/file.go b/route/v1/file.go index ef2f1bf..0a5c83a 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path" + "strconv" "strings" "github.com/IceWhaleTech/CasaOS/model" @@ -177,6 +178,46 @@ func GetDownloadFile(c *gin.Context) { func DirPath(c *gin.Context) { path := c.DefaultQuery("path", "") info := service.MyService.ZiMa().GetDirPath(path) + if path == "/DATA/AppData" { + list := service.MyService.App().GetAllDBApps() + apps := make(map[string]string, len(list)) + for _, v := range list { + apps[v.CustomId] = v.Label + } + 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 + } + } + } + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info}) } @@ -219,7 +260,7 @@ func MkdirAll(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)}) } -// @Summary 创建文件 +// @Summary create file // @Produce application/json // @Accept multipart/form-data // @Tags file @@ -238,6 +279,45 @@ func PostCreateFile(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)}) } +// @Summary upload file +// @Produce application/json +// @Accept multipart/form-data +// @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") + size, _ := strconv.ParseInt(c.Query("totalSize"), 10, 64) + path := c.Query("path") + if fileName != relative { + dirPath := strings.TrimSuffix(relative, fileName) + file.MkDir(path + "/" + dirPath) + } + path += "/" + relative + + if !file.CheckNotExist(path) { + f, _ := os.Stat(path) + + if f.Size() == size { + + c.JSON(200, model.Result{Success: 200, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)}) + return + } + + os.Remove(path) + c.JSON(204, model.Result{Success: 204, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) + return + + } + + c.JSON(204, model.Result{Success: 204, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) +} + // @Summary upload file // @Produce application/json // @Accept multipart/form-data @@ -249,20 +329,32 @@ func PostCreateFile(c *gin.Context) { // @Router /file/upload [post] func PostFileUpload(c *gin.Context) { f, _, _ := c.Request.FormFile("file") - path := c.Query("path") + relative := c.PostForm("relativePath") + fileName := c.PostForm("filename") + path := c.PostForm("path") + 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(oasis_err2.INVALID_PARAMS, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)}) return } + + if fileName != relative { + dirPath := strings.TrimSuffix(relative, fileName) + file.MkDir(path + "/" + dirPath) + } + path += "/" + relative + if !file.CheckNotExist(path) { - c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)}) + + c.JSON(oasis_err2.FILE_ALREADY_EXISTS, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)}) return } + out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) defer out.Close() _, err := io.Copy(out, f) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()}) + c.JSON(oasis_err2.ERROR, 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)}) @@ -275,7 +367,7 @@ func PostFileUpload(c *gin.Context) { // @Security ApiKeyAuth // @Param from formData string true "from path" // @Param to formData string true "to path" -// @Param t formData string true "action" Enums(move,copy) +// @Param type formData string true "action" Enums(move,copy) // @Success 200 {string} string "ok" // @Router /file/operate [post] func PostOperateFileOrDir(c *gin.Context) { @@ -329,3 +421,35 @@ func DeleteFile(c *gin.Context) { } c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) } + +// @Summary update file +// @Produce application/json +// @Accept multipart/form-data +// @Tags file +// @Security ApiKeyAuth +// @Param path formData string true "path" +// @Param content formData string true "content" +// @Success 200 {string} string "ok" +// @Router /file/update [put] +func PutFileContent(c *gin.Context) { + path := c.PostForm("path") + content := c.PostForm("content") + if !file.Exists(path) { + c.JSON(oasis_err2.FILE_ALREADY_EXISTS, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)}) + return + } + //err := os.Remove(path) + err := os.RemoveAll(path) + if err != nil { + fmt.Println(err) + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_DELETE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.FILE_DELETE_ERROR), Data: err}) + return + } + err = file.CreateFileAndWriteContent(path, content) + if err != nil { + fmt.Println(err) + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err}) + return + } + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) +} diff --git a/route/v1/persion.go b/route/v1/persion.go index eadcdd7..b65d53e 100644 --- a/route/v1/persion.go +++ b/route/v1/persion.go @@ -2,11 +2,15 @@ package v1 import ( "encoding/json" + "net/http" "time" "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" + model2 "github.com/IceWhaleTech/CasaOS/service/model" + "github.com/IceWhaleTech/CasaOS/types" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" uuid "github.com/satori/go.uuid" @@ -35,3 +39,47 @@ func PersonTest(c *gin.Context) { return } } + +//get other persion file +func GetPersionFile(c *gin.Context) { + path := c.Query("path") + persion := c.Query("persion") + if len(path) == 0 && len(persion) == 0 { + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)}) + return + } + //任务标识 + uuid := uuid.NewV4().String() + + //1.通知对方需要下载 + service.MyService.Person().GetFileDetail(uuid, path, persion) + + //2.添加数据库 + + task := model2.PersionDownloadDBModel{} + task.UUID = uuid + task.Name = "" + task.Length = 0 + task.Size = 0 + task.State = types.DOWNLOADAWAIT + task.TempPath = "" + task.Type = 0 + service.MyService.Person().AddDownloadTask(task) + + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) +} +func GetPersionDownloadList(c *gin.Context) { + path := c.Query("path") + persion := c.Query("persion") + if len(path) == 0 && len(persion) == 0 { + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)}) + return + } + //任务标识 + uuid := uuid.NewV4().String() + + //1.通知对方需要下载 + service.MyService.Person().GetFileDetail(uuid, path, persion) + + c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)}) +} diff --git a/service/app.go b/service/app.go index ff2e0ea..0dae664 100644 --- a/service/app.go +++ b/service/app.go @@ -36,6 +36,7 @@ type AppService interface { GetHardwareUsageSteam() GetHardwareUsage() []model.DockerStatsModel GetAppStats(id string) string + GetAllDBApps() []model2.AppListDBModel } type appStruct struct { @@ -167,6 +168,11 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList { return &list } +func (a *appStruct) GetAllDBApps() []model2.AppListDBModel { + var lm []model2.AppListDBModel + a.db.Table(model2.CONTAINERTABLENAME).Select("custom_id,title,icon,container_id,label,slogan,image").Find(&lm) + return lm +} //获取我的应用列表 func (a *appStruct) GetContainerInfo(name string) (types.Container, error) { diff --git a/service/casa.go b/service/casa.go index b7c1b58..66e64cb 100644 --- a/service/casa.go +++ b/service/casa.go @@ -20,6 +20,7 @@ type CasaService interface { GetServerAppInfo(id, t string, language string) model.ServerAppList ShareAppFile(body []byte) string PushHeart(id, t string, language string) + PushAppAnalyse(uuid, t string, name, language string) } type casaService struct { @@ -143,6 +144,26 @@ func (o *casaService) PushHeart(id, t string, language string) { } -func NewOasisService() CasaService { +func (o *casaService) PushAppAnalyse(uuid, t string, name, language string) { + + m := model.AppAnalyse{} + m.UUId = uuid + m.Type = t + m.Name = name + m.Language = language + b, _ := json.Marshal(m) + + head := make(map[string]string) + + head["Authorization"] = GetToken() + + infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/app", b, "application/json", head) + + info := model.ServerAppList{} + json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) + +} + +func NewCasaService() CasaService { return &casaService{} } diff --git a/service/data_ handling.go b/service/data_ handling.go new file mode 100644 index 0000000..6d43c33 --- /dev/null +++ b/service/data_ handling.go @@ -0,0 +1 @@ +package service diff --git a/service/disk.go b/service/disk.go index b597eaf..22f99ab 100644 --- a/service/disk.go +++ b/service/disk.go @@ -171,7 +171,9 @@ func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel { i.Children = c if fsused > 0 { i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64) - d.log.Fatal("diskservice_lsblk_fsused", err) + if err != nil { + d.log.Fatal("diskservice_lsblk_fsused", err) + } } n = append(n, i) health = true diff --git a/service/model/o_download.go b/service/model/o_download.go new file mode 100644 index 0000000..d88d103 --- /dev/null +++ b/service/model/o_download.go @@ -0,0 +1,24 @@ +package model + +type PersionDownloadDBModel struct { + UUID string `gorm:"column:uuid;primary_key" json:"uuid"` + State int `json:"state"` // + Type int `json:"type"` //defult 1 + Name string `json:"name"` //file name + TempPath string `json:"temp_path"` //temp path + Size int64 `json:"size"` //file size + Section string `json:"section"` + Length int `json:"length"` //slice length + Hash string `json:"hash"` + CreatedAt string `gorm:"<-:create;autoCreateTime" json:"created_at"` + UpdatedAt string `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at"` +} + +func (p *PersionDownloadDBModel) TableName() string { + return "o_persion_download" +} + +type PersionFileSectionModel struct { + Index int `json:"index"` + Hash string `json:"hash"` +} diff --git a/service/person.go b/service/person.go index af2732f..846fb34 100644 --- a/service/person.go +++ b/service/person.go @@ -1,30 +1,55 @@ package service import ( - "bytes" + "context" + "crypto/cipher" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" "encoding/json" + "encoding/pem" "fmt" "io" "log" + "math/big" "net" "os" + "path/filepath" "reflect" - "strconv" - "strings" "time" "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" + model2 "github.com/IceWhaleTech/CasaOS/service/model" + "github.com/IceWhaleTech/CasaOS/types" + "github.com/lucas-clemente/quic-go" + "gorm.io/gorm" ) type PersonService interface { GetPersionInfo(token string) (m model.PersionModel, err error) Handshake(m model.ConnectState) + Download(m model.MessageModel) + GetFileDetail(uuid, path, to string) + SendFileData(m model.MessageModel, blockSize int, length int) + ReplyGetFileDetail(m model.MessageModel) + ReceiveFileData(m model.MessageModel) + ReceiveGetFileDetail(m model.MessageModel) + + //------------ database + AddDownloadTask(m model2.PersionDownloadDBModel) //添加下载任务 + EditDownloadState(m model2.PersionDownloadDBModel) //只修改状态 + EditDownloading(m model2.PersionDownloadDBModel, section model2.PersionFileSectionModel) + SaveDownloadState(m model2.PersionDownloadDBModel) + DelDownload(uuid string) + GetDownloadById(uuid string) model2.PersionDownloadDBModel } type personService struct { + db *gorm.DB } var IpInfo model.PersionModel @@ -89,14 +114,93 @@ func (p *personService) Handshake(m model.ConnectState) { } +func (p *personService) AddDownloadTask(m model2.PersionDownloadDBModel) { + p.db.Create(&m) +} +func (p *personService) EditDownloadState(m model2.PersionDownloadDBModel) { + p.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State) +} + +func (p *personService) EditDownloading(m model2.PersionDownloadDBModel, section model2.PersionFileSectionModel) { + b, _ := json.Marshal(section) + m.Section = string(b) + p.db.Model(&m).Where("uuid = ?", m.UUID).Update("section", m.Section) +} + +func (p *personService) DelDownload(uuid string) { + var m model2.PersionDownloadDBModel + p.db.Where("uuid = ?", uuid).Delete(&m) +} +func (p *personService) GetDownloadById(uuid string) model2.PersionDownloadDBModel { + var m model2.PersionDownloadDBModel + p.db.Model(m).Where("uuid = ?", uuid).First(&m) + return m +} + +func (p *personService) SaveDownloadState(m model2.PersionDownloadDBModel) { + p.db.Save(&m) +} + var ipAddress chan string +type sysConn struct { + conn *net.UDPConn + header string + auth cipher.AEAD +} + func UDPConnect(ips []string) { + quicConfig := &quic.Config{ + ConnectionIDLength: 12, + HandshakeIdleTimeout: time.Second * 8, + MaxIdleTimeout: time.Second * 45, + MaxIncomingStreams: 32, + MaxIncomingUniStreams: -1, + KeepAlive: true, + } + fmt.Println(quicConfig) + //PersonUDPMap = make(map[string]*net.UDPAddr) ipAddress = make(chan string) + srcAddr := &net.UDPAddr{ IP: net.IPv4zero, Port: 9901} - - conn, err := net.ListenUDP("udp", srcAddr) + fmt.Println(srcAddr) + //UDPconn, err := net.ListenUDP("udp", srcAddr) + // sysconn := &sysConn{ + // conn: UDPconn, + // header: "", + // auth: nil, + // } + // if err != nil { + // fmt.Println(err) + // } + // liste, err := quic.Listen(UDPconn, generateTLSConfig(), nil) + // if err != nil { + // fmt.Println(err) + // } + // ssss, err := liste.Accept(context.Background()) + // if err != nil { + // fmt.Println(err) + // } + // st, err := ssss.AcceptStream(context.Background()) + // if err != nil { + // fmt.Println(err) + // } + // st.Write([]byte("ssss")) + qlister, err := quic.ListenAddr("0.0.0.0:9901", generateTLSConfig(), nil) + //qlister, err := quic.Listen(UDPconn, nil, nil) + if err != nil { + fmt.Println("quic错误", qlister) + } + //session, e := qlister.Accept() + sess, err := qlister.Accept(context.Background()) + sess.SendMessage([]byte("aaaa")) + stream, err := sess.AcceptStream(context.Background()) + stream.Write([]byte("bbb")) + //quic.Dial() + if err != nil { + fmt.Println("quic错误", qlister) + } if err != nil { fmt.Println("监听错误", err.Error()) @@ -106,24 +210,295 @@ func UDPConnect(ips []string) { IP: net.ParseIP(v), Port: 9901} fmt.Println(v, "开始监听") - go AsyncUDPConnect(conn, dstAddr) + + //quic.Dial() + + go AsyncUDPConnect(dstAddr) } for { data := make([]byte, 1024) - n, _, err := conn.ReadFromUDP(data) + n, add, err := UDPconn.ReadFromUDP(data) + fmt.Println(add) if err != nil { log.Printf("error during read:%s\n", err) } else { + fmt.Println("收到数据:", string(data[:n])) + msg := model.MessageModel{} + err := json.Unmarshal(data[:n], &msg) + if err != nil { + log.Printf("转义错误:%s\n", err) + } + //todo:检查数据库是否为合法请求 + if msg.Type == "hi" { + //add ip + //PersonUDPMap[msg.From] = add + } else if msg.Type == "browse" { + //获取目录结构 + } else if msg.Type == "file_detail" { + MyService.Person().ReplyGetFileDetail(msg) + } else if msg.Type == "file_detail_reply" { + MyService.Person().ReceiveGetFileDetail(msg) + } else if msg.Type == "file_data_reply" { + MyService.Person().ReceiveFileData(msg) + } else { + fmt.Println("未知事件") + } + } } } -func AsyncUDPConnect(conn *net.UDPConn, dst *net.UDPAddr) { +// Setup a bare-bones TLS config for the server +func generateTLSConfig() *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{ + // ClientSessionCache: globalSessionCache, + // RootCAs: root, + // InsecureSkipVerify: false, + // NextProtos: nil, + // SessionTicketsDisabled: true, + // } + return &tls.Config{ + Certificates: []tls.Certificate{tlsCert}, + NextProtos: []string{"quic-echo-example"}, + } +} + +//首次获取文件信息 +func (p *personService) GetFileList(uuid, path, to string) { + + msg := model.MessageModel{} + msg.Type = "file_list" + msg.Data = path + msg.To = to + msg.From = config.ServerInfo.Token + msg.UUId = uuid + b, _ := json.Marshal(msg) + fmt.Println(b) + // if ip, ok := PersonUDPMap[msg.To]; ok { + // _, err := UDPconn.WriteToUDP(b, ip) + // if err != nil { + // fmt.Println("写入错误", err) + // } + // } + //接收 + +} + +//首次获取文件信息 +func (p *personService) GetFileDetail(uuid, path, to string) { + + msg := model.MessageModel{} + msg.Type = "file_detail" + msg.Data = path + msg.To = to + msg.From = config.ServerInfo.Token + msg.UUId = uuid + b, _ := json.Marshal(msg) + fmt.Println(b) + // if ip, ok := PersonUDPMap[msg.To]; ok { + // _, err := UDPconn.WriteToUDP(b, ip) + // if err != nil { + // fmt.Println("写入错误", err) + // } + // } + //创建临时文件夹 + file.MkDir("/oasis/download/" + uuid) +} + +func (p *personService) Download(m model.MessageModel) { + fDetail, err := os.Stat("/Users/liangjianli/Documents/images") + //发送需要发送的数据摘要 + if err != nil { + fmt.Println("未获取到文件信息") + } + summary := model.FileSummaryModel{} + summary.Hash = file.GetHashByPath(fDetail.Name()) + summary.Path = m.Data.(string) + summary.BlockSize, summary.Length = file.GetBlockInfo(fDetail.Size()) + + msg := model.MessageModel{} + msg.Type = "download-reply" + msg.Data = summary + msg.From = config.ServerInfo.Token + msg.UUId = "" + b, _ := json.Marshal(msg) + + fmt.Println(b) + + // if ip, ok := PersonUDPMap[m.From]; ok { + // _, err := UDPconn.WriteToUDP(b, ip) + // if err != nil { + // fmt.Println("写入错误", err) + // } + // } +} + +//receive file data +func (p *personService) ReceiveFileData(m model.MessageModel) { + task := p.GetDownloadById(m.UUId) + + //需要重置参数 + tempPath := "/oasis/download/" + task.UUID + tempFilePath := tempPath + "/" + task.Name + fmt.Println(tempFilePath) + filePath := "/oasis/download/" + task.Name + + bss, _ := json.Marshal(m.Data) + tran := model.TranFileModel{} + err := json.Unmarshal(bss, &tran) + if err != nil { + fmt.Println(err) + } + // if file.ComparisonHash(tran.Hash) { + // f, err := os.Create(tempFilePath + strconv.Itoa(tran.Index)) + // if err != nil { + // fmt.Println("创建文件错误", err) + // } + // defer f.Close() + // // _, err = f.Write(tran.Data) + // if err != nil { + // fmt.Println("写入错误", err, tran.Index) + // } + // } + var k int + err = filepath.Walk(tempPath, func(filename string, fi os.FileInfo, err error) error { //遍历目录 + if fi.IsDir() { // 忽略目录 + return nil + } + k++ + return nil + }) + if err != nil { + fmt.Println("获取文件错误", err) + } + if task.Length == k { + //err := file.SpliceFiles(tempPath, filePath) + if err == nil { + if h := file.GetHashByPath(filePath); h == task.Hash { + //最终文件比对成功 + task.State = types.DOWNLOADFINISH + p.EditDownloadState(task) + //remove temp path + file.RMDir(tempPath) + } + } + } + +} + +//1:say hi +//2:发送文件名称 +//3:发送数据 + +//========================================接收端============================================================================================ + +// reply file detail +func (p *personService) ReplyGetFileDetail(m model.MessageModel) { + path := m.Data.(string) + f, err := os.Stat(path) + if err != nil { + fmt.Println(err) + } + summary := model.FileSummaryModel{} + summary.Name = f.Name() + summary.Size = f.Size() + summary.Hash = file.GetHashByPath(path) + summary.Path = path + summary.BlockSize, summary.Length = file.GetBlockInfo(f.Size()) + + msg := model.MessageModel{} + msg.Type = "file_detail_reply" + msg.Data = summary + msg.From = config.ServerInfo.Token + msg.To = m.From + msg.UUId = m.UUId + b, _ := json.Marshal(msg) + // if ip, ok := PersonUDPMap[m.To]; ok { + // _, err := UDPconn.WriteToUDP(b, ip) + // if err != nil { + // fmt.Println("写入错误", err) + // } + // } + fmt.Println(b) + //开始发送数据 + p.SendFileData(m, summary.BlockSize, summary.Length) +} + +func (p *personService) SendFileData(m model.MessageModel, blockSize int, length int) { + path := m.Data.(string) + + f, err := os.Open(path) + if err != nil { + //读取时移动了文件,需要保存数据到数据库 + fmt.Println("读取失败", err) + } + buf := make([]byte, blockSize) + for i := 0; i < length; i++ { + tran := model.TranFileModel{} + _, err := f.Read(buf) + if err == io.EOF { + fmt.Println("读取完毕", err) + } + tran.Hash = file.GetHashByContent(buf) + tran.Index = i + 1 + + msg := model.MessageModel{} + msg.Type = "file_data_reply" + msg.Data = tran + msg.From = config.ServerInfo.Token + msg.To = m.From + msg.UUId = m.UUId + b, _ := json.Marshal(msg) + // if ip, ok := PersonUDPMap[m.To]; ok { + // _, err := UDPconn.WriteToUDP(b, ip) + // if err != nil { + // fmt.Println("写入错误", err) + // } + // } + fmt.Println(b) + } + +} + +// 文件摘要返回 +func (p *personService) ReceiveGetFileDetail(m model.MessageModel) { + + task := p.GetDownloadById("") + bss, _ := json.Marshal(m.Data) + summary := model.FileSummaryModel{} + err := json.Unmarshal(bss, &summary) + if err != nil { + fmt.Println(err) + } + task.Hash = summary.Hash + task.Length = summary.Length + task.Size = summary.Size + + p.SaveDownloadState(task) +} + +func AsyncUDPConnect(dst *net.UDPAddr) { for { time.Sleep(2 * time.Second) - if _, err := conn.WriteToUDP([]byte(dst.IP.String()+" is ok"), dst); err != nil { + if _, err := UDPconn.WriteToUDP([]byte(dst.IP.String()+" is ok"), dst); err != nil { log.Println("send msg fail", err) return } else { @@ -132,239 +507,6 @@ func AsyncUDPConnect(conn *net.UDPConn, dst *net.UDPAddr) { } } } -func TestTCPOne() { - - for i := 0; i < 100; i++ { - fmt.Println(httper.Get("http://18.136.202.206:8088/v1/ping", nil)) - time.Sleep(time.Second * 2) - } - -} - -func TCPServer() { - localAddress := net.TCPAddr{IP: net.IPv4zero, Port: 8087} //定义一个本机IP和端口。 - var tcpListener, err = net.ListenTCP("tcp", &localAddress) //在刚定义好的地址上进监听请求。 - if err != nil { - fmt.Println("监听出错:", err) - return - } - defer func() { //担心return之前忘记关闭连接,因此在defer中先约定好关它。 - tcpListener.Close() - }() - fmt.Println("正在等待连接...") - var conn, err2 = tcpListener.AcceptTCP() //接受连接。 - - if err2 != nil { - fmt.Println("接受连接失败:", err2) - return - } - var remoteAddr = conn.RemoteAddr() //获取连接到的对像的IP地址。 - fmt.Println("接受到一个连接:", remoteAddr) - fmt.Println("正在读取消息...") - var buf = make([]byte, 1000) - var n, _ = conn.Read(buf) //读取对方发来的内容。 - fmt.Println("接收到客户端的消息:", string(buf[:n])) - conn.Write([]byte("hello, Nice to meet you, my name is SongXingzhu")) //尝试发送消息。 - conn.Close() -} - -func parseAddrTCP(addr string) net.TCPAddr { - - t := strings.Split(addr, ":") - port, _ := strconv.Atoi(t[1]) - return net.TCPAddr{ - - IP: net.ParseIP(t[0]), - Port: port, - } -} - -func TestTCPTwo() { - //localAddress := net.TCPAddr{IP: net.IPv4zero, Port: 8087} //定义一个本机IP和端口。 - // t, _ := net.ResolveTCPAddr("tcp", "18.136.202.206:8088") - - // dstAddr := &net.TCPAddr{IP: net.ParseIP("18.136.202.206"), Port: 8088} - connTCP, err := net.ResolveTCPAddr("tcp", "18.136.202.206:8088") - // ddd,err := net.Dial("tcp", "") - - if err != nil { - fmt.Println(err) - } - fmt.Println(connTCP) - // connTCP.Write([]byte("test")) - // var buf = make([]byte, 1000) - // var n, _ = connTCP.Read(buf) //读取对方发来的内容。 - // anotherPeer := parseAddrTCP(string(buf[:n])) - - // fmt.Println("接收到消息:", anotherPeer) - // connTCP.Close() - // time.Sleep(time.Second * 20) - //go TCPServer() - // bidirectionHoleTCP(&localAddress, &anotherPeer) -} - -func bidirectionHoleTCP(srcAddr *net.TCPAddr, anotherAddr *net.TCPAddr) { - // t, _ := net.ResolveTCPAddr("tcp", srcAddr.String()) - conn, err := net.Dial("tcp", anotherAddr.String()) - if err != nil { - - fmt.Println("send handshake:", err) - } - go func() { - - for { - - time.Sleep(10 * time.Second) - if _, err = conn.Write([]byte("from " + config.ServerInfo.Token)); err != nil { - - log.Println("send msg fail", err) - } - } - }() - - for { - - data := make([]byte, 1024) - n, err := conn.Read(data) - if err != nil { - - log.Printf("error during read:%s\n", err) - } else { - - log.Printf("收到数据:%s\n", data[:n]) - } - } -} - -func TestTCP() { - - conn, err := net.Dial("tcp", "192.168.2.224:8088") - - // srcAddr := &net.TCPAddr{ - // IP: net.IPv4zero, Port: 9901} - // conn, err := net.ListenTCP("tcp", srcAddr) - // con, err := conn.AcceptTCP() - // 连接出错则打印错误消息并退出程序 - if err != nil { - fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) - os.Exit(1) - } - time.Sleep(time.Second * 2) - // 调用返回的连接对象提供的 Write 方法发送请求 - for i := 0; i < 10; i++ { - n, err := conn.Write([]byte("aaaa")) - if err != nil { - fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) - os.Exit(1) - } - - fmt.Println(n) - time.Sleep(time.Second) - } - - // 通过连接对象提供的 Read 方法读取所有响应数据 - result, err := readFully(conn) - if err != nil { - fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) - os.Exit(1) - } - // 打印响应数据 - fmt.Println(string(result)) - os.Exit(0) -} - -func readFully(conn net.Conn) ([]byte, error) { - // 读取所有响应数据后主动关闭连接 - defer conn.Close() - result := bytes.NewBuffer(nil) - var buf [512]byte - for { - n, err := conn.Read(buf[0:]) - result.Write(buf[0:n]) - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - } - return result.Bytes(), nil -} - -func GetUdpConnet() { - srcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 9901} - dstAddr := &net.UDPAddr{IP: net.ParseIP("18.136.202.206"), Port: 9527} - conn, err := net.DialUDP("udp", srcAddr, dstAddr) - if err != nil { - - fmt.Println(err) - } - - if _, err = conn.Write([]byte("hello,I'm new peer:" + config.ServerInfo.Token)); err != nil { - - fmt.Println("写入错误", err) - } - time.Sleep(time.Second) - - data := make([]byte, 1024) - //ReadFromUDP从c读取一个UDP数据包,将有效负载拷贝到b,返回拷贝字节数和数据包来源地址。 - //ReadFromUDP方***在超过一个固定的时间点之后超时,并返回一个错误。 - n, remoteAddr, err := conn.ReadFromUDP(data) - if err != nil { - fmt.Printf("error during read: %s", err) - } - fmt.Println(remoteAddr) - fmt.Println("服务器返回的信息", string(data[:n])) - conn.Close() - anotherPeer := parseAddr(string(data[:n])) - fmt.Printf("local:%s server:%s another:%s\n", srcAddr, remoteAddr, anotherPeer) - bidirectionHole(&anotherPeer) -} - -func bidirectionHole(anotherAddr *net.UDPAddr) { - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: 9901} - conn, err := net.DialUDP("udp", srcAddr, anotherAddr) - if err != nil { - - fmt.Println("send handshake:", err) - } - go func() { - - for { - - time.Sleep(10 * time.Second) - if _, err = conn.Write([]byte("from [" + config.ServerInfo.Token + "]")); err != nil { - - log.Println("send msg fail", err) - } - } - fmt.Println("退出") - }() - - for { - - data := make([]byte, 1024) - n, _, err := conn.ReadFromUDP(data) - if err != nil { - log.Printf("error during read:%s\n", err) - } else { - log.Printf("本机token:%s\n", config.ServerInfo.Token) - log.Printf("收到数据:%s\n", data[:n]) - } - } - -} -func parseAddr(addr string) net.UDPAddr { - - t := strings.Split(addr, ":") - port, _ := strconv.Atoi(t[1]) - return net.UDPAddr{ - - IP: net.ParseIP(t[0]), - Port: port, - } -} -func NewPersonService() PersonService { - return &personService{} +func NewPersonService(db *gorm.DB) PersonService { + return &personService{db: db} } diff --git a/service/service.go b/service/service.go index d534429..9aba0c7 100644 --- a/service/service.go +++ b/service/service.go @@ -23,7 +23,7 @@ type Repository interface { //Redis() RedisService ZeroTier() ZeroTierService ZiMa() ZiMaService - OAPI() CasaService + Casa() CasaService Disk() DiskService Notify() NotifyServer ShareDirectory() ShareDirService @@ -45,7 +45,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository { //redis: NewRedisService(rp), zerotier: NewZeroTierService(), zima: NewZiMaService(), - oapi: NewOasisService(), + casa: NewCasaService(), disk: NewDiskService(log, db), notify: NewNotifyService(db), shareDirectory: NewShareDirService(db, log), @@ -54,7 +54,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository { system: NewSystemService(log), shortcuts: NewShortcutsService(db), search: NewSearchService(), - person: NewPersonService(), + person: NewPersonService(db), } } @@ -66,7 +66,7 @@ type store struct { docker DockerService zerotier ZeroTierService zima ZiMaService - oapi CasaService + casa CasaService disk DiskService notify NotifyServer shareDirectory ShareDirService @@ -117,8 +117,8 @@ func (c *store) ZeroTier() ZeroTierService { func (c *store) ZiMa() ZiMaService { return c.zima } -func (c *store) OAPI() CasaService { - return c.oapi +func (c *store) Casa() CasaService { + return c.casa } func (c *store) Disk() DiskService { diff --git a/service/socket.go b/service/socket.go index f48c399..056e75b 100644 --- a/service/socket.go +++ b/service/socket.go @@ -15,9 +15,6 @@ import ( var WebSocketConn *websocket.Conn func SocketConnect() { - - GetUdpConnet() - return Connect() ticker := time.NewTicker(time.Second * 5) defer ticker.Stop() diff --git a/service/udpconn.go b/service/udpconn.go new file mode 100644 index 0000000..a476f82 --- /dev/null +++ b/service/udpconn.go @@ -0,0 +1,168 @@ +package service + +import ( + "bufio" + "crypto/md5" + "crypto/tls" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net" + "os" + "strconv" + + "github.com/IceWhaleTech/CasaOS/model" + "github.com/IceWhaleTech/CasaOS/pkg/config" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/lucas-clemente/quic-go" + uuid "github.com/satori/go.uuid" +) + +var UDPconn *net.UDPConn +var PeopleMap map[string]quic.Stream + +func Dial(addr string, token string) error { + quicConfig := &quic.Config{ + ConnectionIDLength: 4, + KeepAlive: true, + } + tlsConf := &tls.Config{ + InsecureSkipVerify: true, + NextProtos: []string{"bench"}, + SessionTicketsDisabled: true, + } + session, err := quic.DialAddr(addr, tlsConf, quicConfig) + defer session.CloseWithError(0, "") + if err != nil { + return err + } + // stream, err := session.OpenStreamSync(context.Background()) + // if err != nil { + // return err + // } + + return nil +} + +func SayHello(stream quic.Stream, to string) { + msg := model.MessageModel{} + msg.Type = "hello" + msg.Data = "hello" + msg.To = to + msg.From = config.ServerInfo.Token + msg.UUId = uuid.NewV4().String() + b, _ := json.Marshal(msg) + prefixLength := file.PrefixLength(len(b)) + + data := append(prefixLength, b...) + stream.Write(data) +} + +var pathsss string + +//文件分片发送 +func SendFileData(stream quic.Stream, filePath, to, uuid string) error { + + fStat, err := os.Stat(filePath) + if err != nil { + return err + } + + blockSize, length := file.GetBlockInfo(fStat.Size()) + + f, err := os.Open(filePath) + if err != nil { + fmt.Println("读取失败", err) + return err + } + bufferedReader := bufio.NewReader(f) + buf := make([]byte, blockSize) + for i := 0; i < length; i++ { + + tran := model.TranFileModel{} + + _, err = bufferedReader.Read(buf) + + if err == io.EOF { + fmt.Println("读取完毕", err) + } + + tran.Hash = file.GetHashByContent(buf) + tran.Index = i + + msg := model.MessageModel{} + msg.Type = "file_data" + msg.Data = tran + msg.From = config.ServerInfo.Token + msg.To = to + msg.UUId = uuid + b, _ := json.Marshal(msg) + stream.Write(b) + } + defer stream.Close() + return nil +} + +//发送数据 +func SendData(stream quic.Stream, m model.MessageModel) { + b, _ := json.Marshal(m) + stream.Write(b) +} + +//读取数据 +func ReadContent(stream quic.Stream) (model.MessageModel, error) { + path := "" + for { + prefixByte := make([]byte, 4) + c1, err := io.ReadFull(stream, prefixByte) + fmt.Println(c1, err) + prefixLength, err := strconv.Atoi(string(prefixByte)) + + messageByte := make([]byte, prefixLength) + t, err := io.ReadFull(stream, messageByte) + fmt.Println(t, err) + m := model.MessageModel{} + err = json.Unmarshal(messageByte, &m) + if err != nil { + fmt.Println(err) + } + + //传输数据需要继续读取 + if m.Type == "file_data" { + dataModelByte, _ := json.Marshal(m.Data) + dataModel := model.TranFileModel{} + err := json.Unmarshal(dataModelByte, &dataModel) + fmt.Println(err) + + dataLengthByte := make([]byte, 8) + t, err = io.ReadFull(stream, dataLengthByte) + dataLength, err := strconv.Atoi(string(dataLengthByte)) + if err != nil { + fmt.Println(err) + } + dataByte := make([]byte, dataLength) + t, err = io.ReadFull(stream, dataByte) + if err != nil { + fmt.Println(err) + } + sum := md5.Sum(dataByte) + hash := hex.EncodeToString(sum[:]) + if dataModel.Hash != hash { + fmt.Println("hash不匹配", hash, dataModel.Hash) + } + + filepath := path + strconv.Itoa(dataModel.Index) + + err = ioutil.WriteFile(filepath, dataByte, 0644) + if dataModel.Index >= (dataModel.Length - 1) { + file.SpliceFiles("", path, dataModel.Length) + break + } + } else { + return m, nil + } + } + return model.MessageModel{}, nil +} diff --git a/shell/helper.sh b/shell/helper.sh index 50dd32d..56e5358 100644 --- a/shell/helper.sh +++ b/shell/helper.sh @@ -115,8 +115,8 @@ AddPartition() { parted -s $1 mklabel gpt parted -s $1 mkpart primary ext4 0 100% - PATH=`lsblk -r $1 | sort | grep part | head -n 1 | awk '{print $1}'` - mkfs.ext4 -m 1 /dev/${PATH} + P=`lsblk -r $1 | sort | grep part | head -n 1 | awk '{print $1}'` + mkfs.ext4 -m 1 -F /dev/${P} partprobe $1 diff --git a/types/persion_download.go b/types/persion_download.go new file mode 100644 index 0000000..c0a5f82 --- /dev/null +++ b/types/persion_download.go @@ -0,0 +1,9 @@ +package types + +const ( + DOWNLOADAWAIT = iota //default state + DOWNLOADING + DOWNLOADPAUSE + DOWNLOADFINISH + DOWNLOADERROR +) diff --git a/types/system.go b/types/system.go index e5d185f..22e307a 100644 --- a/types/system.go +++ b/types/system.go @@ -1,5 +1,5 @@ package types -const CURRENTVERSION = "0.2.9" +const CURRENTVERSION = "0.2.10" -const BODY = "
  • Custom installation of new parameters
  • Fixed issues
  • Update front-end translation
  • " +const BODY = "
  • sAdded CasaOS own file manager
  • Fixed issues
  • Update front-end translation
  • "