Skip to content

Commit 4f32630

Browse files
committed
UI for node allocation from Intel Rackscale systems
- Lists available systems from Rackscale Simulator - Allows selection of specific systems for allocation - Creates a node object and allocates the same as a crowbar node - Also refined the controller to obtain system-specific info - UI contains only a list of check-boxes and one Allocate button
1 parent f5630c0 commit 4f32630

File tree

6 files changed

+226
-89
lines changed

6 files changed

+226
-89
lines changed

crowbar_framework/app/controllers/intelrsd_controller.rb

Lines changed: 133 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,32 @@
3131
# where the data model is employed.
3232
#
3333

34-
class IntelRSDController < ApplicationController
35-
attr_reader :logger, :insecure
34+
class RsdController < ApplicationController
35+
attr_reader :redfish_client, :logger
36+
37+
# Client setup for the class
38+
host = ENV["CROWBAR_REDFISH_HOST"] || "localhost"
39+
port = ENV["CROWBAR_REDFISH_PORT"] || "8443"
40+
@redfish_client = RedfishHelper::RedfishClient.new(host, port)
41+
42+
def show
43+
@title = "Welcome to RackScale Design"
44+
sys_list = get_all_systems
45+
@rsd_systems = "Systems not Available"
46+
unless sys_list.empty?
47+
@rsd_systems = sys_list
48+
end
49+
end
3650

37-
def initialize()
38-
@redfish_client = RedfishHelper::RedfishClient.new('localhost', '8443')
39-
@node_object_list = []
51+
def allocate
52+
all_sys_list = get_systems
53+
all_sys_list.each do |sys_id|
54+
next unless params[sys_id.to_s] == "1"
55+
node = get_crowbar_node_object(sys_id)
56+
node.allocate
57+
node.set_state("ready")
58+
end
59+
redirect_to rsd_show_path, notice: "Selected nodes allocated as compute nodes"
4060
end
4161

4262
def get_system_resource_list(sys_id, resource)
@@ -61,7 +81,37 @@ def make_node_object_for_system(sys_id)
6181
return nodeobject
6282
end
6383

64-
def get_systems()
84+
def get_processors(sys_id)
85+
proc_list = get_system_resource_list(sys_id, "Processors")
86+
processors = []
87+
proc_list.each do |proc|
88+
proc_object = Hash.new
89+
proc_object["Model"] = proc["Model"]
90+
proc_object["Manufacturer"] = proc["Manufacturer"]
91+
proc_object["Architecture"] = proc["Architecture"]
92+
proc_object["TotalCores"] = proc["TotalCores"]
93+
proc_object["TotalThreads"] = proc["TotalThreads"]
94+
processors.push(proc_object)
95+
end
96+
processors
97+
end
98+
99+
def get_memory(sys_id)
100+
mem_list = get_system_resource_list(sys_id, "Memory")
101+
memories = []
102+
mem_list.each do |mem|
103+
mem_object = Hash.new
104+
mem_object["MemoryType"] = mem["MemoryType"]
105+
mem_object["CapacityMB"] = mem["CapacityMiB"]
106+
mem_object["Speed"] = mem["OperatingSpeedMHz"]
107+
mem_object["Size"] = mem["SizeMiB"]
108+
mem_object["Health"] = mem["Health"]
109+
memories.push(mem_object)
110+
end
111+
memories
112+
end
113+
114+
def get_systems
65115
@systems = @redfish_client.get_resource("Systems")
66116
sys_list = []
67117

@@ -83,39 +133,46 @@ def get_system_data(sys_id)
83133
return system_data
84134
end
85135

86-
def get_rsd_nodes()
87-
system_list = get_systems()
88-
system_list.each do |system|
89-
node_object = make_node_object_for_system(system)
90-
@node_object_list.push(node_object)
136+
def get_all_systems
137+
sys_list = get_systems
138+
all_systems = []
139+
sys_list.each do |sys_id|
140+
sys_object = Hash.new
141+
sys_object["SystemId"] = sys_id
142+
sys_object["Processors"] = get_processors(sys_id)
143+
sys_object["Memory"] = get_memory(sys_id)
144+
all_systems.push(sys_object)
91145
end
92-
return @node_object_list
93-
end
94-
95-
def reset_system(sys_id)
96-
post_action("Systems/#{sys_id}", action: "ComputerSystem.Reset")
146+
all_systems
97147
end
98148

