Skip to content

Modify storage limit to use admin controlled value

Vijay Hawoldar requested to merge vij-admin-storage-limit into master

What does this MR do and why?

Updates Namespaces::Storage::Enforcement and Namespaces::Storage::RootSize classes to use the admin controlled limit values to determine:

  1. if a storage limit should apply
  2. what that limit should be

Previously, storage limits were going to be controlled via a mix of feature flags and plan_limit.storage_size_limit, but this is no longer the case.

Now, Admins will be able to set an enforcement limit (plan_limit.enforcement_limit) and a dashboard limit (plan_limit.storage_size_limit) (see: https://gitlab.com/groups/gitlab-org/-/epics/9173 for high level overview), and we need to use these to determine the answers to the above.

In short, the rules are:

  • storage limit application settings and feature flags must be enabled
  • namespace is on the free plan
  • the namespace has not been excluded from storage limits
  • either of:

Otherwise, we fallback to having a limit of 0, which indicates unlimited

How to set up and validate locally

  1. Checkout master branch to test behaviour before this MR
  2. Toggle on the various options
    ::Gitlab::CurrentSettings.update automatic_purchased_storage_allocation: true
    
    ::Gitlab::CurrentSettings.update enforce_namespace_storage_limit: true
    
    Feature.enable :namespace_storage_limit
  3. Find a free group on your local instance
    group = Group.find(#id of your free-plan group)
  4. Check enforcement logic against the group:
    Namespaces::Storage::Enforcement.enforce_limit?(group)
    
    => false
  5. Checkout this branch (vij-admin-storage-limit) and retry the above to confirm the same behaviour without any plan limit changes:
    reload!
    
    group = Group.find(#id)
    
    Namespaces::Storage::Enforcement.enforce_limit?(group)
    
    => false
  6. Now, set an enforcement limit and try again:
    group.actual_limits.update(enforcement_limit: 1) # sets the enforcement limit to 1kb
    
    Namespaces::Storage::Enforcement.enforce_limit?(group)
    
    => true
  7. Check the dashboard limit rules:
    group.actual_limits.update(enforcement_limit: 0, storage_size_limit: 1, dashboard_limit_enabled_at: group.created_at - 1.day) 
    
    Namespaces::Storage::Enforcement.enforce_limit?(group)
    
    => true
  8. Temporarily disable caching so we can test the root size limit by modifying this method:
        def limit
         #@limit ||= Rails.cache.fetch(limit_cache_key, expires_in: EXPIRATION_TIME) do
           storage_enforcement.enforceable_storage_limit(root_namespace).megabytes +
             root_namespace.additional_purchased_storage_size.megabytes
         #end
       end
       
       # don't forget to `reload!` the rails console to make sure this takes effect
  9. Lastly, we can check the RootSize class limit works as intended:
    group.actual_limits.update(enforcement_limit: 0, storage_size_limit: 0) 
    
    Namespaces::Storage::RootSize.new(group).limit
    
    => 0
    
    group.actual_limits.update(enforcement_limit: 10) 
    Namespaces::Storage::RootSize.new(group).limit
    
    => 10485760 # returned in KiB
    
    group.actual_limits.update(enforcement_limit: 0, storage_size_limit: 10, dashboard_limit_enabled_at: group.created_at - 1.day) 
    Namespaces::Storage::RootSize.new(group).limit
    
    => 10485760 # returned in KiB
    
    group.actual_limits.update(enforcement_limit: 20, storage_size_limit: 10, dashboard_limit_enabled_at: group.created_at - 1.day) 
    Namespaces::Storage::RootSize.new(group).limit
    
    => 10485760 # still returns dashboard limit

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Vijay Hawoldar

Merge request reports