Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: roscisz/TensorHive
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.0.0
Choose a base ref
...
head repository: roscisz/TensorHive
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Jun 7, 2021

  1. Bump urllib3 from 1.26.4 to 1.26.5

    Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.4 to 1.26.5.
    - [Release notes](https://github.com/urllib3/urllib3/releases)
    - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
    - [Commits](urllib3/urllib3@1.26.4...1.26.5)
    
    ---
    updated-dependencies:
    - dependency-name: urllib3
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Jun 7, 2021
    Copy the full SHA
    ddb0937 View commit details
  2. Bump pyyaml from 5.3.1 to 5.4

    Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.3.1 to 5.4.
    - [Release notes](https://github.com/yaml/pyyaml/releases)
    - [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES)
    - [Commits](yaml/pyyaml@5.3.1...5.4)
    
    ---
    updated-dependencies:
    - dependency-name: pyyaml
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Jun 7, 2021
    Copy the full SHA
    029baa4 View commit details
  3. Bump flask-cors from 3.0.7 to 3.0.9

    Bumps [flask-cors](https://github.com/corydolphin/flask-cors) from 3.0.7 to 3.0.9.
    - [Release notes](https://github.com/corydolphin/flask-cors/releases)
    - [Changelog](https://github.com/corydolphin/flask-cors/blob/master/CHANGELOG.md)
    - [Commits](corydolphin/flask-cors@3.0.7...3.0.9)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Jun 7, 2021
    Copy the full SHA
    3b0832c View commit details

Commits on Jun 23, 2021

  1. extend protection configuration in main_config.ini

    switch from ENABLED flag to protection LEVEL
    add KILL_PROCESSES process killing level conf
    roscisz committed Jun 23, 2021
    Copy the full SHA
    9bed8a0 View commit details
  2. reimplement protection service logic

    Look for violation for each available resource, not reservation.
    Add strict_reservations mode which requires a reservation for
    each GPU-utilizing process, even if there are no other reservations.
    Gather unique violating process PIDs.
    Group violations by intruder.
    Remove unused code.
    roscisz committed Jun 23, 2021
    Copy the full SHA
    ef0e33d View commit details
  3. update mailbot handler and e-mail templates

    upgrade and simplify the e-mail templates, support
    multiple violated resources and owners in one e-mail
    roscisz committed Jun 23, 2021
    Copy the full SHA
    3c6cd04 View commit details
  4. Copy the full SHA
    93a5cf1 View commit details
  5. use host-specific ports in SSH config utility

    limit SSH connections to the configured hosts
    roscisz committed Jun 23, 2021
    Copy the full SHA
    e344071 View commit details
  6. upgrade the TTY messaging violation handler

    support TTY sessions on multiple hosts
    simplify the messages and support multiple violated resources
    roscisz committed Jun 23, 2021
    Copy the full SHA
    ba226a7 View commit details
  7. Copy the full SHA
    3a3eca4 View commit details
  8. Copy the full SHA
    487a34a View commit details
  9. Copy the full SHA
    c76031d View commit details

Commits on Jul 1, 2021

  1. Copy the full SHA
    4a680f4 View commit details

Commits on Dec 7, 2021

  1. Copy the full SHA
    cecb62b View commit details
  2. Merge pull request #349 from roscisz/master

    Merge hotfixes from master to develop
    roscisz authored Dec 7, 2021
    Copy the full SHA
    bbc5a7a View commit details
  3. Merge pull request #319 from roscisz/dependabot/npm_and_yarn/tensorhi…

    …ve/app/web/dev/node-notifier-8.0.1
    
    Bump node-notifier from 5.4.0 to 8.0.1 in /tensorhive/app/web/dev
    roscisz authored Dec 7, 2021
    Copy the full SHA
    ba78f44 View commit details
  4. Merge pull request #333 from roscisz/dependabot/pip/flask-cors-3.0.9

    Bump flask-cors from 3.0.7 to 3.0.9
    roscisz authored Dec 7, 2021
    Copy the full SHA
    7a58f7a View commit details
  5. Merge pull request #339 from roscisz/dependabot/pip/urllib3-1.26.5

    Bump urllib3 from 1.26.4 to 1.26.5
    roscisz authored Dec 7, 2021
    Copy the full SHA
    08241b4 View commit details
  6. Bump path-parse from 1.0.6 to 1.0.7 in /tensorhive/app/web/dev

    Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
    - [Release notes](https://github.com/jbgutierrez/path-parse/releases)
    - [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)
    
    ---
    updated-dependencies:
    - dependency-name: path-parse
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Dec 7, 2021
    Copy the full SHA
    b4a2ec4 View commit details
  7. Bump cryptography from 3.2.1 to 3.3.2

    Bumps [cryptography](https://github.com/pyca/cryptography) from 3.2.1 to 3.3.2.
    - [Release notes](https://github.com/pyca/cryptography/releases)
    - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
    - [Commits](pyca/cryptography@3.2.1...3.3.2)
    
    ---
    updated-dependencies:
    - dependency-name: cryptography
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Dec 7, 2021
    Copy the full SHA
    7ad6c28 View commit details
  8. Merge pull request #340 from roscisz/dependabot/pip/pyyaml-5.4

    Bump pyyaml from 5.3.1 to 5.4
    roscisz authored Dec 7, 2021
    Copy the full SHA
    a2e0cf1 View commit details
  9. Merge pull request #341 from roscisz/dependabot/pip/cryptography-3.3.2

    Bump cryptography from 3.2.1 to 3.3.2
    roscisz authored Dec 7, 2021
    Copy the full SHA
    ec00a85 View commit details
  10. Merge pull request #350 from roscisz/dependabot/npm_and_yarn/tensorhi…

    …ve/app/web/dev/path-parse-1.0.7
    
    Bump path-parse from 1.0.6 to 1.0.7 in /tensorhive/app/web/dev
    roscisz authored Dec 7, 2021
    Copy the full SHA
    22b15fc View commit details
  11. Copy the full SHA
    68d9995 View commit details
  12. Copy the full SHA
    91684ed View commit details
  13. Copy the full SHA
    45c00e2 View commit details
  14. Merge pull request #351 from roscisz/webapp_1.1.0

    Webapp 1.1.0
    roscisz authored Dec 7, 2021
    Copy the full SHA
    8f6aa3f View commit details
  15. bumped connecion version

    Tomasz Boiński authored and roscisz committed Dec 7, 2021
    Copy the full SHA
    bcf0130 View commit details
  16. fix for #288

    Tomasz Boiński authored and roscisz committed Dec 7, 2021
    Copy the full SHA
    e8263f5 View commit details
  17. added instructions

    Tomasz Boiński authored and roscisz committed Dec 7, 2021
    Copy the full SHA
    e90ed39 View commit details
  18. parametrize URL base

    roscisz committed Dec 7, 2021
    Copy the full SHA
    78c8dbf View commit details
  19. add static webapp files

    roscisz committed Dec 7, 2021
    Copy the full SHA
    669dd3b View commit details

Commits on Dec 8, 2021

  1. Copy the full SHA
    29b158a View commit details

Commits on Dec 17, 2021

  1. fixed URL to reltive

    Tomasz Boiński committed Dec 17, 2021
    Copy the full SHA
    a51c863 View commit details
  2. Update tensorhive/app/web/AppServer.py

    Co-authored-by: Paweł Rościszewski <pawel.rosciszewski@pg.edu.pl>
    tboinski and roscisz authored Dec 17, 2021
    Copy the full SHA
    88b1377 View commit details
  3. CHange VueRouter mode to has fixes ReverseProxy

    Tomasz Boiński committed Dec 17, 2021
    Copy the full SHA
    a1c6f74 View commit details
  4. Merge branch 'fix288' of https://github.com/roscisz/TensorHive into f…

    …ix288
    Tomasz Boiński committed Dec 17, 2021
    Copy the full SHA
    516d041 View commit details

Commits on Jan 7, 2022

  1. Copy the full SHA
    0809de6 View commit details
  2. Copy the full SHA
    6891ba2 View commit details

Commits on Jan 8, 2022

  1. Merge pull request #329 from roscisz/fix288

    Fix288
    roscisz authored Jan 8, 2022
    Copy the full SHA
    384a4e0 View commit details
  2. Copy the full SHA
    64554d4 View commit details
  3. fix SSH config builder test

    include proper available node configuration
    roscisz committed Jan 8, 2022
    Copy the full SHA
    fee2e29 View commit details
  4. Copy the full SHA
    e02b8d1 View commit details
  5. Copy the full SHA
    3688bc2 View commit details
  6. fix #326

    roscisz committed Jan 8, 2022
    Copy the full SHA
    dbdad10 View commit details

Commits on Jan 13, 2022

  1. differentiate error messages in create reservation

    refactor reservation creation code
    roscisz committed Jan 13, 2022
    Copy the full SHA
    6783b8e View commit details
  2. Copy the full SHA
    649f4ca View commit details
  3. Copy the full SHA
    a66e4d0 View commit details
  4. Copy the full SHA
    07a1fed View commit details

Commits on Jan 25, 2022

  1. Copy the full SHA
    3b89c6e View commit details
Showing with 610 additions and 299 deletions.
  1. +3 −0 .gitattributes
  2. +87 −6 README.md
  3. +3 −3 setup.py
  4. +1 −1 tensorhive/__init__.py
  5. +3 −2 tensorhive/api/APIServer.py
  6. +4 −3 tensorhive/app/web/AppServer.py
  7. +3 −1 tensorhive/app/web/dev/build_vue/webpack.base.conf.js
  8. +1 −1 tensorhive/app/web/dev/config/index.js
  9. +21 −21 tensorhive/app/web/dev/index.html
  10. +80 −39 tensorhive/app/web/dev/package-lock.json
  11. +3 −3 tensorhive/app/web/dev/package.json
  12. +0 −1 tensorhive/app/web/dev/src/components/views/ReservationsOverview.vue
  13. +88 −33 tensorhive/app/web/dev/src/components/views/reserve_resources/MySchedule.vue
  14. +2 −2 tensorhive/app/web/dev/src/main.js
  15. +1 −1 tensorhive/app/web/dev/src/routes.js
  16. +1 −1 tensorhive/app/web/dev/static/config.json
  17. +1 −1 tensorhive/app/web/dist/index.html
  18. +1 −1 tensorhive/app/web/dist/static/config.json
  19. +2 −2 .../static/css/{app.d51eeb1a1b0a81efd5b0d2270c8b3293.css → app.3b7394218a3a9fc073e380ebb0011d14.css}
  20. +0 −1 tensorhive/app/web/dist/static/js/app.5d5f37876bf13b673a78.js.map
  21. +3 −3 tensorhive/app/web/dist/static/js/{app.5d5f37876bf13b673a78.js → app.9d10b7ca4ab203851b4b.js}
  22. +1 −0 tensorhive/app/web/dist/static/js/app.9d10b7ca4ab203851b4b.js.map
  23. +2 −2 ...hive/app/web/dist/static/js/{manifest.2ae2e69a05c33dfc65f8.js → manifest.3ad1d5771e9b13dbdad2.js}
  24. +1 −1 .../web/dist/static/js/{manifest.2ae2e69a05c33dfc65f8.js.map → manifest.3ad1d5771e9b13dbdad2.js.map}
  25. +8 −14 tensorhive/app/web/dist/static/js/{vendor.025536ba77a5d0687b83.js → vendor.158c84ef759850d22806.js}
  26. +1 −1 .../app/web/dist/static/js/{vendor.025536ba77a5d0687b83.js.map → vendor.158c84ef759850d22806.js.map}
  27. +2 −0 tensorhive/cli.py
  28. +4 −1 tensorhive/config.py
  29. +27 −18 tensorhive/controllers/reservation.py
  30. +11 −2 tensorhive/core/managers/TensorHiveManager.py
  31. +2 −2 tensorhive/core/services/JobSchedulingService.py
  32. +63 −67 tensorhive/core/services/ProtectionService.py
  33. +7 −1 tensorhive/core/ssh.py
  34. +2 −7 tensorhive/core/utils/mailer.py
  35. +1 −3 tensorhive/core/violation_handlers/EmailSendingBehaviour.py
  36. +23 −25 tensorhive/core/violation_handlers/MessageSendingBehaviour.py
  37. +30 −0 tensorhive/core/violation_handlers/SudoProcessKillingBehaviour.py
  38. +31 −0 tensorhive/core/violation_handlers/UserProcessKillingBehaviour.py
  39. +8 −15 tensorhive/mailbot_config.ini
  40. +13 −1 tensorhive/main_config.ini
  41. +27 −9 tests/functional/controllers/test_reservation_controller.py
  42. +28 −0 tests/functional/controllers/test_reservation_controller_superuser.py
  43. +10 −4 tests/unit/test_ssh.py
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
tensorhive/app/web/dev/static/* linguist-vendored
tensorhive/app/web/dev/static/**/* linguist-vendored
tensorhive/app/web/dev/build_vue/* linguist-vendored
tensorhive/app/web/dev/test/**/* linguist-vendored
93 changes: 87 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
TensorHive
===
![](https://img.shields.io/badge/release-v1.0.0-brightgreen.svg?style=popout-square)
![](https://img.shields.io/badge/pypi-v1.0.0-brightgreen.svg?style=popout-square)
![](https://img.shields.io/badge/release-v1.1.0-brightgreen.svg?style=popout-square)
![](https://img.shields.io/badge/pypi-v1.1.0-brightgreen.svg?style=popout-square)
![](https://img.shields.io/badge/Issues%20and%20PRs-welcome-yellow.svg?style=popout-square)
![](https://img.shields.io/badge/platform-Linux-blue.svg?style=popout-square)
![](https://img.shields.io/badge/hardware-Nvidia-green.svg?style=popout-square)
![](https://img.shields.io/badge/platform-GNU/Linux-blue.svg?style=popout-square)
![](https://img.shields.io/badge/python-3.5%20|%203.6%20|%203.7%20|%203.8-blue.svg?style=popout-square)
![](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=popout-square)

@@ -158,14 +157,96 @@ Web application and API Documentation can be accessed via URLs highlighted in gr
##### Advanced configuration
You can fully customize TensorHive behaviours via INI configuration files (which will be created automatically after `tensorhive init`):
```
~/.config/TensorHive/hosts_config.ini
~/.config/TensorHive/main_config.ini
~/.config/TensorHive/mailbot_config.ini
~/.config/TensorHive/hosts_config.ini
```
[(see example)](https://github.com/roscisz/TensorHive/blob/master/tensorhive/main_config.ini)
<details>
<summary>(see example)</summary>
<p>

[hosts_config.ini](https://github.com/roscisz/TensorHive/blob/master/tensorhive/hosts_config.ini)
[main_config.ini](https://github.com/roscisz/TensorHive/blob/master/tensorhive/main_config.ini)
[mailbot_config.ini](https://github.com/roscisz/TensorHive/blob/master/tensorhive/mailbot_config.ini)


</p>
</details>

----------------------

#### Reverse proxy setup

Serving TensorHive through reverse proxy requires proper configuration of URL parameters in the `[api]` section of
`main_config.ini`, including `url_schema`, `url_hostname`, `url_port` and `url_prefix`.

<details>
<summary>(see example)</summary>
<p>

Let's assume that the WebApp is served locally on `http://localhost:5000`, the API on `http://localhost:1111` and we
want to serve TensorHive publicly at `https://some-server/tensorhive`. In such case the following `main_config.ini`:

```
url_schema = https
url_hostname = some-server
url_port = 443
url_prefix = tensorhive/api
```
should be used along with a reverse proxy similar to the following example for nginx:

```
location /tensorhive {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
proxy_pass http://localhost:5000/tensorhive;
proxy_set_header SCRIPT_NAME /tensorhive;
}
location /tensorhive/api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
proxy_pass http://localhost:1111;
}
```

</p>
</details>

Citation
------------------------
If you use TensorHive for a scientific publication, we would appreciate citations:

```bibtex
@article{JMLR:v22:20-225,
author = {Paweł Rościszewski and Michał Martyniak and Filip Schodowski},
title = {TensorHive: Management of Exclusive GPU Access for Distributed Machine Learning Workloads},
journal = {Journal of Machine Learning Research},
year = {2021},
volume = {22},
number = {215},
pages = {1-5},
url = {http://jmlr.org/papers/v22/20-225.html}
}
```

Contribution and feedback
------------------------
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -35,10 +35,10 @@
'Click==7.0',
'clickclick==20.10.2',
'coloredlogs==10.0',
'connexion==2.3.0',
'connexion==2.5.0',
'cryptography==3.2.1',
'Flask==1.1.4',
'Flask-Cors==3.0.7',
'Flask-Cors==3.0.9',
'Flask-JWT-Extended==3.13.1',
'gevent==21.1.2',
'greenlet==1.1.0',
@@ -70,7 +70,7 @@
'ssh2-python==0.26.0',
'stringcase==1.2.0',
'swagger_ui_bundle==0.0.8',
'urllib3==1.26.4',
'urllib3==1.26.5',
'Werkzeug==0.16.1',
'zope.event==4.5.0',
'zope.interface==5.4.0',
2 changes: 1 addition & 1 deletion tensorhive/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.0'
__version__ = '1.1.0'
5 changes: 3 additions & 2 deletions tensorhive/api/APIServer.py
Original file line number Diff line number Diff line change
@@ -32,9 +32,10 @@ def shutdown_session(exception=None):
strict_validation=True)
CORS(app.app)
log.info('[⚙] Starting API server with {} backend'.format(API_SERVER.BACKEND))
URL = 'http://{host}:{port}/{url_prefix}/ui/'.format(
URL = '{schema}://{host}:{port}/{url_prefix}/ui/'.format(
schema=API.URL_SCHEMA,
host=API.URL_HOSTNAME,
port=API_SERVER.PORT,
port=API.URL_PORT,
url_prefix=API.URL_PREFIX)
log.info(green('[✔] API documentation (Swagger UI) available at: {}'.format(URL)))
app.run(server=API_SERVER.BACKEND,
7 changes: 4 additions & 3 deletions tensorhive/app/web/AppServer.py
Original file line number Diff line number Diff line change
@@ -50,9 +50,10 @@ def _inject_api_endpoint_to_app():
try:
web_app_json_config_path = PosixPath(__file__).parent / 'dist/static/config.json'
data = {
'apiPath': 'http://{}:{}/{}'.format(
'apiPath': '{}://{}:{}/{}'.format(
API.URL_SCHEMA,
API.URL_HOSTNAME,
API_SERVER.PORT,
API.URL_PORT,
API.URL_PREFIX),
'version': tensorhive.__version__
}
@@ -78,7 +79,7 @@ def start_server():
'workers': APP_SERVER.WORKERS,
'loglevel': APP_SERVER.LOG_LEVEL
}
log.info(green('[✔] Web App available at: http://{}:{}'.format(API.URL_HOSTNAME, APP_SERVER.PORT)))
log.info(green('[✔] Web App available at: http://{}:{}'.format(APP_SERVER.HOST, APP_SERVER.PORT)))
GunicornStandaloneApplication(app, options).run()
else:
raise NotImplementedError('Selected backend is not supported yet.')
4 changes: 3 additions & 1 deletion tensorhive/app/web/dev/build_vue/webpack.base.conf.js
Original file line number Diff line number Diff line change
@@ -60,7 +60,9 @@ module.exports = {
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
name: utils.assetsPath('fonts/[name].[hash:7].[ext]'),
// workaround for vuejs-templates webpack issue 1266
publicPath: process.env.NODE_ENV === 'production' ? '../../' : '/'
}
}
]
2 changes: 1 addition & 1 deletion tensorhive/app/web/dev/config/index.js
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ module.exports = {
index: path.resolve(__dirname, '../../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
assetsPublicPath: './',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
42 changes: 21 additions & 21 deletions tensorhive/app/web/dev/index.html
Original file line number Diff line number Diff line change
@@ -3,39 +3,39 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="57x57" href="/static/favicon/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/static/favicon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/static/favicon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/static/favicon/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/static/favicon/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/static/favicon/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/static/favicon/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/static/favicon/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/static/favicon/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/static/favicon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon/favicon-16x16.png">
<link rel="manifest" href="/static/favicon/manifest.json">
<link rel="apple-touch-icon" sizes="57x57" href="./static/favicon/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="./static/favicon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="./static/favicon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="./static/favicon/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="./static/favicon/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="./static/favicon/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="./static/favicon/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="./static/favicon/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="./static/favicon/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="./static/favicon/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="./static/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="./static/favicon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="./static/favicon/favicon-16x16.png">
<link rel="manifest" href="./static/favicon/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="msapplication-TileImage" content="./ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<title>TensorHive</title>
<!-- css -->
<link rel="stylesheet" href="/static/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="./static/bootstrap/bootstrap.min.css">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">

<link rel="stylesheet" href="/static/AdminLTE/AdminLTE.min.css">
<link rel="stylesheet" href="/static/AdminLTE/skin-blue.min.css">
<link rel="stylesheet" href="./static/AdminLTE/AdminLTE.min.css">
<link rel="stylesheet" href="./static/AdminLTE/skin-blue.min.css">
</head>
<body class="hold-transition skin-blue sidebar-mini sidebar-collapse">
<div id="root"></div>

<!-- built files will be auto injected. Static files below -->
<script src="/static/jQuery/jQuery-2.2.0.min.js"></script>
<script src="/static/bootstrap/bootstrap.min.js"></script>
<script src="/static/AdminLTE/app.min.js"></script>
<script src="./static/jQuery/jQuery-2.2.0.min.js"></script>
<script src="./static/bootstrap/bootstrap.min.js"></script>
<script src="./static/AdminLTE/app.min.js"></script>
</body>
</html>
Loading