99149
def get_crowbar_node_object(sys_id)
100150
system_object = get_system_data(sys_id)
101151
node_name_prefix = "d"
102-
node_name_prefix = "IRSD" if system_object["Oem"].has_key?("Intel_RackScale")
152+
node_name_prefix = "IRSD-" if system_object["Oem"].key?("Intel_RackScale")
103153

154+
# Pickin up the first IP address. This may not be always the correct address.
155+
# It must be revisited when testing with Rackscale hardware.
104156
eth_interface = system_object["EthernetInterfaces"].first
105-
node_name = node_name_prefix + eth_interface["MACAddress"].gsub(":", "-")
106-
107-
node = NodeObject.create_new node_name
108-
NodeObject.initialize(node)
109-
node.set['name'] = node_name
110-
node.set['target_cpu'] = ""
111-
node.set['target_vendor'] = "suse"
112-
node.set['host_cpu'] = ""
113-
node.set['host_vendor'] = "suse"
114-
node.set['kernel'] = "" # Kernel modules and configurations
115-
node.set['counters'] = "" # various network interfaces and other counters
116-
node.set['hostname'] = node_name
117-
node.set['fqdn'] = node_name + "." + ChefObject.cloud_domain
118-
node.set['domain'] = ChefObject.cloud_domain
157+
node_name = node_name_prefix + eth_interface["MACAddress"].tr(":", "-") + "-#{sys_id}"
158+
159+
node = NodeObject.create_new "#{node_name}.#{Crowbar::Settings.domain}".downcase
160+
161+
node.set["name"] = node_name
162+
# set a flag to identify this node as a rackscale one
163+
node.set["rackscale"] = true
164+
# track the rackscale id for this node
165+
node.set["rackscale_id"] = sys_id
166+
node.set["target_cpu"] = "x86_64"
167+
node.set["target_vendor"] = "suse"
168+
node.set["host_cpu"] = system_object["ProcessorSummary"]["Model"]
169+
node.set["host_vendor"] = "suse"
170+
node.set["kernel"] = "" # Kernel modules and configurations
171+
node.set["counters"] = "" # various network interfaces and other counters
172+
node.set["hostname"] = node_name
173+
node.set["fqdn"] = "#{node_name}.#{Crowbar::Settings.domain}"
174+
node.set["domain"] = Crowbar::Settings.domain
175+
119176
ipaddress_data = eth_interface["IPv4Addresses"].first
120177
node.set['ipaddress'] = ipaddress_data["Address"]
121178
node.set['macaddress'] = eth_interface["MACAddress"]
@@ -125,66 +182,53 @@ def get_crowbar_node_object(sys_id)
125182
node.set['recipes'] = ""
126183

