Skip to content

feat: Migrate filebrowser into storage proxy #710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

leksikov
Copy link
Contributor

@leksikov leksikov commented Sep 5, 2022

Migration to Mono Repository.
Moves file browsers to the storage proxy. This will greatly reduce the burden of manager and webserver to mediate large file transfers.

  • Implement filebrowser container mgmt (with a configurable maximum number of containers)
  • Add new manager-facing storage-proxy APIs to create/destroy filebrowser sessions
  • manager: Add new vfolder APIs to map the new manager-facing storage-proxy APIs
  • client-py: Add new functional wrappers and vfolder subcommands to use the filebrowser session APIs
  • webui: Update the current filebrowser UIs to use the new filebrowser session mgmt APIs

@leksikov leksikov added type:feature Add new features comp:storage-proxy Related to Storage proxy component labels Sep 5, 2022
@leksikov leksikov added this to the 21.03 milestone Sep 5, 2022
@leksikov
Copy link
Contributor Author

leksikov commented Sep 5, 2022

  • Implemented main feature such as the communication between Client, Manager and Storage Proxy to support FileBrowser session where user can attach multiple folders and copy/move data using UI.
  • Implemented the CLI commands on client side to start filebrowser with attached folders.
  • Implemented Manager API interface to redirect requests from Client to Storage Proxy and receive the response from Storage Proxy about the url, port number and container id.
  • The user using CLI can destroy the filebrowser session using the container id information printed out in cli.

While implementing the filebrowser, I decoupled filebrowser from Vfolder as a separate app.
This will allow having filebrowser its own routing management for more complex commands.
Decoupling will help to improve maintenance and advanced feature implementation of Filebrowser without affecting Vfolder.

Previously, did the implementation on the server of preventing multiple monitors run with common.FileLock.

Implemented UID and GID settings in a startup.sh script after the containers are set. The input variables are defined in the .toml settings file.

Refactoring, in order to deal with multiple volumes and their path in the settings file.

Added a host:volume option in client-py. This is needed for the following things: to specify the volume on which folders are located. The same name folder can occur on multiple volumes. Then based on given argument options such as volume and name the vfid of vfolder is infered. Then filebrowser based on volume path and vfid is able to mount those directories into the container.

On client-py command execution example:
backend.ai filebrowser create -host local:volume1 -vf mydata1 -vf mydata2

@achimnol achimnol changed the title Feature/filebrowser in storage proxy feat: Migrate filebrowser into storage proxy Sep 6, 2022
@github-actions github-actions bot added comp:client Related to Client component comp:manager Related to Manager component labels Sep 18, 2022
@leksikov leksikov marked this pull request as ready for review September 19, 2022 09:16
@leksikov leksikov requested a review from achimnol September 19, 2022 09:16
@leksikov leksikov requested a review from kyujin-cho September 30, 2022 16:13
Copy link
Member

@kyujin-cho kyujin-cho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial batch of reviews. Also, since new file browser feature requires Docker to run, I think we need to describe it on our storage proxy's README. Please take that in mind. cc: @achimnol

Comment on lines 146 to 147
cors.add(app.router.add_route("POST", r"/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", r"/destroy", destroy_filebrowser))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're not intending to represent regex literal, I think we need to remove leading r.

Suggested change
cors.add(app.router.add_route("POST", r"/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", r"/destroy", destroy_filebrowser))
cors.add(app.router.add_route("POST", "/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", "/destroy", destroy_filebrowser))

Comment on lines 17 to 24
@asynccontextmanager
async def closing_async(thing):
try:
yield thing
finally:
await thing.close()


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we've migrated into mono-repo setup, I think it's a good chance to remove merge duplicate declarations of closing_async into one, maybe on ai.backend.common.utils. Please replace closing_async usage of cuda plugins and agent also.

Comment on lines 3 to 5
python_tests(
name="tests",
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No test case defined inside this package, so this should be removed.

Suggested change
python_tests(
name="tests",
)

Comment on lines 146 to 147
cors.add(app.router.add_route("POST", r"/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", r"/destroy", destroy_filebrowser))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These regex literals are not used to represent regex literal, so I think it's better to replace with plain string literals.

Suggested change
cors.add(app.router.add_route("POST", r"/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", r"/destroy", destroy_filebrowser))
cors.add(app.router.add_route("POST", "/create", create_or_update_filebrowser))
cors.add(app.router.add_route("DELETE", "/destroy", destroy_filebrowser))

Comment on lines 67 to 68
headers = {}
headers["X-BackendAI-Storage-Auth-Token"] = proxy_info.secret
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refrain from using raw string itself rather than referencing AUTH_TOKEN_HDR constant under ai.backend.manager.models.storage.

Suggested change
headers = {}
headers["X-BackendAI-Storage-Auth-Token"] = proxy_info.secret
headers = {AUTH_TOKEN_HDR: proxy_info.secret}

Comment on lines +67 to +76
for volume_name in volumes.keys():
if requested_volume == volume_name:
volume_cls: Type[AbstractVolume] = BACKENDS[volumes.get(volume_name)["backend"]]
mount_path = Path(volumes.get(volume_name)["path"])
volume_obj = volume_cls(
local_config=ctx.local_config,
mount_path=mount_path,
fsprefix=None,
options={},
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if desired volume does not exist actually?

ctx: Context,
host: str,
vfolders: list[dict],
) -> tuple[str, int, str]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning just tuple can make code readers confused about what the components do. Please replace it with NamedTuple or TypedDict so that readers can easily understand its role.

)
config["HostConfig"]["Mounts"].append(
{
"Target": f"/data/{str(vfolder['name'])}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vfolder['name'] will be automatically converted to str when it's in f-strings.

Suggested change
"Target": f"/data/{str(vfolder['name'])}",
"Target": f"/data/{vfolder['name']}",

)
await container.start()
except Exception as e:
print("Failure to recreate container ", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to notify user that the operation is failed, instead of just eating up raised Exception.

await container.delete()
await tracker_db.delete_container_record(container_id)
except Exception as e:
print(f"Failure to destroy container {container_id[0:7]} ", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: please alert user.

@leksikov
Copy link
Contributor Author

Recent commit changes introduce the following updates:

  1. Before creating a container, added a feature to check if the virtual folder exists and if its status is set to Readable.
  2. Refactored the database handling by switching from SQLAlchemy to aiosqlite.
  3. The database is now initialized through the async ainit method.
  4. Implemented a new feature to ensure that when the Storage Proxy shuts down, all Filebrowser sessions and associated containers are removed accordingly.

@leksikov leksikov requested a review from kyujin-cho March 29, 2023 07:01
Copy link
Member

@fregataa fregataa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any infra set up with multiple storage proxies?
I am curious of DB in storage-proxy.
Is storage-proxy using any DB like sqlite currently or this be the first time to use DB in storage-proxy?
And is there any reason to use aiosqlite rather SQLAlchemy?

@leksikov leksikov requested a review from fregataa March 29, 2023 08:50
@leksikov leksikov removed the request for review from fregataa April 11, 2023 00:56
@Yaminyam Yaminyam added the size:XL 500~ LoC label Apr 13, 2023
@achimnol
Copy link
Member

Now we are going to merge this PR with the SFTP resource group running on storage proxy nodes. (related: #1246, #1250)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:client Related to Client component comp:manager Related to Manager component comp:storage-proxy Related to Storage proxy component size:XL 500~ LoC type:feature Add new features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants