Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

feat: Filebrowser in storage-proxy #25

Closed
wants to merge 94 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
3109889
feat: Add config options for filebrowser containers
achimnol Jul 25, 2021
d319f3b
fix: Correct the example filebrowser image tag
achimnol Jul 25, 2021
307338a
feat: Add config for filebrowser container's user/group
achimnol Jul 25, 2021
5e4a992
feat: Add skeleton for filebrowser mgmt API
achimnol Jul 25, 2021
370f58c
Merge branch 'main' into feature/filebrowser-in-storage-proxy
achimnol Oct 19, 2021
07d122c
fix: lint errors
achimnol Oct 19, 2021
fc8ba32
WIP
achimnol Oct 19, 2021
b55cb4e
Merge remote-tracking branch 'origin/main' into feature/filebrowser-i…
leksikov Jan 11, 2022
d7120e6
feat: add filebrowser container on storage proxy
leksikov Jan 12, 2022
5c7a2e6
fix: return tuple
leksikov Jan 18, 2022
4b0a77f
fix: put aiodocker in local context
leksikov Jan 18, 2022
74867b7
fix: add vfid and file path mangle
leksikov Jan 20, 2022
2dc62ae
feat: add File Browser support
leksikov Jan 21, 2022
e74bed4
fix: black formatting
leksikov Jan 21, 2022
43af0bd
fix: add 38.feature news fragment
leksikov Jan 21, 2022
13f8b8d
fix: update sample.toml for filebrowser
leksikov Jan 21, 2022
d4d980f
fix: accidental file edits
leksikov Jan 21, 2022
7d9a748
fix: news fragment by adding extra line
leksikov Jan 21, 2022
f4bc4ee
fix: add destroy container feature
leksikov Jan 25, 2022
51cad7d
fix: destroy filebrowser on manager side
leksikov Jan 25, 2022
3701e0d
fix: black issues
leksikov Jan 25, 2022
79b3500
fix: add start script to setup filebrowser and config files
leksikov Jan 27, 2022
1423ebd
feat: remove the login screen
leksikov Feb 8, 2022
a4e7a62
fix: add run contained with given CPU and memory
leksikov Feb 8, 2022
2fd498d
fix: feat add container management structure
leksikov Feb 22, 2022
509bb85
fix: add database store to store container session
leksikov Mar 2, 2022
9e22506
fix: refactor file structure
leksikov Mar 18, 2022
529b341
feat: add container network monitor
leksikov Mar 18, 2022
8798505
fix: fix filebrowser config and linter issues
leksikov Mar 22, 2022
388277d
fix: file re-naming from snake-case
leksikov Mar 22, 2022
b4376da
fix: rename file from snake-case style
leksikov Mar 22, 2022
30b1ba9
fix: style and db path
leksikov Mar 22, 2022
326d91a
fix: settings path
leksikov Mar 22, 2022
e515110
fix: add exit to a start shell script
leksikov Mar 22, 2022
999869b
fix: manager.py
leksikov Mar 22, 2022
c27cee4
fix: max_containers
leksikov Mar 22, 2022
24f802c
refactor: add filebrowser subpackage
leksikov Mar 23, 2022
d990b8f
fix: add init file in subpackage directory
leksikov Mar 23, 2022
f39790e
fix: add container_monitor in browser subpackage
leksikov Mar 23, 2022
0dadb11
fox: fix the recreation of container
leksikov Mar 23, 2022
51423ee
fix: disable recreate container function
leksikov Mar 23, 2022
757da0f
refactor: improve code structure
leksikov Mar 23, 2022
fcd1b2f
refactor: implement subpackage for filebrowser
leksikov Mar 24, 2022
efb2f5b
fix: task cancel, delete db record
leksikov Mar 24, 2022
98cbe26
Feature: idle timeout monitor
leksikov Mar 25, 2022
947e676
fix: add additional settings in config file
leksikov Mar 25, 2022
748772d
fix: remove unused functions
leksikov Mar 25, 2022
daa8ecb
Merge remote-tracking branch 'origin/main' into feature/filebrowser-i…
leksikov Mar 25, 2022
04c385b
fix: check condition for max containers
leksikov Mar 25, 2022
b9a35eb
fix: fix flake and black issues
leksikov Mar 26, 2022
9d29582
setup: sqlalchemy in setup.cfg
leksikov Mar 26, 2022
fe316c8
fix: style issues
leksikov Mar 26, 2022
1d1b482
fix: fix style
leksikov Mar 26, 2022
272e393
fix: linter issues
leksikov Mar 26, 2022
ee27577
fix: style
leksikov Mar 26, 2022
4243a3d
fix: busy port binding
leksikov Mar 26, 2022
a17d0a9
fix: code leftovers
leksikov Mar 26, 2022
2891785
refactor: settings files setup
leksikov Mar 26, 2022
2db9656
fix: improvements
leksikov Mar 26, 2022
d42cbe4
fix: isort
leksikov Mar 26, 2022
a1dc7fc
fix: config str type in json
leksikov Mar 26, 2022
347206e
feat: add cgroup
leksikov Mar 27, 2022
974effa
fix: additional fixes
leksikov Mar 27, 2022
f2171e5
fix: db logging and ensure future
leksikov Mar 27, 2022
286b2e1
fix: recreate container with exception
leksikov Mar 27, 2022
f08fe9c
refactor: database as class object
leksikov Mar 31, 2022
581843e
fix: remove feature to recreate containers from db
leksikov Mar 31, 2022
53bc83c
refactot: create task to destroy containers
leksikov Mar 31, 2022
338d67b
fix: setup script
leksikov Mar 31, 2022
7ce0118
fix: resolve code issues
leksikov Apr 1, 2022
3e6f22f
fix: sqlite_db to tracker_db rename
leksikov Apr 1, 2022
4c79144
fix: resolve github issues
leksikov Apr 4, 2022
2dfbb66
setup: mypy setuptools
leksikov Apr 4, 2022
ead97c2
fix: implement simple file lock
leksikov Apr 10, 2022
bccc3e5
fix: the running error
leksikov Apr 11, 2022
40a8f45
fix: write lock file with aiofiles
leksikov Apr 11, 2022
1450f20
fix: flake issues
leksikov Apr 11, 2022
c883e9c
fix: black formatting issues
leksikov Apr 11, 2022
488e4ea
feat: FileLock implementation for monitor
leksikov Apr 11, 2022
c3037e9
fix: error with lock time expiration
leksikov Apr 11, 2022
8ffe5e8
fix,wip: Use relative default paths for ease of install-dev setup
achimnol Apr 11, 2022
70d804c
fix: add user_id and group_id settings
leksikov Apr 11, 2022
2436474
Merge branch 'feature/filebrowser-in-storage-proxy' of https://github…
leksikov Apr 11, 2022
e3873a8
fix: add group id in config sample.toml
leksikov Apr 11, 2022
04e6c76
fix: lint issues
leksikov Apr 11, 2022
1b10a63
fix: add suport for multiple volumes
leksikov Apr 12, 2022
c163bc3
fix: lint issues
leksikov Apr 12, 2022
f116283
fix: add variable typing
leksikov Apr 21, 2022
0b37b09
fix: fix isort and black issues
leksikov Apr 21, 2022
9f40c66
fix: sqlite db cleanup on shutdown
leksikov Apr 25, 2022
27bd591
Merge branch 'main' into feature/filebrowser-in-storage-proxy
leksikov Apr 25, 2022
5bdf2eb
fix: linter issues
leksikov Apr 25, 2022
1560652
Merge branch 'feature/filebrowser-in-storage-proxy' of https://github…
leksikov Apr 25, 2022
7104352
Updating branch with recent Main
leksikov Sep 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/38.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Move file browser to storage proxy.
1 change: 1 addition & 0 deletions config/filebrowser/branding/img/icons/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions config/filebrowser/branding/img/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions config/filebrowser/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
useradd -r -u $1 -g $2 work
su work
/bin/filebrowser config init -d /filebrowser_dir/db/filebrowser_$3.db -p $3
/bin/filebrowser users add admin admin -d /filebrowser_dir/db/filebrowser_$3.db
/bin/filebrowser config import /filebrowser_dir/config.json -d /filebrowser_dir/db/filebrowser_$3.db
/bin/filebrowser -c /filebrowser_dir/settings.json -d /filebrowser_dir/db/filebrowser_$3.db -p $3