127184
# Add other roles as seen fit
128-
node.set['roles'] = []
129-
["deployer-config-default", "network-config-default", "dns-config-default",
130-
"logging-config-default", "ntp-config-default", "nova-compute-kvm",
131-
"provisioner-base", "provisioner-config-default", "crowbar-#{node['fqdn']}"].each do |role_name|
132-
role = RoleObject.find_role_by_name "#{role_name}"
133-
node['roles'] += role
134-
end
135-
136-
node.set['run_list'] = ["role[#{node['roles']}]"]
137-
node.set['keys']['host']['host_dsa_public'] = ""
138-
node.set['keys']['host']['host_rsa_public'] = ""
139-
node.set['keys']['host']['host_ecdsa_public'] = ""
140-
node.set['virtualization']['system'] = "kvm"
141-
node.set['virtualization']['role'] = "guest"
142-
node.set['platform'] = "suse"
143-
node.set['platform_version'] = "12.1"
144-
node.set['dmi']['bios']['all_records'] = ""
145-
node.set['dmi']['bios']['vendor'] = ""
146-
node.set['dmi']['bios']['version'] = system_object["BiosVersion"]
147-
node.set['dmi']['bios']['release_date'] = ""
148-
node.set['dmi']['bios']['address'] = ""
149-
node.set['dmi']['bios']['runtime_size'] = ""
150-
node.set['dmi']['bios']['rom_size'] = ""
151-
node.set['dmi']['bios']['bios_revision'] = ""
152-
node.set['dmi']['system']['product_name'] = ""
153-
node.set['dmi']['system']['manufacturer'] = ""
154-
node.set['dmi']['system']['serial_number'] = "Not Specified"
155-
node.set['dmi']['system']['uuid'] = ""
156-
node.set['dmi']['system']['wake_up_type'] = "Power Switch"
157-
node.set['dmi']['system']['sku_number'] = "Not Specified"
158-
node.set['dmi']['system']['family'] = "Not Specified"
159-
node.set['dmi']['chassis']['serial_number'] = system_object['Chassis']['SerialNumber']
160-
node.set['dmi']['chassis']['all_records'] = ""
161-
node.set['dmi']['chassis']['manufacturer'] = ""
162-
node.set['dmi']['chassis']['all_records'] = ""
163-
node.set['dmi']['chassis']['boot_up_state'] = "Safe"
164-
node.set['dmi']['chassis']['power_supply_state'] = "Safe"
165-
node.set['block_device']['sda'] = ""
166-
node.set['memory']['swap'] = ""
167-
node.set['memory']['buffers'] = ""
168-
169-
system_object["Processors"].each do | processor |
170-
id = processor["Id"]
171-
node.set["cpu"]["#{id}"]['manufacturer'] = processor["Manufacturer"]
172-
node.set["cpu"]["#{id}"]["model"] = processor["Model"]
173-
node.set["cpu"]["#{id}"]["family"] = processor["ProcessorArchitecture"]
174-
node.set["cpu"]["#{id}"]["family"] = "x86_64" if processor["InstructionSet"] == "x86-64"
175-
node.set["cpu"]["#{id}"]["flags"] = processor["Capabilities"]
185+
node.set["roles"] = []
186+
["deployer-config-default", "network-config-default", "dns-config-default",
187+
"logging-config-default", "ntp-config-default",
188+
"provisioner-base", "provisioner-config-default", "nova-compute"].each do |role_name|
189+
node["roles"] << role_name
190+
end
191+
192+
node.set["run_list"] = ["role[crowbar-#{node_name}.#{Crowbar::Settings.domain.tr(".", "_")}]"]
193+
node.set["keys"]["host"]["host_dsa_public"] = ""
194+
node.set["keys"]["host"]["host_rsa_public"] = ""
195+
node.set["keys"]["host"]["host_ecdsa_public"] = ""
196+
node.set["virtualization"]["system"] = "kvm"
197+
node.set["virtualization"]["role"] = "guest"
198+
node.set["platform"] = "suse"
199+
node.set["platform_version"] = "12.1"
200+
node.set["dmi"]["bios"]["version"] = system_object["BiosVersion"]
201+
node.set["dmi"]["system"]["product_name"] = system_object["Model"]
202+
node.set["dmi"]["system"]["manufacturer"] = system_object["Manufacturer"]
203+
node.set["dmi"]["system"]["serial_number"] = system_object["SerialNumber"]
204+
node.set["dmi"]["system"]["uuid"] = system_object["UUID"]
205+
node.set["dmi"]["system"]["wake_up_type"] = "Power Switch"
206+
node.set["dmi"]["system"]["sku_number"] = "Not Specified"
207+
node.set["dmi"]["system"]["family"] = "Not Specified"
208+
node.set["dmi"]["chassis"]["serial_number"] = system_object["SerialNumber"]
209+
node.set["dmi"]["chassis"]["boot_up_state"] = "Safe"
210+
node.set["dmi"]["chassis"]["power_supply_state"] = "Safe"
211+
# this is needed so its counted properly for the UI
212+
node.set["block_device"]["sda"] = { removable: "0" }
213+
node.set["memory"]["swap"] = ""
214+
node.set["memory"]["buffers"] = ""
215+
total_mem = 0
216+
system_object["Memory"].each do |m|
217+
total_mem += m["CapacityMiB"].to_i
218+
end
219+
node.set["memory"]["total"] = "#{total_mem * 1024}kB"
220+
221+
system_object["Processors"].each do |processor|
222+
id = processor["Id"].to_i - 1 # API starts at 1, we start at 0
223+
node.set["cpu"][id.to_s]["manufacturer"] = processor["Manufacturer"]
224+
node.set["cpu"][id.to_s]["model"] = processor["Model"]
225+
node.set["cpu"][id.to_s]["family"] = processor["ProcessorArchitecture"]
226+
node.set["cpu"][id.to_s]["family"] = "x86_64" if processor["InstructionSet"] == "x86-64"
227+
node.set["cpu"][id.to_s]["flags"] = processor["Capabilities"]
176228
end
177229

