Skip to content
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

eosfs: set quota #1477

Merged
merged 6 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
3 changes: 3 additions & 0 deletions changelog/unreleased/eos-set-quota.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Set quota when creating home directory in EOS

https://github.com/cs3org/reva/pull/1477
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ redis_address = "localhost:6379"
{{< /highlight >}}
{{% /dir %}}

{{% dir name="user_groups_cache_expiration" type="int" default=5 %}}
{{% dir name="group_members_cache_expiration" type="int" default=5 %}}
The time in minutes for which the members of a group would be cached [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/cbox/group/rest/rest.go#L75)
{{< highlight toml >}}
[cbox.group.rest]
user_groups_cache_expiration = 5
group_members_cache_expiration = 5
{{< /highlight >}}
{{% /dir %}}

Expand Down
3 changes: 3 additions & 0 deletions internal/grpc/services/gateway/usershareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ func (s *svc) CreateShare(ctx context.Context, req *collaboration.CreateShareReq
// TODO(labkode): if both commits are enabled they could be done concurrently.
if s.c.CommitShareToStorageGrant {
addGrantStatus, err := s.addGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, req.Grant.Permissions.Permissions)
if err != nil {
labkode marked this conversation as resolved.
Show resolved Hide resolved
return nil, errors.New("gateway: error adding grant to storage")
}
if addGrantStatus.Code != rpc.Code_CODE_OK {
return &collaboration.CreateShareResponse{
Status: addGrantStatus,
Expand Down
12 changes: 12 additions & 0 deletions pkg/eosclient/eosbinary/eosbinary.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,18 @@ func (c *Client) GetQuota(ctx context.Context, username, rootUID, rootGID, path
return c.parseQuota(path, stdout)
}

// SetQuota sets the quota of a user on the quota node defined by path
func (c *Client) SetQuota(ctx context.Context, rootUID, rootGID string, info *eosclient.SetQuotaInfo) error {
maxBytes := fmt.Sprintf("%d", info.MaxBytes)
maxFiles := fmt.Sprintf("%d", info.MaxFiles)
cmd := exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "quota", "set", "-u", info.Username, "-p", info.QuotaNode, "-v", maxBytes, "-i", maxFiles)
_, _, err := c.executeEOS(ctx, cmd)
if err != nil {
return err
}
return nil
}

// Touch creates a 0-size,0-replica file in the EOS namespace.
func (c *Client) Touch(ctx context.Context, uid, gid, path string) error {
cmd := exec.CommandContext(ctx, "/usr/bin/eos", "-r", uid, gid, "file", "touch", path)
Expand Down
10 changes: 10 additions & 0 deletions pkg/eosclient/eosclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type EOSClient interface {
SetAttr(ctx context.Context, uid, gid string, attr *Attribute, recursive bool, path string) error
UnsetAttr(ctx context.Context, uid, gid string, attr *Attribute, path string) error
GetQuota(ctx context.Context, username, rootUID, rootGID, path string) (*QuotaInfo, error)
SetQuota(ctx context.Context, rootUID, rootGID string, info *SetQuotaInfo) error
Touch(ctx context.Context, uid, gid, path string) error
Chown(ctx context.Context, uid, gid, chownUID, chownGID, path string) error
Chmod(ctx context.Context, uid, gid, mode, path string) error
Expand Down Expand Up @@ -99,3 +100,12 @@ type QuotaInfo struct {
AvailableBytes, UsedBytes int
AvailableInodes, UsedInodes int
}

// SetQuotaInfo encapsulates the information needed to
// create a quota space in EOS for a user
type SetQuotaInfo struct {
Username string
QuotaNode string
MaxBytes uint64
MaxFiles uint64
}
5 changes: 5 additions & 0 deletions pkg/eosclient/eosgrpc/eosgrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ func (c *Client) GetQuota(ctx context.Context, username, rootUID, rootGID, path
return nil, errtypes.NotSupported("eosgrpc: GetQuota not implemented")
}

// SetQuota sets the quota of a user on the quota node defined by path
func (c *Client) SetQuota(ctx context.Context, rootUID, rootGID string, info *eosclient.SetQuotaInfo) error {
return errtypes.NotSupported("eosgrpc: SetQuota not implemented")
}

// Touch creates a 0-size,0-replica file in the EOS namespace.
func (c *Client) Touch(ctx context.Context, uid, gid, path string) error {
log := appctx.GetLogger(ctx)
Expand Down
9 changes: 9 additions & 0 deletions pkg/storage/utils/eosfs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ type Config struct {
// Namespace for metadata operations
Namespace string `mapstructure:"namespace"`

// QuotaNode for storing quota information
QuotaNode string `mapstructure:"quota_node"`

// DefaultQuotaBytes sets the default maximum bytes available for a user
DefaultQuotaBytes uint64 `mapstructure:"default_quota_bytes"`

// DefaultQuotaFiles sets the default maximum files available for a user
DefaultQuotaFiles uint64 `mapstructure:"default_quota_files"`

// ShadowNamespace for storing shadow data
ShadowNamespace string `mapstructure:"shadow_namespace"`

Expand Down
27 changes: 27 additions & 0 deletions pkg/storage/utils/eosfs/eosfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ func (c *Config) init() {
c.ShadowNamespace = path.Join(c.Namespace, ".shadow")
}

// Quota node defaults to namespace if empty
if c.QuotaNode == "" {
c.QuotaNode = c.Namespace
}

if c.DefaultQuotaBytes == 0 {
c.DefaultQuotaBytes = 1000000000000 // 1 TB
}
if c.DefaultQuotaFiles == 0 {
c.DefaultQuotaFiles = 1000000 // 1 Million
}

if c.ShareFolder == "" {
c.ShareFolder = "/MyShares"
}
Expand Down Expand Up @@ -913,6 +925,21 @@ func (fs *eosfs) createUserDir(ctx context.Context, u *userpb.User, path string,
return errors.Wrap(err, "eos: error setting attribute")
}
}

// set quota for user
quotaInfo := &eosclient.SetQuotaInfo{
Username: u.Username,
MaxBytes: fs.conf.DefaultQuotaBytes,
MaxFiles: fs.conf.DefaultQuotaFiles,
QuotaNode: fs.conf.QuotaNode,
}

err = fs.c.SetQuota(ctx, uid, gid, quotaInfo)
ishank011 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
err := errors.Wrap(err, "eosfs: error setting quota")
return err
}

return nil
}

Expand Down