exit 0
44 changes: 44 additions & 0 deletions config/sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,50 @@ session-expire = "1d"
# user = 1000
# group = 1000

[filebrowser]
# A locally available container image to run as filebrowser containers
image = "cr.backend.ai/stable/filebrowser:21.02-ubuntu20.04"

# The IP address to expose the filebrowser ports
service_ip = "127.0.0.1"

# The service port number by which user will be able to connect to filerowser UI.
service_port = 8080

# Settings pass to configure filebrowser application in the docker container.
# The specific file 'settings.json' should be places in given path,
# otherwise the default settings file will be genrated in the following pass
# For more configuration file info see https://filebrowser.org/installation
settings_path = "./filebrowser_dir/"

# The maxium number of CPU cores available to each filebrowser container
max_cpu = 1

# The maximum size of memory available to each filebrowser container
max_mem = "1g"

# The maximum limit of the number of filebrowser containers
max_containers = 32

# The SQLite db path and name
db_path = './filebrowser_dir/containers.db'

# The group to be used by the filebrowser container
user_id = 1001
group_id = 100

# The frequency to check network I/O status of containers.
activity_check_freq = 1

# The timeout to mark a container idle when there are no activities observed.
activity_check_timeout = 30

# The timeout to destroy a container after it is marked as idle.
idle_timeout = 30

# Define port range which can be used by filebrowser containers.
# For example, port_range="4000-5000"
port_range="4000-5000"

[api.client]
# Client-facing API
Expand Down
8 changes: 8 additions & 0 deletions filebrowser_dir/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