178-
node.set['filesystem']['sysfs'] = ""
230+
node.set["filesystem"]["sysfs"] = ""
179231
node.save
232+
node
180233
end
181234
end
182-
183-
# usage of the controller APIs
184-
rsd_controller = IntelRSDController.new
185-
node_list = rsd_controller.get_rsd_nodes()
186-
first_node = node_list.first
187-
p "FIRST NODE: #{first_node}"
188-
# node_object = rsd_controller.get_crowbar_node_object(first_node["System_Id"])
189-
# p node_object
190-
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.row
2+
.col-xs-12
3+
%h1.page-header
4+
= t(".title")
5+
6+
.row
7+
.col-xs-12
8+
.panel.panel-default
9+
.panel-body
10+
.alert.alert-info
11+
= t(".rsd_header")
12+
13+
= form_for :node, :url => rsd_allocate_path, :html => { :role => "form" } do |f|
14+
= hidden_field_tag "return", @allocated
15+
.panel.panel-default#accordion
16+
%h2
17+
= t(".sys_header")
18+
.panel-panel-body
19+
%table.table.table-hover.table-middle{ :style => "border: 1px; width: 100%" }
20+
%thead
21+
%tr
22+
%th
23+
= t(".rsd_selection")
24+
%th
25+
= t(".system_id")
26+
%tbody
27+
- @rsd_systems.each do |rsd_system|
28+
%tr
29+
%td= check_box_tag "#{rsd_system['SystemId']}"
30+
%td= link_to("System-#{rsd_system['SystemId']}")
31+
.btn-group.pull-right
32+
%input.btn.btn-default{ :type => "submit", :name => "allocate", :value => t(".allocate_switch") }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Copyright 2016, SUSE LINUX GmbH
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
en:
18+
nav:
19+
utils:
20+
rsd: 'Intel RackScale'
21+
rsd:
22+
show:
23+
title: 'Intel Rackscale'
24+
rsd_header: 'Lists Systems available from Intel RackScale server by talking to the Redfish APIs'
25+
man_header: 'Managers'
26+
sys_header: 'Systems'
27+
sw_header: 'Switches'
28+
ch_header: 'Chassis'
29+
allocate_switch: 'Allocate'
30+
rsd_selection: 'Selection'
31+
system_id: 'System ID'
32+
barclamp:
33+
rsd:
34+
login:
35+
provide_creds: 'Please provide Rackscale login credentials.'
36+
please_login: 'No active Rackscale session; please login.'

crowbar_framework/config/navigation.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
level2.item :repositories, t("nav.utils.repositories"), repositories_path
4040
level2.item :backup, t("nav.utils.backup"), backups_path
4141
level2.item :logs, t("nav.utils.logs"), utils_path
42+
level2.item :rsd, t("nav.utils.rsd"), rsd_show_path
4243
end
4344
end
4445
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright 2016, SUSE LINUX GmbH
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
get 'rsd/show' => 'rsd#show', as: 'rsd_show'
18+
post 'rsd/allocate' => 'rsd#allocate', as: 'rsd_allocate'

intelrsd.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ crowbar:
2929
run_order: 112
3030
chef_order: 112
3131
proposal_schema_version: 3
32+
33+
nav:
34+
utils:
35+
rsd:
36+
order: 91
37+
route: 'rsd_edit_path'

0 commit comments

Comments
 (0)