Skip to content

Commit

Permalink
WiP: Implement resource_quotas_hosts and hosts_resources
Browse files Browse the repository at this point in the history
  • Loading branch information
bastian-src committed Nov 13, 2024
1 parent c764aa4 commit 9fd80b7
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ module HostManagedExtensions
validate :verify_resource_quota

has_one :host_resources, class_name: '::ForemanResourceQuota::HostResources',
inverse_of: :host, foreign_key: :host_id, dependent: :destroy
inverse_of: :host, dependent: :destroy
has_one :resource_quota_host, class_name: '::ForemanResourceQuota::ResourceQuotaHost',
inverse_of: :host, dependent: :destroy
has_one :resource_quota, class_name: '::ForemanResourceQuota::ResourceQuota',
through: :host_resources, foreign_key: :resource_quota_id
through: :resource_quota_host
scoped_search relation: :resource_quota, on: :name, complete_value: true, rename: :resource_quota

# A host shall always have a .host_resources attribute
before_create :build_host_resources, unless: proc { |h| h.host_resources.present? }
before_create :build_host_resources, unless: -> { host_resources.present? }
end

def verify_resource_quota
Expand Down
11 changes: 5 additions & 6 deletions app/models/foreman_resource_quota/host_resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ module ForemanResourceQuota
class HostResources < ApplicationRecord
self.table_name = 'hosts_resources'

belongs_to :resource_quota, class_name: 'ResourceQuota'
belongs_to :host, class_name: '::Host::Managed' # , unqiue: true
# // Talk to Manisha regarding mico-service SQL relation
# -> For some reasion, when adding a host like my_quota.hosts << [some_host_a, some_host_b] results in NEW HostResources entries
# -> See the test on the right
# Make this become the relational one again
# Make ResourceQuota.hosts
# AND ResourceQuota.hosts_resources available -> to easily sum the hosts_resources(:disk) for example.
belongs_to :host, class_name: '::Host::Managed', foreign_key: :host_id
validates :host, { presence: true, uniqueness: true }

def resources
Expand All @@ -35,7 +34,7 @@ def resources=(val)
def missing_resources(only_active_resources: true)
empty_resources = []
resources_to_check = [:cpu_cores, :memory_mb, :disk_gb]
resources_to_check = self.resource_quota.active_resources if only_active_resources && self.resource_quota.present?
resources_to_check = host.resource_quota.active_resources if only_active_resources && host.resource_quota.present?

resources_to_check.each do |single_resource|
empty_resources << single_resource if self.send(single_resource).nil?
Expand Down
19 changes: 11 additions & 8 deletions app/models/foreman_resource_quota/resource_quota.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,28 @@ class ResourceQuota < ApplicationRecord

self.table_name = 'resource_quotas'

has_many :hosts_resources, class_name: 'HostResources', inverse_of: :resource_quota
has_many :resource_quota_hosts, class_name: 'ResourceQuotaHost', inverse_of: :resource_quota, dependent: :destroy
has_many :resource_quotas_users, class_name: 'ResourceQuotaUser', inverse_of: :resource_quota, dependent: :destroy
has_many :resource_quotas_usergroups, class_name: 'ResourceQuotaUsergroup', inverse_of: :resource_quota,
dependent: :destroy
has_many :hosts, -> { distinct }, class_name: '::Host::Managed', through: :hosts_resources
has_many :hosts, -> { distinct }, class_name: '::Host::Managed', through: :resource_quota_hosts
scope :hosts_resources, -> {
HostResources.joins(:host).where(hosts: { id: hosts.select(:id) })
}
# has_many :hosts_resources, through: :hosts, source: :host_resources
# has_many :hosts_resources, class_name: 'HostResources', through: :hosts, inverse_of: :host_resources
has_many :users, class_name: '::User', through: :resource_quotas_users
has_many :usergroups, class_name: '::Usergroup', through: :resource_quotas_usergroups

validates :name, presence: true, uniqueness: true

after_save :save_hosts_resources

scoped_search on: :name, complete_value: true
scoped_search on: :id, complete_enabled: false, only_explicit: true, validator: ScopedSearch::Validators::INTEGER

# def hosts_resources
# HostResources.where(host_id: hosts.select(:id))
# end

def number_of_hosts
hosts_resources.size
end
Expand Down Expand Up @@ -159,9 +166,5 @@ def create_hosts_resources_warning(missing_hosts_resources)
warn_text << " '#{host_name}': '#{missing_resources}'\n" unless missing_resources.empty?
end
end

def save_hosts_resources
hosts_resources.each { |host_resource| host_resource.save if host_resource.changed? }
end
end
end
10 changes: 10 additions & 0 deletions app/models/foreman_resource_quota/resource_quota_host.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

module ForemanResourceQuota
class ResourceQuotaHost < ApplicationRecord
self.table_name = 'resource_quotas_hosts'

belongs_to :resource_quota, class_name: 'ResourceQuota', foreign_key: :resource_quota_id
belongs_to :host, class_name: '::Host::Managed', foreign_key: :host_id
end
end
5 changes: 5 additions & 0 deletions config/initializers/inflections.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'resource_quota', 'resource_quotas'
inflect.irregular 'host_resources', 'hosts_resources'
inflect.singular 'host_resources', 'host_resources'
inflect.plural 'hosts_resources', 'hosts_resources'
inflect.irregular 'resource_quota_host', 'resource_quota_hosts'
inflect.singular 'resource_quota_host', 'resource_quota_host'
inflect.plural 'resource_quota_hosts', 'resource_quota_hosts'
end
8 changes: 7 additions & 1 deletion db/migrate/20240611142813_create_hosts_resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ class CreateHostsResources < ActiveRecord::Migration[6.1]
def change
create_table :hosts_resources do |t|
t.belongs_to :host, index: { unique: true }, foreign_key: true, null: false
t.belongs_to :resource_quota, foreign_key: true, default: nil
t.integer :cpu_cores, default: nil
t.integer :memory_mb, default: nil
t.integer :disk_gb, default: nil
end
end

def change
create_table :resource_quotas_hosts do |t|
t.belongs_to :host, index: { unique: true }, foreign_key: true, null: false
t.belongs_to :resource_quota, foreign_key: true, null: false

t.timestamps
end
Expand Down
8 changes: 1 addition & 7 deletions test/models/concerns/host_managed_extension_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,9 @@ def setup
host_b.name => { cpu_cores: 1, memory_mb: 1 },
}
require 'byebug'; byebug
// OK so the issue seems to be that by default in a has many_through through relation
it assumes that there is no entry in the intermediate table (host_resources). However,
we want to keep the entry even if there is no relation (if a host is disassociate from
a quota, we want to keep the relation
because otherwise we must re-calculate
the resources.)
-> try to find a fix for this. Maybe define a custom << method which uses existing entries?
quota = FactoryBot.create(:resource_quota, cpu_cores: 10, memory_mb: 10)
# quota.hosts_resources << [host_a.host_resources, host_b.host_resources]
quota.hosts.add(host_a)
quota.hosts.append([host_a, host_b])
assert quota.save

Expand Down

0 comments on commit 9fd80b7

Please sign in to comment.