/bin/filebrowser config init -d /filebrowser_dir/db/filebrowser_$1.db -p $1;
/bin/filebrowser users add admin admin -d /filebrowser_dir/db/filebrowser_$1.db;
/bin/filebrowser config import /filebrowser_dir/config.json -d /filebrowser_dir/db/filebrowser_$1.db;
/bin/filebrowser -c /filebrowser_dir/settings.json -d /filebrowser_dir/db/filebrowser_$1.db -p $1;

exit 0;
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ python_requires = >=3.10
setup_requires =
setuptools>=50.3.2
install_requires =
aiodocker~=0.21
aiofiles>=0.7.0
types-aiofiles>=0.1.9
aiohttp~=3.8.0
Expand All @@ -45,6 +46,8 @@ install_requires =
uvloop>=0.16.0
zipstream~=1.1.4
backend.ai-common~=22.3.0
sqlalchemy~=1.4.32
types-setuptools~=57.4.11
zip_safe = false
include_package_data = true

Expand Down
51 changes: 51 additions & 0 deletions src/ai/backend/storage/api/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ..abc import AbstractVolume
from ..context import Context
from ..exception import InvalidSubpathError, VFolderNotFoundError
from ..filebrowser import filebrowser
from ..types import VFolderCreationOptions
from ..utils import check_params, log_manager_api_entry

Expand Down Expand Up @@ -358,6 +359,7 @@ async def get_vfolder_usage(request: web.Request) -> web.Response:
},
),
) as params:

try:
await log_manager_api_entry(log, "get_vfolder_usage", params)
ctx: Context = request.app["ctx"]
Expand Down Expand Up @@ -626,6 +628,49 @@ async def delete_files(request: web.Request) -> web.Response:
)


async def create_or_update_filebrowser(request: web.Request) -> web.Response:
ctx: Context = request.app["ctx"]
params = await request.json()
host: str
port: int
container_id: str
host, port, container_id = await filebrowser.create_or_update(
ctx,
params["host"],
params["vfolders"],
)
return web.json_response(
{
"addr": f"http://{host}:{port}", # TODO: SSL?
"container_id": f"{container_id}",
"status": "ok",
},
)


async def destroy_filebrowser(request: web.Request) -> web.Response:
async with check_params(
request,
t.Dict(
{
t.Key("auth_token"): t.String,
t.Key("container_id"): t.String,
},
),
) as params:
await log_manager_api_entry(log, "destroy_filebrowser", params)
ctx: Context = request.app["ctx"]
try:
await filebrowser.destroy_container(ctx, params["container_id"])
return web.json_response(
{
"status": "ok",
},
)
except Exception:
raise Exception


async def init_manager_app(ctx: Context) -> web.Application:
app = web.Application(
middlewares=[
Expand Down Expand Up @@ -655,4 +700,10 @@ async def init_manager_app(ctx: Context) -> web.Application:
app.router.add_route("POST", "/folder/file/download", create_download_session)
app.router.add_route("POST", "/folder/file/upload", create_upload_session)
app.router.add_route("POST", "/folder/file/delete", delete_files)
app.router.add_route(
"POST",
"/storage/filebrowser/create",
create_or_update_filebrowser,
)
app.router.add_route("DELETE", "/storage/filebrowser/destroy", destroy_filebrowser)
return app
37 changes: 37 additions & 0 deletions src/ai/backend/storage/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from contextlib import asynccontextmanager
from pathlib import Path

import trafaret as t
Expand All @@ -13,6 +14,14 @@
_file_perm = (Path(__file__).parent / "server.py").stat()


@asynccontextmanager
async def closing_async(thing):
try:
yield thing
finally:
await thing.close()


local_config_iv = (
t.Dict(
{
Expand All @@ -38,6 +47,34 @@
),
},
),
t.Key("filebrowser"): t.Dict(
{
t.Key("image"): t.String,
t.Key("service_ip"): t.IP,
t.Key("max_cpu", default=1): t.Int[1:_max_cpu_count],
t.Key("max_mem", default="1g"): tx.BinarySize,
t.Key("max_containers", default=32): t.Int[1:],
t.Key("user_id", default=None): tx.UserID(
default_uid=_file_perm.st_uid,
),
t.Key("group_id", default=None): tx.GroupID(
default_gid=_file_perm.st_gid,
),
t.Key("settings_path", default=None): tx.Path(type="dir"),
t.Key("service_port", default=None): t.Int,
t.Key("mount_path", default=None): tx.Path(type="dir"),
t.Key("max_containers", default=None): t.Int,
t.Key("db_path", default=None): tx.Path(
type="file",
allow_nonexisting=True,
allow_devnull=True,
),
t.Key("activity_check_timeout", default=30): t.Int,
t.Key("activity_check_freq", default=1): t.Int,
t.Key("idle_timeout", default=300): t.Int,
t.Key("port_range", default="4000-5000"): t.String,
},
),
t.Key("logging"): logging_config_iv,
t.Key("api"): t.Dict(
{
Expand Down
1 change: 1 addition & 0 deletions src/ai/backend/storage/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Context:
pid: int
etcd: AsyncEtcd
local_config: Mapping[str, Any]
container_id: Any

def __init__(
self,
Expand Down
Empty file.
Loading