Skip to content
This repository has been archived by the owner on Sep 22, 2023. It is now read-only.

Add support for dotfiles of domains and groups #132

Merged
merged 3 commits into from Sep 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/132.feature
@@ -0,0 +1 @@
Add support for adding/updating/deleting/listing domain dotfiles and group dotfiles
64 changes: 48 additions & 16 deletions src/ai/backend/client/cli/dotfile.py
Expand Up @@ -22,8 +22,13 @@ def dotfile():
help='Path to dotfile to upload. '
'If not specified, client will try to read file from STDIN. ')
@click.option('-o', '--owner', '--owner-access-key', 'owner_access_key', metavar='ACCESS_KEY',
help='Set the owner of the target session explicitly.')
def create(path, permission, dotfile_path, owner_access_key):
help='Specify the owner of the target session of user dotfiles.')
@click.option('-d', '--domain', 'domain', metavar='DOMAIN',
help='Specify the domain name of domain dotfiles.')
@click.option('-g', '--group', metavar='GROUP',
help='Sepcify the group name or id of group dotfiles. '
'(If group name is provided, domain name must be specified with option -d)')
def create(path, permission, dotfile_path, owner_access_key, domain, group):
'''
Store dotfile to Backend.AI Manager.
Dotfiles will be automatically loaded when creating kernels.
Expand All @@ -43,7 +48,8 @@ def create(path, permission, dotfile_path, owner_access_key):
if not permission:
permission = '755'
dotfile_ = session.Dotfile.create(body, path, permission,
owner_access_key=owner_access_key)
owner_access_key=owner_access_key,
domain=domain, group=group)
print_info(f'Dotfile {dotfile_.path} created and ready')
except Exception as e:
print_error(e)
Expand All @@ -53,14 +59,20 @@ def create(path, permission, dotfile_path, owner_access_key):
@dotfile.command()
@click.argument('path', metavar='PATH')
@click.option('-o', '--owner', '--owner-access-key', 'owner_access_key', metavar='ACCESS_KEY',
help='Specify the owner of the target session explicitly.')
def get(path, owner_access_key):
help='Specify the owner of the target session of user dotfiles.')
@click.option('-d', '--domain', 'domain', metavar='DOMAIN',
help='Specify the domain name of domain dotfiles.')
@click.option('-g', '--group', metavar='GROUP',
help='Sepcify the group name or id of group dotfiles. '
'(If group name is provided, domain name must be specified with option -d)')
def get(path, owner_access_key, domain, group):
'''
Print dotfile content
Print dotfile content.
'''
with Session() as session:
try:
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key)
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key,
domain=domain, group=group)
body = dotfile_.get()
print(body['data'])
except Exception as e:
Expand All @@ -69,9 +81,16 @@ def get(path, owner_access_key):


@dotfile.command()
def list():
@click.option('-o', '--owner', '--owner-access-key', 'owner_access_key', metavar='ACCESS_KEY',
help='Specify the owner of the target session of user dotfiles.')
@click.option('-d', '--domain', 'domain', metavar='DOMAIN',
help='Specify the domain name of domain dotfiles.')
@click.option('-g', '--group', metavar='GROUP',
help='Sepcify the group name or id of group dotfiles. '
'(If group name is provided, domain name must be specified with option -d)')
def list(owner_access_key, domain, group):
'''
List all availabe dotfiles by user.
List availabe user/domain/group dotfiles.
'''
fields = [
('Path', 'path', None),
Expand All @@ -80,7 +99,8 @@ def list():
]
with Session() as session:
try:
resp = session.Dotfile.list_dotfiles()
resp = session.Dotfile.list_dotfiles(owner_access_key=owner_access_key,
domain=domain, group=group)
if not resp:
print('There is no dotfiles created yet.')
return
Expand All @@ -107,8 +127,13 @@ def list():
help='Path to dotfile to upload. '
'If not specified, client will try to read file from STDIN. ')
@click.option('-o', '--owner', '--owner-access-key', 'owner_access_key', metavar='ACCESS_KEY',
help='Specify the owner of the target session explicitly.')
def update(path, permission, dotfile_path, owner_access_key):
help='Specify the owner of the target session of user dotfiles.')
@click.option('-d', '--domain', 'domain', metavar='DOMAIN',
help='Specify the domain name of domain dotfiles.')
@click.option('-g', '--group', metavar='GROUP',
help='Sepcify the group name or id of group dotfiles. '
'(If group name is provided, domain name must be specified with option -d)')
def update(path, permission, dotfile_path, owner_access_key, domain, group):
'''
Update dotfile stored in Backend.AI Manager.
'''
Expand All @@ -124,7 +149,8 @@ def update(path, permission, dotfile_path, owner_access_key):
try:
if not permission:
permission = '755'
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key)
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key,
domain=domain, group=group)
dotfile_.update(body, permission)
print_info(f'Dotfile {dotfile_.path} updated')
except Exception as e:
Expand All @@ -137,13 +163,19 @@ def update(path, permission, dotfile_path, owner_access_key):
@click.option('-f', '--force', type=bool, is_flag=True,
help='Delete dotfile without confirmation.')
@click.option('-o', '--owner', '--owner-access-key', 'owner_access_key', metavar='ACCESS_KEY',
help='Specify the owner of the target session explicitly.')
def delete(path, force, owner_access_key):
help='Specify the owner of the target session of user dotfiles.')
@click.option('-d', '--domain', 'domain', metavar='DOMAIN',
help='Specify the domain name of domain dotfiles.')
@click.option('-g', '--group', metavar='GROUP',
help='Sepcify the group name or id of group dotfiles. '
'(If group name is provided, domain name must be specified with option -d)')
def delete(path, force, owner_access_key, domain, group):
'''
Delete dotfile from Backend.AI Manager.
'''
with Session() as session:
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key)
dotfile_ = session.Dotfile(path, owner_access_key=owner_access_key,
domain=domain, group=group)
if not force:
print_warn('Are you sure? (y/[n])')
result = input()
Expand Down
106 changes: 83 additions & 23 deletions src/ai/backend/client/func/dotfile.py
@@ -1,4 +1,4 @@
from typing import List, Mapping
from typing import List, Mapping, Optional

from .base import api_function, BaseFunction
from ..request import Request
Expand All @@ -19,39 +19,82 @@ async def create(cls,
path: str,
permission: str,
owner_access_key: str = None,
domain: str = None,
group: str = None
) -> 'Dotfile':
rqst = Request(api_session.get(),
'POST', '/user-config/dotfiles')
body = {
'data': data,
'path': path,
'permission': permission
}
if group:
body['group'] = group
if domain:
body['domain'] = domain
rqst_endpoint = '/group-config/dotfiles'
elif domain:
body['domain'] = domain
rqst_endpoint = '/domain-config/dotfiles'
else:
if owner_access_key:
body['owner_access_key'] = owner_access_key
rqst_endpoint = '/user-config/dotfiles'

rqst = Request(api_session.get(), 'POST', rqst_endpoint)
rqst.set_json(body)
async with rqst.fetch() as resp:
await resp.json()
return cls(path, owner_access_key=owner_access_key)
return cls(path, owner_access_key=owner_access_key, group=group, domain=domain)

@api_function
@classmethod
async def list_dotfiles(cls) -> 'List[Mapping[str, str]]':
rqst = Request(api_session.get(),
'GET', '/user-config/dotfiles')
async def list_dotfiles(cls,
owner_access_key: str = None,
domain: str = None,
group: str = None
) -> 'List[Mapping[str, str]]':
params = {}
if group:
params['group'] = group
if domain:
params['domain'] = domain
rqst_endpoint = '/group-config/dotfiles'
elif domain:
params['domain'] = domain
rqst_endpoint = '/domain-config/dotfiles'
else:
if owner_access_key:
params['onwer_access_key'] = owner_access_key
rqst_endpoint = '/user-config/dotfiles'

rqst = Request(api_session.get(), 'GET', rqst_endpoint, params=params)
async with rqst.fetch() as resp:
return await resp.json()

def __init__(self, path: str, owner_access_key: str = None):
def __init__(self, path: str, owner_access_key: Optional[str] = None,
group: str = None, domain: str = None):
self.path = path
self.owner_access_key = owner_access_key
self.group = group
self.domain = domain

@api_function
async def get(self) -> str:
params = {'path': self.path}
if self.owner_access_key:
params['owner_access_key'] = self.owner_access_key
rqst = Request(api_session.get(),
'GET', '/user-config/dotfiles',
params=params)
if self.group:
params['group'] = self.group
if self.domain:
params['domain'] = self.domain
rqst_endpoint = '/group-config/dotfiles'
elif self.domain:
params['domain'] = self.domain
rqst_endpoint = '/domain-config/dotfiles'
else:
if self.owner_access_key:
params['owner_access_key'] = self.owner_access_key
rqst_endpoint = '/user-config/dotfiles'

rqst = Request(api_session.get(), 'GET', rqst_endpoint, params=params)
async with rqst.fetch() as resp:
return await resp.json()

Expand All @@ -62,23 +105,40 @@ async def update(self, data: str, permission: str):
'path': self.path,
'permission': permission
}
if self.owner_access_key:
body['owner_access_key'] = self.owner_access_key
rqst = Request(api_session.get(),
'PATCH', '/user-config/dotfiles')
rqst.set_json(body)
if self.group:
body['group'] = self.group
if self.domain:
body['domain'] = self.domain
rqst_endpoint = '/group-config/dotfiles'
elif self.domain:
body['domain'] = self.domain
rqst_endpoint = '/domain-config/dotfiles'
else:
if self.owner_access_key:
body['owner_access_key'] = self.owner_access_key
rqst_endpoint = '/user-config/dotfiles'

rqst = Request(api_session.get(), 'PATCH', rqst_endpoint)
rqst.set_json(body)
async with rqst.fetch() as resp:
return await resp.json()

@api_function
async def delete(self):
params = {'path': self.path}
if self.owner_access_key:
params['owner_access_key'] = self.owner_access_key
rqst = Request(api_session.get(),
'DELETE', '/user-config/dotfiles',
params=params)
if self.group:
params['group'] = self.group
if self.domain:
params['domain'] = self.domain
rqst_endpoint = '/group-config/dotfiles'
elif self.domain:
params['domain'] = self.domain
rqst_endpoint = '/domain-config/dotfiles'
else:
if self.owner_access_key:
params['owner_access_key'] = self.owner_access_key
rqst_endpoint = '/user-config/dotfiles'

rqst = Request(api_session.get(), 'DELETE', rqst_endpoint, params=params)
async with rqst.fetch() as resp:
return await resp.json()