From mmorsi at redhat.com Wed Apr 1 00:17:44 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 31 Mar 2009 20:17:44 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238533522-962-1-git-send-email-dpierce@redhat.com> References: <1238533522-962-1-git-send-email-dpierce@redhat.com> Message-ID: <49D2B2A8.5000904@redhat.com> Looks good for most part, save a few specifics, comments below. Darryl L. Pierce wrote: > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > Signed-off-by: Darryl L. Pierce > --- > src/lib/managed_node_configuration.rb | 77 +++++++++----------- > src/test/fixtures/nics.yml | 6 +- > .../functional/managed_node_configuration_test.rb | 15 +++-- > 3 files changed, 48 insertions(+), 50 deletions(-) > > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..f864c46 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > - > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > > - result.puts "#{entry}|ONBOOT=yes" > + add_bridge(result, > + "none", > + bonding.interface_name, > + (bonding.ip_addresses.empty? ? "dhcp" : "static"), > + (bonding.ip_addresses.empty? ? nil : bonding.ip_addresses[0])) > > Are you sure bonding bridges don't need to have an assigned mac address? Also instead of checking for bonding.ip_addresses.empty? shouldn't we utilize bonding.vlan.nil?. Furthermore bonding.vlan.proto should be employed similar to nic.physical_network.proto below Furthermore I believe simply passing in / using the bonding ip address for netmask / broadcast won't work as explained below. > bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + iface_name = macs[nic.mac] > + if iface_name > + add_slave(result, nic.mac, iface_name, bonding.interface_name) > + end > end > end > > - has_bridge = false > host.nics.each do |nic| > - # only process this nic if it doesn't have a bonding > - # TODO remove the hack to force a bridge into the picture > if nic.bondings.empty? > - process_nic result, nic, macs, nil, false, true > - > - # TODO remove this when bridges are properly supported > - unless has_bridge > - macs[nic.mac] = "breth0" > - process_nic result, nic, macs, nil, true, false > - has_bridge = true > - end > + iface_name = macs[nic.mac] > + if iface_name > + add_bridge(result, > + nic.mac, > + iface_name, > + nic.physical_network.boot_type.proto, > + nic.ip_addresses[0]) > I believe we should have the same ip_addresses.empty? check here as we do w/ bondings as if a nic can be assigned to a dhcp network and have no explicitly associated ip addresses. Furthermore nic.physical_network should be checked to see if null, as a nic doesn't have to be assigned to a network. (actually I believe one of the reqs is that if it a nic isn't assigned to a network, it shouldn't be included in the config returned to the node here, but we should check w/ Hugh to make sure) Also the same issue w/ passing in / using the nic ip address for netmask / broadcast won't work as explained below. > + add_nic(result, nic.mac, iface_name) > + end > end > end > > @@ -102,27 +104,20 @@ class ManagedNodeConfiguration > > private > > - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) > - iface_name = macs[nic.mac] > - > - if iface_name > - entry = "ifcfg=#{nic.mac}|#{iface_name}" > - > - if bonding > - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" > - else > - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" > - if nic.physical_network.boot_type.proto == 'static' > - ip = nic.ip_addresses[0] > - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > While for static networks the ip associated w/ the nic / bonding will contain the assigned ip address, it will not contain the netmask and the broadcast. Rather this data is contained in the ip_address associated w/ the network which the nic / bonding is assigned to (physical net or vlan). Essentially you configure the gateway / netmask / broadcast when configuring the network and simply assign an ip address to the actual device. > - end > - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge > - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge > - entry += "|TYPE=bridge" if is_bridge > - end > - entry += "|ONBOOT=yes" > + def self.add_bridge(result, mac, iface_name, bootproto, ipaddress) > + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" > + if ipaddress > + entry += "|IPADDR=#{ipaddress.address}|NETMASK=#{ipaddress.netmask}|BROADCAST=#{ipaddress.broadcast}" > end > + entry += "|TYPE=bridge|ONBOOT=yes" > We also need 'PEERDNS=no' associated w/ bridge configuration here. > + result.puts entry > + end > + > + def self.add_nic(result, mac, iface_name) > + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" > + end > > - result.puts entry if defined? entry > + def self.add_slave(result, mac, iface_name, master) > + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" > end > end > diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml > index b8bb6c7..048d80c 100644 > --- a/src/test/fixtures/nics.yml > +++ b/src/test/fixtures/nics.yml > @@ -10,7 +10,7 @@ mailserver_nic_two: > usage_type: 1 > bandwidth: 100 > host: mailservers_managed_node > - physical_network: dhcp_physical_network_one > + physical_network: dhcp_physical_network_two > > fileserver_nic_one: > mac: 00:99:00:99:13:07 > @@ -23,7 +23,7 @@ ldapserver_nic_one: > mac: 00:03:02:00:09:06 > usage_type: 1 > bandwidth: 100 > - bridge: breth0 > + bridge: > host: ldapserver_managed_node > physical_network: static_physical_network_one > > @@ -53,4 +53,4 @@ mediaserver_nic_two: > usage_type: 1 > bandwidth: 100 > host: mediaserver_managed_node > - physical_network: dhcp_physical_network_one > + physical_network: dhcp_physical_network_two > diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb > index 6ce4885..b6e591c 100644 > --- a/src/test/functional/managed_node_configuration_test.rb > +++ b/src/test/functional/managed_node_configuration_test.rb > @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes > ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes > ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes > ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes > -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > @@ -140,7 +142,8 @@ HERE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > -Mo From mmorsi at redhat.com Wed Apr 1 00:19:12 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 31 Mar 2009 20:19:12 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238533522-962-1-git-send-email-dpierce@redhat.com> References: <1238533522-962-1-git-send-email-dpierce@redhat.com> Message-ID: <49D2B300.7020006@redhat.com> Looks good for most part, save a few specifics, comments below. Darryl L. Pierce wrote: > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > Signed-off-by: Darryl L. Pierce > --- > src/lib/managed_node_configuration.rb | 77 +++++++++----------- > src/test/fixtures/nics.yml | 6 +- > .../functional/managed_node_configuration_test.rb | 15 +++-- > 3 files changed, 48 insertions(+), 50 deletions(-) > > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..f864c46 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > - > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > > - result.puts "#{entry}|ONBOOT=yes" > + add_bridge(result, > + "none", > + bonding.interface_name, > + (bonding.ip_addresses.empty? ? "dhcp" : "static"), > + (bonding.ip_addresses.empty? ? nil : bonding.ip_addresses[0])) > > Are you sure bonding bridges don't need to have an assigned mac address? Also instead of checking for bonding.ip_addresses.empty? shouldn't we utilize bonding.vlan.nil?. Furthermore bonding.vlan.proto should be employed similar to nic.physical_network.proto below Furthermore I believe simply passing in / using the bonding ip address for netmask / broadcast won't work as explained below. > bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + iface_name = macs[nic.mac] > + if iface_name > + add_slave(result, nic.mac, iface_name, bonding.interface_name) > + end > end > end > > - has_bridge = false > host.nics.each do |nic| > - # only process this nic if it doesn't have a bonding > - # TODO remove the hack to force a bridge into the picture > if nic.bondings.empty? > - process_nic result, nic, macs, nil, false, true > - > - # TODO remove this when bridges are properly supported > - unless has_bridge > - macs[nic.mac] = "breth0" > - process_nic result, nic, macs, nil, true, false > - has_bridge = true > - end > + iface_name = macs[nic.mac] > + if iface_name > + add_bridge(result, > + nic.mac, > + iface_name, > + nic.physical_network.boot_type.proto, > + nic.ip_addresses[0]) > I believe we should have the same ip_addresses.empty? check here as we do w/ bondings as if a nic can be assigned to a dhcp network and have no explicitly associated ip addresses. Furthermore nic.physical_network should be checked to see if null, as a nic doesn't have to be assigned to a network. (actually I believe one of the reqs is that if it a nic isn't assigned to a network, it shouldn't be included in the config returned to the node here, but we should check w/ Hugh to make sure) Also the same issue w/ passing in / using the nic ip address for netmask / broadcast won't work as explained below. > + add_nic(result, nic.mac, iface_name) > + end > end > end > > @@ -102,27 +104,20 @@ class ManagedNodeConfiguration > > private > > - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) > - iface_name = macs[nic.mac] > - > - if iface_name > - entry = "ifcfg=#{nic.mac}|#{iface_name}" > - > - if bonding > - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" > - else > - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" > - if nic.physical_network.boot_type.proto == 'static' > - ip = nic.ip_addresses[0] > - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > While for static networks the ip associated w/ the nic / bonding will contain the assigned ip address, it will not contain the netmask and the broadcast. Rather this data is contained in the ip_address associated w/ the network which the nic / bonding is assigned to (physical net or vlan). Essentially you configure the gateway / netmask / broadcast when configuring the network and simply assign an ip address to the actual device. > - end > - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge > - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge > - entry += "|TYPE=bridge" if is_bridge > - end > - entry += "|ONBOOT=yes" > + def self.add_bridge(result, mac, iface_name, bootproto, ipaddress) > + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" > + if ipaddress > + entry += "|IPADDR=#{ipaddress.address}|NETMASK=#{ipaddress.netmask}|BROADCAST=#{ipaddress.broadcast}" > end > + entry += "|TYPE=bridge|ONBOOT=yes" > We also need 'PEERDNS=no' associated w/ bridge configuration here. > + result.puts entry > + end > + > + def self.add_nic(result, mac, iface_name) > + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" > + end > > - result.puts entry if defined? entry > + def self.add_slave(result, mac, iface_name, master) > + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" > end > end > diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml > index b8bb6c7..048d80c 100644 > --- a/src/test/fixtures/nics.yml > +++ b/src/test/fixtures/nics.yml > @@ -10,7 +10,7 @@ mailserver_nic_two: > usage_type: 1 > bandwidth: 100 > host: mailservers_managed_node > - physical_network: dhcp_physical_network_one > + physical_network: dhcp_physical_network_two > > fileserver_nic_one: > mac: 00:99:00:99:13:07 > @@ -23,7 +23,7 @@ ldapserver_nic_one: > mac: 00:03:02:00:09:06 > usage_type: 1 > bandwidth: 100 > - bridge: breth0 > + bridge: > host: ldapserver_managed_node > physical_network: static_physical_network_one > > @@ -53,4 +53,4 @@ mediaserver_nic_two: > usage_type: 1 > bandwidth: 100 > host: mediaserver_managed_node > - physical_network: dhcp_physical_network_one > + physical_network: dhcp_physical_network_two > diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb > index 6ce4885..b6e591c 100644 > --- a/src/test/functional/managed_node_configuration_test.rb > +++ b/src/test/functional/managed_node_configuration_test.rb > @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes > ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes > ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes > ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes > -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > @@ -140,7 +142,8 @@ HERE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > -Mo From mmorsi at redhat.com Wed Apr 1 00:21:10 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 31 Mar 2009 20:21:10 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <49D2B300.7020006@redhat.com> References: <1238533522-962-1-git-send-email-dpierce@redhat.com> <49D2B300.7020006@redhat.com> Message-ID: <49D2B376.3080902@redhat.com> Sorry, you can ignore this second message, its just a resend of the first (net connection died mid-send). -Mo From dpierce at redhat.com Wed Apr 1 12:32:20 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 08:32:20 -0400 Subject: [Ovirt-devel] [PATCH server] Fixed a few bugs in o-identify-node processing. In-Reply-To: <49D29C92.8060707@redhat.com> References: <1238513166-25425-1-git-send-email-dpierce@redhat.com> <49D29C92.8060707@redhat.com> Message-ID: <20090401123220.GC4652@mcpierce-laptop.rdu.redhat.com> On Tue, Mar 31, 2009 at 06:43:30PM -0400, Mohammed Morsi wrote: > This 'collect' should more optimally be 'each' as we're not using the > array returned by collect. Fixed those. > > - if detail['MAC'] == nic.mac > > + if detail['MAC'].upcase == nic.mac > > + puts "Updating details for: #{nic.interface_name} [#{nic.mac}]}" > > nic_info.delete(detail) > > > The 'detail' nic is being removed from the nic_info array here, and at > the end of this if block as well (see below) D'oh! Fixed that. > > > > updated_nic = Nic.find_by_id(nic.id) > > @@ -286,7 +288,6 @@ class HostBrowser > > updated_nic.bandwidth = detail['BANDWIDTH'].to_i > > updated_nic.interface_name = detail['IFACE_NAME'] > > > > - updated_nic.save! > > > Will this work if you remove this? If I understand what your doing by > reading this, you are relying on the host.save! a little further down to > save the updated nics, but the manipulation of the nic object (eg > updating bandwidth and interface name) occurs on a nic object you > explicitly retrieve via find_by_id here. Unless I'm mistaken you will > either need this updated_nic.save! or instead of updating the nic via > the "updated_nic" object, you can simply use the "nic" object (eg the > iterator as set via the host.nics.collect{ |nic| above). This was some old code. I refactored that whole chunk so that it would use the nic object it already had. Now it'll update that and save it inline. Updated patch is in-flight for this. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 1 12:34:16 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 08:34:16 -0400 Subject: [Ovirt-devel] [PATCH server] Fixed a few bugs in o-identify-node processing. Message-ID: <1238589256-7478-1-git-send-email-dpierce@redhat.com> NOTE: This version includes fixes based on feedback from mmorsi and some refactorings to the way nics are updated. Fixed the processing of NICs to handle properly deleting a NIC that was not identified by the node. All unidentified NICs are now deleted from the database after o-i-node runs. Signed-off-by: Darryl L. Pierce --- src/host-browser/host-browser.rb | 36 ++++++++++++++++++------------------ 1 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb index 1c5cf83..b927d3c 100755 --- a/src/host-browser/host-browser.rb +++ b/src/host-browser/host-browser.rb @@ -248,7 +248,7 @@ class HostBrowser Cpu.delete_all(['host_id = ?', host.id]) puts "Saving new CPU records" - cpu_info.collect do |cpu| + cpu_info.each do |cpu| detail = Cpu.new( "cpu_number" => cpu['CPUNUM'].to_i, "core_number" => cpu['CORENUM]'].to_i, @@ -271,37 +271,37 @@ class HostBrowser puts "Updating NIC records for the node" nics = Array.new + nics_to_delete = Array.new - host.nics.collect do |nic| + host.nics.each do |nic| found = false - nic_info.collect do |detail| + nic_info.each do |detail| # if we have a match, then update the database and remove # the received data to avoid creating a dupe later - if detail['MAC'] == nic.mac - nic_info.delete(detail) - - updated_nic = Nic.find_by_id(nic.id) - - updated_nic.bandwidth = detail['BANDWIDTH'].to_i - updated_nic.interface_name = detail['IFACE_NAME'] - - updated_nic.save! - found=true - nic_info.delete detail + puts "Searching for existing record for: #{detail['MAC'].upcase}" + if detail['MAC'].upcase == nic.mac + puts "Updating details for: #{detail['IFACE_NAME']} [#{nic.mac}]}" + nic.bandwidth = detail['BANDWIDTH'].to_i + nic.interface_name = detail['IFACE_NAME'] + nic.save! + found = true + nic_info.delete(detail) end end # if the record wasn't found, then remove it from the database unless found - host.nics.delete(nic) - nic.destroy + puts "Marking NIC for removal: #{nic.interface_name} [#{nic.mac}]" + nics_to_delete << nic end end + nics_to_delete.each { |nic| puts "Removing NIC: #{nic.interface_name} []#{nic.mac}]"; host.nics.delete(nic) } + # iterate over any nics left and create new records for them. - nic_info.collect do |nic| - puts "Creating a new nic..." + nic_info.each do |nic| + puts "Creating a new nic: #{nic.interface_name} [#{nic.mac}]" detail = Nic.new( 'mac' => nic['MAC'].upcase, 'bandwidth' => nic['BANDWIDTH'].to_i, -- 1.6.0.6 From dpierce at redhat.com Wed Apr 1 12:43:56 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 08:43:56 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <49D2B2A8.5000904@redhat.com> References: <1238533522-962-1-git-send-email-dpierce@redhat.com> <49D2B2A8.5000904@redhat.com> Message-ID: <20090401124356.GD4652@mcpierce-laptop.rdu.redhat.com> On Tue, Mar 31, 2009 at 08:17:44PM -0400, Mohammed Morsi wrote: > > - result.puts "#{entry}|ONBOOT=yes" > > + add_bridge(result, > > + "none", > > + bonding.interface_name, > > + (bonding.ip_addresses.empty? ? "dhcp" : "static"), > > + (bonding.ip_addresses.empty? ? nil : bonding.ip_addresses[0])) > > > > > Are you sure bonding bridges don't need to have an assigned mac address? Yes, I'm certain: 8. Where does a bonding device get its MAC address from? If not explicitly configured with ifconfig, the MAC address of the bonding device is taken from its first slave device. This MAC address is then passed to all following slaves and remains persistent (even if the the first slave is removed) until the bonding device is brought down or reconfigured. http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/bonding.txt Applying your other comments. Updated patch to follow. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From bkearney at redhat.com Wed Apr 1 13:59:54 2009 From: bkearney at redhat.com (Bryan Kearney) Date: Wed, 01 Apr 2009 09:59:54 -0400 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090331120417.46cc64ef@tp.mains.net> References: <20090331120417.46cc64ef@tp.mains.net> Message-ID: <49D3735A.8070808@redhat.com> Ian Main wrote: > > # Look up completed tasks. > tasks = s.objects(:class => 'Task', 'completed' => true) How does this work on the backend? Are all Tasks instantiated and managed by the agent, or does this turn into a method call to get he managed objects? > > tasks.each do |task| > puts "task #{task.description} completed" > puts "Error message: #{task.message}" if task.error > end > > > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From jason.guiditta at gmail.com Wed Apr 1 14:15:30 2009 From: jason.guiditta at gmail.com (Jason Guiditta) Date: Wed, 1 Apr 2009 10:15:30 -0400 Subject: [Ovirt-devel] [PATCH server] Correct errors in fixtures. Message-ID: <1238595330-3709-1-git-send-email-jason.guiditta@gmail.com> These errors were killing all the tests. Currently there should only be one remaining error on storage_volume_test, which will be fixed in a subsequent patch. --- src/test/fixtures/networks.yml | 30 ++++++++++++++++++++++++++++++ src/test/fixtures/nics.yml | 12 ++++++------ src/test/unit/ip_address_test.rb | 4 +++- src/test/unit/nic_test.rb | 7 ++++--- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/test/fixtures/networks.yml b/src/test/fixtures/networks.yml index f78d1b4..fa32f0f 100644 --- a/src/test/fixtures/networks.yml +++ b/src/test/fixtures/networks.yml @@ -21,11 +21,41 @@ static_physical_network_one: name: Static Physical Network 1 boot_type: boot_type_static_ip +mail_network_one: + type: PhysicalNetwork + name: DHCP Mail Network 1 + boot_type: boot_type_dhcp + +mail_network_two: + type: PhysicalNetwork + name: DHCP Mail Network 2 + boot_type: boot_type_dhcp + +fileserver_network: + type: PhysicalNetwork + name: DHCP Fileserver Network + boot_type: boot_type_dhcp + +mediaserver_network_one: + type: PhysicalNetwork + name: DHCP Mediaserver Network 1 + boot_type: boot_type_dhcp + +mediaserver_network_two: + type: PhysicalNetwork + name: DHCP Mediaserver Network 2 + boot_type: boot_type_dhcp + dhcp_physical_network_one: type: PhysicalNetwork name: DHCP Physical Network 1 boot_type: boot_type_dhcp +dhcp_physical_network_two: + type: PhysicalNetwork + name: DHCP Physical Network 2 + boot_type: boot_type_dhcp + bootp_physical_network_one: type: PhysicalNetwork name: BOOTP Physical Network 1 diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index b8bb6c7..1cf3223 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -3,21 +3,21 @@ mailserver_nic_one: usage_type: 1 bandwidth: 100 host: mailservers_managed_node - physical_network: dhcp_physical_network_one + physical_network: mail_network_one mailserver_nic_two: mac: 22:11:33:66:44:55 usage_type: 1 bandwidth: 100 host: mailservers_managed_node - physical_network: dhcp_physical_network_one + physical_network: mail_network_two fileserver_nic_one: mac: 00:99:00:99:13:07 usage_type: 1 bandwidth: 100 host: fileserver_managed_node - physical_network: dhcp_physical_network_one + physical_network: fileserver_network ldapserver_nic_one: mac: 00:03:02:00:09:06 @@ -39,18 +39,18 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_one + physical_network: static_physical_network_two mediaserver_nic_one: mac: 07:17:19:65:03:32 usage_type: 1 bandwidth: 100 host: mediaserver_managed_node - physical_network: dhcp_physical_network_one + physical_network: mediaserver_network_one mediaserver_nic_two: mac: 07:17:19:65:03:31 usage_type: 1 bandwidth: 100 host: mediaserver_managed_node - physical_network: dhcp_physical_network_one + physical_network: mediaserver_network_two diff --git a/src/test/unit/ip_address_test.rb b/src/test/unit/ip_address_test.rb index 4cfc694..89972ad 100644 --- a/src/test/unit/ip_address_test.rb +++ b/src/test/unit/ip_address_test.rb @@ -13,6 +13,8 @@ class IpAddressTest < ActiveSupport::TestCase def test_valid_fails_without_foreign_entity @ip_address = IpAddress.new - flunk "Ip Address must be associated with network, nic, or bonding" if @ip_address.valid? +# FIXME: this is a temporary fix. Validations were dropped in models while +# this networking is in flux. Revisit this test once that stabilizes. + flunk "Ip Address must be associated with network, nic, or bonding" unless @ip_address.valid? end end diff --git a/src/test/unit/nic_test.rb b/src/test/unit/nic_test.rb index 2644148..07f54c6 100644 --- a/src/test/unit/nic_test.rb +++ b/src/test/unit/nic_test.rb @@ -60,10 +60,11 @@ class NicTest < Test::Unit::TestCase flunk 'Nic must have a host' if @nic.valid? end - def test_valid_fails_without_physical_network - @nic.physical_network = nil + def test_valid_fails_without_unique_physical_network + @nic.host = hosts(:ldapserver_managed_node) - flunk 'Nic must have a physical network' if @nic.valid? + assert_equal false, @nic.valid?, 'This nic is not valid' + flunk 'This physical network is already used on this host.' if @nic.valid? end def test_valid_fails_with_invalid_bandwidth -- 1.6.0.6 From dpierce at redhat.com Wed Apr 1 14:24:31 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 10:24:31 -0400 Subject: [Ovirt-devel] [PATCH server] Correct errors in fixtures. In-Reply-To: <1238595330-3709-1-git-send-email-jason.guiditta@gmail.com> References: <1238595330-3709-1-git-send-email-jason.guiditta@gmail.com> Message-ID: <20090401142431.GE4652@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 01, 2009 at 10:15:30AM -0400, Jason Guiditta wrote: > These errors were killing all the tests. Currently > there should only be one remaining error on storage_volume_test, > which will be fixed in a subsequent patch. > --- ACK. All of the tests work but the one identified. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 1 15:35:35 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 11:35:35 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. Message-ID: <1238600135-17216-1-git-send-email-dpierce@redhat.com> Refactored how interfaces, bonded interfaces and bridges are defined. When returning a configuration for the node, a bridge is first created, using the networking definition for the device. The network interface is then bridged over that device. When a bonded interface is created, a bridge is created for it as well. Signed-off-by: Darryl L. Pierce --- src/lib/managed_node_configuration.rb | 77 +++++++++----------- src/test/fixtures/ip_addresses.yml | 9 +++ src/test/fixtures/nics.yml | 4 +- .../functional/managed_node_configuration_test.rb | 21 +++--- 4 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index c412917..61ee09e 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -65,35 +65,37 @@ class ManagedNodeConfiguration # now process the network interfaces and bondings host.bondings.each do |bonding| - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" - - if bonding.ip_addresses.empty? - entry += "|BOOTPROTO=dhcp" - else - ip = bonding.ip_addresses[0] - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" + entry += "|ONBOOT=yes" + result.puts entry - result.puts "#{entry}|ONBOOT=yes" + ipaddress=(bonding.ip_addresses.empty? ? nil : bonding.ip_addresses.first.address) + netmask =(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.netmask) + broadcast=(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.broadcast) + add_bridge(result,"none",bonding.interface_name, + bonding.vlan.boot_type.proto, ipaddress, netmask, broadcast) bonding.nics.each do |nic| - process_nic result, nic, macs, bonding + iface_name = macs[nic.mac] + if iface_name + add_slave(result, nic.mac, iface_name, bonding.interface_name) + end end end - has_bridge = false host.nics.each do |nic| - # only process this nic if it doesn't have a bonding - # TODO remove the hack to force a bridge into the picture if nic.bondings.empty? - process_nic result, nic, macs, nil, false, true - - # TODO remove this when bridges are properly supported - unless has_bridge - macs[nic.mac] = "breth0" - process_nic result, nic, macs, nil, true, false - has_bridge = true - end + iface_name = macs[nic.mac] + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.address) + netmask =(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.netmask) + broadcast=(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.broadcast) + if iface_name + add_bridge(result,nic.mac,iface_name, + nic.physical_network.boot_type.proto,ipaddress,netmask,broadcast) + add_nic(result, nic.mac, iface_name) + end end end @@ -102,27 +104,20 @@ class ManagedNodeConfiguration private - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) - iface_name = macs[nic.mac] - - if iface_name - entry = "ifcfg=#{nic.mac}|#{iface_name}" - - if bonding - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" - else - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" - if nic.physical_network.boot_type.proto == 'static' - ip = nic.ip_addresses[0] - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge - entry += "|TYPE=bridge" if is_bridge - end - entry += "|ONBOOT=yes" + def self.add_bridge(result, mac, iface_name, bootproto, ipaddress, netmask, broadcast) + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" + if bootproto == "static" + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}" end + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + result.puts entry + end + + def self.add_nic(result, mac, iface_name) + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" + end - result.puts entry if defined? entry + def self.add_slave(result, mac, iface_name, master) + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" end end diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml index b19e9e1..bca0f11 100644 --- a/src/test/fixtures/ip_addresses.yml +++ b/src/test/fixtures/ip_addresses.yml @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: nic: ldapserver_nic_one type: IpV4Address address: 172.31.0.25 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 + gateway: 172.31.0.1 + +ip_v4_ldapserver_physical_nic_one: + network: static_physical_network_one + address: 172.31.0.26 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 gateway: 172.31.0.1 ip_v4_buildserver_nic_one: diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index 1cf3223..97397cd 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -23,7 +23,7 @@ ldapserver_nic_one: mac: 00:03:02:00:09:06 usage_type: 1 bandwidth: 100 - bridge: breth0 + bridge: host: ldapserver_managed_node physical_network: static_physical_network_one @@ -39,7 +39,7 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_two + physical_network: static_physical_network_one mediaserver_nic_one: mac: 07:17:19:65:03:32 diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb index 6ce4885..2393227 100644 --- a/src/test/functional/managed_node_configuration_test.rb +++ b/src/test/functional/managed_node_configuration_test.rb @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.physical_network.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.physical_network.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE @@ -140,7 +142,8 @@ HERE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE -- 1.6.0.6 From zamsden at redhat.com Wed Apr 1 17:22:48 2009 From: zamsden at redhat.com (Zachary Amsden) Date: Wed, 01 Apr 2009 07:22:48 -1000 Subject: [Ovirt-devel] test, please ignore Message-ID: <49D3A2E8.5000703@redhat.com> From mmorsi at redhat.com Wed Apr 1 18:31:46 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 14:31:46 -0400 Subject: [Ovirt-devel] [PATCH server] Fixed a few bugs in o-identify-node processing. In-Reply-To: <1238589256-7478-1-git-send-email-dpierce@redhat.com> References: <1238589256-7478-1-git-send-email-dpierce@redhat.com> Message-ID: <49D3B312.5000305@redhat.com> Looks good for the most part save one small, but critical bug, see below. Darryl L. Pierce wrote: > NOTE: This version includes fixes based on feedback from mmorsi and some > refactorings to the way nics are updated. > > Fixed the processing of NICs to handle properly deleting a NIC that was > not identified by the node. All unidentified NICs are now deleted from > the database after o-i-node runs. > > Signed-off-by: Darryl L. Pierce > --- > src/host-browser/host-browser.rb | 36 ++++++++++++++++++------------------ > 1 files changed, 18 insertions(+), 18 deletions(-) > > diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb > index 1c5cf83..b927d3c 100755 > --- a/src/host-browser/host-browser.rb > +++ b/src/host-browser/host-browser.rb > @@ -248,7 +248,7 @@ class HostBrowser > Cpu.delete_all(['host_id = ?', host.id]) > > puts "Saving new CPU records" > - cpu_info.collect do |cpu| > + cpu_info.each do |cpu| > detail = Cpu.new( > "cpu_number" => cpu['CPUNUM'].to_i, > "core_number" => cpu['CORENUM]'].to_i, > @@ -271,37 +271,37 @@ class HostBrowser > > puts "Updating NIC records for the node" > nics = Array.new > + nics_to_delete = Array.new > > - host.nics.collect do |nic| > + host.nics.each do |nic| > found = false > > - nic_info.collect do |detail| > + nic_info.each do |detail| > # if we have a match, then update the database and remove > # the received data to avoid creating a dupe later > - if detail['MAC'] == nic.mac > - nic_info.delete(detail) > - > - updated_nic = Nic.find_by_id(nic.id) > - > - updated_nic.bandwidth = detail['BANDWIDTH'].to_i > - updated_nic.interface_name = detail['IFACE_NAME'] > - > - updated_nic.save! > - found=true > - nic_info.delete detail > + puts "Searching for existing record for: #{detail['MAC'].upcase}" > + if detail['MAC'].upcase == nic.mac > + puts "Updating details for: #{detail['IFACE_NAME']} [#{nic.mac}]}" > + nic.bandwidth = detail['BANDWIDTH'].to_i > + nic.interface_name = detail['IFACE_NAME'] > + nic.save! > + found = true > + nic_info.delete(detail) > end > end > > # if the record wasn't found, then remove it from the database > unless found > - host.nics.delete(nic) > - nic.destroy > + puts "Marking NIC for removal: #{nic.interface_name} [#{nic.mac}]" > + nics_to_delete << nic > end > end > > + nics_to_delete.each { |nic| puts "Removing NIC: #{nic.interface_name} []#{nic.mac}]"; host.nics.delete(nic) } > + > # iterate over any nics left and create new records for them. > - nic_info.collect do |nic| > - puts "Creating a new nic..." > + nic_info.each do |nic| > + puts "Creating a new nic: #{nic.interface_name} [#{nic.mac}]" > In this puts statement you are accessing the 'nic' object as if it were an instance of the Nic class but really it is just a member of the nic_info has retreived from the node. This will either need to be changed to nic['INTERFACE_NAME'] and ['MAC'] or moved a few lines below, accessing the attributes through the detail object created. > detail = Nic.new( > 'mac' => nic['MAC'].upcase, > 'bandwidth' => nic['BANDWIDTH'].to_i, > -Mo From mmorsi at redhat.com Wed Apr 1 18:32:03 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 14:32:03 -0400 Subject: [Ovirt-devel] Re: [PATCH node] Report on physical network devices when identifying the node. In-Reply-To: <1238513109-25351-1-git-send-email-dpierce@redhat.com> References: <1238513109-25351-1-git-send-email-dpierce@redhat.com> Message-ID: <49D3B323.5000006@redhat.com> Don't want to ack this just yet as there are some outstanding issues I'm not sure about. Hugh there is a requirements question below which is why I'm cc'ing you Darryl L. Pierce wrote: > From: Mohammed Morsi > > I'm still listed as the author here, can we change this? > The default interface configuration is only applied if a configuration > was not retrieved from the server for some reason. > > When ovirt-identify-node collects NIC details to send back to the > server, it only collects for physical devices that support the net.80203 > capability as reported by HAL. > > Signed-off-by: Darryl L. Pierce > --- > ovirt-identify-node/gather.c | 24 ++++++++++++------------ > scripts/ovirt-early | 31 +++++++++++++++++++------------ > 2 files changed, 31 insertions(+), 24 deletions(-) > > diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c > index c12ed08..2f26f46 100644 > --- a/ovirt-identify-node/gather.c > +++ b/ovirt-identify-node/gather.c > @@ -286,7 +286,7 @@ get_nic_info(void) > > int i; > > - nics = libhal_find_device_by_capability(hal_ctx, "net", > + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", > &num_results, &dbus_error); > Not too familiar w/ libhal, but I'm assuming net.80203 will only return physical devices and not bridges and whatnot. > > DEBUG("Found %d NICs\n", num_results); > @@ -294,15 +294,15 @@ get_nic_info(void) > for (i = 0; i < num_results; i++) { > char *nic = nics[i]; > > - VERBOSE("Starting new NIC.\n"); > + DEBUG("Starting new NIC; %s.\n", nic); > > - if (current != NULL) { > - last = current; > - current = create_nic_info(); > - last->next = current; > - } else { > - nic_info = current = create_nic_info(); > - } > + if (current != NULL) { > + last = current; > + current = create_nic_info(); > + last->next = current; > + } else { > + nic_info = current = create_nic_info(); > + } > This seems to be an indentation issue only. Not too happy with ack'ing this as part of this patch, but it won't hold my ack up. > > snprintf(current->mac_address, BUFFER_LENGTH, "%s", > libhal_device_get_property_string(hal_ctx, nic, > @@ -310,9 +310,9 @@ get_nic_info(void) > &dbus_error)); > get_nic_data(nic, current); > > - DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", > - nic_info->mac_address, nic_info->bandwidth, > - nic_info->ip_address); > + DEBUG("NIC details: MAC:%s, IFACE_NAME: %s, speed:%s, IP:%s\n", > + current->mac_address, current->iface_name, > + current->bandwidth, current->ip_address); > } > Same indentation comment. > > return result; > diff --git a/scripts/ovirt-early b/scripts/ovirt-early > index 9ab2981..9b7e902 100755 > --- a/scripts/ovirt-early > +++ b/scripts/ovirt-early > @@ -20,6 +20,7 @@ get_mac_addresses() { > > configure_from_network() { > DEVICE=$1 > + > if [ -n "$DEVICE" ]; then > log "Configuring network Using interface $DEVICE" > # setup temporary interface to retrieve configuration > @@ -46,13 +47,14 @@ configure_from_network() { > ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG > if [ $? -eq 0 ]; then > log "Remote configuration retrieved and applied" > + rm $cfgdb > + return > else > log "Failure to retrieve or apply remote configuration" > fi > else > log "Failed to retrieve configuration bundle" > fi > - rm $cfgdb > fi > fi > fi > @@ -62,17 +64,22 @@ configure_from_network() { > ETHDEVS=$(cd /sys/class/net && ls -d eth*) > for eth in $ETHDEVS; do > BRIDGE=br$eth > - log "Applying default configuration to $eth and $BRIDGE" > - printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > - > /etc/sysconfig/network-scripts/ifcfg-$eth > - if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > - dhcp="BOOTPROTO=dhcp" > - else > - dhcp="" > - fi > - printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + > + # only write a default file if one does not exist > + if [ ! -f $ifcfg ]; then > + log "Applying default configuration to $eth and $BRIDGE" > + printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > + > /etc/sysconfig/network-scripts/ifcfg-$eth > + if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > + dhcp="BOOTPROTO=dhcp" > + else > + dhcp="" > + fi > + printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + fi > done > log "Default config applied" > } > The requirements issue I'm not sure about is whether or not we want to configure all interfaces by default as you are doing so here. I recall discussion pertaining to when the configuration isn't received from the server, to only configure / initialize the boot device and not any of the other nics. Hugh am I right about this? Overall, other than those few issues, it looks good though. -Mo From mmorsi at redhat.com Wed Apr 1 18:32:59 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 14:32:59 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238600135-17216-1-git-send-email-dpierce@redhat.com> References: <1238600135-17216-1-git-send-email-dpierce@redhat.com> Message-ID: <49D3B35B.80804@redhat.com> NACK. While testing this out, I have discovered some major issues with this patch. Darryl L. Pierce wrote: > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > Signed-off-by: Darryl L. Pierce > --- > src/lib/managed_node_configuration.rb | 77 +++++++++----------- > src/test/fixtures/ip_addresses.yml | 9 +++ > src/test/fixtures/nics.yml | 4 +- > .../functional/managed_node_configuration_test.rb | 21 +++--- > 4 files changed, 59 insertions(+), 52 deletions(-) > > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..61ee09e 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > - > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > > - result.puts "#{entry}|ONBOOT=yes" > + ipaddress=(bonding.ip_addresses.empty? ? nil : bonding.ip_addresses.first.address) > + netmask =(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.netmask) > + broadcast=(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.broadcast) > + add_bridge(result,"none",bonding.interface_name, > + bonding.vlan.boot_type.proto, ipaddress, netmask, broadcast) > > bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + iface_name = macs[nic.mac] > + if iface_name > + add_slave(result, nic.mac, iface_name, bonding.interface_name) > + end > end > end > > - has_bridge = false > host.nics.each do |nic| > - # only process this nic if it doesn't have a bonding > - # TODO remove the hack to force a bridge into the picture > if nic.bondings.empty? > - process_nic result, nic, macs, nil, false, true > - > - # TODO remove this when bridges are properly supported > - unless has_bridge > - macs[nic.mac] = "breth0" > - process_nic result, nic, macs, nil, true, false > - has_bridge = true > - end > + iface_name = macs[nic.mac] > This does not work here, as the nic mac addresses are upcased when they arrive via host-browser, but when they arrive here they are in their default casing (on my node, lowercase but I'm not sure we can assume that or not). Furthermore I've discovered a big issue (more to do w/ the managed_node_controller) where the mac addresses aren't being parsed correctly from the query string. Looking at the controller, line 57 where the hash is populated "@macs[key] = value" I inserted a "print "Got mac " + key.to_s + " - " + value.to_s + " \n"" preceeding it, and see this in the logs "54%3A52%3A00%3A28%3Ae1%3Ae3%3Deth1". Looking at /var/log/ovirt.log on the node, I see in the request url it seems to be escaping the "%" symbols w/ their ascii value "%25" resulting in the colons and equal signs in the url never getting decoded properly when it arrives at the server. I believed this regression was not introduced here but in the "Changes how macs are collected by ovirt-early" recently committed but will need to be fixed neverless. Manually running wget on the server w/ a correct url works in retreiving the config. > + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.address) > + netmask =(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.netmask) > + broadcast=(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.broadcast) > + if iface_name > + add_bridge(result,nic.mac,iface_name, > + nic.physical_network.boot_type.proto,ipaddress,netmask,broadcast) > + add_nic(result, nic.mac, iface_name) > + end > end > end > NICs and bondings don't necessarily need to be assigned to networks, and thus both sections will blow up if there is at least one device on a host not associated w/ a network (very likely / common scenario). At the very least we should be checking to see if nic.physical_network and bonding.vlan is nil before trying to proceed. If the network is nil, I believe the requirements is to ignore the device all together and not return it w/ the config that's sent back to the node. -Mo From slinabery at redhat.com Wed Apr 1 18:36:24 2009 From: slinabery at redhat.com (Steve Linabery) Date: Wed, 1 Apr 2009 13:36:24 -0500 Subject: [Ovirt-devel] [PATCH server] Fix admin_dns_server variable to use interfaces[admin_dev] rather than admin_ip which no longer exists In-Reply-To: <1238515049-29151-1-git-send-email-jboggs@redhat.com> References: <1238515049-29151-1-git-send-email-jboggs@redhat.com> Message-ID: <20090401183624.GE9861@redhat.com> On Tue, Mar 31, 2009 at 11:57:29AM -0400, Joey Boggs wrote: > Enter the dhcp domain you wish to use (example: example.com): |ovirt.priv| ovirt.priv > /usr/sbin/ovirt-installer:218: undefined local variable or method `admin_ip' for # (NameError) > --- > installer/bin/ovirt-installer | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/installer/bin/ovirt-installer b/installer/bin/ovirt-installer > index f25998b..2d88886 100755 > --- a/installer/bin/ovirt-installer > +++ b/installer/bin/ovirt-installer > @@ -215,7 +215,7 @@ if dhcp_setup == "n" > dhcp_start = prompt_for_answer("Enter the dhcp pool start address (example: 3):", :regex => OCTET) > dhcp_stop = prompt_for_answer("Enter the dhcp pool end addess (example: 100):", :regex => OCTET) > dhcp_domain = prompt_for_answer("Enter the dhcp domain you wish to use (example: example.com):", :default => dnsdomainname.chomp, :regex => IP_OR_FQDN) > - admin_dns_server = admin_ip.scan(/\s*inet addr:([\d.]+)/) > + admin_dns_server = interfaces[admin_dev] > admin_network_gateway = prompt_for_answer("Enter the network gateway for your Admin network (example: 192.168.50.254):", :default => default_gw.chomp, :regex => IP_OR_FQDN) > tftp_setup = prompt_yes_no("Provide pxe/tftp capability?") > end > -- > 1.6.0.6 > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel Works for me, ACK. Steve From dpierce at redhat.com Wed Apr 1 19:28:58 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 15:28:58 -0400 Subject: [Ovirt-devel] [PATCH node] Removes URL encoding from the mac list. Message-ID: <1238614138-17213-1-git-send-email-dpierce@redhat.com> Signed-off-by: Darryl L. Pierce --- scripts/ovirt-early | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 11a32cb..1260900 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -22,11 +22,10 @@ get_mac_addresses() { if [ "$device" != "$DEVICE" ]; then mac=$(cat /sys/class/net/$device/address 2>/dev/null) if [ -n "$mac" -a "$mac" != "00:00:00:00:00:00" ]; then - macs="${macs}${mac}=${device} " + macs="${macs}${mac}=${device}," fi fi done - macs=$(echo $macs | sed 's/ /%2C/g;s/:/%3A/g;s/=/%3D/g') } configure_from_network() { -- 1.6.0.6 From apevec at gmail.com Wed Apr 1 19:35:37 2009 From: apevec at gmail.com (Alan Pevec) Date: Wed, 1 Apr 2009 21:35:37 +0200 Subject: [Ovirt-devel] [PATCH node] Removes URL encoding from the mac list. In-Reply-To: <1238614138-17213-1-git-send-email-dpierce@redhat.com> References: <1238614138-17213-1-git-send-email-dpierce@redhat.com> Message-ID: <2be7262f0904011235p59992c57jb1ab402f3b61d282@mail.gmail.com> ACK From dpierce at redhat.com Wed Apr 1 19:52:34 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 15:52:34 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. Message-ID: <1238615554-18556-1-git-send-email-dpierce@redhat.com> Refactored how interfaces, bonded interfaces and bridges are defined. When returning a configuration for the node, a bridge is first created, using the networking definition for the device. The network interface is then bridged over that device. When a bonded interface is created, a bridge is created for it as well. Signed-off-by: Darryl L. Pierce --- src/app/controllers/managed_node_controller.rb | 4 +- src/lib/managed_node_configuration.rb | 79 +++++++++---------- src/test/fixtures/ip_addresses.yml | 9 ++ src/test/fixtures/nics.yml | 4 +- .../functional/managed_node_configuration_test.rb | 21 +++-- 5 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb index f5948be..29e4a4f 100644 --- a/src/app/controllers/managed_node_controller.rb +++ b/src/app/controllers/managed_node_controller.rb @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController def load_host @host = Host.find_by_hostname(params[:host]) - render :nothing => true, :status => :error unless @host + render :nothing => true unless @host end def load_macs @@ -58,6 +58,6 @@ class ManagedNodeController < ApplicationController end end - render :nothing => true, :status => :error if @macs.empty? + render :nothing => true if @macs.empty? end end diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index c412917..054836f 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -65,35 +65,37 @@ class ManagedNodeConfiguration # now process the network interfaces and bondings host.bondings.each do |bonding| - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" - - if bonding.ip_addresses.empty? - entry += "|BOOTPROTO=dhcp" - else - ip = bonding.ip_addresses[0] - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" + entry += "|ONBOOT=yes" + result.puts entry - result.puts "#{entry}|ONBOOT=yes" + ipaddress=(bonding.ip_addresses.empty? ? nil : bonding.ip_addresses.first.address) + netmask =(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.netmask) + broadcast=(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.broadcast) + add_bridge(result,"none",bonding.interface_name, + bonding.vlan.boot_type.proto, ipaddress, netmask, broadcast) bonding.nics.each do |nic| - process_nic result, nic, macs, bonding + iface_name = macs[nic.mac] + if iface_name + add_slave(result, nic.mac, iface_name, bonding.interface_name) + end end end - has_bridge = false host.nics.each do |nic| - # only process this nic if it doesn't have a bonding - # TODO remove the hack to force a bridge into the picture - if nic.bondings.empty? - process_nic result, nic, macs, nil, false, true - - # TODO remove this when bridges are properly supported - unless has_bridge - macs[nic.mac] = "breth0" - process_nic result, nic, macs, nil, true, false - has_bridge = true - end + if nic.bondings.empty? && nic.physical_network + iface_name = macs[nic.mac] + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.address) + netmask =(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.netmask) + broadcast=(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.broadcast) + if iface_name + add_bridge(result,nic.mac,iface_name, + nic.physical_network.boot_type.proto,ipaddress,netmask,broadcast) + add_nic(result, nic.mac, iface_name) + end end end @@ -102,27 +104,20 @@ class ManagedNodeConfiguration private - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) - iface_name = macs[nic.mac] - - if iface_name - entry = "ifcfg=#{nic.mac}|#{iface_name}" - - if bonding - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" - else - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" - if nic.physical_network.boot_type.proto == 'static' - ip = nic.ip_addresses[0] - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge - entry += "|TYPE=bridge" if is_bridge - end - entry += "|ONBOOT=yes" + def self.add_bridge(result, mac, iface_name, bootproto, ipaddress, netmask, broadcast) + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" + if bootproto == "static" + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}" end + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + result.puts entry + end + + def self.add_nic(result, mac, iface_name) + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" + end - result.puts entry if defined? entry + def self.add_slave(result, mac, iface_name, master) + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" end end diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml index b19e9e1..bca0f11 100644 --- a/src/test/fixtures/ip_addresses.yml +++ b/src/test/fixtures/ip_addresses.yml @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: nic: ldapserver_nic_one type: IpV4Address address: 172.31.0.25 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 + gateway: 172.31.0.1 + +ip_v4_ldapserver_physical_nic_one: + network: static_physical_network_one + address: 172.31.0.26 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 gateway: 172.31.0.1 ip_v4_buildserver_nic_one: diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index 1cf3223..97397cd 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -23,7 +23,7 @@ ldapserver_nic_one: mac: 00:03:02:00:09:06 usage_type: 1 bandwidth: 100 - bridge: breth0 + bridge: host: ldapserver_managed_node physical_network: static_physical_network_one @@ -39,7 +39,7 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_two + physical_network: static_physical_network_one mediaserver_nic_one: mac: 07:17:19:65:03:32 diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb index 6ce4885..2393227 100644 --- a/src/test/functional/managed_node_configuration_test.rb +++ b/src/test/functional/managed_node_configuration_test.rb @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.physical_network.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.physical_network.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE @@ -140,7 +142,8 @@ HERE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE -- 1.6.0.6 From dpierce at redhat.com Wed Apr 1 19:53:08 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 15:53:08 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. Message-ID: <1238615588-18613-1-git-send-email-dpierce@redhat.com> The default interface configuration is only applied if a configuration was not retrieved from the server for some reason. When ovirt-identify-node collects NIC details to send back to the server, it only collects for physical devices that support the net.80203 capability as reported by HAL. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/gather.c | 4 ++-- scripts/ovirt-early | 31 +++++++++++++++++++------------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c index c12ed08..d0d9250 100644 --- a/ovirt-identify-node/gather.c +++ b/ovirt-identify-node/gather.c @@ -286,7 +286,7 @@ get_nic_info(void) int i; - nics = libhal_find_device_by_capability(hal_ctx, "net", + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", &num_results, &dbus_error); DEBUG("Found %d NICs\n", num_results); @@ -294,7 +294,7 @@ get_nic_info(void) for (i = 0; i < num_results; i++) { char *nic = nics[i]; - VERBOSE("Starting new NIC.\n"); + DEBUG("Starting new NIC; %s.\n", nic); if (current != NULL) { last = current; diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 1260900..02b949b 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -30,6 +30,7 @@ get_mac_addresses() { configure_from_network() { DEVICE=$1 + if [ -n "$DEVICE" ]; then log "Configuring network Using interface $DEVICE" # setup temporary interface to retrieve configuration @@ -56,13 +57,14 @@ configure_from_network() { ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG if [ $? -eq 0 ]; then log "Remote configuration retrieved and applied" + rm $cfgdb + return else log "Failure to retrieve or apply remote configuration" fi else log "Failed to retrieve configuration bundle" fi - rm $cfgdb fi fi fi @@ -72,17 +74,22 @@ configure_from_network() { ETHDEVS=$(cd /sys/class/net && ls -d eth*) for eth in $ETHDEVS; do BRIDGE=br$eth - log "Applying default configuration to $eth and $BRIDGE" - printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ - > /etc/sysconfig/network-scripts/ifcfg-$eth - if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then - dhcp="BOOTPROTO=dhcp" - else - dhcp="" - fi - printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE + + # only write a default file if one does not exist + if [ ! -f $ifcfg ]; then + log "Applying default configuration to $eth and $BRIDGE" + printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ + > /etc/sysconfig/network-scripts/ifcfg-$eth + if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then + dhcp="BOOTPROTO=dhcp" + else + dhcp="" + fi + printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE + fi done log "Default config applied" } -- 1.6.0.6 From mmorsi at redhat.com Wed Apr 1 20:01:25 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 16:01:25 -0400 Subject: [Ovirt-devel] [PATCH server] Fixed a few bugs in o-identify-node processing. In-Reply-To: <49D3B312.5000305@redhat.com> References: <1238589256-7478-1-git-send-email-dpierce@redhat.com> <49D3B312.5000305@redhat.com> Message-ID: <49D3C815.5000003@redhat.com> >> # iterate over any nics left and create new records for them. >> - nic_info.collect do |nic| >> - puts "Creating a new nic..." >> + nic_info.each do |nic| >> + puts "Creating a new nic: #{nic.interface_name} [#{nic.mac}]" >> >> > In this puts statement you are accessing the 'nic' object as if it were > an instance of the Nic class but really it is just a member of the > nic_info has retreived from the node. This will either need to be > changed to nic['INTERFACE_NAME'] and ['MAC'] or moved a few lines below, > accessing the attributes through the detail object created. > > ACK pending this small bugfix. -Mo From dpierce at redhat.com Wed Apr 1 20:33:50 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 1 Apr 2009 16:33:50 -0400 Subject: [Ovirt-devel] [PATCH node] Ignores the management interface when identifying hardware. Message-ID: <1238618030-21909-1-git-send-email-dpierce@redhat.com> On the commandline the argument "-m [device name]" can be used to identify the management interface. If such a device is identified, then during the communications phase that device is not reported to the server. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/main.c | 8 +++++++- ovirt-identify-node/ovirt-identify-node.h | 1 + ovirt-identify-node/protocol.c | 16 ++++++++++------ scripts/ovirt-post | 6 +++++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ovirt-identify-node/main.c b/ovirt-identify-node/main.c index 039a878..400ea54 100644 --- a/ovirt-identify-node/main.c +++ b/ovirt-identify-node/main.c @@ -42,6 +42,8 @@ char *hostname; int hostport = -1; +char *management_interface; + int socketfd; cpu_info_ptr cpu_info; @@ -108,7 +110,7 @@ config(int argc, char **argv) int option; - while ((option = getopt(argc, argv, "s:p:dvth")) != -1) { + while ((option = getopt(argc, argv, "s:p:m:dvth")) != -1) { DEBUG("Processing argument: %c (optarg:%s)\n", option, optarg); switch (option) { @@ -118,6 +120,9 @@ config(int argc, char **argv) case 'p': hostport = atoi(optarg); break; + case 'm': + management_interface = optarg; + break; case 't': testing = 1; break; @@ -159,6 +164,7 @@ usage() fprintf(stdout, "\n"); fprintf(stdout, "\t-s [server]\t\tThe remote server's hostname.\n"); fprintf(stdout, "\t-p [port]\t\tThe remote server's port.\n"); + fprintf(stdout, "\t-m [iface]\t\tThe management interface.\n"); fprintf(stdout, "\t-d\t\tDisplays debug information during execution.\n"); fprintf(stdout, diff --git a/ovirt-identify-node/ovirt-identify-node.h b/ovirt-identify-node/ovirt-identify-node.h index 405ca4b..e608051 100644 --- a/ovirt-identify-node/ovirt-identify-node.h +++ b/ovirt-identify-node/ovirt-identify-node.h @@ -122,6 +122,7 @@ extern char numcpus[BUFFER_LENGTH]; extern char cpuspeed[BUFFER_LENGTH]; extern char *hostname; extern int hostport; +extern char *management_interface; extern int socketfd; extern cpu_info_ptr cpu_info; extern nic_info_ptr nic_info; diff --git a/ovirt-identify-node/protocol.c b/ovirt-identify-node/protocol.c index 261773d..0382dac 100644 --- a/ovirt-identify-node/protocol.c +++ b/ovirt-identify-node/protocol.c @@ -177,20 +177,24 @@ send_nic_details(void) nic_info_ptr current = nic_info; while (current != NULL) { - send_text("NIC"); + if((!management_interface) || (strcmp(management_interface, current->iface_name))) { + send_text("NIC"); - if (!(get_text("NICINFO?")) && - (!send_value("MAC", current->mac_address)) && - (!send_value("BANDWIDTH", current->bandwidth)) && + if (!(get_text("NICINFO?")) && + (!send_value("MAC", current->mac_address)) && + (!send_value("BANDWIDTH", current->bandwidth)) && (!send_value("IFACE_NAME", current->iface_name)) && (!send_value("IP_ADDRESS", current->ip_address)) && (!send_value("NETMASK", current->netmask)) && (!send_value("BROADCAST", current->broadcast))) { - send_text("ENDNIC"); - result = get_text("ACK NIC"); + send_text("ENDNIC"); + result = get_text("ACK NIC"); } current = current->next; + } else { + current = current->next; + } } return result; diff --git a/scripts/ovirt-post b/scripts/ovirt-post index faec023..647b049 100755 --- a/scripts/ovirt-post +++ b/scripts/ovirt-post @@ -61,7 +61,11 @@ start() { find_srv identify tcp if [ -n "$SRV_HOST" -a -n "$SRV_PORT" ]; then - ovirt-identify-node -s $SRV_HOST -p $SRV_PORT + if [ -n "$OVIRT_BOOTIF" ]; then + ovirt-identify-node -s $SRV_HOST -p $SRV_PORT -m $OVIRT_BOOTIF + else + ovirt-identify-node -s $SRV_HOST -p $SRV_PORT + fi else log "skipping ovirt-identify-node, oVirt registration service not available" fi -- 1.6.0.6 From katzj at redhat.com Wed Apr 1 20:44:48 2009 From: katzj at redhat.com (Jeremy Katz) Date: Wed, 1 Apr 2009 16:44:48 -0400 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090331120417.46cc64ef@tp.mains.net> References: <20090331120417.46cc64ef@tp.mains.net> Message-ID: <20090401204448.GD2854@redhat.com> On Tuesday, March 31 2009, Ian Main said: > Through much discussion it was decided that we would leverage the rails > models created for use in the WUI, and create an alternative way to > access these models, start tasks etc. This will be integrated with the > current task management system (taskomatic) to produce a complete package. > > The idea is to create a set of classes available via QMF as objects. > These classes would then be backed by either a mid-level API that > encompasses the models, or by active record models directly. Any changes > made to these records outside of the API (eg by the WUI) would require > notification of changes to taskomatic. So, by integrating deeply like this, how much is going to be tied to underlying implementation details that (may|might|will) change in the future? From looking through it, it seems very tightly tied which given the many unanswered questions, is at least of some concern imho. Also, who is the expected target user of this API? Someone who is deploying guests within the cloud or someone who is managing the overall cloud? As there's probably a different level of care for what are the important things to expose accordingly. It looks more like the latter but with a mix of some of the former, but at a far more detailed level than a cloud user would need/want Jeremy From apevec at gmail.com Wed Apr 1 21:05:02 2009 From: apevec at gmail.com (Alan Pevec) Date: Wed, 1 Apr 2009 23:05:02 +0200 Subject: [Ovirt-devel] Re: [PATCH node] Report on physical network devices when identifying the node. In-Reply-To: <49D3B323.5000006@redhat.com> References: <1238513109-25351-1-git-send-email-dpierce@redhat.com> <49D3B323.5000006@redhat.com> Message-ID: <2be7262f0904011405s5f0959b4r5b7591396258a15a@mail.gmail.com> On Wed, Apr 1, 2009 at 8:32 PM, Mohammed Morsi wrote: >> - ? ? ? ?DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", >> - ? ? ? ? ? ? ?nic_info->mac_address, nic_info->bandwidth, >> - ? ? ? ? ? ? ?nic_info->ip_address); >> + ? ? DEBUG("NIC details: MAC:%s, IFACE_NAME: %s, speed:%s, IP:%s\n", >> + ? ? ? ? ? current->mac_address, current->iface_name, >> + ? ? ? ? ? current->bandwidth, current->ip_address); >> ? ? ?} >> > Same indentation comment. this is actually a bugfix, right :) please keep that From apevec at gmail.com Wed Apr 1 21:07:02 2009 From: apevec at gmail.com (Alan Pevec) Date: Wed, 1 Apr 2009 23:07:02 +0200 Subject: [Ovirt-devel] [PATCH node] Ignores the management interface when identifying hardware. In-Reply-To: <1238618030-21909-1-git-send-email-dpierce@redhat.com> References: <1238618030-21909-1-git-send-email-dpierce@redhat.com> Message-ID: <2be7262f0904011407g589b7a16w39fbf175fbc431d6@mail.gmail.com> ACK From apevec at redhat.com Wed Apr 1 22:11:48 2009 From: apevec at redhat.com (Alan Pevec) Date: Thu, 2 Apr 2009 00:11:48 +0200 Subject: [Ovirt-devel] [PATCH node] wait for HostVG to show up Message-ID: <1238623908-13206-1-git-send-email-apevec@redhat.com> For local install HostVG *must* be available, so wait as long as needed, some HBAs are just slow to initialize. For normal cases this will never loop and just continue immediatelly. Signed-off-by: Alan Pevec --- scripts/ovirt-config-boot | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot index e4fb365..f923b0c 100755 --- a/scripts/ovirt-config-boot +++ b/scripts/ovirt-config-boot @@ -104,10 +104,17 @@ ovirt_boot_setup() { echo SCSI wait for scans\ /sbin/modprobe scsi_wait_scan\ /sbin/modprobe -r scsi_wait_scan\ -echo Scanning logical volumes\ -lvm vgscan --ignorelockingfailure\ -echo Activating logical volumes\ -lvm vgchange -ay --ignorelockingfailure HostVG \ +set +e\ +while true; do\ + echo Scanning logical volumes\ + lvm vgscan --ignorelockingfailure\ + echo Activating logical volumes\ + if lvm vgchange -ay --ignorelockingfailure HostVG; then\ + break\ + fi\ + sleep 1\ +done\ +set -e\ ' $init_script # fix emergency shell sed -i 's/^ bash$/ bash < \/dev\/console/' $init_script -- 1.6.0.6 From imain at redhat.com Wed Apr 1 23:03:26 2009 From: imain at redhat.com (Ian Main) Date: Wed, 1 Apr 2009 16:03:26 -0700 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <49D3735A.8070808@redhat.com> References: <20090331120417.46cc64ef@tp.mains.net> <49D3735A.8070808@redhat.com> Message-ID: <20090401160326.1e883852@tp.mains.net> On Wed, 01 Apr 2009 09:59:54 -0400 Bryan Kearney wrote: > Ian Main wrote: > > > > # Look up completed tasks. > > tasks = s.objects(:class => 'Task', 'completed' => true) > > How does this work on the backend? Are all Tasks instantiated and > managed by the agent, or does this turn into a method call to get he > managed objects? > All tasks are instantiated and managed by the agent as you say. When you do a query like this QMF uses AMQP to send a message to all agents requesting that each agent return all object IDs for objects that match the given criteria. The criteria at this point are all just AND'd together. However hopefully we will have more powerful search ability soonish.. things like OR's and regular expressions etc. Ian From lutter at redhat.com Wed Apr 1 23:29:06 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 01 Apr 2009 16:29:06 -0700 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090401204448.GD2854@redhat.com> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> Message-ID: <1238628546.23359.4.camel@avon.watzmann.net> On Wed, 2009-04-01 at 16:44 -0400, Jeremy Katz wrote: > On Tuesday, March 31 2009, Ian Main said: > > Through much discussion it was decided that we would leverage the rails > > models created for use in the WUI, and create an alternative way to > > access these models, start tasks etc. This will be integrated with the > > current task management system (taskomatic) to produce a complete package. > > > > The idea is to create a set of classes available via QMF as objects. > > These classes would then be backed by either a mid-level API that > > encompasses the models, or by active record models directly. Any changes > > made to these records outside of the API (eg by the WUI) would require > > notification of changes to taskomatic. > > So, by integrating deeply like this, how much is going to be tied to underlying > implementation details that (may|might|will) change in the future? From > looking through it, it seems very tightly tied which given the many > unanswered questions, is at least of some concern imho. Can you give examples of what in the API proposal worries you in that regard ? What the QMF API exposes isn't too different from what the REST API (would) expose. > Also, who is the expected target user of this API? Someone who is > deploying guests within the cloud or someone who is managing the overall > cloud? As there's probably a different level of care for what are the > important things to expose accordingly. It looks more like the latter > but with a mix of some of the former, but at a far more detailed level > than a cloud user would need/want The API is targetted at both - whether an 'ordinary' cloud user is allowed to do certain operations is a question of permissions. Some of that complexity will/can be hidden with more targetted tools on top of the API, either in the form of a client library or the command line tools that I started writing a while ago, but never finished. David From lutter at redhat.com Wed Apr 1 23:46:07 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 01 Apr 2009 16:46:07 -0700 Subject: [Ovirt-devel] [PATCH server] verify hostname is not on the loopback entry in /etc/hosts In-Reply-To: <1238008866-13329-1-git-send-email-jboggs@redhat.com> References: <1238008866-13329-1-git-send-email-jboggs@redhat.com> Message-ID: <1238629567.23359.15.camel@avon.watzmann.net> On Wed, 2009-03-25 at 15:21 -0400, Joey Boggs wrote: > +# verify hostname is not on the loopback line in /etc/hosts to prevent kerberos problems > +hostname = `hostname` > +hostsfile = File.new("/etc/hosts", "r") > +while (line = hostsfile.gets) > + if line =~ /127.0.0.1/ && line.include?(hostname.chomp) > + if hostname !~ /localhost.localdomain/ > + @cli.say("\nHostname must not be on the loopback 127.0.0.1 line in /etc/hosts") > + @cli.say("#{line}") > + exit(0) > + end > + end > +end > +hostsfile.close This can produce false positives in a number of ways: (1) it will get confused by comments: # We used to have, but that's wrong # 127.0.0.1 host.exmaple.com 127.0.0.1 localhost.localdomain It also gets confused if hostname is 'host.example.com' and the 127.0.0.1 line has an alias 'myhost.example.com'. Finally, (but that should happen throughout the installer), the installer shouldn't exit with status 0 when there was an error. It would be good to have a convention like status == 0 when installer finished successfully, status == 1 when an error happened, status == 2 when user exited installer (e.g., by answering 'no' to some question) A more robust implementation of the above would be: aug = Augeas::init(nil, nil, 0) hosts = "/files/etc/hosts/*" paths = aug.match("#{hosts}/canonical[../ipaddr = '127.0.0.1']") + aug.match("#{hosts}/alias[../ipaddr = '127.0.0.1']") paths.each do |p| name = aug.get(p) if hostname == name @cli.say("\nHostname must not be on the loopback 127.0.0.1 line in /etc/hosts") if (prompt_yes_no("Should I fix that ?", :default => "n") == "y") aug.rm(p) aug.save end end end David From mmorsi at redhat.com Wed Apr 1 23:51:21 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 19:51:21 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238615554-18556-1-git-send-email-dpierce@redhat.com> References: <1238615554-18556-1-git-send-email-dpierce@redhat.com> Message-ID: <49D3FDF9.8030303@redhat.com> NACK, still a few issues Darryl L. Pierce wrote: > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > Signed-off-by: Darryl L. Pierce > --- > src/app/controllers/managed_node_controller.rb | 4 +- > src/lib/managed_node_configuration.rb | 79 +++++++++---------- > src/test/fixtures/ip_addresses.yml | 9 ++ > src/test/fixtures/nics.yml | 4 +- > .../functional/managed_node_configuration_test.rb | 21 +++-- > 5 files changed, 62 insertions(+), 55 deletions(-) > > diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb > index f5948be..29e4a4f 100644 > --- a/src/app/controllers/managed_node_controller.rb > +++ b/src/app/controllers/managed_node_controller.rb > @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController > def load_host > @host = Host.find_by_hostname(params[:host]) > > - render :nothing => true, :status => :error unless @host > + render :nothing => true unless @host > end > > def load_macs > @@ -58,6 +58,6 @@ class ManagedNodeController < ApplicationController > end > end > > - render :nothing => true, :status => :error if @macs.empty? > + render :nothing => true if @macs.empty? > end > end > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..054836f 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > - > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > > - result.puts "#{entry}|ONBOOT=yes" > The following needs nil network check like the one being done for nics if bonding.vlan? > + ipaddress=(bonding.ip_addresses.empty? ? nil : bonding.ip_addresses.first.address) > + netmask =(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.netmask) > + broadcast=(bonding.vlan.ip_addresses.empty? ? nil : bonding.vlan.ip_addresses.first.broadcast) > + add_bridge(result,"none",bonding.interface_name, > + bonding.vlan.boot_type.proto, ipaddress, netmask, broadcast) > end > > bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + iface_name = macs[nic.mac] > + if iface_name > + add_slave(result, nic.mac, iface_name, bonding.interface_name) > + end > end > end > > - has_bridge = false > host.nics.each do |nic| > - # only process this nic if it doesn't have a bonding > - # TODO remove the hack to force a bridge into the picture > - if nic.bondings.empty? > - process_nic result, nic, macs, nil, false, true > - > - # TODO remove this when bridges are properly supported > - unless has_bridge > - macs[nic.mac] = "breth0" > - process_nic result, nic, macs, nil, true, false > - has_bridge = true > - end > + if nic.bondings.empty? && nic.physical_network > + iface_name = macs[nic.mac] > + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.address) > + netmask =(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.netmask) > + broadcast=(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.broadcast) > Switch the source of the ip_addresses here. The previous should be: + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.ip_addresses.first.address) + netmask =(nic.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.netmask) + broadcast=(nic.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.broadcast) Furthermore app/controllers/managed_node_controller needs a change. As previously mentioned the nics arriving are lowercase while being compared to nics stored in the db which are uppercase. The following change is needed for the controller line 57: - @macs[key] = value + @macs[key.upcase] = value -Mo From mmorsi at redhat.com Wed Apr 1 23:51:32 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Wed, 01 Apr 2009 19:51:32 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. In-Reply-To: <1238615588-18613-1-git-send-email-dpierce@redhat.com> References: <1238615588-18613-1-git-send-email-dpierce@redhat.com> Message-ID: <49D3FE04.7050409@redhat.com> This functionally works but I believe it doesn't satisfy the requirements Here the default config is only applied when the node fails to make a valid request to the server's managed_node_controller. Regardless of whether this request succeeds or not we need to configure the boot network device, as that config won't be retrieved from the server. As it is now, when a valid response comes back from the server, the boot-nic doesn't get configured and bridges. I'm not sure if a default config should be applied to the other non-boot nics should the request fail though. -Mo Darryl L. Pierce wrote: > The default interface configuration is only applied if a configuration > was not retrieved from the server for some reason. > > When ovirt-identify-node collects NIC details to send back to the > server, it only collects for physical devices that support the net.80203 > capability as reported by HAL. > > Signed-off-by: Darryl L. Pierce > --- > ovirt-identify-node/gather.c | 4 ++-- > scripts/ovirt-early | 31 +++++++++++++++++++------------ > 2 files changed, 21 insertions(+), 14 deletions(-) > > diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c > index c12ed08..d0d9250 100644 > --- a/ovirt-identify-node/gather.c > +++ b/ovirt-identify-node/gather.c > @@ -286,7 +286,7 @@ get_nic_info(void) > > int i; > > - nics = libhal_find_device_by_capability(hal_ctx, "net", > + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", > &num_results, &dbus_error); > > DEBUG("Found %d NICs\n", num_results); > @@ -294,7 +294,7 @@ get_nic_info(void) > for (i = 0; i < num_results; i++) { > char *nic = nics[i]; > > - VERBOSE("Starting new NIC.\n"); > + DEBUG("Starting new NIC; %s.\n", nic); > > if (current != NULL) { > last = current; > diff --git a/scripts/ovirt-early b/scripts/ovirt-early > index 1260900..02b949b 100755 > --- a/scripts/ovirt-early > +++ b/scripts/ovirt-early > @@ -30,6 +30,7 @@ get_mac_addresses() { > > configure_from_network() { > DEVICE=$1 > + > if [ -n "$DEVICE" ]; then > log "Configuring network Using interface $DEVICE" > # setup temporary interface to retrieve configuration > @@ -56,13 +57,14 @@ configure_from_network() { > ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG > if [ $? -eq 0 ]; then > log "Remote configuration retrieved and applied" > + rm $cfgdb > + return > else > log "Failure to retrieve or apply remote configuration" > fi > else > log "Failed to retrieve configuration bundle" > fi > - rm $cfgdb > fi > fi > fi > @@ -72,17 +74,22 @@ configure_from_network() { > ETHDEVS=$(cd /sys/class/net && ls -d eth*) > for eth in $ETHDEVS; do > BRIDGE=br$eth > - log "Applying default configuration to $eth and $BRIDGE" > - printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > - > /etc/sysconfig/network-scripts/ifcfg-$eth > - if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > - dhcp="BOOTPROTO=dhcp" > - else > - dhcp="" > - fi > - printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + > + # only write a default file if one does not exist > + if [ ! -f $ifcfg ]; then > + log "Applying default configuration to $eth and $BRIDGE" > + printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > + > /etc/sysconfig/network-scripts/ifcfg-$eth > + if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > + dhcp="BOOTPROTO=dhcp" > + else > + dhcp="" > + fi > + printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + fi > done > log "Default config applied" > } > From berrange at redhat.com Thu Apr 2 09:57:02 2009 From: berrange at redhat.com (Daniel P. Berrange) Date: Thu, 2 Apr 2009 10:57:02 +0100 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <1238628546.23359.4.camel@avon.watzmann.net> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> Message-ID: <20090402095702.GA16298@redhat.com> On Wed, Apr 01, 2009 at 04:29:06PM -0700, David Lutterkort wrote: > On Wed, 2009-04-01 at 16:44 -0400, Jeremy Katz wrote: > > On Tuesday, March 31 2009, Ian Main said: > > > Through much discussion it was decided that we would leverage the rails > > > models created for use in the WUI, and create an alternative way to > > > access these models, start tasks etc. This will be integrated with the > > > current task management system (taskomatic) to produce a complete package. > > > > > > The idea is to create a set of classes available via QMF as objects. > > > These classes would then be backed by either a mid-level API that > > > encompasses the models, or by active record models directly. Any changes > > > made to these records outside of the API (eg by the WUI) would require > > > notification of changes to taskomatic. > > > > So, by integrating deeply like this, how much is going to be tied to underlying > > implementation details that (may|might|will) change in the future? From > > looking through it, it seems very tightly tied which given the many > > unanswered questions, is at least of some concern imho. > > Can you give examples of what in the API proposal worries you in that > regard ? What the QMF API exposes isn't too different from what the REST > API (would) expose. I was just going to ask about the REST api.... The idea of having a formal QMF API is very nice, but I can't help thinking it will limit the potential userbase of the API since you of course need to get a QMF api for your client. The really compelling thing about REST APIs is that they are immediately usable by any client which has web browsing capabilities - which is basically every device with a network connection these days. No extra/special client side software required. I could see a REST and QMF api co-existing - perhaps you could in fact write one in terms of the other to provide guarenteed parity of functionality between the two, and reduce the burden of having 2 apis. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| From apevec at redhat.com Thu Apr 2 10:55:40 2009 From: apevec at redhat.com (Alan Pevec) Date: Thu, 2 Apr 2009 12:55:40 +0200 Subject: [Ovirt-devel] [PATCH node] allow ovirt-firstboot to run unconfined Message-ID: <1238669740-32030-1-git-send-email-apevec@redhat.com> Signed-off-by: Alan Pevec --- Makefile.am | 1 + ovirt-node-selinux.fc | 1 + ovirt-node-selinux.te | 25 ++++++++++++++++++++++--- ovirt-node.spec.in | 3 ++- 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 ovirt-node-selinux.fc diff --git a/Makefile.am b/Makefile.am index af23ae4..d60abe9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,6 +23,7 @@ EXTRA_DIST = \ ovirt-node.spec \ ovirt-node.spec.in \ ovirt-node-selinux.te \ + ovirt-node-selinux.fc \ images/grub-splash.xpm.gz \ images/syslinux-vesa-splash.jpg \ scripts/collectd \ diff --git a/ovirt-node-selinux.fc b/ovirt-node-selinux.fc new file mode 100644 index 0000000..cf1ea96 --- /dev/null +++ b/ovirt-node-selinux.fc @@ -0,0 +1 @@ +/etc/rc\.d/init\.d/ovirt-firstboot -- gen_context(system_u:object_r:ovirt_exec_t) diff --git a/ovirt-node-selinux.te b/ovirt-node-selinux.te index 327c231..c6da141 100644 --- a/ovirt-node-selinux.te +++ b/ovirt-node-selinux.te @@ -1,14 +1,33 @@ -module ovirt 1.0.0; +module ovirt 1.0.1; require { type fixed_disk_device_t; attribute file_type; type mount_t; type qemu_t; class blk_file { ioctl getattr setattr read write }; - class file mounton; + class file { mounton getattr read write append entrypoint execute ioctl lock }; + class chr_file { getattr read write append ioctl lock }; + class fifo_file { getattr read write append lock ioctl }; + class lnk_file { getattr read }; + class sock_file { getattr write }; + class fd { use }; + class process { sigchld signull transition noatsecure siginh rlimitinh }; + class filesystem { getattr }; + class dir { getattr search read lock ioctl }; + class unix_stream_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } connectto }; + + type initrc_t; + type unconfined_t; } # Give qemu_t access to any block device allow qemu_t fixed_disk_device_t:blk_file { ioctl getattr setattr read write }; # allow any file to be bindmounted (for /config) allow mount_t file_type:file mounton; - +# allow ovirt-firstboot to run unconfined +# TODO restrict to ovirt_t +#type ovirt_t; +#domain_type(ovirt_t) +#unconfined_domain_noaudit(ovirt_t) +#domain_entry_file(ovirt_t,ovirt_exec_t) +type ovirt_exec_t; +init_daemon_domain(unconfined_t,ovirt_exec_t) diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in index 02e90ce..75fb56f 100644 --- a/ovirt-node.spec.in +++ b/ovirt-node.spec.in @@ -13,6 +13,7 @@ Group: Applications/System %define selinux_policyver %(sed -n 's,.*selinux-policy-\([^/]*\)/.*,\1,p' /usr/share/selinux/devel/policyhelp) %define modulename %{name}-selinux Source1: %{modulename}.te +Source2: %{modulename}.fc BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot URL: http://www.ovirt.org/ @@ -116,7 +117,7 @@ SELinux policy module supporting ovirt-node %setup -q mkdir SELinux -cp -p %{SOURCE1} SELinux +cp -p %{SOURCE1} %{SOURCE2} SELinux %build %configure -- 1.6.0.6 From apevec at redhat.com Thu Apr 2 12:25:18 2009 From: apevec at redhat.com (Alan Pevec) Date: Thu, 2 Apr 2009 14:25:18 +0200 Subject: [Ovirt-devel] [PATCH node-image] use persistent state unless firstboot is forced Message-ID: <1238675118-441-1-git-send-email-apevec@redhat.com> Signed-off-by: Alan Pevec --- ovirt-node-image.ks | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ovirt-node-image.ks b/ovirt-node-image.ks index 39eed51..e1ae65c 100644 --- a/ovirt-node-image.ks +++ b/ovirt-node-image.ks @@ -15,13 +15,15 @@ rm -f /var/lib/rpm/__db* touch /.autorelabel # prepare for STATE_MOUNT in rc.sysinit -augtool < Forced firstboot is for troubleshooting or forced installation when existing persistent configuration shouldn't be applied automatically. Signed-off-by: Alan Pevec --- scripts/ovirt-early | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 02b949b..dbe5811 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -360,7 +360,10 @@ start() { fi # save boot parameters as defaults for ovirt-config-* params="bootif init vol_boot_size vol_swap_size vol_root_size vol_config_size vol_logging_size vol_data_size local_boot standalone overcommit ip_address ip_netmask ip_gateway ipv6 dns ntp syslog_server syslog_port collectd_server collectd_port bootparams hostname firstboot" - mount_config + # mount /config unless firstboot is forced + if [ "$firstboot" != "1" ]; then + mount_config + fi log "Updating $OVIRT_DEFAULTS" tmpaug=$(mktemp) for p in $params; do -- 1.6.0.6 From dpierce at redhat.com Thu Apr 2 12:51:22 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 08:51:22 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <49D3FDF9.8030303@redhat.com> References: <1238615554-18556-1-git-send-email-dpierce@redhat.com> <49D3FDF9.8030303@redhat.com> Message-ID: <20090402125122.GA4232@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 01, 2009 at 07:51:21PM -0400, Mohammed Morsi wrote: > NACK, still a few issues Some of the issues surrounding retrieving the network details are pretty fragile. I think it should be refactored to hide all of that detail and provide just simple methods in Bonding and Nic to get this info. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From bkearney at redhat.com Thu Apr 2 12:51:46 2009 From: bkearney at redhat.com (Bryan Kearney) Date: Thu, 02 Apr 2009 08:51:46 -0400 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090401160326.1e883852@tp.mains.net> References: <20090331120417.46cc64ef@tp.mains.net> <49D3735A.8070808@redhat.com> <20090401160326.1e883852@tp.mains.net> Message-ID: <49D4B4E2.9070701@redhat.com> Ian Main wrote: > On Wed, 01 Apr 2009 09:59:54 -0400 > Bryan Kearney wrote: > >> Ian Main wrote: >>> # Look up completed tasks. >>> tasks = s.objects(:class => 'Task', 'completed' => true) >> How does this work on the backend? Are all Tasks instantiated and >> managed by the agent, or does this turn into a method call to get he >> managed objects? >> > > All tasks are instantiated and managed by the agent as you say. > When you do a query like this QMF uses AMQP to send a message to all > agents requesting that each agent return all object IDs for objects that > match the given criteria. Here is my real question. The c++ and java agents all have "registerObject" and "registerClass" methods. The methods store in memory copies of the objects which queries go against. If the goal is to get an object out of the DB, it seems like you would need to register a Factory/Finder/EJBHome type class which returns the managed objects. So. when I see this method: tasks = s.objects(:class => 'Task', 'completed' => false) I assume that the query will only return those tasks which are completed _and_ in memory at the time. Not against the DB. Is that correct and intended? -- bk From apevec at redhat.com Thu Apr 2 13:27:02 2009 From: apevec at redhat.com (Alan Pevec) Date: Thu, 2 Apr 2009 15:27:02 +0200 Subject: [Ovirt-devel] [PATCH node] add function chkconfig_persist Message-ID: <1238678822-25405-1-git-send-email-apevec@redhat.com> Since symlinks cannot be persisted, replace symlinks with hardlinks and persist them. Signed-off-by: Alan Pevec --- scripts/ovirt-functions | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index c5c1a4e..4024efa 100755 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -574,6 +574,31 @@ reboot() { /sbin/reboot } +# chkconfig_persist +# since symlinks cannot be persisted, replace symlinks with hardlinks and persist +chkconfig_persist() { + local service=$1 + if [ -z "$service" ]; then + return 1 + fi + cd /etc/rc.d + local to_persist="" + for f in rc*.d/[S,K]??$service ; do + local dir=$(dirname $f) + local name=$(basename $f) + cd $dir + link=$(readlink $name) + if [ -e "$link" ]; then + rm -f $name + ln $link $name + to_persist="$to_persist /etc/rc.d/$f" + fi + cd .. + done + ovirt_store_config $to_persist +} + + # execute a function if called as a script, e.g. # ovirt-functions ovirt_store_config /etc/hosts -- 1.6.0.6 From dpierce at redhat.com Thu Apr 2 13:48:39 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 09:48:39 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <49D3FDF9.8030303@redhat.com> References: <1238615554-18556-1-git-send-email-dpierce@redhat.com> <49D3FDF9.8030303@redhat.com> Message-ID: <20090402134839.GB4232@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 01, 2009 at 07:51:21PM -0400, Mohammed Morsi wrote: > NACK, still a few issues > > Darryl L. Pierce wrote: > > Refactored how interfaces, bonded interfaces and bridges are defined. > > > > When returning a configuration for the node, a bridge is first created, > > using the networking definition for the device. The network interface is > > then bridged over that device. > > > > When a bonded interface is created, a bridge is created for it as well. > > > > Signed-off-by: Darryl L. Pierce > > --- > > src/app/controllers/managed_node_controller.rb | 4 +- > > src/lib/managed_node_configuration.rb | 79 +++++++++---------- > > src/test/fixtures/ip_addresses.yml | 9 ++ > > src/test/fixtures/nics.yml | 4 +- > > .../functional/managed_node_configuration_test.rb | 21 +++-- > > 5 files changed, 62 insertions(+), 55 deletions(-) > > > > diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb > > index f5948be..29e4a4f 100644 > > --- a/src/app/controllers/managed_node_controller.rb > > +++ b/src/app/controllers/managed_node_controller.rb > > @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController > > def load_host > > @host = Host.find_by_hostname(params[:host]) > > > > - render :nothing => true, :status => :error unless @host > > + render :nothing => true unless @host > > end > > > > def load_macs > > @@ -58,6 +58,6 @@ class ManagedNodeController < ApplicationController > > end > > end > > > > - render :nothing => true, :status => :error if @macs.empty? > > + render :nothing => true if @macs.empty? > > end > > end > > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > > index c412917..054836f 100644 > > --- a/src/lib/managed_node_configuration.rb > > +++ b/src/lib/managed_node_configuration.rb > > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > > # now process the network interfaces and bondings > > > > host.bondings.each do |bonding| > > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > > - > > - if bonding.ip_addresses.empty? > > - entry += "|BOOTPROTO=dhcp" > > - else > > - ip = bonding.ip_addresses[0] > > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > > - end > > + entry = "ifcfg=none|#{bonding.interface_name}" > > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > > + entry += "|BRIDGE=br#{bonding.interface_name}" > > + entry += "|ONBOOT=yes" > > + result.puts entry > > > > - result.puts "#{entry}|ONBOOT=yes" > > > The following needs nil network check like the one being done for nics The updated patch has added the following methods to Bonding and Nic: Bonding.networking? -- returns if networking is defined Bonding.boot_protocol, Bonding.ip_address, Bonding.netmask, Bonding.broadcast, Bonding.gatewway -- that part of the network address Nic.networking? -- returns if networking is defined Nic.bonded? -- returns whether this nic is enslaved to a bonded interface Nic.boot_protocol, Nic.ip_address, Nic.netmask, Nic.broadcast, Nic.gateway -- that part of the network address This should isolate where the details for networking come from and how networking is determined. > > + if nic.bondings.empty? && nic.physical_network > > + iface_name = macs[nic.mac] > > + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : nic.physical_network.ip_addresses.first.address) > > + netmask =(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.netmask) > > + broadcast=(nic.ip_addresses.empty? ? nil : nic.ip_addresses.first.broadcast) > > > Switch the source of the ip_addresses here. The previous should be: > > + ipaddress=(nic.physical_network.ip_addresses.empty? ? nil : > nic.ip_addresses.first.address) > + netmask =(nic.ip_addresses.empty? ? nil : > nic.physical_network.ip_addresses.first.netmask) > + broadcast=(nic.ip_addresses.empty? ? nil : > nic.physical_network.ip_addresses.first.broadcast) > > Furthermore app/controllers/managed_node_controller needs a change. As > previously mentioned the nics arriving are lowercase while being > compared to nics stored in the db which are uppercase. The following > change is needed for the controller line 57: > - @macs[key] = value > + @macs[key.upcase] = value > Done. Sending the updated patch. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Thu Apr 2 13:50:16 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 09:50:16 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. Message-ID: <1238680216-8130-1-git-send-email-dpierce@redhat.com> Added public APIs to Bonding and Nic to retrieve networking details for the respective interface. Refactored how interfaces, bonded interfaces and bridges are defined. When returning a configuration for the node, a bridge is first created, using the networking definition for the device. The network interface is then bridged over that device. When a bonded interface is created, a bridge is created for it as well. Signed-off-by: Darryl L. Pierce --- src/app/controllers/managed_node_controller.rb | 6 +- src/app/models/bonding.rb | 40 +++++++++ src/app/models/nic.rb | 39 +++++++++ src/lib/managed_node_configuration.rb | 86 +++++++++---------- src/test/fixtures/ip_addresses.yml | 9 ++ src/test/fixtures/nics.yml | 4 +- .../functional/managed_node_configuration_test.rb | 21 +++-- 7 files changed, 146 insertions(+), 59 deletions(-) diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb index f5948be..0922d92 100644 --- a/src/app/controllers/managed_node_controller.rb +++ b/src/app/controllers/managed_node_controller.rb @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController def load_host @host = Host.find_by_hostname(params[:host]) - render :nothing => true, :status => :error unless @host + render :nothing => true unless @host end def load_macs @@ -54,10 +54,10 @@ class ManagedNodeController < ApplicationController if mac_text != nil mac_text.scan(/([^,]+)\,?/).each do |line| key, value = line.first.split("=") - @macs[key] = value + @macs[key] = value.upcase end end - render :nothing => true, :status => :error if @macs.empty? + render :nothing => true if @macs.empty? end end diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb index 32b9a37..d87f3a0 100644 --- a/src/app/models/bonding.rb +++ b/src/app/models/bonding.rb @@ -72,6 +72,46 @@ class Bonding < ActiveRecord::Base :greater_than_or_equal_to => 0, :unless => Proc.new { |bonding| bonding.arp_interval.nil? } + # Returns whether networking is defined for this interface. + def networking? + # there is network if there's a vlan defined. + (vlan.nil? == false) + end + + # Returns the boot protocol for the interface, or +nil+ if networking + # is not defined. + def boot_protocol + return vlan.boot_type.proto if networking? + return nil + end + + # Returns the ip address assigned to this bonded interface, or +nil+ + # if no networking is defined. + def ip_address + return ip_addresses.first.address unless ip_addresses.empty? + return nil + end + + # Returns the netmask assigned to this bonded interface, or +nil+ + # if no networking is defined. + def netmask + return vlan.ip_addresses.first.netmask if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the broadcast address assigned to this bonded interface, + # or +nil if no networking is defined. + def broadcast + return vlan.ip_addresses.first.broadcast if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the gateway address for the bonded interface if networking is defined. + def gateway + return vlan.ip_addresses.first.gateway if networking? && !vlan.ip_addresses.empty? + return nil + end + protected def validate if ! vlan.nil? and diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb index e26c110..8e19c26 100644 --- a/src/app/models/nic.rb +++ b/src/app/models/nic.rb @@ -43,6 +43,45 @@ class Nic < ActiveRecord::Base :scope => :host_id, :unless => Proc.new { |nic| nic.physical_network_id.nil? } + # Returns whether the nic has networking defined. + def networking? + (physical_network != nil) + end + + # Returns the boot protocol for the nic if networking is defined. + def boot_protocol + return physical_network.boot_type.proto if networking? + end + + # Returns whether the nic is enslaved by a bonded interface. + def bonded? + !bondings.empty? + end + + # Returns the ip address for the nic if networking is defined. + def ip_address + return ip_addresses.first.address if networking? && !ip_addresses.empty? + return nil + end + + # Returns the netmask for the nic if networking is defined. + def netmask + return physical_network.ip_addresses.first.netmask if networking? && !ip_addresses.empty? + return nil + end + + # Returns the broadcast address for the nic if networking is defined. + def broadcast + return physical_network.ip_addresses.first.broadcast if networking? && !ip_addresses.empty? + return nil + end + + # Returns the gateway address fo rthe nic if networking is defined. + def gateway + return physical_network.ip_addresses.first.gateway if networking? && !ip_addresses.empty? + return nil + end + # validate 'bridge' or 'usage_type' attribute ? protected diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index c412917..028573b 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -65,35 +65,37 @@ class ManagedNodeConfiguration # now process the network interfaces and bondings host.bondings.each do |bonding| - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" - - if bonding.ip_addresses.empty? - entry += "|BOOTPROTO=dhcp" - else - ip = bonding.ip_addresses[0] - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - - result.puts "#{entry}|ONBOOT=yes" - - bonding.nics.each do |nic| - process_nic result, nic, macs, bonding + if bonding.networking? + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" + entry += "|ONBOOT=yes" + result.puts entry + + add_bridge(result,"none",bonding.interface_name, + bonding.boot_protocol, bonding.ip_address, + bonding.netmask, bonding.broadcast, + bonding.gateway) + + bonding.nics.each do |nic| + iface_name = macs[nic.mac] + if iface_name + add_slave(result, nic.mac, iface_name, bonding.interface_name) + end + end end end - has_bridge = false host.nics.each do |nic| - # only process this nic if it doesn't have a bonding - # TODO remove the hack to force a bridge into the picture - if nic.bondings.empty? - process_nic result, nic, macs, nil, false, true - - # TODO remove this when bridges are properly supported - unless has_bridge - macs[nic.mac] = "breth0" - process_nic result, nic, macs, nil, true, false - has_bridge = true - end + if nic.networking? && !nic.bonded? + iface_name = macs[nic.mac] + if iface_name + add_bridge(result, nic.mac, iface_name, + nic.boot_protocol, nic.ip_address, + nic.netmask, nic.broadcast, + nic.gateway) + add_nic(result, nic.mac, iface_name) + end end end @@ -102,27 +104,21 @@ class ManagedNodeConfiguration private - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) - iface_name = macs[nic.mac] - - if iface_name - entry = "ifcfg=#{nic.mac}|#{iface_name}" - - if bonding - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" - else - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" - if nic.physical_network.boot_type.proto == 'static' - ip = nic.ip_addresses[0] - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge - entry += "|TYPE=bridge" if is_bridge - end - entry += "|ONBOOT=yes" + def self.add_bridge(result, mac, iface_name, bootproto, + ipaddress, netmask, broadcast, gateway) + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" + if bootproto == "static" + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}|GATEWAY=#{gateway}" end + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + result.puts entry + end + + def self.add_nic(result, mac, iface_name) + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" + end - result.puts entry if defined? entry + def self.add_slave(result, mac, iface_name, master) + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" end end diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml index b19e9e1..bca0f11 100644 --- a/src/test/fixtures/ip_addresses.yml +++ b/src/test/fixtures/ip_addresses.yml @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: nic: ldapserver_nic_one type: IpV4Address address: 172.31.0.25 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 + gateway: 172.31.0.1 + +ip_v4_ldapserver_physical_nic_one: + network: static_physical_network_one + address: 172.31.0.26 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 gateway: 172.31.0.1 ip_v4_buildserver_nic_one: diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index 1cf3223..97397cd 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -23,7 +23,7 @@ ldapserver_nic_one: mac: 00:03:02:00:09:06 usage_type: 1 bandwidth: 100 - bridge: breth0 + bridge: host: ldapserver_managed_node physical_network: static_physical_network_one @@ -39,7 +39,7 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_two + physical_network: static_physical_network_one mediaserver_nic_one: mac: 07:17:19:65:03:32 diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb index 6ce4885..b66705e 100644 --- a/src/test/functional/managed_node_configuration_test.rb +++ b/src/test/functional/managed_node_configuration_test.rb @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|IPADDR=#{nic.ip_address}|NETMASK=#{nic.netmask}|BROADCAST=#{nic.broadcast}|GATEWAY=#{nic.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.boot_protocol}|IPADDR=#{nic1.ip_address}|NETMASK=#{nic1.netmask}|BROADCAST=#{nic1.broadcast}|GATEWAY=#{nic1.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE @@ -140,7 +142,8 @@ HERE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=#{bonding.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE -- 1.6.0.6 From mmorsi at redhat.com Thu Apr 2 15:34:25 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 02 Apr 2009 11:34:25 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238680216-8130-1-git-send-email-dpierce@redhat.com> References: <1238680216-8130-1-git-send-email-dpierce@redhat.com> Message-ID: <49D4DB01.2050904@redhat.com> Almost there, just a few caveats below Darryl L. Pierce wrote: > Added public APIs to Bonding and Nic to retrieve networking details for > the respective interface. > > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > Signed-off-by: Darryl L. Pierce > --- > src/app/controllers/managed_node_controller.rb | 6 +- > src/app/models/bonding.rb | 40 +++++++++ > src/app/models/nic.rb | 39 +++++++++ > src/lib/managed_node_configuration.rb | 86 +++++++++---------- > src/test/fixtures/ip_addresses.yml | 9 ++ > src/test/fixtures/nics.yml | 4 +- > .../functional/managed_node_configuration_test.rb | 21 +++-- > 7 files changed, 146 insertions(+), 59 deletions(-) > > diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb > index f5948be..0922d92 100644 > --- a/src/app/controllers/managed_node_controller.rb > +++ b/src/app/controllers/managed_node_controller.rb > @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController > def load_host > @host = Host.find_by_hostname(params[:host]) > > - render :nothing => true, :status => :error unless @host > + render :nothing => true unless @host > end > Removing this :status => error seems to break managed_node_controller_test::test_config_with_invalid_hostname. This test probably can now be removed. > > def load_macs > @@ -54,10 +54,10 @@ class ManagedNodeController < ApplicationController > if mac_text != nil > mac_text.scan(/([^,]+)\,?/).each do |line| > key, value = line.first.split("=") > - @macs[key] = value > + @macs[key] = value.upcase > end > end > As discussed, key (mac) should be upcased as opposed to value (interface_name). So this should be changed to @mac[key.upcase] = value > > - render :nothing => true, :status => :error if @macs.empty? > + render :nothing => true if @macs.empty? > end > end > Removing this :status => error seems to break managed_node_controller_test::test_config_with_invalid_macs. This test probably can now be removed. > diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb > index 32b9a37..d87f3a0 100644 > --- a/src/app/models/bonding.rb > +++ b/src/app/models/bonding.rb > @@ -72,6 +72,46 @@ class Bonding < ActiveRecord::Base > :greater_than_or_equal_to => 0, > :unless => Proc.new { |bonding| bonding.arp_interval.nil? } > > + # Returns whether networking is defined for this interface. > + def networking? > + # there is network if there's a vlan defined. > + (vlan.nil? == false) > + end > + > + # Returns the boot protocol for the interface, or +nil+ if networking > + # is not defined. > + def boot_protocol > + return vlan.boot_type.proto if networking? > + return nil > + end > + > + # Returns the ip address assigned to this bonded interface, or +nil+ > + # if no networking is defined. > + def ip_address > + return ip_addresses.first.address unless ip_addresses.empty? > + return nil > + end > + > + # Returns the netmask assigned to this bonded interface, or +nil+ > + # if no networking is defined. > + def netmask > + return vlan.ip_addresses.first.netmask if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > + # Returns the broadcast address assigned to this bonded interface, > + # or +nil if no networking is defined. > + def broadcast > + return vlan.ip_addresses.first.broadcast if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > + # Returns the gateway address for the bonded interface if networking is defined. > + def gateway > + return vlan.ip_addresses.first.gateway if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > protected > def validate > if ! vlan.nil? and > diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb > index e26c110..8e19c26 100644 > --- a/src/app/models/nic.rb > +++ b/src/app/models/nic.rb > @@ -43,6 +43,45 @@ class Nic < ActiveRecord::Base > :scope => :host_id, > :unless => Proc.new { |nic| nic.physical_network_id.nil? } > > + # Returns whether the nic has networking defined. > + def networking? > + (physical_network != nil) > + end > + > + # Returns the boot protocol for the nic if networking is defined. > + def boot_protocol > + return physical_network.boot_type.proto if networking? > + end > + > + # Returns whether the nic is enslaved by a bonded interface. > + def bonded? > + !bondings.empty? > + end > + > + # Returns the ip address for the nic if networking is defined. > + def ip_address > + return ip_addresses.first.address if networking? && !ip_addresses.empty? > + return nil > + end > I'm not sure if we need to check networking? here, as we're not currently performing the same check in the 'ip_address' method in bonding. Doesn't currently break anything though, so could be left as is, just want to highlight the discrepancy as it may cause future confusion. > + > + # Returns the netmask for the nic if networking is defined. > + def netmask > + return physical_network.ip_addresses.first.netmask if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the broadcast address for the nic if networking is defined. > + def broadcast > + return physical_network.ip_addresses.first.broadcast if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the gateway address fo rthe nic if networking is defined. > + def gateway > + return physical_network.ip_addresses.first.gateway if networking? && !ip_addresses.empty? > + return nil > + end > + > The conditional first line of the previous three methods should be changed to check physical_network.ip_addresses.empty? > # validate 'bridge' or 'usage_type' attribute ? > > protected > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..028573b 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > - > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > - > - result.puts "#{entry}|ONBOOT=yes" > - > - bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + if bonding.networking? > Should we not be creating the bonding whatsoever if no network is assigned? This "bonding.networking?" conditional should surround the add_bridge call for sure. But I'm not sure if the bonding should be created regardless of whether a network is assigned. Hugh? Alan? -Mo From jboggs at redhat.com Thu Apr 2 15:44:55 2009 From: jboggs at redhat.com (Joey Boggs) Date: Thu, 02 Apr 2009 11:44:55 -0400 Subject: [Ovirt-devel] [PATCH server] verify hostname is not on the loopback entry in /etc/hosts In-Reply-To: <1238629567.23359.15.camel@avon.watzmann.net> References: <1238008866-13329-1-git-send-email-jboggs@redhat.com> <1238629567.23359.15.camel@avon.watzmann.net> Message-ID: <49D4DD77.9090800@redhat.com> Trying to get this working on a test file but running into: tundefined method `init' for Augeas:Class (NoMethodError) I've built augeas from source and still run into the same problem. Tried latest available in F10 (0.3.6-1.fc10) Then upgraded to: augeas-0.0.5 built from source ruby-augeas-0.2.0-2.fc11.x86_64 from rawhide augeas-libs-0.4.2-1.fc11.x86_64 from rawhide #!/usr/bin/ruby require 'augeas' aug = Augeas::init(nil, nil, 0) hosts = "/files/etc/hosts/*" paths = aug.match("#{hosts}/canonical[../ipaddr = '127.0.0.1']") + aug.match("#{hosts}/alias[../ipaddr = '127.0.0.1']") paths.each do |p| name = aug.get(p) if hostname == name @cli.say("\nHostname must not be on the loopback 127.0.0.1 line in /etc/hosts") if (prompt_yes_no("Should I fix that ?", :default => "n") == "y") aug.rm(p) aug.save end end end David Lutterkort wrote: > On Wed, 2009-03-25 at 15:21 -0400, Joey Boggs wrote: > >> +# verify hostname is not on the loopback line in /etc/hosts to prevent kerberos problems >> +hostname = `hostname` >> +hostsfile = File.new("/etc/hosts", "r") >> +while (line = hostsfile.gets) >> + if line =~ /127.0.0.1/ && line.include?(hostname.chomp) >> + if hostname !~ /localhost.localdomain/ >> + @cli.say("\nHostname must not be on the loopback 127.0.0.1 line in /etc/hosts") >> + @cli.say("#{line}") >> + exit(0) >> + end >> + end >> +end >> +hostsfile.close >> > > This can produce false positives in a number of ways: (1) it will get > confused by comments: > > # We used to have, but that's wrong > # 127.0.0.1 host.exmaple.com > 127.0.0.1 localhost.localdomain > > It also gets confused if hostname is 'host.example.com' and the > 127.0.0.1 line has an alias 'myhost.example.com'. > > Finally, (but that should happen throughout the installer), the > installer shouldn't exit with status 0 when there was an error. It would > be good to have a convention like status == 0 when installer finished > successfully, status == 1 when an error happened, status == 2 when user > exited installer (e.g., by answering 'no' to some question) > > A more robust implementation of the above would be: > > aug = Augeas::init(nil, nil, 0) > hosts = "/files/etc/hosts/*" > paths = aug.match("#{hosts}/canonical[../ipaddr = '127.0.0.1']") + > aug.match("#{hosts}/alias[../ipaddr = '127.0.0.1']") > paths.each do |p| > name = aug.get(p) > if hostname == name > @cli.say("\nHostname must not be on the loopback 127.0.0.1 line in /etc/hosts") > if (prompt_yes_no("Should I fix that ?", :default => "n") == "y") > aug.rm(p) > aug.save > end > end > end > > David > > > From katzj at redhat.com Thu Apr 2 15:46:12 2009 From: katzj at redhat.com (Jeremy Katz) Date: Thu, 2 Apr 2009 11:46:12 -0400 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <1238628546.23359.4.camel@avon.watzmann.net> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> Message-ID: <20090402154612.GA4293@redhat.com> On Wednesday, April 01 2009, David Lutterkort said: > On Wed, 2009-04-01 at 16:44 -0400, Jeremy Katz wrote: > > On Tuesday, March 31 2009, Ian Main said: > > > Through much discussion it was decided that we would leverage the rails > > > models created for use in the WUI, and create an alternative way to > > > access these models, start tasks etc. This will be integrated with the > > > current task management system (taskomatic) to produce a complete package. > > > > > > The idea is to create a set of classes available via QMF as objects. > > > These classes would then be backed by either a mid-level API that > > > encompasses the models, or by active record models directly. Any changes > > > made to these records outside of the API (eg by the WUI) would require > > > notification of changes to taskomatic. > > > > So, by integrating deeply like this, how much is going to be tied to underlying > > implementation details that (may|might|will) change in the future? From > > looking through it, it seems very tightly tied which given the many > > unanswered questions, is at least of some concern imho. > > Can you give examples of what in the API proposal worries you in that > regard ? What the QMF API exposes isn't too different from what the REST > API (would) expose. All of the specifics around pools and the way that storage works today seems pretty closely tied. Since direction of virt mgmt vs cloud mgmt are pretty different here, it's the thing that immediately jumps out. > > Also, who is the expected target user of this API? Someone who is > > deploying guests within the cloud or someone who is managing the overall > > cloud? As there's probably a different level of care for what are the > > important things to expose accordingly. It looks more like the latter > > but with a mix of some of the former, but at a far more detailed level > > than a cloud user would need/want > > The API is targetted at both - whether an 'ordinary' cloud user is > allowed to do certain operations is a question of permissions. > > Some of that complexity will/can be hidden with more targetted tools on > top of the API, either in the form of a client library or the command > line tools that I started writing a while ago, but never finished. So rather than getting people to use QMF (which is going to be a challenge in and of itself given its still relative obscurity), we're going to try to push people to using more lirbaries, etc on top of it? Which means that if I want to use it from $some_other_crack_language, I'm either going to have to bind it or use the underlying QMF api that we're not wanting people to use? This feels backwards. The exposed API should be what we're targeting people to use, not some mid-layer that stems from how we've implemented the world Jeremy From dpierce at redhat.com Thu Apr 2 15:53:20 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 11:53:20 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. Message-ID: <1238687600-16391-1-git-send-email-dpierce@redhat.com> Added public APIs to Bonding and Nic to retrieve networking details for the respective interface. Refactored how interfaces, bonded interfaces and bridges are defined. When returning a configuration for the node, a bridge is first created, using the networking definition for the device. The network interface is then bridged over that device. When a bonded interface is created, a bridge is created for it as well. If a hostname is unknown, or it does not send up any macs, then it is returned an empty configuration payload and not an error status code. Signed-off-by: Darryl L. Pierce --- src/app/controllers/managed_node_controller.rb | 6 +- src/app/models/bonding.rb | 40 ++++++++++ src/app/models/nic.rb | 39 ++++++++++ src/lib/managed_node_configuration.rb | 80 +++++++++---------- src/test/fixtures/ip_addresses.yml | 9 ++ src/test/fixtures/nics.yml | 4 +- .../functional/managed_node_configuration_test.rb | 21 +++-- .../functional/managed_node_controller_test.rb | 21 ----- 8 files changed, 143 insertions(+), 77 deletions(-) diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb index f5948be..062b3d4 100644 --- a/src/app/controllers/managed_node_controller.rb +++ b/src/app/controllers/managed_node_controller.rb @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController def load_host @host = Host.find_by_hostname(params[:host]) - render :nothing => true, :status => :error unless @host + render :nothing => true unless @host end def load_macs @@ -54,10 +54,10 @@ class ManagedNodeController < ApplicationController if mac_text != nil mac_text.scan(/([^,]+)\,?/).each do |line| key, value = line.first.split("=") - @macs[key] = value + @macs[key.upcase] = value end end - render :nothing => true, :status => :error if @macs.empty? + render :nothing => true if @macs.empty? end end diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb index 32b9a37..2dd84fa 100644 --- a/src/app/models/bonding.rb +++ b/src/app/models/bonding.rb @@ -72,6 +72,46 @@ class Bonding < ActiveRecord::Base :greater_than_or_equal_to => 0, :unless => Proc.new { |bonding| bonding.arp_interval.nil? } + # Returns whether networking is defined for this interface. + def networking? + # there is network if there's a vlan defined. + (vlan.nil? == false) + end + + # Returns the boot protocol for the interface, or +nil+ if networking + # is not defined. + def boot_protocol + return vlan.boot_type.proto if networking? + return nil + end + + # Returns the ip address assigned to this bonded interface, or +nil+ + # if no networking is defined. + def ip_address + return ip_addresses.first.address if networking? && !ip_addresses.empty? + return nil + end + + # Returns the netmask assigned to this bonded interface, or +nil+ + # if no networking is defined. + def netmask + return vlan.ip_addresses.first.netmask if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the broadcast address assigned to this bonded interface, + # or +nil if no networking is defined. + def broadcast + return vlan.ip_addresses.first.broadcast if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the gateway address for the bonded interface if networking is defined. + def gateway + return vlan.ip_addresses.first.gateway if networking? && !vlan.ip_addresses.empty? + return nil + end + protected def validate if ! vlan.nil? and diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb index e26c110..8e19c26 100644 --- a/src/app/models/nic.rb +++ b/src/app/models/nic.rb @@ -43,6 +43,45 @@ class Nic < ActiveRecord::Base :scope => :host_id, :unless => Proc.new { |nic| nic.physical_network_id.nil? } + # Returns whether the nic has networking defined. + def networking? + (physical_network != nil) + end + + # Returns the boot protocol for the nic if networking is defined. + def boot_protocol + return physical_network.boot_type.proto if networking? + end + + # Returns whether the nic is enslaved by a bonded interface. + def bonded? + !bondings.empty? + end + + # Returns the ip address for the nic if networking is defined. + def ip_address + return ip_addresses.first.address if networking? && !ip_addresses.empty? + return nil + end + + # Returns the netmask for the nic if networking is defined. + def netmask + return physical_network.ip_addresses.first.netmask if networking? && !ip_addresses.empty? + return nil + end + + # Returns the broadcast address for the nic if networking is defined. + def broadcast + return physical_network.ip_addresses.first.broadcast if networking? && !ip_addresses.empty? + return nil + end + + # Returns the gateway address fo rthe nic if networking is defined. + def gateway + return physical_network.ip_addresses.first.gateway if networking? && !ip_addresses.empty? + return nil + end + # validate 'bridge' or 'usage_type' attribute ? protected diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index c412917..889869a 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -65,35 +65,37 @@ class ManagedNodeConfiguration # now process the network interfaces and bondings host.bondings.each do |bonding| - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" - - if bonding.ip_addresses.empty? - entry += "|BOOTPROTO=dhcp" - else - ip = bonding.ip_addresses[0] - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" + if bonding.networking? + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" + entry += "|ONBOOT=yes" + result.puts entry + + add_bridge(result,"none",bonding.interface_name, + bonding.boot_protocol, bonding.ip_address, + bonding.netmask, bonding.broadcast, + bonding.gateway) end - result.puts "#{entry}|ONBOOT=yes" - bonding.nics.each do |nic| - process_nic result, nic, macs, bonding + iface_name = macs[nic.mac] + if iface_name + add_slave(result, nic.mac, iface_name, bonding.interface_name) + end end end - has_bridge = false host.nics.each do |nic| - # only process this nic if it doesn't have a bonding - # TODO remove the hack to force a bridge into the picture - if nic.bondings.empty? - process_nic result, nic, macs, nil, false, true - - # TODO remove this when bridges are properly supported - unless has_bridge - macs[nic.mac] = "breth0" - process_nic result, nic, macs, nil, true, false - has_bridge = true - end + if nic.networking? && !nic.bonded? + iface_name = macs[nic.mac] + if iface_name + add_bridge(result, nic.mac, iface_name, + nic.boot_protocol, nic.ip_address, + nic.netmask, nic.broadcast, + nic.gateway) + add_nic(result, nic.mac, iface_name) + end end end @@ -102,27 +104,21 @@ class ManagedNodeConfiguration private - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) - iface_name = macs[nic.mac] - - if iface_name - entry = "ifcfg=#{nic.mac}|#{iface_name}" - - if bonding - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" - else - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" - if nic.physical_network.boot_type.proto == 'static' - ip = nic.ip_addresses[0] - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge - entry += "|TYPE=bridge" if is_bridge - end - entry += "|ONBOOT=yes" + def self.add_bridge(result, mac, iface_name, bootproto, + ipaddress, netmask, broadcast, gateway) + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" + if bootproto == "static" + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}|GATEWAY=#{gateway}" end + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + result.puts entry + end + + def self.add_nic(result, mac, iface_name) + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" + end - result.puts entry if defined? entry + def self.add_slave(result, mac, iface_name, master) + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" end end diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml index b19e9e1..bca0f11 100644 --- a/src/test/fixtures/ip_addresses.yml +++ b/src/test/fixtures/ip_addresses.yml @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: nic: ldapserver_nic_one type: IpV4Address address: 172.31.0.25 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 + gateway: 172.31.0.1 + +ip_v4_ldapserver_physical_nic_one: + network: static_physical_network_one + address: 172.31.0.26 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 gateway: 172.31.0.1 ip_v4_buildserver_nic_one: diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index 1cf3223..97397cd 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -23,7 +23,7 @@ ldapserver_nic_one: mac: 00:03:02:00:09:06 usage_type: 1 bandwidth: 100 - bridge: breth0 + bridge: host: ldapserver_managed_node physical_network: static_physical_network_one @@ -39,7 +39,7 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_two + physical_network: static_physical_network_one mediaserver_nic_one: mac: 07:17:19:65:03:32 diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb index 6ce4885..b66705e 100644 --- a/src/test/functional/managed_node_configuration_test.rb +++ b/src/test/functional/managed_node_configuration_test.rb @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|IPADDR=#{nic.ip_address}|NETMASK=#{nic.netmask}|BROADCAST=#{nic.broadcast}|GATEWAY=#{nic.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.boot_protocol}|IPADDR=#{nic1.ip_address}|NETMASK=#{nic1.netmask}|BROADCAST=#{nic1.broadcast}|GATEWAY=#{nic1.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE @@ -140,7 +142,8 @@ HERE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=#{bonding.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE diff --git a/src/test/functional/managed_node_controller_test.rb b/src/test/functional/managed_node_controller_test.rb index a6d2667..dd93e80 100644 --- a/src/test/functional/managed_node_controller_test.rb +++ b/src/test/functional/managed_node_controller_test.rb @@ -26,27 +26,6 @@ class ManagedNodeControllerTest < ActionController::TestCase fixtures :hosts fixtures :nics - # Ensures that the request fails if it's missing a hostname, or if the - # hostname is invalid. - # - def test_config_with_invalid_hostname - get :config - - assert_response :error - - get :config, {:host => 'invalid.prod.com'} - - assert_response :error - end - - # Ensures the request fails if no mac addresses are supplied. - # - def test_config_without_macs - get :config, {:host => hosts(:mailservers_managed_node).hostname} - - assert_response :error - end - # Ensures the request succeeds if it is well-formed. # def test_config -- 1.6.0.6 From sseago at redhat.com Thu Apr 2 15:57:57 2009 From: sseago at redhat.com (Scott Seago) Date: Thu, 02 Apr 2009 11:57:57 -0400 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090402154612.GA4293@redhat.com> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> <20090402154612.GA4293@redhat.com> Message-ID: <49D4E085.1040905@redhat.com> Jeremy Katz wrote: > On Wednesday, April 01 2009, David Lutterkort said: > >> On Wed, 2009-04-01 at 16:44 -0400, Jeremy Katz wrote: >> >>> On Tuesday, March 31 2009, Ian Main said: >>> >>>> Through much discussion it was decided that we would leverage the rails >>>> models created for use in the WUI, and create an alternative way to >>>> access these models, start tasks etc. This will be integrated with the >>>> current task management system (taskomatic) to produce a complete package. >>>> >>>> The idea is to create a set of classes available via QMF as objects. >>>> These classes would then be backed by either a mid-level API that >>>> encompasses the models, or by active record models directly. Any changes >>>> made to these records outside of the API (eg by the WUI) would require >>>> notification of changes to taskomatic. >>>> >>> So, by integrating deeply like this, how much is going to be tied to underlying >>> implementation details that (may|might|will) change in the future? From >>> looking through it, it seems very tightly tied which given the many >>> unanswered questions, is at least of some concern imho. >>> >> Can you give examples of what in the API proposal worries you in that >> regard ? What the QMF API exposes isn't too different from what the REST >> API (would) expose. >> > > All of the specifics around pools and the way that storage works today > seems pretty closely tied. Since direction of virt mgmt vs cloud mgmt > are pretty different here, it's the thing that immediately jumps out. > > It may be that we need multiple API levels here, but tying it to (hardware and VM) pools and the current oVirt model is actually pretty deliberate here. We _want_ to expose all of the oVirt-specific actions here so that everything that the UI does can be performed by other means as well -- cmdline, other mgmt apps, etc. If we don't expose ovirt-specific bits, then we can't perform oVirt-specific actions. Having a non-oVirt-specific mid-level API would be useful too, but that's not my understanding of what we're doing here. Scott From mmorsi at redhat.com Thu Apr 2 16:12:47 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 02 Apr 2009 12:12:47 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238687600-16391-1-git-send-email-dpierce@redhat.com> References: <1238687600-16391-1-git-send-email-dpierce@redhat.com> Message-ID: <49D4E3FF.7030702@redhat.com> Still two issues left. > diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb > ... > + > + # Returns the netmask for the nic if networking is defined. > + def netmask > + return physical_network.ip_addresses.first.netmask if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the broadcast address for the nic if networking is defined. > + def broadcast > + return physical_network.ip_addresses.first.broadcast if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the gateway address fo rthe nic if networking is defined. > + def gateway > + return physical_network.ip_addresses.first.gateway if networking? && !ip_addresses.empty? > + return nil > + end > These three methods still need to be changed to check physical_network.ip_addresses.empty? and not just ip_addresses.empty? Also the following code block should be changed from this: > + if bonding.networking? > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > + > + add_bridge(result,"none",bonding.interface_name, > + bonding.boot_protocol, bonding.ip_address, > + bonding.netmask, bonding.broadcast, > + bonding.gateway) > end > > To this: + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" if bonding.networking? # <--- don't forget this conditional as well + entry += "|ONBOOT=yes" + result.puts entry + if bonding.networking? # <-- move this conditional here + add_bridge(result,"none",bonding.interface_name, + bonding.boot_protocol, bonding.ip_address, + bonding.netmask, bonding.broadcast, + bonding.gateway) end eg the placing of if bonding.networking? should be moved to just surround the call to add_bridge. The additions to the entry string (save the 'BRIDGE=brfoo' addition) should still take place regardless to the call to bonding.networking? else the bonding will not get created. -Mo From dpierce at redhat.com Thu Apr 2 16:15:55 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 12:15:55 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. Message-ID: <1238688955-17599-1-git-send-email-dpierce@redhat.com> NOTE: with feedback from mmorsi dated 02 April @ 12:12:47 -0400 Added public APIs to Bonding and Nic to retrieve networking details for the respective interface. Refactored how interfaces, bonded interfaces and bridges are defined. When returning a configuration for the node, a bridge is first created, using the networking definition for the device. The network interface is then bridged over that device. When a bonded interface is created, a bridge is created for it as well. If a hostname is unknown, or it does not send up any macs, then it is returned an empty configuration payload and not an error status code. Signed-off-by: Darryl L. Pierce --- src/app/controllers/managed_node_controller.rb | 6 +- src/app/models/bonding.rb | 40 ++++++++++ src/app/models/nic.rb | 39 ++++++++++ src/lib/managed_node_configuration.rb | 78 +++++++++---------- src/test/fixtures/ip_addresses.yml | 9 ++ src/test/fixtures/nics.yml | 4 +- .../functional/managed_node_configuration_test.rb | 21 +++-- .../functional/managed_node_controller_test.rb | 21 ----- 8 files changed, 142 insertions(+), 76 deletions(-) diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb index f5948be..062b3d4 100644 --- a/src/app/controllers/managed_node_controller.rb +++ b/src/app/controllers/managed_node_controller.rb @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController def load_host @host = Host.find_by_hostname(params[:host]) - render :nothing => true, :status => :error unless @host + render :nothing => true unless @host end def load_macs @@ -54,10 +54,10 @@ class ManagedNodeController < ApplicationController if mac_text != nil mac_text.scan(/([^,]+)\,?/).each do |line| key, value = line.first.split("=") - @macs[key] = value + @macs[key.upcase] = value end end - render :nothing => true, :status => :error if @macs.empty? + render :nothing => true if @macs.empty? end end diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb index 32b9a37..2dd84fa 100644 --- a/src/app/models/bonding.rb +++ b/src/app/models/bonding.rb @@ -72,6 +72,46 @@ class Bonding < ActiveRecord::Base :greater_than_or_equal_to => 0, :unless => Proc.new { |bonding| bonding.arp_interval.nil? } + # Returns whether networking is defined for this interface. + def networking? + # there is network if there's a vlan defined. + (vlan.nil? == false) + end + + # Returns the boot protocol for the interface, or +nil+ if networking + # is not defined. + def boot_protocol + return vlan.boot_type.proto if networking? + return nil + end + + # Returns the ip address assigned to this bonded interface, or +nil+ + # if no networking is defined. + def ip_address + return ip_addresses.first.address if networking? && !ip_addresses.empty? + return nil + end + + # Returns the netmask assigned to this bonded interface, or +nil+ + # if no networking is defined. + def netmask + return vlan.ip_addresses.first.netmask if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the broadcast address assigned to this bonded interface, + # or +nil if no networking is defined. + def broadcast + return vlan.ip_addresses.first.broadcast if networking? && !vlan.ip_addresses.empty? + return nil + end + + # Returns the gateway address for the bonded interface if networking is defined. + def gateway + return vlan.ip_addresses.first.gateway if networking? && !vlan.ip_addresses.empty? + return nil + end + protected def validate if ! vlan.nil? and diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb index e26c110..e8b7768 100644 --- a/src/app/models/nic.rb +++ b/src/app/models/nic.rb @@ -43,6 +43,45 @@ class Nic < ActiveRecord::Base :scope => :host_id, :unless => Proc.new { |nic| nic.physical_network_id.nil? } + # Returns whether the nic has networking defined. + def networking? + (physical_network != nil) + end + + # Returns the boot protocol for the nic if networking is defined. + def boot_protocol + return physical_network.boot_type.proto if networking? + end + + # Returns whether the nic is enslaved by a bonded interface. + def bonded? + !bondings.empty? + end + + # Returns the ip address for the nic if networking is defined. + def ip_address + return ip_addresses.first.address if networking? && !ip_addresses.empty? + return nil + end + + # Returns the netmask for the nic if networking is defined. + def netmask + return physical_network.ip_addresses.first.netmask if networking? && !physical_network.ip_addresses.empty? + return nil + end + + # Returns the broadcast address for the nic if networking is defined. + def broadcast + return physical_network.ip_addresses.first.broadcast if networking? && !physical_network.ip_addresses.empty? + return nil + end + + # Returns the gateway address fo rthe nic if networking is defined. + def gateway + return physical_network.ip_addresses.first.gateway if networking? && !physical_network.ip_addresses.empty? + return nil + end + # validate 'bridge' or 'usage_type' attribute ? protected diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index c412917..f93bccd 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -65,35 +65,37 @@ class ManagedNodeConfiguration # now process the network interfaces and bondings host.bondings.each do |bonding| - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry = "ifcfg=none|#{bonding.interface_name}" + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" + entry += "|BRIDGE=br#{bonding.interface_name}" + entry += "|ONBOOT=yes" + result.puts entry - if bonding.ip_addresses.empty? - entry += "|BOOTPROTO=dhcp" - else - ip = bonding.ip_addresses[0] - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" + if bonding.networking? + add_bridge(result,"none",bonding.interface_name, + bonding.boot_protocol, bonding.ip_address, + bonding.netmask, bonding.broadcast, + bonding.gateway) end - result.puts "#{entry}|ONBOOT=yes" - bonding.nics.each do |nic| - process_nic result, nic, macs, bonding + iface_name = macs[nic.mac] + if iface_name + add_slave(result, nic.mac, iface_name, bonding.interface_name) + end end end - has_bridge = false host.nics.each do |nic| - # only process this nic if it doesn't have a bonding - # TODO remove the hack to force a bridge into the picture - if nic.bondings.empty? - process_nic result, nic, macs, nil, false, true - - # TODO remove this when bridges are properly supported - unless has_bridge - macs[nic.mac] = "breth0" - process_nic result, nic, macs, nil, true, false - has_bridge = true - end + if nic.networking? && !nic.bonded? + iface_name = macs[nic.mac] + if iface_name + add_bridge(result, nic.mac, iface_name, + nic.boot_protocol, nic.ip_address, + nic.netmask, nic.broadcast, + nic.gateway) + add_nic(result, nic.mac, iface_name) + end end end @@ -102,27 +104,21 @@ class ManagedNodeConfiguration private - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) - iface_name = macs[nic.mac] - - if iface_name - entry = "ifcfg=#{nic.mac}|#{iface_name}" - - if bonding - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" - else - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" - if nic.physical_network.boot_type.proto == 'static' - ip = nic.ip_addresses[0] - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" - end - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge - entry += "|TYPE=bridge" if is_bridge - end - entry += "|ONBOOT=yes" + def self.add_bridge(result, mac, iface_name, bootproto, + ipaddress, netmask, broadcast, gateway) + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" + if bootproto == "static" + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}|GATEWAY=#{gateway}" end + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + result.puts entry + end + + def self.add_nic(result, mac, iface_name) + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" + end - result.puts entry if defined? entry + def self.add_slave(result, mac, iface_name, master) + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" end end diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml index b19e9e1..bca0f11 100644 --- a/src/test/fixtures/ip_addresses.yml +++ b/src/test/fixtures/ip_addresses.yml @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: nic: ldapserver_nic_one type: IpV4Address address: 172.31.0.25 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 + gateway: 172.31.0.1 + +ip_v4_ldapserver_physical_nic_one: + network: static_physical_network_one + address: 172.31.0.26 + netmask: 255.255.255.0 + broadcast: 172.31.0.255 gateway: 172.31.0.1 ip_v4_buildserver_nic_one: diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml index 1cf3223..97397cd 100644 --- a/src/test/fixtures/nics.yml +++ b/src/test/fixtures/nics.yml @@ -23,7 +23,7 @@ ldapserver_nic_one: mac: 00:03:02:00:09:06 usage_type: 1 bandwidth: 100 - bridge: breth0 + bridge: host: ldapserver_managed_node physical_network: static_physical_network_one @@ -39,7 +39,7 @@ buildserver_nic_two: usage_type: 1 bandwidth: 100 host: buildserver_managed_node - physical_network: static_physical_network_two + physical_network: static_physical_network_one mediaserver_nic_one: mac: 07:17:19:65:03:32 diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb index 6ce4885..b66705e 100644 --- a/src/test/functional/managed_node_configuration_test.rb +++ b/src/test/functional/managed_node_configuration_test.rb @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|IPADDR=#{nic.ip_address}|NETMASK=#{nic.netmask}|BROADCAST=#{nic.broadcast}|GATEWAY=#{nic.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR expected = <<-HERE # THIS FILE IS GENERATED! -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.boot_protocol}|IPADDR=#{nic1.ip_address}|NETMASK=#{nic1.netmask}|BROADCAST=#{nic1.broadcast}|GATEWAY=#{nic1.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes HERE result = ManagedNodeConfiguration.generate( @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE @@ -140,7 +142,8 @@ HERE expected = <<-HERE # THIS FILE IS GENERATED! bonding=#{bonding.interface_name} -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=#{bonding.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes HERE diff --git a/src/test/functional/managed_node_controller_test.rb b/src/test/functional/managed_node_controller_test.rb index a6d2667..dd93e80 100644 --- a/src/test/functional/managed_node_controller_test.rb +++ b/src/test/functional/managed_node_controller_test.rb @@ -26,27 +26,6 @@ class ManagedNodeControllerTest < ActionController::TestCase fixtures :hosts fixtures :nics - # Ensures that the request fails if it's missing a hostname, or if the - # hostname is invalid. - # - def test_config_with_invalid_hostname - get :config - - assert_response :error - - get :config, {:host => 'invalid.prod.com'} - - assert_response :error - end - - # Ensures the request fails if no mac addresses are supplied. - # - def test_config_without_macs - get :config, {:host => hosts(:mailservers_managed_node).hostname} - - assert_response :error - end - # Ensures the request succeeds if it is well-formed. # def test_config -- 1.6.0.6 From mmorsi at redhat.com Thu Apr 2 16:25:59 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 02 Apr 2009 12:25:59 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <1238688955-17599-1-git-send-email-dpierce@redhat.com> References: <1238688955-17599-1-git-send-email-dpierce@redhat.com> Message-ID: <49D4E717.7080501@redhat.com> Looks and works great. ACK. -Mo Darryl L. Pierce wrote: > NOTE: with feedback from mmorsi dated 02 April @ 12:12:47 -0400 > > Added public APIs to Bonding and Nic to retrieve networking details for > the respective interface. > > Refactored how interfaces, bonded interfaces and bridges are defined. > > When returning a configuration for the node, a bridge is first created, > using the networking definition for the device. The network interface is > then bridged over that device. > > When a bonded interface is created, a bridge is created for it as well. > > If a hostname is unknown, or it does not send up any macs, then it is > returned an empty configuration payload and not an error status code. > > Signed-off-by: Darryl L. Pierce > --- > src/app/controllers/managed_node_controller.rb | 6 +- > src/app/models/bonding.rb | 40 ++++++++++ > src/app/models/nic.rb | 39 ++++++++++ > src/lib/managed_node_configuration.rb | 78 +++++++++---------- > src/test/fixtures/ip_addresses.yml | 9 ++ > src/test/fixtures/nics.yml | 4 +- > .../functional/managed_node_configuration_test.rb | 21 +++-- > .../functional/managed_node_controller_test.rb | 21 ----- > 8 files changed, 142 insertions(+), 76 deletions(-) > > diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb > index f5948be..062b3d4 100644 > --- a/src/app/controllers/managed_node_controller.rb > +++ b/src/app/controllers/managed_node_controller.rb > @@ -44,7 +44,7 @@ class ManagedNodeController < ApplicationController > def load_host > @host = Host.find_by_hostname(params[:host]) > > - render :nothing => true, :status => :error unless @host > + render :nothing => true unless @host > end > > def load_macs > @@ -54,10 +54,10 @@ class ManagedNodeController < ApplicationController > if mac_text != nil > mac_text.scan(/([^,]+)\,?/).each do |line| > key, value = line.first.split("=") > - @macs[key] = value > + @macs[key.upcase] = value > end > end > > - render :nothing => true, :status => :error if @macs.empty? > + render :nothing => true if @macs.empty? > end > end > diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb > index 32b9a37..2dd84fa 100644 > --- a/src/app/models/bonding.rb > +++ b/src/app/models/bonding.rb > @@ -72,6 +72,46 @@ class Bonding < ActiveRecord::Base > :greater_than_or_equal_to => 0, > :unless => Proc.new { |bonding| bonding.arp_interval.nil? } > > + # Returns whether networking is defined for this interface. > + def networking? > + # there is network if there's a vlan defined. > + (vlan.nil? == false) > + end > + > + # Returns the boot protocol for the interface, or +nil+ if networking > + # is not defined. > + def boot_protocol > + return vlan.boot_type.proto if networking? > + return nil > + end > + > + # Returns the ip address assigned to this bonded interface, or +nil+ > + # if no networking is defined. > + def ip_address > + return ip_addresses.first.address if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the netmask assigned to this bonded interface, or +nil+ > + # if no networking is defined. > + def netmask > + return vlan.ip_addresses.first.netmask if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > + # Returns the broadcast address assigned to this bonded interface, > + # or +nil if no networking is defined. > + def broadcast > + return vlan.ip_addresses.first.broadcast if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > + # Returns the gateway address for the bonded interface if networking is defined. > + def gateway > + return vlan.ip_addresses.first.gateway if networking? && !vlan.ip_addresses.empty? > + return nil > + end > + > protected > def validate > if ! vlan.nil? and > diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb > index e26c110..e8b7768 100644 > --- a/src/app/models/nic.rb > +++ b/src/app/models/nic.rb > @@ -43,6 +43,45 @@ class Nic < ActiveRecord::Base > :scope => :host_id, > :unless => Proc.new { |nic| nic.physical_network_id.nil? } > > + # Returns whether the nic has networking defined. > + def networking? > + (physical_network != nil) > + end > + > + # Returns the boot protocol for the nic if networking is defined. > + def boot_protocol > + return physical_network.boot_type.proto if networking? > + end > + > + # Returns whether the nic is enslaved by a bonded interface. > + def bonded? > + !bondings.empty? > + end > + > + # Returns the ip address for the nic if networking is defined. > + def ip_address > + return ip_addresses.first.address if networking? && !ip_addresses.empty? > + return nil > + end > + > + # Returns the netmask for the nic if networking is defined. > + def netmask > + return physical_network.ip_addresses.first.netmask if networking? && !physical_network.ip_addresses.empty? > + return nil > + end > + > + # Returns the broadcast address for the nic if networking is defined. > + def broadcast > + return physical_network.ip_addresses.first.broadcast if networking? && !physical_network.ip_addresses.empty? > + return nil > + end > + > + # Returns the gateway address fo rthe nic if networking is defined. > + def gateway > + return physical_network.ip_addresses.first.gateway if networking? && !physical_network.ip_addresses.empty? > + return nil > + end > + > # validate 'bridge' or 'usage_type' attribute ? > > protected > diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb > index c412917..f93bccd 100644 > --- a/src/lib/managed_node_configuration.rb > +++ b/src/lib/managed_node_configuration.rb > @@ -65,35 +65,37 @@ class ManagedNodeConfiguration > # now process the network interfaces and bondings > > host.bondings.each do |bonding| > - entry = "ifcfg=none|#{bonding.interface_name}|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry = "ifcfg=none|#{bonding.interface_name}" > + entry += "|BONDING_OPTS=\"mode=#{bonding.bonding_type.mode} miimon=100\"" > + entry += "|BRIDGE=br#{bonding.interface_name}" > + entry += "|ONBOOT=yes" > + result.puts entry > > - if bonding.ip_addresses.empty? > - entry += "|BOOTPROTO=dhcp" > - else > - ip = bonding.ip_addresses[0] > - entry += "|BOOTPROTO=static|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > + if bonding.networking? > + add_bridge(result,"none",bonding.interface_name, > + bonding.boot_protocol, bonding.ip_address, > + bonding.netmask, bonding.broadcast, > + bonding.gateway) > end > > - result.puts "#{entry}|ONBOOT=yes" > - > bonding.nics.each do |nic| > - process_nic result, nic, macs, bonding > + iface_name = macs[nic.mac] > + if iface_name > + add_slave(result, nic.mac, iface_name, bonding.interface_name) > + end > end > end > > - has_bridge = false > host.nics.each do |nic| > - # only process this nic if it doesn't have a bonding > - # TODO remove the hack to force a bridge into the picture > - if nic.bondings.empty? > - process_nic result, nic, macs, nil, false, true > - > - # TODO remove this when bridges are properly supported > - unless has_bridge > - macs[nic.mac] = "breth0" > - process_nic result, nic, macs, nil, true, false > - has_bridge = true > - end > + if nic.networking? && !nic.bonded? > + iface_name = macs[nic.mac] > + if iface_name > + add_bridge(result, nic.mac, iface_name, > + nic.boot_protocol, nic.ip_address, > + nic.netmask, nic.broadcast, > + nic.gateway) > + add_nic(result, nic.mac, iface_name) > + end > end > end > > @@ -102,27 +104,21 @@ class ManagedNodeConfiguration > > private > > - def self.process_nic(result, nic, macs, bonding = nil, is_bridge = false, bridged = true) > - iface_name = macs[nic.mac] > - > - if iface_name > - entry = "ifcfg=#{nic.mac}|#{iface_name}" > - > - if bonding > - entry += "|MASTER=#{bonding.interface_name}|SLAVE=yes" > - else > - entry += "|BOOTPROTO=#{nic.physical_network.boot_type.proto}" > - if nic.physical_network.boot_type.proto == 'static' > - ip = nic.ip_addresses[0] > - entry += "|IPADDR=#{ip.address}|NETMASK=#{ip.netmask}|BROADCAST=#{ip.broadcast}" > - end > - entry += "|BRIDGE=#{nic.bridge}" if nic.bridge && !is_bridge > - entry += "|BRIDGE=breth0" if !nic.bridge && !is_bridge > - entry += "|TYPE=bridge" if is_bridge > - end > - entry += "|ONBOOT=yes" > + def self.add_bridge(result, mac, iface_name, bootproto, > + ipaddress, netmask, broadcast, gateway) > + entry = "ifcfg=#{mac}|br#{iface_name}|BOOTPROTO=#{bootproto}" > + if bootproto == "static" > + entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}|GATEWAY=#{gateway}" > end > + entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" > + result.puts entry > + end > + > + def self.add_nic(result, mac, iface_name) > + result.puts "ifcfg=#{mac}|#{iface_name}|BRIDGE=br#{iface_name}|ONBOOT=yes" > + end > > - result.puts entry if defined? entry > + def self.add_slave(result, mac, iface_name, master) > + result.puts "ifcfg=#{mac}|#{iface_name}|MASTER=#{master}|SLAVE=yes|ONBOOT=yes" > end > end > diff --git a/src/test/fixtures/ip_addresses.yml b/src/test/fixtures/ip_addresses.yml > index b19e9e1..bca0f11 100644 > --- a/src/test/fixtures/ip_addresses.yml > +++ b/src/test/fixtures/ip_addresses.yml > @@ -10,6 +10,15 @@ ip_v4_ldapserver_nic_one: > nic: ldapserver_nic_one > type: IpV4Address > address: 172.31.0.25 > + netmask: 255.255.255.0 > + broadcast: 172.31.0.255 > + gateway: 172.31.0.1 > + > +ip_v4_ldapserver_physical_nic_one: > + network: static_physical_network_one > + address: 172.31.0.26 > + netmask: 255.255.255.0 > + broadcast: 172.31.0.255 > gateway: 172.31.0.1 > > ip_v4_buildserver_nic_one: > diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml > index 1cf3223..97397cd 100644 > --- a/src/test/fixtures/nics.yml > +++ b/src/test/fixtures/nics.yml > @@ -23,7 +23,7 @@ ldapserver_nic_one: > mac: 00:03:02:00:09:06 > usage_type: 1 > bandwidth: 100 > - bridge: breth0 > + bridge: > host: ldapserver_managed_node > physical_network: static_physical_network_one > > @@ -39,7 +39,7 @@ buildserver_nic_two: > usage_type: 1 > bandwidth: 100 > host: buildserver_managed_node > - physical_network: static_physical_network_two > + physical_network: static_physical_network_one > > mediaserver_nic_one: > mac: 07:17:19:65:03:32 > diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb > index 6ce4885..b66705e 100644 > --- a/src/test/functional/managed_node_configuration_test.rb > +++ b/src/test/functional/managed_node_configuration_test.rb > @@ -48,8 +48,8 @@ class ManagedNodeConfigurationTest < Test::Unit::TestCase > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=dhcp|BRIDGE=breth0|ONBOOT=yes > -ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -67,8 +67,8 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=dhcp|TYPE=bridge|ONBOOT=yes > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic.mac}|eth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=#{nic.ip_addresses.first.netmask}|BROADCAST=#{nic.ip_addresses.first.broadcast}|BRIDGE=#{nic.bridge}|ONBOOT=yes > -ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR=#{nic.ip_addresses.first.address}|NETMASK=|BROADCAST=#{nic.ip_addresses.first.netmask}|TYPE=bridge|ONBOOT=yes > +ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.boot_protocol}|IPADDR=#{nic.ip_address}|NETMASK=#{nic.netmask}|BROADCAST=#{nic.broadcast}|GATEWAY=#{nic.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes > +ifcfg=#{nic.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -87,9 +87,10 @@ ifcfg=#{nic.mac}|breth0|BOOTPROTO=#{nic.physical_network.boot_type.proto}|IPADDR > > expected = <<-HERE > # THIS FILE IS GENERATED! > -ifcfg=#{nic1.mac}|eth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|BRIDGE=breth0|ONBOOT=yes > -ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.physical_network.boot_type.proto}|IPADDR=#{nic1.ip_addresses.first.address}|NETMASK=#{nic1.ip_addresses.first.netmask}|BROADCAST=#{nic1.ip_addresses.first.broadcast}|TYPE=bridge|ONBOOT=yes > -ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic1.mac}|breth0|BOOTPROTO=#{nic1.boot_protocol}|IPADDR=#{nic1.ip_address}|NETMASK=#{nic1.netmask}|BROADCAST=#{nic1.broadcast}|GATEWAY=#{nic1.gateway}|TYPE=bridge|PEERDNS=no|ONBOOT=yes > +ifcfg=#{nic1.mac}|eth0|BRIDGE=breth0|ONBOOT=yes > +ifcfg=#{nic2.mac}|breth1|BOOTPROTO=#{nic2.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes > +ifcfg=#{nic2.mac}|eth1|BRIDGE=breth1|ONBOOT=yes > HERE > > result = ManagedNodeConfiguration.generate( > @@ -114,7 +115,8 @@ ifcfg=#{nic2.mac}|eth1|BOOTPROTO=#{nic2.physical_network.boot_type.proto}|BRIDGE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=static|IPADDR=#{bonding.ip_addresses.first.address}|NETMASK=#{bonding.ip_addresses.first.netmask}|BROADCAST=#{bonding.ip_addresses.first.broadcast}|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=dhcp|TYPE=bridge|PEERDNS=no|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > @@ -140,7 +142,8 @@ HERE > expected = <<-HERE > # THIS FILE IS GENERATED! > bonding=#{bonding.interface_name} > -ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BOOTPROTO=dhcp|ONBOOT=yes > +ifcfg=none|#{bonding.interface_name}|BONDING_OPTS="mode=#{bonding.bonding_type.mode} miimon=100"|BRIDGE=br#{bonding.interface_name}|ONBOOT=yes > +ifcfg=none|br#{bonding.interface_name}|BOOTPROTO=#{bonding.boot_protocol}|TYPE=bridge|PEERDNS=no|ONBOOT=yes > ifcfg=#{nic1.mac}|eth0|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > ifcfg=#{nic2.mac}|eth1|MASTER=#{bonding.interface_name}|SLAVE=yes|ONBOOT=yes > HERE > diff --git a/src/test/functional/managed_node_controller_test.rb b/src/test/functional/managed_node_controller_test.rb > index a6d2667..dd93e80 100644 > --- a/src/test/functional/managed_node_controller_test.rb > +++ b/src/test/functional/managed_node_controller_test.rb > @@ -26,27 +26,6 @@ class ManagedNodeControllerTest < ActionController::TestCase > fixtures :hosts > fixtures :nics > > - # Ensures that the request fails if it's missing a hostname, or if the > - # hostname is invalid. > - # > - def test_config_with_invalid_hostname > - get :config > - > - assert_response :error > - > - get :config, {:host => 'invalid.prod.com'} > - > - assert_response :error > - end > - > - # Ensures the request fails if no mac addresses are supplied. > - # > - def test_config_without_macs > - get :config, {:host => hosts(:mailservers_managed_node).hostname} > - > - assert_response :error > - end > - > # Ensures the request succeeds if it is well-formed. > # > def test_config > From dpierce at redhat.com Thu Apr 2 16:25:25 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 12:25:25 -0400 Subject: [Ovirt-devel] [PATCH server] Fixes to the managed_node_configuration code. In-Reply-To: <49D4E717.7080501@redhat.com> References: <1238688955-17599-1-git-send-email-dpierce@redhat.com> <49D4E717.7080501@redhat.com> Message-ID: <20090402162525.GC4232@mcpierce-laptop.rdu.redhat.com> On Thu, Apr 02, 2009 at 12:25:59PM -0400, Mohammed Morsi wrote: > Looks and works great. ACK. Pushed. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From lutter at redhat.com Thu Apr 2 17:51:03 2009 From: lutter at redhat.com (David Lutterkort) Date: Thu, 02 Apr 2009 10:51:03 -0700 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090402095702.GA16298@redhat.com> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> <20090402095702.GA16298@redhat.com> Message-ID: <1238694663.23359.24.camel@avon.watzmann.net> On Thu, 2009-04-02 at 10:57 +0100, Daniel P. Berrange wrote: > The idea of having a formal QMF API is very nice, but I can't help thinking > it will limit the potential userbase of the API since you of course need to > get a QMF api for your client. The really compelling thing about REST APIs > is that they are immediately usable by any client which has web browsing > capabilities - which is basically every device with a network connection > these days. No extra/special client side software required. Surely, both have their advantages; it's true that you can access the REST API from anything that can make web requests (and handle XML) - but to actually use the API you still need convenience wrappers around all that so you can get from a VM to the hardware pool it's in without going crazy. > I could see a REST and QMF api co-existing - perhaps you could in fact > write one in terms of the other to provide guarenteed parity of functionality > between the two, and reduce the burden of having 2 apis. I think in the longer run we'll have a REST API that is more focussed on queries (which are easy + flexible with REST) and a small number of generally useful tasks, and a QMF API for the heavy lifting. David From dpierce at redhat.com Thu Apr 2 18:16:19 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 14:16:19 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. Message-ID: <1238696179-31507-1-git-send-email-dpierce@redhat.com> The default interface configuration is only applied if a configuration was not retrieved from the server for some reason. It is only applied to the management interface. When ovirt-identify-node collects NIC details to send back to the server, it only collects for physical devices that support the net.80203 capability as reported by HAL. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/gather.c | 8 ++++---- scripts/ovirt-early | 25 ++++++++++++++----------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c index c12ed08..ae0bb73 100644 --- a/ovirt-identify-node/gather.c +++ b/ovirt-identify-node/gather.c @@ -286,7 +286,7 @@ get_nic_info(void) int i; - nics = libhal_find_device_by_capability(hal_ctx, "net", + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", &num_results, &dbus_error); DEBUG("Found %d NICs\n", num_results); @@ -294,7 +294,7 @@ get_nic_info(void) for (i = 0; i < num_results; i++) { char *nic = nics[i]; - VERBOSE("Starting new NIC.\n"); + DEBUG("Starting new NIC; %s.\n", nic); if (current != NULL) { last = current; @@ -311,8 +311,8 @@ get_nic_info(void) get_nic_data(nic, current); DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", - nic_info->mac_address, nic_info->bandwidth, - nic_info->ip_address); + current->mac_address, current->bandwidth, + current->ip_address); } return result; diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 1260900..b27d5ae 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -30,6 +30,7 @@ get_mac_addresses() { configure_from_network() { DEVICE=$1 + if [ -n "$DEVICE" ]; then log "Configuring network Using interface $DEVICE" # setup temporary interface to retrieve configuration @@ -56,35 +57,37 @@ configure_from_network() { ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG if [ $? -eq 0 ]; then log "Remote configuration retrieved and applied" + rm $cfgdb else log "Failure to retrieve or apply remote configuration" fi else log "Failed to retrieve configuration bundle" fi - rm $cfgdb fi fi fi fi # default oVirt network configuration: # bridge each ethernet device in the system - ETHDEVS=$(cd /sys/class/net && ls -d eth*) - for eth in $ETHDEVS; do - BRIDGE=br$eth + BRIDGE=br$DEVICE + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE + + # only write a default file if one does not exist + if [ ! -f $ifcfg ]; then log "Applying default configuration to $eth and $BRIDGE" printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ - > /etc/sysconfig/network-scripts/ifcfg-$eth + > /etc/sysconfig/network-scripts/ifcfg-$eth if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then - dhcp="BOOTPROTO=dhcp" + dhcp="BOOTPROTO=dhcp" else - dhcp="" + dhcp="" fi printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE - done - log "Default config applied" + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE + log "Default config applied" + fi } # $(get_live_disk) -- 1.6.0.6 From mmorsi at redhat.com Thu Apr 2 18:47:59 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 02 Apr 2009 14:47:59 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. In-Reply-To: <1238696179-31507-1-git-send-email-dpierce@redhat.com> References: <1238696179-31507-1-git-send-email-dpierce@redhat.com> Message-ID: <49D5085F.7080805@redhat.com> Just need two small changes concerning the default config. In the following code snippet you didn't change all the "$eth" (previously the loop iterator) to "$DEVICE" Also the "if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; " check is pretty pointless now, just need to remove it and put the "BOOTPROTO=dhcp" in the printf string. -Mo Darryl L. Pierce wrote: > + # only write a default file if one does not exist > + if [ ! -f $ifcfg ]; then > log "Applying default configuration to $eth and $BRIDGE" > printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > - > /etc/sysconfig/network-scripts/ifcfg-$eth > + > /etc/sysconfig/network-scripts/ifcfg-$eth > if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > - dhcp="BOOTPROTO=dhcp" > + dhcp="BOOTPROTO=dhcp" > else > - dhcp="" > + dhcp="" > fi > printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > - done > - log "Default config applied" > + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + log "Default config applied" > + fi > } > > # $(get_live_disk) > From dpierce at redhat.com Thu Apr 2 18:49:05 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 14:49:05 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. Message-ID: <1238698145-1544-1-git-send-email-dpierce@redhat.com> The default interface configuration is only applied if a configuration was not retrieved from the server for some reason. It is only applied to the management interface. When ovirt-identify-node collects NIC details to send back to the server, it only collects for physical devices that support the net.80203 capability as reported by HAL. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/gather.c | 8 ++++---- scripts/ovirt-early | 26 +++++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c index c12ed08..ae0bb73 100644 --- a/ovirt-identify-node/gather.c +++ b/ovirt-identify-node/gather.c @@ -286,7 +286,7 @@ get_nic_info(void) int i; - nics = libhal_find_device_by_capability(hal_ctx, "net", + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", &num_results, &dbus_error); DEBUG("Found %d NICs\n", num_results); @@ -294,7 +294,7 @@ get_nic_info(void) for (i = 0; i < num_results; i++) { char *nic = nics[i]; - VERBOSE("Starting new NIC.\n"); + DEBUG("Starting new NIC; %s.\n", nic); if (current != NULL) { last = current; @@ -311,8 +311,8 @@ get_nic_info(void) get_nic_data(nic, current); DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", - nic_info->mac_address, nic_info->bandwidth, - nic_info->ip_address); + current->mac_address, current->bandwidth, + current->ip_address); } return result; diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 1260900..bdd4ed1 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -30,6 +30,7 @@ get_mac_addresses() { configure_from_network() { DEVICE=$1 + if [ -n "$DEVICE" ]; then log "Configuring network Using interface $DEVICE" # setup temporary interface to retrieve configuration @@ -56,35 +57,38 @@ configure_from_network() { ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG if [ $? -eq 0 ]; then log "Remote configuration retrieved and applied" + rm $cfgdb else log "Failure to retrieve or apply remote configuration" fi else log "Failed to retrieve configuration bundle" fi - rm $cfgdb fi fi fi fi # default oVirt network configuration: # bridge each ethernet device in the system - ETHDEVS=$(cd /sys/class/net && ls -d eth*) - for eth in $ETHDEVS; do - BRIDGE=br$eth + BRIDGE=br$DEVICE + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE + + # only write a default file if one does not exist + if [ ! -f $ifcfg ]; then + eth=$DEVICE log "Applying default configuration to $eth and $BRIDGE" printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ - > /etc/sysconfig/network-scripts/ifcfg-$eth + > /etc/sysconfig/network-scripts/ifcfg-$eth if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then - dhcp="BOOTPROTO=dhcp" + dhcp="BOOTPROTO=dhcp" else - dhcp="" + dhcp="" fi printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE - done - log "Default config applied" + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE + log "Default config applied" + fi } # $(get_live_disk) -- 1.6.0.6 From dpierce at redhat.com Thu Apr 2 18:52:53 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 2 Apr 2009 14:52:53 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. Message-ID: <1238698373-1828-1-git-send-email-dpierce@redhat.com> The default interface configuration is only applied if a configuration was not retrieved from the server for some reason. It is only applied to the management interface. When ovirt-identify-node collects NIC details to send back to the server, it only collects for physical devices that support the net.80203 capability as reported by HAL. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/gather.c | 8 ++++---- scripts/ovirt-early | 29 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c index c12ed08..ae0bb73 100644 --- a/ovirt-identify-node/gather.c +++ b/ovirt-identify-node/gather.c @@ -286,7 +286,7 @@ get_nic_info(void) int i; - nics = libhal_find_device_by_capability(hal_ctx, "net", + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", &num_results, &dbus_error); DEBUG("Found %d NICs\n", num_results); @@ -294,7 +294,7 @@ get_nic_info(void) for (i = 0; i < num_results; i++) { char *nic = nics[i]; - VERBOSE("Starting new NIC.\n"); + DEBUG("Starting new NIC; %s.\n", nic); if (current != NULL) { last = current; @@ -311,8 +311,8 @@ get_nic_info(void) get_nic_data(nic, current); DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", - nic_info->mac_address, nic_info->bandwidth, - nic_info->ip_address); + current->mac_address, current->bandwidth, + current->ip_address); } return result; diff --git a/scripts/ovirt-early b/scripts/ovirt-early index 1260900..c05ed54 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -30,6 +30,7 @@ get_mac_addresses() { configure_from_network() { DEVICE=$1 + if [ -n "$DEVICE" ]; then log "Configuring network Using interface $DEVICE" # setup temporary interface to retrieve configuration @@ -56,35 +57,33 @@ configure_from_network() { ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG if [ $? -eq 0 ]; then log "Remote configuration retrieved and applied" + rm $cfgdb else log "Failure to retrieve or apply remote configuration" fi else log "Failed to retrieve configuration bundle" fi - rm $cfgdb fi fi fi fi # default oVirt network configuration: # bridge each ethernet device in the system - ETHDEVS=$(cd /sys/class/net && ls -d eth*) - for eth in $ETHDEVS; do - BRIDGE=br$eth + BRIDGE=br$DEVICE + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE + + # only write a default file if one does not exist + if [ ! -f $ifcfg ]; then + eth=$DEVICE log "Applying default configuration to $eth and $BRIDGE" printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ - > /etc/sysconfig/network-scripts/ifcfg-$eth - if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then - dhcp="BOOTPROTO=dhcp" - else - dhcp="" - fi - printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE - done - log "Default config applied" + > /etc/sysconfig/network-scripts/ifcfg-$eth + printf '%s\n' "DEVICE=$BRIDGE" "BOOTPROTO=dhcp" \ + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE + log "Default config applied" + fi } # $(get_live_disk) -- 1.6.0.6 From mmorsi at redhat.com Thu Apr 2 19:12:40 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 02 Apr 2009 15:12:40 -0400 Subject: [Ovirt-devel] [PATCH node] Report on physical network devices when identifying the node. In-Reply-To: <1238698373-1828-1-git-send-email-dpierce@redhat.com> References: <1238698373-1828-1-git-send-email-dpierce@redhat.com> Message-ID: <49D50E28.9060605@redhat.com> Looks and works great. ACK (with you eth/DEVICE cleanup bits). -Mo Darryl L. Pierce wrote: > The default interface configuration is only applied if a configuration > was not retrieved from the server for some reason. It is only applied to > the management interface. > > When ovirt-identify-node collects NIC details to send back to the > server, it only collects for physical devices that support the net.80203 > capability as reported by HAL. > > Signed-off-by: Darryl L. Pierce > --- > ovirt-identify-node/gather.c | 8 ++++---- > scripts/ovirt-early | 29 ++++++++++++++--------------- > 2 files changed, 18 insertions(+), 19 deletions(-) > > diff --git a/ovirt-identify-node/gather.c b/ovirt-identify-node/gather.c > index c12ed08..ae0bb73 100644 > --- a/ovirt-identify-node/gather.c > +++ b/ovirt-identify-node/gather.c > @@ -286,7 +286,7 @@ get_nic_info(void) > > int i; > > - nics = libhal_find_device_by_capability(hal_ctx, "net", > + nics = libhal_find_device_by_capability(hal_ctx, "net.80203", > &num_results, &dbus_error); > > DEBUG("Found %d NICs\n", num_results); > @@ -294,7 +294,7 @@ get_nic_info(void) > for (i = 0; i < num_results; i++) { > char *nic = nics[i]; > > - VERBOSE("Starting new NIC.\n"); > + DEBUG("Starting new NIC; %s.\n", nic); > > if (current != NULL) { > last = current; > @@ -311,8 +311,8 @@ get_nic_info(void) > get_nic_data(nic, current); > > DEBUG("NIC details: MAC:%s, speed:%s, IP:%s\n", > - nic_info->mac_address, nic_info->bandwidth, > - nic_info->ip_address); > + current->mac_address, current->bandwidth, > + current->ip_address); > } > > return result; > diff --git a/scripts/ovirt-early b/scripts/ovirt-early > index 1260900..c05ed54 100755 > --- a/scripts/ovirt-early > +++ b/scripts/ovirt-early > @@ -30,6 +30,7 @@ get_mac_addresses() { > > configure_from_network() { > DEVICE=$1 > + > if [ -n "$DEVICE" ]; then > log "Configuring network Using interface $DEVICE" > # setup temporary interface to retrieve configuration > @@ -56,35 +57,33 @@ configure_from_network() { > ovirt-process-config $cfgdb $BONDING_MODCONF_FILE $AUGTOOL_CONFIG > if [ $? -eq 0 ]; then > log "Remote configuration retrieved and applied" > + rm $cfgdb > else > log "Failure to retrieve or apply remote configuration" > fi > else > log "Failed to retrieve configuration bundle" > fi > - rm $cfgdb > fi > fi > fi > fi > # default oVirt network configuration: > # bridge each ethernet device in the system > - ETHDEVS=$(cd /sys/class/net && ls -d eth*) > - for eth in $ETHDEVS; do > - BRIDGE=br$eth > + BRIDGE=br$DEVICE > + local ifcfg=/etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + > + # only write a default file if one does not exist > + if [ ! -f $ifcfg ]; then > + eth=$DEVICE > log "Applying default configuration to $eth and $BRIDGE" > printf '%s\n' "DEVICE=$eth" ONBOOT=yes "BRIDGE=$BRIDGE" \ > - > /etc/sysconfig/network-scripts/ifcfg-$eth > - if [ -z "$DEVICE" -o "$DEVICE" = "$eth" ]; then > - dhcp="BOOTPROTO=dhcp" > - else > - dhcp="" > - fi > - printf '%s\n' "DEVICE=$BRIDGE" "$dhcp" \ > - ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > - > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > - done > - log "Default config applied" > + > /etc/sysconfig/network-scripts/ifcfg-$eth > + printf '%s\n' "DEVICE=$BRIDGE" "BOOTPROTO=dhcp" \ > + ONBOOT=yes TYPE=Bridge PEERNTP=yes DELAY=0 \ > + > /etc/sysconfig/network-scripts/ifcfg-$BRIDGE > + log "Default config applied" > + fi > } > > # $(get_live_disk) > From sseago at redhat.com Thu Apr 2 19:35:28 2009 From: sseago at redhat.com (Scott Seago) Date: Thu, 2 Apr 2009 19:35:28 +0000 Subject: [Ovirt-devel] [PATCH server] Added roles and privileges for the cloud controller. Message-ID: <1238700928-15016-1-git-send-email-sseago@redhat.com> Signed-off-by: Scott Seago --- src/app/models/privilege.rb | 3 ++ src/app/models/role.rb | 2 +- .../migrate/038_add_cloud_role.rb} | 35 +++++++++++++------- src/test/fixtures/privileges.yml | 4 ++ src/test/fixtures/roles.yml | 3 ++ 5 files changed, 34 insertions(+), 13 deletions(-) copy src/{app/models/privilege.rb => db/migrate/038_add_cloud_role.rb} (50%) diff --git a/src/app/models/privilege.rb b/src/app/models/privilege.rb index 7a30b8f..18c0f16 100644 --- a/src/app/models/privilege.rb +++ b/src/app/models/privilege.rb @@ -31,5 +31,8 @@ class Privilege < ActiveRecord::Base VM_CONTROL = "vm_control" VIEW = "view" + CLOUD_CREATE = "cloud_create" + CLOUD_VIEW = "cloud_view" + end diff --git a/src/app/models/role.rb b/src/app/models/role.rb index 969fbbe..c850d64 100644 --- a/src/app/models/role.rb +++ b/src/app/models/role.rb @@ -30,5 +30,5 @@ class Role < ActiveRecord::Base ADMIN = "Administrator" USER = "User" MONITOR = "Monitor" - + CLOUD_USER = "Cloud User" end diff --git a/src/app/models/privilege.rb b/src/db/migrate/038_add_cloud_role.rb similarity index 50% copy from src/app/models/privilege.rb copy to src/db/migrate/038_add_cloud_role.rb index 7a30b8f..2487f0c 100644 --- a/src/app/models/privilege.rb +++ b/src/db/migrate/038_add_cloud_role.rb @@ -17,19 +17,30 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. -class Privilege < ActiveRecord::Base - has_and_belongs_to_many :roles +class AddCloudRoles < ActiveRecord::Migration + def self.up + Role.transaction do + role_cloud_user = Role.new({:name => "Cloud User"}) + role_cloud_user.save! - validates_presence_of :name - validates_uniqueness_of :name - - - #default privileges - PERM_SET = "set_perms" - PERM_VIEW = "view_perms" - MODIFY = "modify" - VM_CONTROL = "vm_control" - VIEW = "view" + priv_cloud_create = Privilege.new({:name => "cloud_create"}) + priv_cloud_create.save! + priv_cloud_view = Privilege.new({:name => "cloud_view"}) + priv_cloud_view.save! + priv_vm_control = Privilege.find_by_name("vm_control") + role_cloud_user.privileges = [priv_cloud_view, + priv_vm_control, + priv_cloud_create] + role_cloud_user.save! + end + end + def self.down + Role.transaction do + Role.find_by_name("Cloud User").destroy + Privilege.find_by_name("cloud_create").destroy + Privilege.find_by_name("cloud_view").destroy + end + end end diff --git a/src/test/fixtures/privileges.yml b/src/test/fixtures/privileges.yml index 3f19584..54a24be 100644 --- a/src/test/fixtures/privileges.yml +++ b/src/test/fixtures/privileges.yml @@ -8,3 +8,7 @@ vm_control: name: vm_control view: name: view +cloud_create: + name: cloud_create +cloud_view: + name: cloud_view diff --git a/src/test/fixtures/roles.yml b/src/test/fixtures/roles.yml index 774158d..e90851d 100644 --- a/src/test/fixtures/roles.yml +++ b/src/test/fixtures/roles.yml @@ -10,3 +10,6 @@ user: monitor: name: Monitor privileges: view +cloud_user: + name: Cloud User + privileges: cloud_view, vm_control, cloud_create -- 1.6.0.6 From lutter at redhat.com Thu Apr 2 21:44:13 2009 From: lutter at redhat.com (David Lutterkort) Date: Thu, 02 Apr 2009 21:44:13 +0000 Subject: [Ovirt-devel] [PATCH server] verify hostname is not on the loopback entry in /etc/hosts In-Reply-To: <49D4DD77.9090800@redhat.com> References: <1238008866-13329-1-git-send-email-jboggs@redhat.com> <1238629567.23359.15.camel@avon.watzmann.net> <49D4DD77.9090800@redhat.com> Message-ID: <1238708653.23359.106.camel@avon.watzmann.net> On Thu, 2009-04-02 at 11:44 -0400, Joey Boggs wrote: > Trying to get this working on a test file but running into: tundefined > method `init' for Augeas:Class (NoMethodError) I should have tried it first ;) The method in question is Augeas::open. This works (with one crazy match instead of a loop calling aug.get ;): require 'augeas' hostname="host.example.com" aug = Augeas::open(nil, nil, 0) bad_entries = aug.match("/files/etc/hosts/*/*[../ipaddr = '127.0.0.1'][label() = 'alias' or label() = 'canonical'][ . = '#{hostname}']") if bad_entries.size > 0 puts "Hostname #{hostname} mentioned on the line for 127.0.0.1" should_fix = false # Change to prompt user if should_fix bad_entries.each { |e| aug.rm(e) } end end David From imain at redhat.com Fri Apr 3 04:14:46 2009 From: imain at redhat.com (Ian Main) Date: Thu, 2 Apr 2009 21:14:46 -0700 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <1238694663.23359.24.camel@avon.watzmann.net> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> <20090402095702.GA16298@redhat.com> <1238694663.23359.24.camel@avon.watzmann.net> Message-ID: <20090402211446.43d5e0bb@tp.mains.net> On Thu, 02 Apr 2009 10:51:03 -0700 David Lutterkort wrote: > On Thu, 2009-04-02 at 10:57 +0100, Daniel P. Berrange wrote: > > The idea of having a formal QMF API is very nice, but I can't help thinking > > it will limit the potential userbase of the API since you of course need to > > get a QMF api for your client. The really compelling thing about REST APIs > > is that they are immediately usable by any client which has web browsing > > capabilities - which is basically every device with a network connection > > these days. No extra/special client side software required. > > Surely, both have their advantages; it's true that you can access the > REST API from anything that can make web requests (and handle XML) - but > to actually use the API you still need convenience wrappers around all > that so you can get from a VM to the hardware pool it's in without going > crazy. My understanding was that it was actually fairly difficult to use the REST API from various languages? Ian From imain at redhat.com Fri Apr 3 04:28:16 2009 From: imain at redhat.com (Ian Main) Date: Thu, 2 Apr 2009 21:28:16 -0700 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090401204448.GD2854@redhat.com> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> Message-ID: <20090402212816.4441fa5d@tp.mains.net> On Wed, 1 Apr 2009 16:44:48 -0400 Jeremy Katz wrote: > On Tuesday, March 31 2009, Ian Main said: > > Through much discussion it was decided that we would leverage the rails > > models created for use in the WUI, and create an alternative way to > > access these models, start tasks etc. This will be integrated with the > > current task management system (taskomatic) to produce a complete package. > > > > The idea is to create a set of classes available via QMF as objects. > > These classes would then be backed by either a mid-level API that > > encompasses the models, or by active record models directly. Any changes > > made to these records outside of the API (eg by the WUI) would require > > notification of changes to taskomatic. > > So, by integrating deeply like this, how much is going to be tied to underlying > implementation details that (may|might|will) change in the future? From > looking through it, it seems very tightly tied which given the many > unanswered questions, is at least of some concern imho. This was my concern as well.. by working with models directly we tie the hands of the UI developers to an extent. However I think they have a good understanding of this and I do believe we are going to have a mid-level API that both the UI and the QMF API will use. I was originally proposing that the UI be based on top of QMF as well to provide a single API/entry point but there were concerns with performance and type changes. QMF lets you get a schema of the API as well, so it would be possible to check for capabilities/versions via QMF itself. Also, to a good extent, an API will always be dependent on some implementation details. > Also, who is the expected target user of this API? Someone who is > deploying guests within the cloud or someone who is managing the overall > cloud? As there's probably a different level of care for what are the > important things to expose accordingly. It looks more like the latter > but with a mix of some of the former, but at a far more detailed level > than a cloud user would need/want Basically this just implements a portion of the existing ovirt functionality. Cloud is a work in progress at this point and I expect we will develop the API in conjuction with the new features. There is nothing stopping us from creating a new 'make VM anywhere with xx GB storage' method and having taskomatic handle all of that magically. Ian From lutter at redhat.com Fri Apr 3 19:18:59 2009 From: lutter at redhat.com (David Lutterkort) Date: Fri, 03 Apr 2009 19:18:59 +0000 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090402211446.43d5e0bb@tp.mains.net> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <1238628546.23359.4.camel@avon.watzmann.net> <20090402095702.GA16298@redhat.com> <1238694663.23359.24.camel@avon.watzmann.net> <20090402211446.43d5e0bb@tp.mains.net> Message-ID: <1238786339.25506.5.camel@avon.watzmann.net> On Thu, 2009-04-02 at 21:14 -0700, Ian Main wrote: > > Surely, both have their advantages; it's true that you can access the > > REST API from anything that can make web requests (and handle XML) - but > > to actually use the API you still need convenience wrappers around all > > that so you can get from a VM to the hardware pool it's in without going > > crazy. > > My understanding was that it was actually fairly difficult to use the REST > API from various languages? There's two levels of 'support' here: since REST uses normal web requests with data in XML documents, you could write shell scripts that work against your REST API (though you'd quickly lose your mind) To use REST more comfortably, you want a library that takes care of serializing/deserializing the XML and make the web requests - that's what ActiveResource does for ruby, and where support for other languages is behind. David From hbrock at redhat.com Fri Apr 3 22:59:50 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Fri, 3 Apr 2009 18:59:50 -0400 Subject: [Ovirt-devel] [PATCH][server] Final network fixes Message-ID: <20090403225950.GU10299@redhat.com> commit b2e5788e2b0945635f79578091757ac3cc826580 Author: Hugh O. Brock Date: Fri Apr 3 18:53:42 2009 -0400 Final two fixes for the network code. The hack in taskomatic.rb (adding "br" to the front of the network device we put in the VM config) should be fixed. diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb index f93bccd..fac653b 100644 --- a/src/lib/managed_node_configuration.rb +++ b/src/lib/managed_node_configuration.rb @@ -110,7 +110,7 @@ class ManagedNodeConfiguration if bootproto == "static" entry += "|IPADDR=#{ipaddress}|NETMASK=#{netmask}|BROADCAST=#{broadcast}|GATEWAY=#{gateway}" end - entry += "|TYPE=bridge|PEERDNS=no|ONBOOT=yes" + entry += "|TYPE=Bridge|PEERDNS=no|ONBOOT=yes" result.puts entry end diff --git a/src/task-omatic/taskomatic.rb b/src/task-omatic/taskomatic.rb index df59e8d..f852c32 100755 --- a/src/task-omatic/taskomatic.rb +++ b/src/task-omatic/taskomatic.rb @@ -352,13 +352,13 @@ class TaskOmatic device = Nic.find(:first, :conditions => ["host_id = ? AND physical_network_id = ?", db_host.id, db_vm.network_id ]) - net_device = device.interface_name unless device.nil? + net_device = "br" + device.interface_name unless device.nil? else device = Bonding.find(:first, :conditions => ["host_id = ? AND vlan_id = ?", db_host.id, db_vm.network_id]) - net_device = device.interface_name unless device.nil? + net_device = "br" + device.interface_name unless device.nil? end end From thomas.vonsteiger at bluewin.ch Sat Apr 4 13:30:58 2009 From: thomas.vonsteiger at bluewin.ch (Thomas von Steiger) Date: Sat, 4 Apr 2009 15:30:58 +0200 Subject: [Ovirt-devel] Ovirt QMF API Proposal In-Reply-To: <20090402212816.4441fa5d@tp.mains.net> References: <20090331120417.46cc64ef@tp.mains.net> <20090401204448.GD2854@redhat.com> <20090402212816.4441fa5d@tp.mains.net> Message-ID: <770DF2E9-4796-44BA-8A62-2B7F81F63173@bluewin.ch> On 03.04.2009, at 06:28, Ian Main wrote: > On Wed, 1 Apr 2009 16:44:48 -0400 > Jeremy Katz wrote: > >> On Tuesday, March 31 2009, Ian Main said: >>> Through much discussion it was decided that we would leverage the >>> rails >>> models created for use in the WUI, and create an alternative way to >>> access these models, start tasks etc. This will be integrated >>> with the >>> current task management system (taskomatic) to produce a complete >>> package. >>> >>> The idea is to create a set of classes available via QMF as objects. >>> These classes would then be backed by either a mid-level API that >>> encompasses the models, or by active record models directly. Any >>> changes >>> made to these records outside of the API (eg by the WUI) would >>> require >>> notification of changes to taskomatic. >> >> So, by integrating deeply like this, how much is going to be tied >> to underlying >> implementation details that (may|might|will) change in the future? >> From >> looking through it, it seems very tightly tied which given the many >> unanswered questions, is at least of some concern imho. > > This was my concern as well.. by working with models directly we tie > the > hands of the UI developers to an extent. However I think they have a > good understanding of this and I do believe we are going to have a > mid-level API that both the UI and the QMF API will use. I was > originally proposing that the UI be based on top of QMF as well to > provide a single API/entry point but there were concerns with > performance and type changes. > > QMF lets you get a schema of the API as well, so it would be possible > to check for capabilities/versions via QMF itself. > > Also, to a good extent, an API will always be dependent on some > implementation details. > >> Also, who is the expected target user of this API? Someone who is >> deploying guests within the cloud or someone who is managing the >> overall >> cloud? As there's probably a different level of care for what are >> the >> important things to expose accordingly. It looks more like the >> latter >> but with a mix of some of the former, but at a far more detailed >> level >> than a cloud user would need/want > > Basically this just implements a portion of the existing ovirt > functionality. Cloud is a work in progress at this point and I expect > we will develop the API in conjuction with the new features. There is > nothing stopping us from creating a new 'make VM anywhere with xx GB In a cloud, there are 1'000 - 500'000 virtual servers, virtual services, there are 100-50'000 baremetals. There are xx TB of storage and memory and everything is connected over networks. Each of them has information about itself, there are information about customers, application, capabilities, billing etc. I think it's not possible for one framework to manage everthing. There are massiv information in future between differend frameworks only for cloud management and this will be generate traffic. Tomorrow, we need to create 1000 server before the coffee break, after the coffee break we can check them. This are all small task they need to be done inside differend connected frameworks. This frameworks need to talk in common. With QMF it's great, it's possible to have managment communication between this differend frameworks. For example, we write a framework where we can manage baremetal's. For this we need coordinate information about geographic, city, building, room, racks. Finally in the rack, there are my baremetal. For a logical UI we need to define everything from top/down before we can load a baremetal in a rack. At this point where i click ok in my framewok for adding a city or building, it can send a message over qmf to all other necessary frameworks. Next time if i'm using ovirt, i can sea automatically my defined city or building. Search and browsing is everything that we need to find something in future. Or at this point where i attached a baremetal do a rack, this baremetal should be scanned and deployed to other frameworks automatically. Over qmf are walking messages to cobbler for scanning this baremetal. cobbler send's back detail information about this baremetal if scanning is complete to all necessary frameworks. In ovirt or other frameworks, i can see by browsing oder searching my defined city, building, baremetal, servers or customers. It depends on which logical view i have defined. I read there are ideas for a qmf api for cobbler, libvirt-qpid is life. You are right, this is a work in progress. Thomas From mmorsi at redhat.com Mon Apr 6 15:52:00 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Mon, 06 Apr 2009 11:52:00 -0400 Subject: [Ovirt-devel] [PATCH][server] Final network fixes In-Reply-To: <20090403225950.GU10299@redhat.com> References: <20090403225950.GU10299@redhat.com> Message-ID: <49DA2520.3020102@redhat.com> ACK and pushed. From apevec at redhat.com Wed Apr 8 10:02:20 2009 From: apevec at redhat.com (Alan Pevec) Date: Wed, 8 Apr 2009 12:02:20 +0200 Subject: [Ovirt-devel] [PATCH node] always use absolute path for persistent files Message-ID: <1239184940-23353-1-git-send-email-apevec@redhat.com> Signed-off-by: Alan Pevec --- scripts/ovirt-functions | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index 4024efa..a3991c0 100755 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -408,11 +408,12 @@ ovirt_store_config() { rc=0 if grep -q " /config ext3" /proc/mounts; then printf "storing to /config :\n" - for f in "$@"; do + for p in "$@"; do + f=$(readlink -f $p) printf "$f" # skip if file does not exist or is empty - if [ ! -s $f ]; then - printf " Skipping, file does not exist or is empty\n" + if [ ! -s "$f" ]; then + printf " Skipping, file '%s' does not exist or is empty\n" $p continue fi # skip if already bind-mounted -- 1.6.0.6 From dpierce at redhat.com Wed Apr 8 12:23:13 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 8 Apr 2009 08:23:13 -0400 Subject: [Ovirt-devel] [PATCH node] always use absolute path for persistent files In-Reply-To: <1239184940-23353-1-git-send-email-apevec@redhat.com> References: <1239184940-23353-1-git-send-email-apevec@redhat.com> Message-ID: <20090408122313.GA4547@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 08, 2009 at 12:02:20PM +0200, Alan Pevec wrote: > Signed-off-by: Alan Pevec > --- > scripts/ovirt-functions | 7 ++++--- > 1 files changed, 4 insertions(+), 3 deletions(-) > > diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions > index 4024efa..a3991c0 100755 > --- a/scripts/ovirt-functions > +++ b/scripts/ovirt-functions > @@ -408,11 +408,12 @@ ovirt_store_config() { > rc=0 > if grep -q " /config ext3" /proc/mounts; then > printf "storing to /config :\n" > - for f in "$@"; do > + for p in "$@"; do > + f=$(readlink -f $p) > printf "$f" > # skip if file does not exist or is empty > - if [ ! -s $f ]; then > - printf " Skipping, file does not exist or is empty\n" > + if [ ! -s "$f" ]; then > + printf " Skipping, file '%s' does not exist or is empty\n" $p > continue > fi > # skip if already bind-mounted ACK. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 8 19:33:33 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 8 Apr 2009 15:33:33 -0400 Subject: [Ovirt-devel] [PATCH node] Provide a wrapper script for ovirt_store_config. Message-ID: <1239219213-13669-1-git-send-email-dpierce@redhat.com> Files can be persisted using the persist command. Files can be unpersisted using the unpersist command. Both scripts are located in /usr/sbin. Signed-off-by: Darryl L. Pierce --- Makefile.am | 2 ++ ovirt-node.spec.in | 4 ++++ scripts/persist | 37 +++++++++++++++++++++++++++++++++++++ scripts/unpersist | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 0 deletions(-) create mode 100755 scripts/persist create mode 100755 scripts/unpersist diff --git a/Makefile.am b/Makefile.am index d60abe9..57eceb5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,6 +45,8 @@ EXTRA_DIST = \ scripts/ovirt-functions \ scripts/ovirt-install-node-stateful \ scripts/ovirt-install-node-stateless \ + scripts/persist \ + scripts/unpersist \ scripts/ovirt-post \ scripts/ovirt-process-config \ scripts/ovirt-uninstall-node-stateful \ diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in index 75fb56f..1a73066 100644 --- a/ovirt-node.spec.in +++ b/ovirt-node.spec.in @@ -158,6 +158,8 @@ cd - %{__install} -D -m0755 scripts/ovirt-install-node-stateful %{buildroot}%{_sbindir} %{__install} -D -m0755 scripts/ovirt-install-node-stateless %{buildroot}%{_sbindir} %{__install} -D -m0755 scripts/ovirt-uninstall-node-stateful %{buildroot}%{_sbindir} +%{__install} -p -m0755 scripts/persist %{buildroot}%{_sbindir} +%{__install} -p -m0755 scripts/unpersist %{buildroot}%{_sbindir} %{__install} -p -m0755 ovirt-identify-node/ovirt-identify-node %{buildroot}%{_sbindir} %{__install} -p -m0755 ovirt-listen-awake/ovirt-listen-awake %{buildroot}%{_sbindir} %{__install} -Dp -m0755 ovirt-listen-awake/ovirt-listen-awake.init %{buildroot}%{_initrddir}/ovirt-listen-awake @@ -312,6 +314,8 @@ fi %{_sbindir}/ovirt-install-node-stateless %{_sbindir}/gptsync %{_sbindir}/showpart +%{_sbindir}/persist +%{_sbindir}/unpersist %{_initrddir}/ovirt-early %{_initrddir}/ovirt-firstboot %{_initrddir}/ovirt diff --git a/scripts/persist b/scripts/persist new file mode 100755 index 0000000..85a022e --- /dev/null +++ b/scripts/persist @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Copyright (C) 2009, Red Hat, Inc. +# Written by Darryl L. Pierce +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# +# Convenience wrapper to give access to the ovirt_store_config +# function in /etc/init.d/ovirt-functions + +. /etc/init.d/ovirt-functions + +ME=$(basename "$0") +warn() { printf '%s: %s\n' "$ME" "$*" >&2; } +help() { printf "Usage: $ME FILE ...\n +Copies the specified file to /config and then bindmounts it back at it's original location. +The file is stored with its full path detail.\n\n" >&2; exit 1; +} +die() { warn "$*"; help; exit 1; } + +if [ $# -eq 0 ]; then die "You need to specify at least one file."; fi + +ovirt_store_config $* + diff --git a/scripts/unpersist b/scripts/unpersist new file mode 100755 index 0000000..cef0d36 --- /dev/null +++ b/scripts/unpersist @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Copyright (C) 2009, Red Hat, Inc. +# Written by Darryl L. Pierce +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# +# Convenience wrapper to give access to the ovirt_store_config +# function in /etc/init.d/ovirt-functions + +. /etc/init.d/ovirt-functions + +ME=$(basename "$0") +warn() { printf '%s: %s\n' "$ME" "$*" >&2; } +help() { printf "Usage: $ME FILE ...\n +Unpersists a previous persisted file, removing it from /config. +The file is restored to its original location.\n\n" >&2; exit 1; +} +die() { warn "$*"; help; exit 1; } + +if [ $# -eq 0 ]; then die "You need to specify at least one file."; fi + +unmount_config $* + -- 1.6.0.6 From apevec at gmail.com Wed Apr 8 19:37:19 2009 From: apevec at gmail.com (Alan Pevec) Date: Wed, 8 Apr 2009 21:37:19 +0200 Subject: [Ovirt-devel] [PATCH node] Provide a wrapper script for ovirt_store_config. In-Reply-To: <1239219213-13669-1-git-send-email-dpierce@redhat.com> References: <1239219213-13669-1-git-send-email-dpierce@redhat.com> Message-ID: <2be7262f0904081237j233af9e3i29eaab2f76624016@mail.gmail.com> ACK From apevec at redhat.com Wed Apr 8 19:54:35 2009 From: apevec at redhat.com (Alan Pevec) Date: Wed, 8 Apr 2009 21:54:35 +0200 Subject: [Ovirt-devel] [PATCH node] always use absolute path for persistent files II Message-ID: <1239220475-8904-1-git-send-email-apevec@redhat.com> same as ovirt_store_config, unmount_config must use absolute paths Signed-off-by: Alan Pevec --- scripts/ovirt-functions | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index 018cd84..e89898d 100755 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -452,7 +452,8 @@ ovirt_store_config() { # unmount_config() { if grep -q " /config ext3" /proc/mounts; then - for f in "$@"; do + for p in "$@"; do + f=$(readlink -f $p) if grep -q " $f ext3" /proc/mounts ; then umount -n $f # refresh rootfs copy -- 1.6.0.6 From apevec at redhat.com Wed Apr 8 20:00:49 2009 From: apevec at redhat.com (Alan Pevec) Date: Wed, 8 Apr 2009 22:00:49 +0200 Subject: [Ovirt-devel] [PATCH node] change working directory before reboot Message-ID: <1239220849-9110-1-git-send-email-apevec@redhat.com> to avoid "error retrieving current directory" in the upgrade logs Signed-off-by: Alan Pevec --- scripts/ovirt-functions | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index a3991c0..018cd84 100755 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -559,6 +559,7 @@ lvremove() { # reboot wrapper # cleanup before reboot reboot() { + cd / # setup new Root if update is prepared if [ -e /dev/HostVG/RootUpdate ]; then lvrename HostVG Root RootBackup -- 1.6.0.6 From dpierce at redhat.com Wed Apr 8 20:04:59 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 8 Apr 2009 16:04:59 -0400 Subject: [Ovirt-devel] [PATCH node] always use absolute path for persistent files II In-Reply-To: <1239220475-8904-1-git-send-email-apevec@redhat.com> References: <1239220475-8904-1-git-send-email-apevec@redhat.com> Message-ID: <20090408200459.GD3912@mcpierce-laptop.mcpierce.org> On Wed, Apr 08, 2009 at 09:54:35PM +0200, Alan Pevec wrote: > same as ovirt_store_config, unmount_config must use absolute paths > > Signed-off-by: Alan Pevec > --- > scripts/ovirt-functions | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions > index 018cd84..e89898d 100755 > --- a/scripts/ovirt-functions > +++ b/scripts/ovirt-functions > @@ -452,7 +452,8 @@ ovirt_store_config() { > # > unmount_config() { > if grep -q " /config ext3" /proc/mounts; then > - for f in "$@"; do > + for p in "$@"; do > + f=$(readlink -f $p) > if grep -q " $f ext3" /proc/mounts ; then > umount -n $f > # refresh rootfs copy > -- > 1.6.0.6 ACK. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 8 20:05:51 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 8 Apr 2009 16:05:51 -0400 Subject: [Ovirt-devel] [PATCH node] change working directory before reboot In-Reply-To: <1239220849-9110-1-git-send-email-apevec@redhat.com> References: <1239220849-9110-1-git-send-email-apevec@redhat.com> Message-ID: <20090408200551.GE3912@mcpierce-laptop.mcpierce.org> On Wed, Apr 08, 2009 at 10:00:49PM +0200, Alan Pevec wrote: > to avoid "error retrieving current directory" in the upgrade logs > > Signed-off-by: Alan Pevec > --- > scripts/ovirt-functions | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions > index a3991c0..018cd84 100755 > --- a/scripts/ovirt-functions > +++ b/scripts/ovirt-functions > @@ -559,6 +559,7 @@ lvremove() { > # reboot wrapper > # cleanup before reboot > reboot() { > + cd / > # setup new Root if update is prepared > if [ -e /dev/HostVG/RootUpdate ]; then > lvrename HostVG Root RootBackup > -- > 1.6.0.6 > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel ACK. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From mmcgrath at redhat.com Thu Apr 9 16:33:04 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 9 Apr 2009 11:33:04 -0500 (CDT) Subject: [Ovirt-devel] Get rid of dns requirements Message-ID: I'm working on the cumulus install and the dns requirements are a bit silly. I'm going to keep emailing the list with steps I think we should take to simplify the cumulus cloud. Right now it is huge, has tons of requirements (I know some of these will go away as kerberos goes away), and tons of moving parts. So my first suggestion, get rid of the dns requirements. My team right now has a ton of turnover, and as I recall correctly the last large company I worked for had lots of turnover as well meaning simplicity is highly valued. So what do I suggest? non-fqdn searches like how puppet is initially setup. When you run puppet for the first time it auto contacts 'puppet'.searchdomain. This is simple, predictable and can be explained to a junior admin in about 15 seconds. -Mike From mdehaan at redhat.com Thu Apr 9 18:41:32 2009 From: mdehaan at redhat.com (Michael DeHaan) Date: Thu, 09 Apr 2009 14:41:32 -0400 Subject: [Ovirt-devel] Unification of cobbler/cloud/deployment APIs / other deployment topics Message-ID: <49DE415C.3090007@redhat.com> Hi folks! I talked a little bit about this already with Hugh and Iain, but figured it would be nice to bring up on the list. One thing a lot of us are interested in is a common "deployment" building block between various OSS management applications. Ideally I'd like to be able to go to the same place and say "add a distro" "now add a profile" "install this on physical X" "on pool of machines Y, add a guest Z". Basically this means the entire model of the deployment is stored in the deployment server, all in one place, one system of objects, one API, etc. Right now it's stored in a mixture of OVirt API and Cobbler API, so an application needs to install both to do basic deployment tasks in "cloud" context, and we can't use the full deployment server API to query things about the deployment infrastrucutre... nor the ovirt API ... because things are in a mixture of each. Kind of messy. I'm starting to work some of this into cobbler's development branch, but it currently doesn't know about storage pools. We need to fix this, for starters. Long term, my strategy is: * Teach cobbler about libvirt-qmf (and also provide an objecty QMF interface to cobblerd, including events for things changing in cobbler) * have cobbler "deploy" API calls send out commands via libvirt-qmf, so koan is required only for legacy installations * teach cobler to, at minimum, remember the name of each storage pool a machine is attached to. * have cobbler "deploy" support primative concepts of cloud deployment (deploy into this pool and keep track of which machine is deployed where). Right now it thinks in terms of "virt groups" not storage pools. This is done by creating a Cobbler system record for each host, and a system record for each guest, and then using the deploy API call to instantiate a guest on each system. So, what I'm basicaly proposing is we move the "cloud deployment API" backend at the lowest levels into cobblerd, so that the workflow can encourage consistent usage of cobbler objects. Obviously I don't want to own all of this or do it myself and would like to see lots of contributions and upgrades to what we have now to get us there -- but it would be hugely beneficial to have services we could talk to for deployment, versus having to talk to full-stack applications -- at least for installation purposes. I don't want to approach anything resembling monitoring, configuration management, definining the nodes, or so forth -- only to be able to say "install this system foo into this group of systems bar", and get Ovirt to use that API to do it so we can have an API in common. The idea is that for a local cloud, the API to deploy something point to point, or into the cloud, should be the same API, and that API callers shouldn't have to use two APIs (Cobbler+OVirt) to get what they want arranged/done. For instance, right now, spacewalk does a pretty good job of creating Distros, Profiles, and Systems for each things it wants to manage .... OVirt primarily seems to create image records, but the cloud API doesn't know about systems. Beaker does it a little different, so does Genome. The goal is to make sure the deployment server is fully featured enough so that everything can go through that central pipe, and where it's not, we can add to the deployment server to make it doable. What I'm looking for is standardization around the various ways the apps use the deployment API, and making "cloud" part of the deployment API. Anyway, please take a look at https://fedorahosted.org/cobbler/wiki/DeployFeature Right now this is /rather/ primative, so I'm hoping some folks like Ian can offer some suggestions. Making a storage pool object in cobbler seems to be a requirement for sure, so we can point systems at the storage pools. Heuristics for where to deploy would probably be pluggable. Right now the easiest thing to do is "system with least amount of deployed VMs", somewhat like the current round robin impl, but we should also make it pluggable to say "ask ovirt where this thinks it should go". The other thing I'd like to see is to get OVirt to create cobbler system records for each VM. Once we start creating system records for each VM (as well as each host) we can start enabling things like using the Provisioning API to manage DHCP, DNS, and physical host power (via fence), and virt power -- you can, for instance, use the API to power cycle a given system by looking it up via hostname -- without knowing whether it's physical or virtual, etc. Another topic we should probably talk about is what kind of events we might want the deployment server to transmit, as well as what types of commands we want it to send. Right now, I'm planning on doing a QMF API that is mostly like the Python API (so there should be few suprises), with basic events that say when a cobbler object is edited or when a command completes (like a sync or import), much like the triggers system today. Comments welcome! --Michael From mmcgrath at redhat.com Thu Apr 9 19:11:21 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 9 Apr 2009 14:11:21 -0500 (CDT) Subject: [Ovirt-devel] ovirt and freeipa Message-ID: So if we have an organization that, for any reason, cannot run freeipa. They cannot use ovirt. Freeipa is a false requirement for cloud and virtualization. The web frontend already uses basic auth, by doing this it makes it easy to swap auth out with many of the apache mod_auth modules allowing people to pick whatever auth mechanism they want. Use case: 1) Admin uses mod_auth_postgres 2) User exists in postgres logs in to ovirtwui 3) ovirt creates the user if it doesn't exist 4) admin can then create permissions and things for the user How hard would it to be the above? -Mike "lets find some stuff to take out before we add" McGrath From jboggs at redhat.com Thu Apr 9 19:17:05 2009 From: jboggs at redhat.com (Joey Boggs) Date: Thu, 9 Apr 2009 15:17:05 -0400 Subject: [Ovirt-devel] [PATCH server] move add_guest_server_to_etc_hosts into common dns Message-ID: <1239304625-13237-1-git-send-email-jboggs@redhat.com> If using a remote dns server the installer will fail, since the imported dns::remote class does not contain add_guest_server_to_etc_hosts, adding it to common is the quickest fix until the classes are better organized to common/remote/bundled --- installer/modules/ovirt/manifests/dns.pp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/installer/modules/ovirt/manifests/dns.pp b/installer/modules/ovirt/manifests/dns.pp index 57c128b..7709cbf 100644 --- a/installer/modules/ovirt/manifests/dns.pp +++ b/installer/modules/ovirt/manifests/dns.pp @@ -65,17 +65,17 @@ define dns::common($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev=" require => [Single_exec["set_hostname"], Package["dnsmasq"], File["/etc/dhclient.conf"]] , notify => Service[dnsmasq], } + + single_exec {"add_guest_server_to_etc_hosts": + command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", + notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] + } } define dns::bundled($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev="") { dns::common{"setup": guest_ipaddr=>$guest_ipaddr, admin_ipaddr=>$admin_ipaddr, guest_dev=>$guest_dev, admin_dev=>$admin_dev} - single_exec {"add_guest_server_to_etc_hosts": - command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", - notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] - } - augeas{"set_system_hostname": context => "/files/etc/sysconfig/network", changes => [ -- 1.6.0.6 From imain at redhat.com Thu Apr 9 19:20:33 2009 From: imain at redhat.com (Ian Main) Date: Thu, 9 Apr 2009 12:20:33 -0700 Subject: [Ovirt-devel] Get rid of dns requirements In-Reply-To: References: Message-ID: <20090409122033.31f5b14f@tp.mains.net> On Thu, 9 Apr 2009 11:33:04 -0500 (CDT) Mike McGrath wrote: > I'm working on the cumulus install and the dns requirements are a bit > silly. I'm going to keep emailing the list with steps I think we should > take to simplify the cumulus cloud. Right now it is huge, has tons of > requirements (I know some of these will go away as kerberos goes away), and > tons of moving parts. > > So my first suggestion, get rid of the dns requirements. My team right now > has a ton of turnover, and as I recall correctly the last large company I > worked for had lots of turnover as well meaning simplicity is highly > valued. > > So what do I suggest? non-fqdn searches like how puppet is initially > setup. When you run puppet for the first time it auto contacts > 'puppet'.searchdomain. This is simple, predictable and can be explained > to a junior admin in about 15 seconds. Wooo.. I like that idea. Will require node changes though.. don't think it can make it for this release but I'd like to see that on the list.. Ian From imain at redhat.com Thu Apr 9 19:31:25 2009 From: imain at redhat.com (Ian Main) Date: Thu, 9 Apr 2009 12:31:25 -0700 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: References: Message-ID: <20090409123125.3042496a@tp.mains.net> On Thu, 9 Apr 2009 14:11:21 -0500 (CDT) Mike McGrath wrote: > So if we have an organization that, for any reason, cannot run freeipa. > They cannot use ovirt. Freeipa is a false requirement for cloud and > virtualization. > > The web frontend already uses basic auth, by doing this it makes it easy > to swap auth out with many of the apache mod_auth modules allowing people > to pick whatever auth mechanism they want. > > Use case: > > 1) Admin uses mod_auth_postgres > 2) User exists in postgres logs in to ovirtwui > 3) ovirt creates the user if it doesn't exist > 4) admin can then create permissions and things for the user > > How hard would it to be the above? The other issue is that the qpid infrastructure is currently set up to require kerberos authentication. However, it's kind of silly in a way because the default roll out has it grabbing the ticket from the web server specified in the DNS SRV records, which means that no authentication of nodes really takes place. The right way to securely connect nodes is to copy the ticket to some persistent storage on the node before deployment. The thing this protects against is malicious nodes.. note that a VM could also register as a node so you have to trust your VMs too.. this is actually a problem with the current default config. Note that you don't need a node image booted, you just need the ovirt scripts to register with the ovirt server etc. The danger of a rogue node is that it gives that node access to whatever VMs happen to get created on it (take snapshot, scp it to home computer or such - image stealing). I think it would be a good idea to enable the qpid infrastructure to work without kerberos for demoing/testing/evaluating. If we could have a mode where we get rid of the freeipa and dns requirements, it would definitely make it much easier to deploy for evaluation etc. It would be good for developers to get up and running as well which may also be advantageous. Ian From mdehaan at redhat.com Thu Apr 9 19:34:50 2009 From: mdehaan at redhat.com (Michael DeHaan) Date: Thu, 09 Apr 2009 15:34:50 -0400 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: References: Message-ID: <49DE4DDA.8040900@redhat.com> Mike McGrath wrote: > So if we have an organization that, for any reason, cannot run freeipa. > They cannot use ovirt. Freeipa is a false requirement for cloud and > virtualization. > > The web frontend already uses basic auth, by doing this it makes it easy > to swap auth out with many of the apache mod_auth modules allowing people > to pick whatever auth mechanism they want. > > Use case: > > 1) Admin uses mod_auth_postgres > 2) User exists in postgres logs in to ovirtwui > 3) ovirt creates the user if it doesn't exist > 4) admin can then create permissions and things for the user > > How hard would it to be the above? > > -Mike "lets find some stuff to take out before we add" McGrath > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel > +1. There's also a likelihood that an ovirt userbase could have an existing kerberos server they want to use, or don't want an LDAP server. Are those supportable now? From experience, organizations tend to be picky about site-specific details, and supporting multiple systems provides a greater chance of adoption. Thus it is very nice to support auth, via say, pam, or Apache (including what Mike mentions, but also doing basic auth for demos), or something that allows for configuring options. The other question is that if they must also set up FreeIPA, is a user is more likely to get frustrated during the demo or not install it? Ideally, "yum install" and having a guest up and running in 30 minutes should be a good goal to have. That was one of the major reasons, I think, why virt-factory didn't take off -- they had to understand Puppet + virt, at a time when they really wanted to wrap their heads around one new thing. So FreeIPA + OVirt is also two new things, in much the same kind of way. Providing simple options as well as the IPA options would probably help reach a wider install base, and also make setting it up for a proof of concept/demo easier too, I think. If I could just say, point it at an existing kerberos source and allow only these 7 users access, even, that would be useful. --Michael From mdehaan at redhat.com Thu Apr 9 19:37:45 2009 From: mdehaan at redhat.com (Michael DeHaan) Date: Thu, 09 Apr 2009 15:37:45 -0400 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: <20090409123125.3042496a@tp.mains.net> References: <20090409123125.3042496a@tp.mains.net> Message-ID: <49DE4E89.4040904@redhat.com> Ian Main wrote: > On Thu, 9 Apr 2009 14:11:21 -0500 (CDT) > Mike McGrath wrote: > > >> So if we have an organization that, for any reason, cannot run freeipa. >> They cannot use ovirt. Freeipa is a false requirement for cloud and >> virtualization. >> >> The web frontend already uses basic auth, by doing this it makes it easy >> to swap auth out with many of the apache mod_auth modules allowing people >> to pick whatever auth mechanism they want. >> >> Use case: >> >> 1) Admin uses mod_auth_postgres >> 2) User exists in postgres logs in to ovirtwui >> 3) ovirt creates the user if it doesn't exist >> 4) admin can then create permissions and things for the user >> >> How hard would it to be the above? >> > > The other issue is that the qpid infrastructure is currently set up > to require kerberos authentication. However, it's kind of silly in > a way because the default roll out has it grabbing the ticket from > the web server specified in the DNS SRV records, which means that no > authentication of nodes really takes place. The right way to securely > connect nodes is to copy the ticket to some persistent storage on the > node before deployment. > > The thing this protects against is malicious nodes.. note that a VM > could also register as a node so you have to trust your VMs too.. > this is actually a problem with the current default config. Note > that you don't need a node image booted, you just need the ovirt > scripts to register with the ovirt server etc. The danger of a rogue > node is that it gives that node access to whatever VMs happen to get > created on it (take snapshot, scp it to home computer or such - image > stealing). > > I think it would be a good idea to enable the qpid infrastructure to > work without kerberos for demoing/testing/evaluating. > I'm really going to want this, especially speaking out to libvirt-qmf. Not just in OVirt context, but in general. IIRC this does support anything GSSAPI though, so we're really just talking about internal QMF to ovirt requiring kerberos? Yes, anything that makes life easier on developers would be a huge plus. Requiring kerberos (but not IPA) in the installed environment seems reasonable though... but one shouldn't assume the kerb source is IPA or that folks need to have an LDAP server. --Michael From mmcgrath at redhat.com Thu Apr 9 19:38:31 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 9 Apr 2009 14:38:31 -0500 (CDT) Subject: [Ovirt-devel] ipa-server conflicts with mod_ssl Message-ID: Just about every https+apache configuration I've seen in the last many years used mod_ssl. This requirement on ipa-server means I cannot use mod_ssl, this is sub-optimal as I now have to learn a new system to put our purchased fedora-cert on this system so https:// doesn't throw a self-signed error for users browsers. -Mike From imain at redhat.com Thu Apr 9 19:46:24 2009 From: imain at redhat.com (Ian Main) Date: Thu, 9 Apr 2009 12:46:24 -0700 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: <49DE4E89.4040904@redhat.com> References: <20090409123125.3042496a@tp.mains.net> <49DE4E89.4040904@redhat.com> Message-ID: <20090409124624.11bd084f@tp.mains.net> On Thu, 09 Apr 2009 15:37:45 -0400 Michael DeHaan wrote: > Ian Main wrote: [snip] > > The thing this protects against is malicious nodes.. note that a VM > > could also register as a node so you have to trust your VMs too.. > > this is actually a problem with the current default config. Note > > that you don't need a node image booted, you just need the ovirt > > scripts to register with the ovirt server etc. The danger of a rogue > > node is that it gives that node access to whatever VMs happen to get > > created on it (take snapshot, scp it to home computer or such - image > > stealing). > > > > I think it would be a good idea to enable the qpid infrastructure to > > work without kerberos for demoing/testing/evaluating. > > > > I'm really going to want this, especially speaking out to libvirt-qmf. > Not just in OVirt context, > but in general. IIRC this does support anything GSSAPI though, so we're > really just talking about > internal QMF to ovirt requiring kerberos? Yes, it's just the way it's configured on the nodes and the server via the default install. libvirt-qpid itself can use any of the GSSAPI authentication systems... and actually if you run qpidd with --auth no then you can use no authentication at all if you like. :) > Yes, anything that makes life easier on developers would be a huge plus. > Requiring kerberos > (but not IPA) in the installed environment seems reasonable though... > but one shouldn't assume > the kerb source is IPA or that folks need to have an LDAP server. I think we only really require kerberos at this level. Even the calls in the scripts use straight kerberos commands to generate principals and tickets. I'm not entirely sure it would still all work though.. Ian From lutter at redhat.com Thu Apr 9 19:57:29 2009 From: lutter at redhat.com (David Lutterkort) Date: Thu, 09 Apr 2009 19:57:29 +0000 Subject: [Ovirt-devel] Get rid of dns requirements In-Reply-To: References: Message-ID: <1239307049.9599.519.camel@avon.watzmann.net> On Thu, 2009-04-09 at 11:33 -0500, Mike McGrath wrote: > So my first suggestion, get rid of the dns requirements. Just to be clear: with DNS requirements you mean the need for those SRV records, right ? That can indeed be avoided by looking up 'ovirt' or whatever in the default domain. Working forward and reverse DNS for the server and the nodes will always be a requirement, since both krb5 and any other auth mechanism (say x509) would need that. David From Brian.Carb at unisys.com Thu Apr 9 21:01:29 2009 From: Brian.Carb at unisys.com (Carb, Brian A) Date: Thu, 9 Apr 2009 16:01:29 -0500 Subject: [Ovirt-devel] Next Release Date? Message-ID: <0AAE5AB84B013E45A7B61CB66943C17215E7425AE7@USEA-EXCH7.na.uis.unisys.com> We've been using the .96 version without patching it. Just curious if anyone has any information on the next release date. Thanks. brian carb unisys corporation - malvern, pa brian.carb at unisys.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From hbrock at redhat.com Thu Apr 9 21:55:52 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 9 Apr 2009 17:55:52 -0400 Subject: [Ovirt-devel] Get rid of dns requirements In-Reply-To: <1239307049.9599.519.camel@avon.watzmann.net> References: <1239307049.9599.519.camel@avon.watzmann.net> Message-ID: <20090409215552.GI10299@redhat.com> On Thu, Apr 09, 2009 at 07:57:29PM +0000, David Lutterkort wrote: > On Thu, 2009-04-09 at 11:33 -0500, Mike McGrath wrote: > > So my first suggestion, get rid of the dns requirements. > > Just to be clear: with DNS requirements you mean the need for those SRV > records, right ? That can indeed be avoided by looking up 'ovirt' or > whatever in the default domain. > > Working forward and reverse DNS for the server and the nodes will always > be a requirement, since both krb5 and any other auth mechanism (say > x509) would need that. Yeah Mike I have a ton of sympathy here and I really want to make it as simple as possible to set things up. Maybe defaults in the absence of SRV records is a good way to go. However as David says, we absolutely have to have some kind of mechanism for authentication and encryption between the server and the nodes. That can be krb5, or PKI (which I would prefer when it becomes available for us, because anything is better than kerberos), but if we try to do anything else (say, passing around ssh keys) we're going to wind up reimplementing our own certificate management system anyway. So at least for the cluster(s) of machines that are managed by oVirt, working DNS is going to be a hard requirement. We've tried to simplify this as much as possible by providing a DNS server for the admin network with the install. I am, as always, open to suggestions for other ways to simplify things... Take care, --Hugh From hbrock at redhat.com Thu Apr 9 22:17:22 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 9 Apr 2009 18:17:22 -0400 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: <20090409123125.3042496a@tp.mains.net> References: <20090409123125.3042496a@tp.mains.net> Message-ID: <20090409221721.GJ10299@redhat.com> On Thu, Apr 09, 2009 at 12:31:25PM -0700, Ian Main wrote: > On Thu, 9 Apr 2009 14:11:21 -0500 (CDT) > Mike McGrath wrote: > > > So if we have an organization that, for any reason, cannot run freeipa. > > They cannot use ovirt. Freeipa is a false requirement for cloud and > > virtualization. > > > > The web frontend already uses basic auth, by doing this it makes it easy > > to swap auth out with many of the apache mod_auth modules allowing people > > to pick whatever auth mechanism they want. > > > > Use case: > > > > 1) Admin uses mod_auth_postgres > > 2) User exists in postgres logs in to ovirtwui > > 3) ovirt creates the user if it doesn't exist > > 4) admin can then create permissions and things for the user > > > > How hard would it to be the above? I'd be perfectly happy to offer this as an option, or some other form of pluggable authentication. We wanted to avoid writing our own user management system for oVirt and using IPA for it seems like an obvious choice, but it does not have to be the only choice. > > The other issue is that the qpid infrastructure is currently set up > to require kerberos authentication. However, it's kind of silly in > a way because the default roll out has it grabbing the ticket from > the web server specified in the DNS SRV records, which means that no > authentication of nodes really takes place. The right way to securely > connect nodes is to copy the ticket to some persistent storage on the > node before deployment. > > The thing this protects against is malicious nodes.. note that a VM > could also register as a node so you have to trust your VMs too.. > this is actually a problem with the current default config. Note > that you don't need a node image booted, you just need the ovirt > scripts to register with the ovirt server etc. The danger of a rogue > node is that it gives that node access to whatever VMs happen to get > created on it (take snapshot, scp it to home computer or such - image > stealing). > > I think it would be a good idea to enable the qpid infrastructure to > work without kerberos for demoing/testing/evaluating. > > If we could have a mode where we get rid of the freeipa and dns > requirements, it would definitely make it much easier to deploy for > evaluation etc. It would be good for developers to get up and running > as well which may also be advantageous. As I've said elsewhere, I think it's going to be difficult for us to avoid having a coherent authentication and encryption system between the server and the nodes, and for that we have two choices: kerberos and PKI. I think it's a really bad idea to offer a "development" mode where one of those systems are not enabled, because they will never get any testing otherwise. Ultimately that means you need working DNS on the admin network, but I don't see why this has to be a showstopper requirement. The questions around the boot process are a little bit of a red herring. If you are working in an infrastructure where you don't trust your nodes, then you use the mechanisms already built into the node to store a key locally. If you do trust your environment to not have malicious people spoofing mac addresses (like several clients I've visited), then you can use the mac address. As far as I'm concerned, what we need to do is keep troubleshooting the installer and make it as painless as possible in a two-network case, and add some additional authentication methods for the UI side. Thanks, --Hugh From hbrock at redhat.com Thu Apr 9 22:28:45 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 9 Apr 2009 18:28:45 -0400 Subject: [Ovirt-devel] ipa-server conflicts with mod_ssl In-Reply-To: References: Message-ID: <20090409222845.GL10299@redhat.com> On Thu, Apr 09, 2009 at 02:38:31PM -0500, Mike McGrath wrote: > Just about every https+apache configuration I've seen in the last many > years used mod_ssl. This requirement on ipa-server means I cannot use > mod_ssl, this is sub-optimal as I now have to learn a new system to put > our purchased fedora-cert on this system so https:// doesn't throw a > self-signed error for users browsers. > > -Mike Simo, can you elaborate on why IPA requires mod_nss instead of mod_ssl? ISTR there was some reasonably good reason. Mike, you're not actually sharing an httpd instance with some other fedora app, right? Just oVirt? Thanks, --Hugh From hbrock at redhat.com Thu Apr 9 22:31:06 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 9 Apr 2009 18:31:06 -0400 Subject: [Ovirt-devel] Next Release Date? In-Reply-To: <0AAE5AB84B013E45A7B61CB66943C17215E7425AE7@USEA-EXCH7.na.uis.unisys.com> References: <0AAE5AB84B013E45A7B61CB66943C17215E7425AE7@USEA-EXCH7.na.uis.unisys.com> Message-ID: <20090409223106.GN10299@redhat.com> On Thu, Apr 09, 2009 at 04:01:29PM -0500, Carb, Brian A wrote: > We've been using the .96 version without patching it. Just curious if anyone has any information on the next release date. Thanks. > 0.98 is now in the repo, with many enhancements and bug fixes. I will have install documentation and a real announcement shortly. --Hugh From lutter at redhat.com Fri Apr 10 00:34:59 2009 From: lutter at redhat.com (David Lutterkort) Date: Fri, 10 Apr 2009 00:34:59 +0000 Subject: [Ovirt-devel] Refactoring controllers for QMF and profit Message-ID: <1239323699.9599.606.camel@avon.watzmann.net> For the QMF API, we need to reorganize the code that is in the Rails controllers currently. The basic issue is that Rails controllers fundamentally need a web request to do their thing, but since QMF is not web based, there is none (and the possibility of faking a web request would get us too deep into Rails internals to be supportable) The Rails controllers serve two purposes: (1) presentation logic and (2) business logic. Of course, we do not want to replicate business logic in the QMF API, instead we want to make sure that both the WUI and the QMF API use the same code for their business logic. That means we need to leave the presentation logic in the controllers and move the business logic to somewhere else. To make this more concrete, good examples of business logic are the permission checks that accompany each action in the WUI, or the work needed to create a new VM - business logic in general has (a) a notion of a current user and (b) touches multiple model objects at once. In the Java world, this new layer is known as 'stateless session beans'. What I am proposing here is a general strategy of what this new layer will look like and (most importantly) what it will be called - since the word 'Session' is so terribly overloaded, I am going with the marginally less overloaded word 'Service' (and am willing to pay the person who comes up with a better name $2.55) Architecturally, the layers in the combined WUI/QMF system would look like this: ActiveRecord models | service modules / \ / \ QMF controller/view ActionController | WUI view (templates etc.) As a side effect, the code will be written in a way that would let us service QMF requests and web requests from the same process - whether we'd ever actually deploy like that remains to be seen, and we might very well wind up with deployments where one of the two branches is always turned off through some config option. The meat of the service layer will happen in modules, which has the advantage that we do not use the inheritance slot in users of the service layer (so that Rails controllers can still inherit in the usual fashion); by including service modules in the classes that use them, we can still use instance variables for various purposes, just as we do in the Rails controllers today. To make all that a little concrete, I sketched out what that would look like for the code around VM creation; attached is that sketch - it has all the Ruby code (which is definitely not working) in one file. David -------------- next part -------------- A non-text attachment was scrubbed... Name: service.rb Type: application/x-ruby Size: 8580 bytes Desc: not available URL: From mmcgrath at redhat.com Fri Apr 10 00:54:35 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 9 Apr 2009 19:54:35 -0500 (CDT) Subject: [Ovirt-devel] Get rid of dns requirements In-Reply-To: <20090409215552.GI10299@redhat.com> References: <1239307049.9599.519.camel@avon.watzmann.net> <20090409215552.GI10299@redhat.com> Message-ID: On Thu, 9 Apr 2009, Hugh O. Brock wrote: > On Thu, Apr 09, 2009 at 07:57:29PM +0000, David Lutterkort wrote: > > On Thu, 2009-04-09 at 11:33 -0500, Mike McGrath wrote: > > > So my first suggestion, get rid of the dns requirements. > > > > Just to be clear: with DNS requirements you mean the need for those SRV > > records, right ? That can indeed be avoided by looking up 'ovirt' or > > whatever in the default domain. > > > > Working forward and reverse DNS for the server and the nodes will always > > be a requirement, since both krb5 and any other auth mechanism (say > > x509) would need that. > > Yeah Mike I have a ton of sympathy here and I really want to make it > as simple as possible to set things up. Maybe defaults in the absence > of SRV records is a good way to go. > > However as David says, we absolutely have to have some kind of > mechanism for authentication and encryption between the server and the > nodes. That can be krb5, or PKI (which I would prefer when it becomes > available for us, because anything is better than kerberos), but if we > try to do anything else (say, passing around ssh keys) we're going to > wind up reimplementing our own certificate management system > anyway. So at least for the cluster(s) of machines that are managed by > oVirt, working DNS is going to be a hard requirement. We've tried to > simplify this as much as possible by providing a DNS server for the > admin network with the install. > > I am, as always, open to suggestions for other ways to simplify > things... > Forward dns is an obvious need, well not really one could use IP's. But lots of systems (puppet from my example earlier) do not have that hard requirement. I guess if I had to compare it to a competitor like enomalism which does not have such a requirement. Why do we have it and what does it give us that enomalism is missing out on. -Mike From mmcgrath at redhat.com Fri Apr 10 00:55:28 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 9 Apr 2009 19:55:28 -0500 (CDT) Subject: [Ovirt-devel] ipa-server conflicts with mod_ssl In-Reply-To: <20090409222845.GL10299@redhat.com> References: <20090409222845.GL10299@redhat.com> Message-ID: On Thu, 9 Apr 2009, Hugh O. Brock wrote: > On Thu, Apr 09, 2009 at 02:38:31PM -0500, Mike McGrath wrote: > > Just about every https+apache configuration I've seen in the last many > > years used mod_ssl. This requirement on ipa-server means I cannot use > > mod_ssl, this is sub-optimal as I now have to learn a new system to put > > our purchased fedora-cert on this system so https:// doesn't throw a > > self-signed error for users browsers. > > > > -Mike > > Simo, can you elaborate on why IPA requires mod_nss instead of > mod_ssl? ISTR there was some reasonably good reason. > > Mike, you're not actually sharing an httpd instance with some other > fedora app, right? Just oVirt? > Correct, it's dedicated we just have puppet recipes and everything for ssl enabled websites and now we have to come up with some other method just for ovirt. -Mike From katzj at redhat.com Fri Apr 10 02:13:19 2009 From: katzj at redhat.com (Jeremy Katz) Date: Thu, 9 Apr 2009 22:13:19 -0400 Subject: [Ovirt-devel] ovirt and freeipa In-Reply-To: <20090409221721.GJ10299@redhat.com> References: <20090409123125.3042496a@tp.mains.net> <20090409221721.GJ10299@redhat.com> Message-ID: <20090410021318.GA5287@redhat.com> On Thursday, April 09 2009, Hugh O. Brock said: > On Thu, Apr 09, 2009 at 12:31:25PM -0700, Ian Main wrote: > > On Thu, 9 Apr 2009 14:11:21 -0500 (CDT) > > Mike McGrath wrote: > > > So if we have an organization that, for any reason, cannot run freeipa. > > > They cannot use ovirt. Freeipa is a false requirement for cloud and > > > virtualization. > > > > > > The web frontend already uses basic auth, by doing this it makes it easy > > > to swap auth out with many of the apache mod_auth modules allowing people > > > to pick whatever auth mechanism they want. > > > > > > Use case: > > > > > > 1) Admin uses mod_auth_postgres > > > 2) User exists in postgres logs in to ovirtwui > > > 3) ovirt creates the user if it doesn't exist > > > 4) admin can then create permissions and things for the user > > > > > > How hard would it to be the above? > > I'd be perfectly happy to offer this as an option, or some other form > of pluggable authentication. We wanted to avoid writing our own user > management system for oVirt and using IPA for it seems like an obvious > choice, but it does not have to be the only choice. The question that comes to my mind at least is do we expect oVirt to be deployed within a vacuum (ie, it is a system unto itself) or within a larger ecosystem. If the latter, then pluggable is probably the only way to go. And at that point, having a super-simple "dummy" type system for when you're not plugging into a larger org's existing auth mechanism may be simpler than having oVirt depend on a full-blown IPA setup even if it is something we have to write ourselves. It could be nothing more than a combination of a sqlite db on disk + hashed passwords. If, instead, we think that oVirt deployments should be largely run unto themselves, then building in IPA and using IPA for everything makes sense. But at that point, we should really be sure we're using it and not try to give outs for people to plug in different things > > The other issue is that the qpid infrastructure is currently set up > > to require kerberos authentication. However, it's kind of silly in > > a way because the default roll out has it grabbing the ticket from > > the web server specified in the DNS SRV records, which means that no > > authentication of nodes really takes place. The right way to securely > > connect nodes is to copy the ticket to some persistent storage on the > > node before deployment. > > > > The thing this protects against is malicious nodes.. note that a VM > > could also register as a node so you have to trust your VMs too.. > > this is actually a problem with the current default config. Note > > that you don't need a node image booted, you just need the ovirt > > scripts to register with the ovirt server etc. The danger of a rogue > > node is that it gives that node access to whatever VMs happen to get > > created on it (take snapshot, scp it to home computer or such - image > > stealing). > > > > I think it would be a good idea to enable the qpid infrastructure to > > work without kerberos for demoing/testing/evaluating. > > > > If we could have a mode where we get rid of the freeipa and dns > > requirements, it would definitely make it much easier to deploy for > > evaluation etc. It would be good for developers to get up and running > > as well which may also be advantageous. > > As I've said elsewhere, I think it's going to be difficult for us to > avoid having a coherent authentication and encryption system between > the server and the nodes, and for that we have two choices: kerberos > and PKI. I think it's a really bad idea to offer a "development" mode > where one of those systems are not enabled, because they will never > get any testing otherwise. Ultimately that means you need working DNS > on the admin network, but I don't see why this has to be a showstopper > requirement. There are plenty of ways that don't involve working DNS -- IP-based, SSH keys, func doesn't iirc. Even using SSL certs doesn't have any strong requirements around DNS for the most part. The developer mode certainly needs to do auth and encryption, but we may be making both of those harder than they need to be. Kerberos has a lot of really nice advantages for a certain set of applications. If you get outside of that, it really starts to be hammering a square peg into a (smaller) round hole. > The questions around the boot process are a little bit of a red > herring. If you are working in an infrastructure where you don't trust > your nodes, then you use the mechanisms already built into the node to > store a key locally. If you do trust your environment to not have > malicious people spoofing mac addresses (like several clients I've > visited), then you can use the mac address. To be perfectly honest, the local storage story with the node is very weak and to Mike's earlier points, is a whole other new set of things to learn. Even if you do a node "install", only special things are preserved. And then on top of that, the provisioning of the node is unlike anything else you're doing. So if we really care about the "node running off of a disk" case, then getting to where it's a more normal type of provisioning/installation is going to help a lot in getting admins more comfortable. Jeremy From ssorce at redhat.com Thu Apr 9 22:36:23 2009 From: ssorce at redhat.com (Simo Sorce) Date: Thu, 09 Apr 2009 18:36:23 -0400 Subject: [Ovirt-devel] ipa-server conflicts with mod_ssl In-Reply-To: <20090409222845.GL10299@redhat.com> References: <20090409222845.GL10299@redhat.com> Message-ID: <1239316584.26768.52.camel@localhost.localdomain> On Thu, 2009-04-09 at 18:28 -0400, Hugh O. Brock wrote: > On Thu, Apr 09, 2009 at 02:38:31PM -0500, Mike McGrath wrote: > > Just about every https+apache configuration I've seen in the last many > > years used mod_ssl. This requirement on ipa-server means I cannot use > > mod_ssl, this is sub-optimal as I now have to learn a new system to put > > our purchased fedora-cert on this system so https:// doesn't throw a > > self-signed error for users browsers. > > > > -Mike > > Simo, can you elaborate on why IPA requires mod_nss instead of > mod_ssl? ISTR there was some reasonably good reason. I guess because we wanted to use NSS instead of OpenSSL. Simo. -- Simo Sorce * Red Hat, Inc * New York From berrange at redhat.com Fri Apr 10 10:25:46 2009 From: berrange at redhat.com (Daniel P. Berrange) Date: Fri, 10 Apr 2009 11:25:46 +0100 Subject: [Ovirt-devel] Get rid of dns requirements In-Reply-To: References: <1239307049.9599.519.camel@avon.watzmann.net> <20090409215552.GI10299@redhat.com> Message-ID: <20090410102546.GB1201@redhat.com> On Thu, Apr 09, 2009 at 07:54:35PM -0500, Mike McGrath wrote: > > However as David says, we absolutely have to have some kind of > > mechanism for authentication and encryption between the server and the > > nodes. That can be krb5, or PKI (which I would prefer when it becomes > > available for us, because anything is better than kerberos), but if we > > try to do anything else (say, passing around ssh keys) we're going to > > wind up reimplementing our own certificate management system > > anyway. So at least for the cluster(s) of machines that are managed by > > oVirt, working DNS is going to be a hard requirement. We've tried to > > simplify this as much as possible by providing a DNS server for the > > admin network with the install. > > > > I am, as always, open to suggestions for other ways to simplify > > things... > > > > Forward dns is an obvious need, well not really one could use IP's. But > lots of systems (puppet from my example earlier) do not have that hard > requirement. I guess if I had to compare it to a competitor like > enomalism which does not have such a requirement. Why do we have it and > what does it give us that enomalism is missing out on. The DNS requirement is not a requirement of oVirt per-se, but of the underlying authentication / encryption technology. If using Kerberos you need to have forward & reverse DNS working, and make sure that matches the hostname as seen by the OS. If using SSL with x509 certs you can use IP addresses, but you have to be consistent. Either use IP addresses all the time, or use hostnames all the time. You can't mix use of IP addresses and hostnames, because then the certificate CNAME checks will fail. x509 is more forgiving about lack of reverse DNS than kerberos, so its not critical in that instance. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| From berrange at redhat.com Fri Apr 10 10:29:33 2009 From: berrange at redhat.com (Daniel P. Berrange) Date: Fri, 10 Apr 2009 11:29:33 +0100 Subject: [Ovirt-devel] ipa-server conflicts with mod_ssl In-Reply-To: References: Message-ID: <20090410102933.GC1201@redhat.com> On Thu, Apr 09, 2009 at 02:38:31PM -0500, Mike McGrath wrote: > Just about every https+apache configuration I've seen in the last many > years used mod_ssl. This requirement on ipa-server means I cannot use > mod_ssl, this is sub-optimal as I now have to learn a new system to put > our purchased fedora-cert on this system so https:// doesn't throw a > self-signed error for users browsers. This is a really bad packaging decision from Fedora/IPA server. There are two competing SSL plugins for Apache, mod_ssl and mod_nss. Fedora and IPA should standardize on one, and ditch the other and make sure everything works with the chosen one. I've no idea why IPA wants mod_nss instead of mod_ssl - particularly with everyone else in the world mostly using mod_ssl it is certainly a PITA having this imposition from IPA. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| From mmcgrath at redhat.com Fri Apr 10 14:43:33 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Fri, 10 Apr 2009 09:43:33 -0500 (CDT) Subject: [Ovirt-devel] Dnsmasq on the ovirt-server Message-ID: This is probably because of my unfamiliarity with dnsmasq but right now I've got a dhcp server setup to give out proper info but it's fighting with the dnsmasq service on the ovirt-server. Can someone explain how dnsmasq fits into the ovirt stack? -Mike From mmcgrath at redhat.com Fri Apr 10 14:48:08 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Fri, 10 Apr 2009 09:48:08 -0500 (CDT) Subject: [Ovirt-devel] Dnsmasq on the ovirt-server In-Reply-To: References: Message-ID: On Fri, 10 Apr 2009, Mike McGrath wrote: > This is probably because of my unfamiliarity with dnsmasq but right now > I've got a dhcp server setup to give out proper info but it's fighting > with the dnsmasq service on the ovirt-server. > > Can someone explain how dnsmasq fits into the ovirt stack? > Ok so I've found /etc/dnsmasq.d/ and it has an ovirt dhcp server in it. I assume that the intent is that when a node reboots it could come up as any other node? The IP and hostname of a node would change with every reboot? -Mike From hbrock at redhat.com Fri Apr 10 14:50:51 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Fri, 10 Apr 2009 10:50:51 -0400 Subject: [Ovirt-devel] Dnsmasq on the ovirt-server In-Reply-To: References: Message-ID: <20090410145050.GU10299@redhat.com> On Fri, Apr 10, 2009 at 09:43:33AM -0500, Mike McGrath wrote: > This is probably because of my unfamiliarity with dnsmasq but right now > I've got a dhcp server setup to give out proper info but it's fighting > with the dnsmasq service on the ovirt-server. > > Can someone explain how dnsmasq fits into the ovirt stack? > Hey Mike. We install dnsmasq on the oVirt server for the sole purpose of doing DNS/DHCP/PXE for the oVirt admin network. If you are providing those services with your own infrastructure, which is perfectly fine, then you should kill the dnsmasq instance on the oVirt server altogether. Hope this helps, --Hugh From hbrock at redhat.com Fri Apr 10 14:59:46 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Fri, 10 Apr 2009 10:59:46 -0400 Subject: [Ovirt-devel] Dnsmasq on the ovirt-server In-Reply-To: References: Message-ID: <20090410145946.GV10299@redhat.com> On Fri, Apr 10, 2009 at 09:48:08AM -0500, Mike McGrath wrote: > On Fri, 10 Apr 2009, Mike McGrath wrote: > > > This is probably because of my unfamiliarity with dnsmasq but right now > > I've got a dhcp server setup to give out proper info but it's fighting > > with the dnsmasq service on the ovirt-server. > > > > Can someone explain how dnsmasq fits into the ovirt stack? > > > > Ok so I've found /etc/dnsmasq.d/ and it has an ovirt dhcp server in it. I > assume that the intent is that when a node reboots it could come up as any > other node? The IP and hostname of a node would change with every reboot? > This is a bug. We need to preserve the hostname/mac address mapping and write it to the dnsmasq config as nodes come up. The only reason we care at all is that you don't want a node to spontaneously move out of the hardware pool it's in just because you rebooted it and it happened to get a new DHCP lease + IP address. Anyway we need to fix it. Since you're doing your own DHCP you could set up your own mac-address-to-hostname mappings and you would never have a problem. --H From mmcgrath at redhat.com Fri Apr 10 15:02:14 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Fri, 10 Apr 2009 10:02:14 -0500 (CDT) Subject: [Ovirt-devel] Dnsmasq on the ovirt-server In-Reply-To: <20090410145946.GV10299@redhat.com> References: <20090410145946.GV10299@redhat.com> Message-ID: On Fri, 10 Apr 2009, Hugh O. Brock wrote: > On Fri, Apr 10, 2009 at 09:48:08AM -0500, Mike McGrath wrote: > > On Fri, 10 Apr 2009, Mike McGrath wrote: > > > > > This is probably because of my unfamiliarity with dnsmasq but right now > > > I've got a dhcp server setup to give out proper info but it's fighting > > > with the dnsmasq service on the ovirt-server. > > > > > > Can someone explain how dnsmasq fits into the ovirt stack? > > > > > > > Ok so I've found /etc/dnsmasq.d/ and it has an ovirt dhcp server in it. I > > assume that the intent is that when a node reboots it could come up as any > > other node? The IP and hostname of a node would change with every reboot? > > > > This is a bug. We need to preserve the hostname/mac address mapping > and write it to the dnsmasq config as nodes come up. The only reason > we care at all is that you don't want a node to spontaneously move out > of the hardware pool it's in just because you rebooted it and it > happened to get a new DHCP lease + IP address. Anyway we need to fix it. > > Since you're doing your own DHCP you could set up your own > mac-address-to-hostname mappings and you would never have a problem. > Sounds good thanks. -Mike From hbrock at redhat.com Mon Apr 13 02:01:01 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Sun, 12 Apr 2009 22:01:01 -0400 Subject: [Ovirt-devel] [PATCH server] move add_guest_server_to_etc_hosts into common dns In-Reply-To: <1239304625-13237-1-git-send-email-jboggs@redhat.com> References: <1239304625-13237-1-git-send-email-jboggs@redhat.com> Message-ID: <20090413020100.GB10299@redhat.com> On Thu, Apr 09, 2009 at 03:17:05PM -0400, Joey Boggs wrote: > If using a remote dns server the installer will fail, since the imported dns::remote class does not contain add_guest_server_to_etc_hosts, adding it to common is the quickest fix until the classes are better organized to common/remote/bundled > > --- > installer/modules/ovirt/manifests/dns.pp | 10 +++++----- > 1 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/installer/modules/ovirt/manifests/dns.pp b/installer/modules/ovirt/manifests/dns.pp > index 57c128b..7709cbf 100644 > --- a/installer/modules/ovirt/manifests/dns.pp > +++ b/installer/modules/ovirt/manifests/dns.pp > @@ -65,17 +65,17 @@ define dns::common($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev=" > require => [Single_exec["set_hostname"], Package["dnsmasq"], File["/etc/dhclient.conf"]] , > notify => Service[dnsmasq], > } > + > + single_exec {"add_guest_server_to_etc_hosts": > + command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", > + notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] > + } > } > > define dns::bundled($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev="") { > > dns::common{"setup": guest_ipaddr=>$guest_ipaddr, admin_ipaddr=>$admin_ipaddr, guest_dev=>$guest_dev, admin_dev=>$admin_dev} > > - single_exec {"add_guest_server_to_etc_hosts": > - command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", > - notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] > - } > - > augeas{"set_system_hostname": > context => "/files/etc/sysconfig/network", > changes => [ This was tested by Mike McGrath and works, so ACK --Hugh From jboggs at redhat.com Mon Apr 13 02:05:18 2009 From: jboggs at redhat.com (Joey Boggs) Date: Sun, 12 Apr 2009 22:05:18 -0400 Subject: [Ovirt-devel] [PATCH server] move add_guest_server_to_etc_hosts into common dns In-Reply-To: <20090413020100.GB10299@redhat.com> References: <1239304625-13237-1-git-send-email-jboggs@redhat.com> <20090413020100.GB10299@redhat.com> Message-ID: <49E29DDE.3030407@redhat.com> pushed Hugh O. Brock wrote: > On Thu, Apr 09, 2009 at 03:17:05PM -0400, Joey Boggs wrote: > >> If using a remote dns server the installer will fail, since the imported dns::remote class does not contain add_guest_server_to_etc_hosts, adding it to common is the quickest fix until the classes are better organized to common/remote/bundled >> >> --- >> installer/modules/ovirt/manifests/dns.pp | 10 +++++----- >> 1 files changed, 5 insertions(+), 5 deletions(-) >> >> diff --git a/installer/modules/ovirt/manifests/dns.pp b/installer/modules/ovirt/manifests/dns.pp >> index 57c128b..7709cbf 100644 >> --- a/installer/modules/ovirt/manifests/dns.pp >> +++ b/installer/modules/ovirt/manifests/dns.pp >> @@ -65,17 +65,17 @@ define dns::common($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev=" >> require => [Single_exec["set_hostname"], Package["dnsmasq"], File["/etc/dhclient.conf"]] , >> notify => Service[dnsmasq], >> } >> + >> + single_exec {"add_guest_server_to_etc_hosts": >> + command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", >> + notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] >> + } >> } >> >> define dns::bundled($guest_ipaddr="", $admin_ipaddr="",$guest_dev="",$admin_dev="") { >> >> dns::common{"setup": guest_ipaddr=>$guest_ipaddr, admin_ipaddr=>$admin_ipaddr, guest_dev=>$guest_dev, admin_dev=>$admin_dev} >> >> - single_exec {"add_guest_server_to_etc_hosts": >> - command => "/bin/echo $guest_ipaddr $ipa_host >> /etc/hosts", >> - notify => [Service[dnsmasq], Single_exec["add_dns_server_to_resolv.conf"]] >> - } >> - >> augeas{"set_system_hostname": >> context => "/files/etc/sysconfig/network", >> changes => [ >> > > This was tested by Mike McGrath and works, so ACK > > --Hugh > From jguiditt at redhat.com Mon Apr 13 19:41:03 2009 From: jguiditt at redhat.com (Jason Guiditta) Date: Mon, 13 Apr 2009 15:41:03 -0400 Subject: [Ovirt-devel] [PATCH server] First step of detail pane UI cleanup. Message-ID: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> This patch implements layout fixes to clean up look of the details pane throughout the site, so it looks more like the design here: http://ovirt.org/page/Summary_UX Note that this does not include the actual rearrangement of Hardware Pools summary pages. Best place to see changes is on the summary for a Resource Pool. --- src/app/views/layouts/selection.rhtml | 15 +++++++++------ src/app/views/resources/quick_summary.rhtml | 6 ++---- src/public/stylesheets/components.css | 11 +++++++---- src/public/stylesheets/layout.css | 11 +++-------- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/app/views/layouts/selection.rhtml b/src/app/views/layouts/selection.rhtml index e7aefc2..1f313d7 100644 --- a/src/app/views/layouts/selection.rhtml +++ b/src/app/views/layouts/selection.rhtml @@ -1,8 +1,11 @@ -
-
<%= yield :title -%>
+
<%= yield :title -%>
<% tools = yield :action_links -%> <% if tools %> +
  • <%= image_tag "icon_separator.png", :style=>"vertical-align: middle;" %> @@ -11,13 +14,13 @@
<% end %>
+
+ <%= yield %> +
- <%= yield %> - -
<% right = yield :right -%> <% if right %> -
+
<%= right -%>
<% end %> diff --git a/src/app/views/resources/quick_summary.rhtml b/src/app/views/resources/quick_summary.rhtml index 31c4033..0a01105 100644 --- a/src/app/views/resources/quick_summary.rhtml +++ b/src/app/views/resources/quick_summary.rhtml @@ -38,7 +38,6 @@ }, 'json'); } - <% resources = @pool.full_resources %>
@@ -58,7 +57,6 @@ <%= item[2]%>
<% end %>
-
-
+<%- content_for :right do -%> <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @pool.id, :target => 'resource' %> -
+<% end -%> \ No newline at end of file diff --git a/src/public/stylesheets/components.css b/src/public/stylesheets/components.css index 2313d1c..708eb0e 100644 --- a/src/public/stylesheets/components.css +++ b/src/public/stylesheets/components.css @@ -208,11 +208,14 @@ } /* snapshot graphs on hardware / resource summary tab */ -#snapshot_graphs table { - width: 98%; -} #snapshot_graphs th { background: #EEEEEE; text-align: left; padding-left: 10px;border:1px solid #CCCCCC;} -#snapshot_graphs td { padding-left: 10px; background: #FFFFFF;border:1px solid #CCCCCC;} +#snapshot_graphs td { + padding-left: 10px; + padding-right: 10px; + white-space: nowrap; + background: #FFFFFF; + border:1px solid #CCCCCC; +} .snapshot_graph_container{ width: 180px; height: 10px; diff --git a/src/public/stylesheets/layout.css b/src/public/stylesheets/layout.css index 987462d..981ff22 100644 --- a/src/public/stylesheets/layout.css +++ b/src/public/stylesheets/layout.css @@ -256,13 +256,11 @@ a { color:#000000; text-decoration: none;} background: #DEE7EB; border-top: #CCCCCC solid 1px; overflow: auto; + padding: 10px 10px 10px 15px; } .selection_left { - padding: 10px 10px 10px 15px; - height: 126px; float:left; - width: 40%; } .selection_title { @@ -315,12 +313,9 @@ a { color:#000000; text-decoration: none;} } .selection_right { - width:55%; float: right; - padding-top: 10px; - /*background: #F0F0F0;*/ - height: 140px; - } + padding-right: 10px; +} .selection_right_title { padding: 4px 4px 4px 6px; -- 1.6.0.6 From mmorsi at redhat.com Mon Apr 13 17:00:19 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Mon, 13 Apr 2009 13:00:19 -0400 Subject: [Ovirt-devel] [PATCH] viewer bugfixes / interfaces improvements Message-ID: <1239642019-3827-1-git-send-email-mmorsi@redhat.com> - allow user to click enter to submit hostname / login forms - wire 'refresh list of virtual machines' menu item to correct action - display error on incorrect login - change title when viewing vm, indicate ctrl+alt to grab mouse - check if vm is running before trying to connect to it (also we may want to not show non-running vms) --- internal.h | 7 ++++- main.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- wui_thread.c | 15 +++++++++++ 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/internal.h b/internal.h index 950fd05..04512f9 100644 --- a/internal.h +++ b/internal.h @@ -106,6 +106,7 @@ struct vm { int vnc_port; int forward_vnc_port; char *uuid; /* Printable UUID. */ + char *state; /* Only the fields above this point are required. The remainder may * be NULL / -1 to indicate they were missing in the data we got @@ -116,7 +117,6 @@ struct vm { long mem_used; /* Kbytes */ int vcpus_allocated; int vcpus_used; - char *state; char *mac_addr; /* Printable MAC addr. */ }; @@ -144,6 +144,11 @@ extern gboolean wui_thread_has_valid_vmlist (void); */ extern gboolean wui_thread_is_busy (void); +/* Returns true if the main vm list contains a + * running vm w/ the same name as specified one + */ +extern gboolean main_vmlist_has_running_vm(struct vm*); + /* Callbacks from the WUI thread to the main thread. The WUI thread * adds these to the Glib main loop using g_idle_add, which means they * actually get executed in the context of the main thread. diff --git a/main.c b/main.c index 390046a..7a543e0 100644 --- a/main.c +++ b/main.c @@ -63,7 +63,10 @@ gboolean check_cert = TRUE; /* Private functions. */ static void start_ui (void); static GtkWidget *menu_item_new (int which_menu); +static void refresh_menu_vm_list (GtkWidget *, gpointer); +static void connect_to_wui_on_enter (GtkWidget *, gpointer); static void connect_to_wui (GtkWidget *, gpointer); +static void login_to_wui_on_enter (GtkWidget *, gpointer); static void login_to_wui (GtkWidget *, gpointer); static gboolean delete_event (GtkWidget *widget, GdkEvent *event, gpointer data); static void destroy (GtkWidget *widget, gpointer data); @@ -94,6 +97,7 @@ static GtkWidget *login_area; static GtkWidget *la_username; static GtkWidget *la_password; static GtkWidget *la_button; +static GtkWidget *la_error; static GtkWidget *notebook; static GtkWidget *statusbar; static guint statusbar_ctx; @@ -126,6 +130,11 @@ static struct menuItem menuItems[] = { /* Window title. */ static const char *title = "oVirt Viewer"; +// when running vm +// 47 chars +static const char *title_vm = + "oVirt Viewer: (ctrl+alt to grab/release mouse) "; + /* Gtk widget styles. Avoid installation hassles by keeping this * inside the binary. It can still be overridden by the user (who * will do that?) @@ -242,7 +251,9 @@ start_ui (void) GtkWidget *ca_vbox; GtkWidget *ca_hbox; GtkWidget *ca_label; + GtkWidget *la_vbox; GtkWidget *la_hbox; + GtkWidget *la_label; DEBUG ("creating viewer windows and menus"); @@ -287,6 +298,9 @@ start_ui (void) refresh_vmlist_separator = gtk_separator_menu_item_new (); g_object_ref (refresh_vmlist_separator); + g_signal_connect (G_OBJECT (refresh_vmlist), "activate", + G_CALLBACK (refresh_menu_vm_list), NULL); + #if 0 screenshot = gtk_menu_item_new_with_mnemonic ("_Screenshot"); gtk_menu_append (GTK_MENU (filemenu), screenshot); @@ -338,24 +352,36 @@ start_ui (void) gtk_widget_set_name (connection_area, "ovirt-viewer-connection-area"); + g_signal_connect (G_OBJECT (ca_hostname), "key-release-event", + G_CALLBACK (connect_to_wui_on_enter), NULL); g_signal_connect (G_OBJECT (ca_button), "clicked", G_CALLBACK (connect_to_wui), NULL); login_area = gtk_event_box_new (); + la_vbox = gtk_vbox_new (FALSE, 0); la_hbox = gtk_hbox_new (FALSE, 0); + la_label = gtk_label_new ("Username / password:"); la_username = gtk_entry_new (); gtk_entry_set_width_chars (GTK_ENTRY (la_username), 12); la_password = gtk_entry_new (); gtk_entry_set_width_chars (GTK_ENTRY (la_password), 12); gtk_entry_set_visibility (GTK_ENTRY (la_password), FALSE); la_button = gtk_button_new_with_label ("Login"); + la_error = gtk_label_new (NULL); gtk_container_add (GTK_CONTAINER (la_hbox), la_username); gtk_container_add (GTK_CONTAINER (la_hbox), la_password); gtk_container_add (GTK_CONTAINER (la_hbox), la_button); - gtk_container_add (GTK_CONTAINER (login_area), la_hbox); + gtk_box_pack_start (GTK_BOX (la_vbox), la_label, TRUE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (la_vbox), la_hbox, TRUE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (la_vbox), la_error, TRUE, FALSE, 4); + gtk_container_add (GTK_CONTAINER (login_area), la_vbox); gtk_widget_set_name (login_area, "ovirt-viewer-login-area"); + g_signal_connect (G_OBJECT (la_username), "key-release-event", + G_CALLBACK (login_to_wui_on_enter), NULL); + g_signal_connect (G_OBJECT (la_password), "key-release-event", + G_CALLBACK (login_to_wui_on_enter), NULL); g_signal_connect (G_OBJECT (la_button), "clicked", G_CALLBACK (login_to_wui), NULL); @@ -467,6 +493,21 @@ help_about (GtkWidget *menu) } static void +refresh_menu_vm_list(GtkWidget *widget, gpointer data) +{ + wui_thread_send_refresh_vm_list(); +} + +static void +connect_to_wui_on_enter (GtkWidget *widget, gpointer data) +{ + // if key released was not 'enter' key + if(((GdkEventKey *)data)->type == GDK_KEY_RELEASE && (((GdkEventKey *)data)->keyval & 0xFF) != 13 ) return; + + connect_to_wui(widget, data); +} + +static void connect_to_wui (GtkWidget *widget, gpointer data) { const char *hostname; @@ -485,6 +526,15 @@ connect_to_wui (GtkWidget *widget, gpointer data) } static void +login_to_wui_on_enter (GtkWidget *widget, gpointer data) +{ + // if key released was not 'enter' key + if(((GdkEventKey *)data)->type == GDK_KEY_RELEASE && (((GdkEventKey *)data)->keyval & 0xFF) != 13 ) return; + + login_to_wui(widget, data); +} + +static void login_to_wui (GtkWidget *widget, gpointer data) { const char *username, *password; @@ -511,6 +561,7 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) const char *label; const char* hostname; char *label2; + char new_title[97]; // 47 chars for title + 50 for vm name DEBUG ("searching tabs for uuid %s", vm->uuid); @@ -531,6 +582,14 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) DEBUG ("not found, creating new tab"); + // before we open vnc connection, make sure vm is running + gboolean vm_running = main_vmlist_has_running_vm(vm); + + if(!vm_running){ + main_status_error (g_strdup ("VM not running")); + return; + } + /* This VM isn't in the notebook already, so create a new console. */ hostname = gtk_entry_get_text (GTK_ENTRY (ca_hostname)); fd = viewer_open_vnc_socket(hostname, vm->forward_vnc_port); @@ -542,6 +601,16 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) return; } + main_status_error(g_strdup("")); + + for(i = 0; i < 47; ++i) new_title[i] = title_vm[i]; + for(i = 0; i < 50; ++i){ + if(vm->description[i] == '\0') break; + new_title[47 + i] = vm->description[i]; + } + new_title[i < 50 ? i+47 : 96] = '\0'; + gtk_window_set_title (GTK_WINDOW (window), new_title); + /* gtk_signal_connect(GTK_OBJECT(child), "vnc-pointer-grab", GTK_SIGNAL_FUNC(viewer_grab), window); @@ -912,9 +981,7 @@ main_login_error (gpointer _str) DEBUG ("login error: %s", str); ASSERT_IS_MAIN_THREAD (); - /* gtk_label_set_text (GTK_LABEL (la_error), str); - */ g_free (str); return FALSE; @@ -985,6 +1052,9 @@ add_vm_to_connectmenu (gpointer _vm, gpointer data) struct vm *vm = (struct vm *) _vm; GtkWidget *item; + // TODO only present running vms ? + // if(vm->state == "running") + DEBUG ("adding %s to Connect menu", vm->description); item = gtk_menu_item_new_with_label (vm->description); diff --git a/wui_thread.c b/wui_thread.c index c51c43f..cbf7892 100644 --- a/wui_thread.c +++ b/wui_thread.c @@ -1093,3 +1093,18 @@ parse_vm_from_xml (xmlNodePtr node) return ret; } + +gboolean +main_vmlist_has_running_vm(struct vm* _vm) +{ + // TODO ? get list and wait to be retreived + // wui_thread_send_refresh_vm_list(); + + // find vm in list + GSList* res = g_slist_find_custom (vmlist, _vm, compare_vm); + + // return true if running + if(res != NULL) return STREQ (((struct vm*) res->data)->state, "running"); + + return FALSE; +} -- 1.6.0.6 From jboggs at redhat.com Mon Apr 13 21:07:12 2009 From: jboggs at redhat.com (Joey Boggs) Date: Mon, 13 Apr 2009 17:07:12 -0400 Subject: [Ovirt-devel] [PATCH server] add system language check Message-ID: <1239656832-13654-1-git-send-email-jboggs@redhat.com> This adds a sanity check for the system language. If another system language is used, the method to gather the networking devices could drop all potential devices due to a translated "inet addr" in the output of ifconfig Feel free to reword the text if need be Test via system-config-language and set to another language, the bug was discovered while using french. --- installer/bin/ovirt-installer | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/installer/bin/ovirt-installer b/installer/bin/ovirt-installer index 2d88886..f6e5f93 100755 --- a/installer/bin/ovirt-installer +++ b/installer/bin/ovirt-installer @@ -124,6 +124,16 @@ if (prompt_yes_no(welcome, :default => "y") == "n") exit(0) end +lang = `echo $LANG`.chop +unless lang == "C" || lang =~ /en_US/ + @cli.say("\nSystem language set to: #{lang}") + @cli.say("\nYou will need to set the LANG variable to C for the installer to run") + @cli.say("\n export LANG=C") + @cli.say("\nTo revert after installation run: export LANG=#{lang} or relogin") + exit (1) +end + + if File.exist?("/usr/sbin/selinuxenabled") sestatus = system "/usr/sbin/selinuxenabled" if sestatus == true -- 1.6.0.6 From mmorsi at redhat.com Mon Apr 13 22:57:30 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Mon, 13 Apr 2009 18:57:30 -0400 Subject: [Ovirt-devel] [PATCH server] First step of detail pane UI cleanup. In-Reply-To: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> References: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> Message-ID: <49E3C35A.4080506@redhat.com> Looks good, so ACK, with a comment below. Jason Guiditta wrote: > This patch implements layout fixes to clean up look of the > details pane throughout the site, so it looks more like > the design here: > http://ovirt.org/page/Summary_UX > > Note that this does not include the actual rearrangement of > Hardware Pools summary pages. Best place to see changes is > on the summary for a Resource Pool. > --- > src/app/views/layouts/selection.rhtml | 15 +++++++++------ > src/app/views/resources/quick_summary.rhtml | 6 ++---- > src/public/stylesheets/components.css | 11 +++++++---- > src/public/stylesheets/layout.css | 11 +++-------- > 4 files changed, 21 insertions(+), 22 deletions(-) > > diff --git a/src/app/views/layouts/selection.rhtml b/src/app/views/layouts/selection.rhtml > index e7aefc2..1f313d7 100644 > --- a/src/app/views/layouts/selection.rhtml > +++ b/src/app/views/layouts/selection.rhtml > @@ -1,8 +1,11 @@ > -
> -
<%= yield :title -%>
> +
<%= yield :title -%>
> > <% tools = yield :action_links -%> > <% if tools %> > + > Does it being a list break anything specifically? I think a list is fine, we're not only using it for a separator but we're styling it in the css to appear horizontal / have the same effect you described. We'd need the same css for the divs if we we're to remove the list plus the exception for the first. So not sure if this comment should go in. Other than that, the patch looks good, the details pane output looks just like Jeremy's screenshot. -Mo From jguiditt at redhat.com Tue Apr 14 14:51:49 2009 From: jguiditt at redhat.com (Jason Guiditta) Date: Tue, 14 Apr 2009 10:51:49 -0400 Subject: [Ovirt-devel] [PATCH server] First step of detail pane UI cleanup. In-Reply-To: <49E3C35A.4080506@redhat.com> References: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> <49E3C35A.4080506@redhat.com> Message-ID: <1239720709.4710.17.camel@localhost.localdomain> > > + > > > Does it being a list break anything specifically? I think a list is > fine, we're not only using it for a separator but we're styling it in > the css to appear horizontal / have the same effect you described. We'd > need the same css for the divs if we we're to remove the list plus the > exception for the first. So not sure if this comment should go in. Mo, really there are two things here. If it was indeed a list of links, that would actually be perfect. The thing is, while this may have been the intent, it was not executed that way. Take a look at any content_for :action_links (for example views/resources/quick_summary.rhtml) and you will see not a list but a bunch of links not contained in li's. So not only is it presented as a bunch of links, they are links in this context: which is syntactically incorrect, and would fail any validator we threw it at. For the second point I am more trying to push the concept of separating content from layout, which is really just an extension of mvc and separating presentation from business logic, so we should all feel pretty comfortable with the idea. The idea of using an image as a border is completely fine. However, it is also completely unrelated to the content, and therefore belongs in the stylesheet rather than the rhtml. In this case if we really wanted to use an image as the separator, I would likely add a class along the lines of: .first { background: url('../images/list_separator.png') center left no-repeat; } There may be some additional setting that need to be dropped in to make it look completely correct, but I think the idea is clear. However, as it is just a gray line, my inclination would be to just use border-left with a matching color. One less image to maintain, and preferable css style-wise. Anyway, my point here is to improve our markup quality. While some think it is unimportant, I think it reflects poorly on our attention to detail to not try to do these things the correct way. I would like to see this treated as more craftsmanship than 'just get it done'. -j > > > Other than that, the patch looks good, the details pane output looks > just like Jeremy's screenshot. > > -Mo From mmorsi at redhat.com Tue Apr 14 16:34:22 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 14 Apr 2009 12:34:22 -0400 Subject: [Ovirt-devel] [PATCH server] First step of detail pane UI cleanup. In-Reply-To: <1239720709.4710.17.camel@localhost.localdomain> References: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> <49E3C35A.4080506@redhat.com> <1239720709.4710.17.camel@localhost.localdomain> Message-ID: <49E4BB0E.6060101@redhat.com> Jason Guiditta wrote: >>> + >>> >>> >> Does it being a list break anything specifically? I think a list is >> fine, we're not only using it for a separator but we're styling it in >> the css to appear horizontal / have the same effect you described. We'd >> need the same css for the divs if we we're to remove the list plus the >> exception for the first. So not sure if this comment should go in. >> > > Mo, really there are two things here. If it was indeed a list of links, > that would actually be perfect. The thing is, while this may have been > the intent, it was not executed that way. Take a look at any > content_for :action_links (for example > views/resources/quick_summary.rhtml) and you will see not a list but a > bunch of links not contained in li's. So not only is it presented as a > bunch of links, they are links in this context: > > > which is syntactically incorrect, and would fail any validator we threw > it at. > Ah, hadn't realized that the actual content isn't generated w/ the
  • tags that would make sense here. Yes that needs to be syntactically fixed at some point. > For the second point I am more trying to push the concept of separating > content from layout, which is really just an extension of mvc and > separating presentation from business logic, so we should all feel > pretty comfortable with the idea. The idea of using an image as a > border is completely fine. However, it is also completely unrelated to > the content, and therefore belongs in the stylesheet rather than the > rhtml. In this case if we really wanted to use an image as the > separator, I would likely add a class along the lines of: > .first { > background: url('../images/list_separator.png') center left no-repeat; > } > There may be some additional setting that need to be dropped in to make > it look completely correct, but I think the idea is clear. However, as > it is just a gray line, my inclination would be to just use border-left > with a matching color. One less image to maintain, and preferable css > style-wise. Anyway, my point here is to improve our markup quality. > While some think it is unimportant, I think it reflects poorly on our > attention to detail to not try to do these things the correct way. I > would like to see this treated as more craftsmanship than 'just get it > done'. > > -j > Agreed, we should use style where necessary / appropriate. Either way, by adding the li's to the appropriate detail-pane templates, as we're still dealing w/ a list, or adding divs, styling would probably most be suited for the css stylesheet. >> Other than that, the patch looks good, the details pane output looks >> just like Jeremy's screenshot. >> >> -Mo >> > > Once again ACK still stands, perhaps with a bit of rewording in the comment ( for the love of pete ;-) ), but its not a show stopper so you can go ahead and push it. -Mo From apevec at gmail.com Tue Apr 14 17:28:48 2009 From: apevec at gmail.com (Alan Pevec) Date: Tue, 14 Apr 2009 19:28:48 +0200 Subject: [Ovirt-devel] [PATCH server] add system language check In-Reply-To: <1239656832-13654-1-git-send-email-jboggs@redhat.com> References: <1239656832-13654-1-git-send-email-jboggs@redhat.com> Message-ID: <2be7262f0904141028o14c29347ibfe8e4a390c8b94a@mail.gmail.com> On Mon, Apr 13, 2009 at 11:07 PM, Joey Boggs wrote: > This adds a sanity check for the system language. If another system language is used, the method to gather the networking devices could drop all potential devices due to a translated "inet addr" in the output of ifconfig can't we just set LANG=C before running ifconfig or better yet use some other way to check for IP address? From jguiditt at redhat.com Tue Apr 14 18:56:09 2009 From: jguiditt at redhat.com (Jason Guiditta) Date: Tue, 14 Apr 2009 18:56:09 +0000 Subject: [Ovirt-devel] [PATCH server] first round of permissions refactoring. In-Reply-To: <1238440113-25538-1-git-send-email-sseago@redhat.com> References: <1238440113-25538-1-git-send-email-sseago@redhat.com> Message-ID: <1239735369.4710.21.camel@localhost.localdomain> ACK, one super-minor nit inline. -j On Mon, 2009-03-30 at 19:08 +0000, Scott Seago wrote: > diff --git a/src/db/migrate/037_add_roles_and_privileges.rb b/src/db/migrate/037_add_roles_and_privileges.rb > new file mode 100644 > index 0000000..322014e > --- /dev/null > +++ b/src/db/migrate/037_add_roles_and_privileges.rb > @@ -0,0 +1,119 @@ > +class AddRolesAndPrivileges < ActiveRecord::Migration > + def self.up > +# create_table :permissions do |t| > +# t.string :user_role > +# t.string :user > +# t.integer :pool_id > +# t.integer :inherited_from_id > +# t.integer :lock_version, :default => 0 > +# end Unless there is a reason to keep the above, could you delete it rather than commenting out? > + create_table :roles do |t| From sseago at redhat.com Tue Apr 14 19:22:57 2009 From: sseago at redhat.com (Scott Seago) Date: Tue, 14 Apr 2009 15:22:57 -0400 Subject: [Ovirt-devel] [PATCH server] first round of permissions refactoring. In-Reply-To: <1239735369.4710.21.camel@localhost.localdomain> References: <1238440113-25538-1-git-send-email-sseago@redhat.com> <1239735369.4710.21.camel@localhost.localdomain> Message-ID: <49E4E291.2090600@redhat.com> Jason Guiditta wrote: > ACK, one super-minor nit inline. > > -j > > >> +class AddRolesAndPrivileges < ActiveRecord::Migration >> + def self.up >> +# create_table :permissions do |t| >> +# t.string :user_role >> +# t.string :user >> +# t.integer :pool_id >> +# t.integer :inherited_from_id >> +# t.integer :lock_version, :default => 0 >> +# end >> > > Unless there is a reason to keep the above, could you delete it rather > than commenting out Agreed. I was only leaving it there while I was writing the initial migration and had intended on removing before I sent the patch. I think I already pulled this out on my local checkout. Will push soon. Scott From jguiditt at redhat.com Tue Apr 14 20:48:25 2009 From: jguiditt at redhat.com (Jason Guiditta) Date: Tue, 14 Apr 2009 16:48:25 -0400 Subject: [Ovirt-devel] [PATCH server] Added roles and privileges for the cloud controller. In-Reply-To: <1238700928-15016-1-git-send-email-sseago@redhat.com> References: <1238700928-15016-1-git-send-email-sseago@redhat.com> Message-ID: <1239742106.4710.25.camel@localhost.localdomain> One minor fix, inline. On Thu, 2009-04-02 at 19:35 +0000, Scott Seago wrote: > Signed-off-by: Scott Seago > diff --git a/src/app/models/privilege.rb b/src/db/migrate/038_add_cloud_role.rb > similarity index 50% > copy from src/app/models/privilege.rb > copy to src/db/migrate/038_add_cloud_role.rb > index 7a30b8f..2487f0c 100644 > --- a/src/app/models/privilege.rb > +++ b/src/db/migrate/038_add_cloud_role.rb > @@ -17,19 +17,30 @@ > # MA 02110-1301, USA. A copy of the GNU General Public License is > # also available at http://www.gnu.org/copyleft/gpl.html. > > -class Privilege < ActiveRecord::Base > - has_and_belongs_to_many :roles The class name and filename difference caused this to fail for me, so they just need to be fixed as we discussed in irc, then ACK. > +class AddCloudRoles < ActiveRecord::Migration > + def self.up > + Role.transaction do > + role_cloud_user = Role.new({:name => "Cloud User"}) > + From apevec at redhat.com Wed Apr 15 00:32:22 2009 From: apevec at redhat.com (Alan Pevec) Date: Wed, 15 Apr 2009 02:32:22 +0200 Subject: [Ovirt-devel] [PATCH node] ovirt_firstboot=no to skip the firstboot menu Message-ID: <1239755542-27077-1-git-send-email-apevec@redhat.com> force skipping the firstboot menu for debugging/testing when local storage is not available Signed-off-by: Alan Pevec --- scripts/ovirt-early | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/scripts/ovirt-early b/scripts/ovirt-early index d99e287..432d5b7 100755 --- a/scripts/ovirt-early +++ b/scripts/ovirt-early @@ -298,6 +298,9 @@ start() { standalone=1 bootparams="$bootparams $i" ;; + ovirt_firstboot=no | ovirt_firstboot=0) + firstboot=0 + ;; ovirt_firstboot*) firstboot=1 ;; -- 1.6.0.6 From jboggs at redhat.com Wed Apr 15 13:38:37 2009 From: jboggs at redhat.com (Joey Boggs) Date: Wed, 15 Apr 2009 09:38:37 -0400 Subject: [Ovirt-devel] [PATCH Server] resend: set LANG variable within installer to prevent translation errors Message-ID: <1239802717-4350-1-git-send-email-jboggs@redhat.com> --- installer/bin/ovirt-installer | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/installer/bin/ovirt-installer b/installer/bin/ovirt-installer index 2d88886..3e87a40 100755 --- a/installer/bin/ovirt-installer +++ b/installer/bin/ovirt-installer @@ -26,6 +26,9 @@ require 'erb' require 'rubygems' require 'highline' +# set $LANG env variable +ENV['LANG'] = 'C' + # # Input output controls # -- 1.6.0.6 From dpierce at redhat.com Wed Apr 15 14:46:18 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 15 Apr 2009 10:46:18 -0400 Subject: [Ovirt-devel] [PATCH node] ovirt_firstboot=no to skip the firstboot menu In-Reply-To: <1239755542-27077-1-git-send-email-apevec@redhat.com> References: <1239755542-27077-1-git-send-email-apevec@redhat.com> Message-ID: <20090415144618.GH5534@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 15, 2009 at 02:32:22AM +0200, Alan Pevec wrote: > force skipping the firstboot menu for debugging/testing when local > storage is not available > > Signed-off-by: Alan Pevec > --- > scripts/ovirt-early | 3 +++ > 1 files changed, 3 insertions(+), 0 deletions(-) > > diff --git a/scripts/ovirt-early b/scripts/ovirt-early > index d99e287..432d5b7 100755 > --- a/scripts/ovirt-early > +++ b/scripts/ovirt-early > @@ -298,6 +298,9 @@ start() { > standalone=1 > bootparams="$bootparams $i" > ;; > + ovirt_firstboot=no | ovirt_firstboot=0) > + firstboot=0 > + ;; > ovirt_firstboot*) > firstboot=1 > ;; > -- > 1.6.0.6 ACK. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 15 15:11:50 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 15 Apr 2009 11:11:50 -0400 Subject: [Ovirt-devel] [PATCH node] Changed the size of the buffers to 768 bytes. Message-ID: <1239808310-21627-1-git-send-email-dpierce@redhat.com> Also removed the customize buffer size for CPU flags so that all buffers are consistent in length. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/ovirt-identify-node.h | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ovirt-identify-node/ovirt-identify-node.h b/ovirt-identify-node/ovirt-identify-node.h index e608051..bf439bd 100644 --- a/ovirt-identify-node/ovirt-identify-node.h +++ b/ovirt-identify-node/ovirt-identify-node.h @@ -45,8 +45,7 @@ #include #include -#define BUFFER_LENGTH 128 -#define CPU_FLAGS_BUFFER_LENGTH 256 +#define BUFFER_LENGTH 768 typedef struct _cpu_info { char cpu_num[BUFFER_LENGTH]; @@ -58,7 +57,7 @@ typedef struct _cpu_info { char cpuid_level[BUFFER_LENGTH]; char speed[BUFFER_LENGTH]; char cache[BUFFER_LENGTH]; - char flags[CPU_FLAGS_BUFFER_LENGTH]; + char flags[BUFFER_LENGTH]; struct _cpu_info* next; } t_cpu_info; -- 1.6.0.6 From slinabery at redhat.com Wed Apr 15 15:27:08 2009 From: slinabery at redhat.com (Steve Linabery) Date: Wed, 15 Apr 2009 10:27:08 -0500 Subject: [Ovirt-devel] [PATCH node] Changed the size of the buffers to 768 bytes. In-Reply-To: <1239808310-21627-1-git-send-email-dpierce@redhat.com> References: <1239808310-21627-1-git-send-email-dpierce@redhat.com> Message-ID: <20090415152708.GA17184@redhat.com> On Wed, Apr 15, 2009 at 11:11:50AM -0400, Darryl L. Pierce wrote: > Also removed the customize buffer size for CPU flags so that all > buffers are consistent in length. > > Signed-off-by: Darryl L. Pierce > --- > ovirt-identify-node/ovirt-identify-node.h | 5 ++--- > 1 files changed, 2 insertions(+), 3 deletions(-) > > diff --git a/ovirt-identify-node/ovirt-identify-node.h b/ovirt-identify-node/ovirt-identify-node.h > index e608051..bf439bd 100644 > --- a/ovirt-identify-node/ovirt-identify-node.h > +++ b/ovirt-identify-node/ovirt-identify-node.h > @@ -45,8 +45,7 @@ > #include > #include > > -#define BUFFER_LENGTH 128 > -#define CPU_FLAGS_BUFFER_LENGTH 256 > +#define BUFFER_LENGTH 768 > > typedef struct _cpu_info { > char cpu_num[BUFFER_LENGTH]; > @@ -58,7 +57,7 @@ typedef struct _cpu_info { > char cpuid_level[BUFFER_LENGTH]; > char speed[BUFFER_LENGTH]; > char cache[BUFFER_LENGTH]; > - char flags[CPU_FLAGS_BUFFER_LENGTH]; > + char flags[BUFFER_LENGTH]; > struct _cpu_info* next; > } t_cpu_info; > > -- > 1.6.0.6 Works as expected. ACK. Steve From dpierce at redhat.com Wed Apr 15 15:40:23 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 15 Apr 2009 11:40:23 -0400 Subject: [Ovirt-devel] [PATCH node] Changed the size of the buffers to 768 bytes. In-Reply-To: <20090415152708.GA17184@redhat.com> References: <1239808310-21627-1-git-send-email-dpierce@redhat.com> <20090415152708.GA17184@redhat.com> Message-ID: <20090415154023.GI5534@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 15, 2009 at 10:27:08AM -0500, Steve Linabery wrote: > Works as expected. ACK. Thanks. Pushed. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Wed Apr 15 18:05:43 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 15 Apr 2009 14:05:43 -0400 Subject: [Ovirt-devel] [PATCH node-image] Fixed how autotest would exit in the middle of a run. Message-ID: <1239818743-20953-1-git-send-email-dpierce@redhat.com> The ultimate cause was "virsh ttyconsole" setting the return code to 1 regardless of whether it ran successfully or not. So, for the time being, fail-on-error has been disabled in autotest. Signed-off-by: Darryl L. Pierce --- autotest.sh | 29 ++++++++++++++--------------- 1 files changed, 14 insertions(+), 15 deletions(-) diff --git a/autotest.sh b/autotest.sh index 0dbe934..6cba9fa 100755 --- a/autotest.sh +++ b/autotest.sh @@ -45,14 +45,15 @@ warn() { printf '%s: %s\n' "$ME" "$*" >&2; } die() { warn "$*"; exit 1; } # trap '__st=$?; stop_log; exit $__st' 0 -trap '__st=$?; cleanup; exit $__st' 0 -trap 'cleanup; exit $?' 1 2 13 15 +trap '__st=$?; log "Exiting normally."; cleanup; exit $__st' 0 +trap '__st=$?; log "Dying a horrible death."; cleanup; exit $__st' 1 2 13 15 test -n "$1" && RESULTS=$1 || RESULTS=autotest.log echo "Running oVirt node image Autotest" -set -e +# BZ#495954 needs to be fixed to uncomment this +# set -e # set -v OVIRT_NODE_IMAGE_ISO=$PWD/ovirt-node-image.iso @@ -68,7 +69,7 @@ log () { } cleanup () { - destroy_node + log "CLEANING UP" stop_dnsmasq destroy_test_iface } @@ -173,8 +174,6 @@ define_node () { # now define the vm sudo virsh define $filename - NODENAME=$nodename - log "Defined VM: name=${NODENAME}" if [ $? != 0 ]; then die "Unable to define virtual machine: $nodename"; fi } @@ -210,10 +209,6 @@ start_node () { destroy_node () { local nodename=$1 - if [ -z "${nodename}" ]; then - nodename=$NODENAME - fi - if [ -n "${nodename}" ]; then log "Destroying VM: ${nodename}" check=$(sudo virsh list --all) @@ -279,7 +274,7 @@ pxeboot_node_vm () { create_test_iface $bridge define_node $xmlfile $nodename $memsize "$diskfile" "" $bridge "local bootdev='network'; local noapic='yes'" get_mac_address $nodename "node_mac_address" - start_dnsmasq $bridge $tftproot $node_mac_address + start_dnsmasq $bridge $tftproot $node_mac_address $nodename start_node $nodename if [ -n "$verify_method" ]; then eval $verify_method @@ -294,7 +289,7 @@ pxeboot_node_vm () { log "Test ended in failure" fi - test $return_code == 0 && return 0 || exit 1 + test $return_code == 0 && return 0 || return 1 } # Launches the node as a virtual machine with a CDROM. @@ -389,10 +384,12 @@ destroy_test_iface () { # $1 - the iface on which dnsmasq works # $2 - the root for tftp files # $3 - the mac address for the node (ignored if blank) +# $4 - the nodename start_dnsmasq () { local iface=$1 local tftproot=$2 local macaddress=$3 + local nodename=$4 local pidfile=$2/dnsmasq.pid stop_dnsmasq @@ -405,6 +402,7 @@ start_dnsmasq () { --dhcp-boot=tftpboot/pxelinux.0 --enable-tftp --tftp-root=${tftproot} + --log-facility=/tmp/dnsmasq-${nodename}.log --log-queries --log-dhcp --pid-file=${pidfile}" @@ -414,10 +412,12 @@ start_dnsmasq () { # start dnsmasq eval $dns_startup DNSMASQ_PID=$(sudo cat $pidfile) + log "dnsmasq start: PID=${DNSMASQ_PID}" } # Kills the running instance of dnsmasq. stop_dnsmasq () { + log "Killing dnsmasq: DNSMASQ_PID=${DNSMASQ_PID}" if [ -n "$DNSMASQ_PID" -a "$DNSMASQ_PID" != "0" ]; then local check=$(ps -ef | awk "/${DNSMASQ_PID}/"' { if ($2 ~ '"${DNSMASQ_PID}"') print $2 }') @@ -455,7 +455,7 @@ verify_pxeboot_stateless_standalone () { local port=$(sudo virsh ttyconsole $nodename) local logfile=$2 - log "Verifying the node is booted correctly" + log "Verifying ${nodename} is booted correctly" local script=' log_file -noappend '"${logfile}"' set timeout 60 @@ -507,7 +507,7 @@ verify_pxeboot_stateful_standalone () { # leverage the existing stateless test verify_pxeboot_stateless_standalone $nodename - log "Verifying the node is booted correctly" + log "Verifying ${nodename} is booted correctly" local script=' log_file -noappend '"${logfile}"' set timeout 180 @@ -554,7 +554,6 @@ test_cdrom_stateless_standalone () { # automated testing entry points { IFACE_NAME=testbr$$ - NODENAME= NETWORK=192.168.$(echo "scale=0; print $$ % 255" | bc -l) NODE_ADDRESS=$NETWORK.100 DNSMASQ_PID=0 -- 1.6.0.6 From imain at redhat.com Wed Apr 15 18:30:56 2009 From: imain at redhat.com (Ian Main) Date: Wed, 15 Apr 2009 11:30:56 -0700 Subject: [Ovirt-devel] [PATCH server] Log broker connect/disconnect. Message-ID: <1239820256-32716-1-git-send-email-imain@redhat.com> This patch makes dbomatic log agent connect/disconnect and also fixes a formatting bug in an exception. Signed-off-by: Ian Main --- src/db-omatic/db_omatic.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/src/db-omatic/db_omatic.rb b/src/db-omatic/db_omatic.rb index 7ae08da..e043a6f 100755 --- a/src/db-omatic/db_omatic.rb +++ b/src/db-omatic/db_omatic.rb @@ -412,7 +412,7 @@ class DbOmatic < Qpid::Qmf::Console begin VmVnc.deallocate_all rescue Exception => e # just log any errors here - @logger.error "Error with closing all VM VNCs operation: " + e + @logger.error "Error with closing all VM VNCs operation: #{e.message}" end db_vm = Vm.find(:all) @@ -423,6 +423,14 @@ class DbOmatic < Qpid::Qmf::Console end end + def broker_connected(broker) + @logger.info "Connected to broker." + end + + def broker_disconnected(broker) + @logger.error "Broker disconnected." + end + # This is the mainloop that is called into as a separate thread. This just loops through # and makes sure all the agents are still reporting. If they aren't they get marked as -- 1.6.0.6 From mburns at redhat.com Wed Apr 15 19:18:17 2009 From: mburns at redhat.com (Mike Burns) Date: Wed, 15 Apr 2009 15:18:17 -0400 Subject: [Ovirt-devel] [PATCH node-image] Fixed how autotest would exit in the middle of a run. In-Reply-To: <1239818743-20953-1-git-send-email-dpierce@redhat.com> References: <1239818743-20953-1-git-send-email-dpierce@redhat.com> Message-ID: <49E632F9.9070908@redhat.com> Darryl L. Pierce wrote: > The ultimate cause was "virsh ttyconsole" setting the return code to 1 > regardless of whether it ran successfully or not. So, for the time > being, fail-on-error has been disabled in autotest. > > Signed-off-by: Darryl L. Pierce > --- > autotest.sh | 29 ++++++++++++++--------------- > 1 files changed, 14 insertions(+), 15 deletions(-) > > diff --git a/autotest.sh b/autotest.sh > index 0dbe934..6cba9fa 100755 > --- a/autotest.sh > +++ b/autotest.sh > @@ -45,14 +45,15 @@ warn() { printf '%s: %s\n' "$ME" "$*" >&2; } > die() { warn "$*"; exit 1; } > > # trap '__st=$?; stop_log; exit $__st' 0 > -trap '__st=$?; cleanup; exit $__st' 0 > -trap 'cleanup; exit $?' 1 2 13 15 > +trap '__st=$?; log "Exiting normally."; cleanup; exit $__st' 0 > +trap '__st=$?; log "Dying a horrible death."; cleanup; exit $__st' 1 2 13 15 > > test -n "$1" && RESULTS=$1 || RESULTS=autotest.log > > echo "Running oVirt node image Autotest" > > -set -e > +# BZ#495954 needs to be fixed to uncomment this > +# set -e > # set -v > > OVIRT_NODE_IMAGE_ISO=$PWD/ovirt-node-image.iso > @@ -68,7 +69,7 @@ log () { > } > > cleanup () { > - destroy_node > + log "CLEANING UP" > stop_dnsmasq > destroy_test_iface > } > @@ -173,8 +174,6 @@ define_node () { > > # now define the vm > sudo virsh define $filename > - NODENAME=$nodename > - log "Defined VM: name=${NODENAME}" > > if [ $? != 0 ]; then die "Unable to define virtual machine: $nodename"; fi > } > @@ -210,10 +209,6 @@ start_node () { > destroy_node () { > local nodename=$1 > > - if [ -z "${nodename}" ]; then > - nodename=$NODENAME > - fi > - > if [ -n "${nodename}" ]; then > log "Destroying VM: ${nodename}" > check=$(sudo virsh list --all) > @@ -279,7 +274,7 @@ pxeboot_node_vm () { > create_test_iface $bridge > define_node $xmlfile $nodename $memsize "$diskfile" "" $bridge "local bootdev='network'; local noapic='yes'" > get_mac_address $nodename "node_mac_address" > - start_dnsmasq $bridge $tftproot $node_mac_address > + start_dnsmasq $bridge $tftproot $node_mac_address $nodename > start_node $nodename > if [ -n "$verify_method" ]; then > eval $verify_method > @@ -294,7 +289,7 @@ pxeboot_node_vm () { > log "Test ended in failure" > fi > > - test $return_code == 0 && return 0 || exit 1 > + test $return_code == 0 && return 0 || return 1 > } > > # Launches the node as a virtual machine with a CDROM. > @@ -389,10 +384,12 @@ destroy_test_iface () { > # $1 - the iface on which dnsmasq works > # $2 - the root for tftp files > # $3 - the mac address for the node (ignored if blank) > +# $4 - the nodename > start_dnsmasq () { > local iface=$1 > local tftproot=$2 > local macaddress=$3 > + local nodename=$4 > local pidfile=$2/dnsmasq.pid > > stop_dnsmasq > @@ -405,6 +402,7 @@ start_dnsmasq () { > --dhcp-boot=tftpboot/pxelinux.0 > --enable-tftp > --tftp-root=${tftproot} > + --log-facility=/tmp/dnsmasq-${nodename}.log > --log-queries > --log-dhcp > --pid-file=${pidfile}" > @@ -414,10 +412,12 @@ start_dnsmasq () { > # start dnsmasq > eval $dns_startup > DNSMASQ_PID=$(sudo cat $pidfile) > + log "dnsmasq start: PID=${DNSMASQ_PID}" > } > > # Kills the running instance of dnsmasq. > stop_dnsmasq () { > + log "Killing dnsmasq: DNSMASQ_PID=${DNSMASQ_PID}" > if [ -n "$DNSMASQ_PID" -a "$DNSMASQ_PID" != "0" ]; then > local check=$(ps -ef | awk "/${DNSMASQ_PID}/"' { if ($2 ~ '"${DNSMASQ_PID}"') print $2 }') > > @@ -455,7 +455,7 @@ verify_pxeboot_stateless_standalone () { > local port=$(sudo virsh ttyconsole $nodename) > local logfile=$2 > > - log "Verifying the node is booted correctly" > + log "Verifying ${nodename} is booted correctly" > local script=' > log_file -noappend '"${logfile}"' > set timeout 60 > @@ -507,7 +507,7 @@ verify_pxeboot_stateful_standalone () { > > # leverage the existing stateless test > verify_pxeboot_stateless_standalone $nodename > - log "Verifying the node is booted correctly" > + log "Verifying ${nodename} is booted correctly" > local script=' > log_file -noappend '"${logfile}"' > set timeout 180 > @@ -554,7 +554,6 @@ test_cdrom_stateless_standalone () { > # automated testing entry points > { > IFACE_NAME=testbr$$ > - NODENAME= > NETWORK=192.168.$(echo "scale=0; print $$ % 255" | bc -l) > NODE_ADDRESS=$NETWORK.100 > DNSMASQ_PID=0 > Applied and autobuild run. No issues found. ACK From dpierce at redhat.com Wed Apr 15 19:40:38 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Wed, 15 Apr 2009 15:40:38 -0400 Subject: [Ovirt-devel] [PATCH node-image] Fixed how autotest would exit in the middle of a run. In-Reply-To: <49E632F9.9070908@redhat.com> References: <1239818743-20953-1-git-send-email-dpierce@redhat.com> <49E632F9.9070908@redhat.com> Message-ID: <20090415194038.GK5534@mcpierce-laptop.rdu.redhat.com> On Wed, Apr 15, 2009 at 03:18:17PM -0400, Mike Burns wrote: > Applied and autobuild run. No issues found. Thanks. Pushed. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From thomas.vonsteiger at bluewin.ch Wed Apr 15 21:47:51 2009 From: thomas.vonsteiger at bluewin.ch (Thomas von Steiger) Date: Wed, 15 Apr 2009 23:47:51 +0200 Subject: [Ovirt-devel] ovirt-identity-node.rpm Message-ID: If i see all the discussion about ovirt,dns,kerberos,ldap,freeipa. This are information about networks, hostnames, users and security and to manage them it's practicale to have a ovirt-identity-node.rpm as kvm guest. This node helps to organise and manage other framworks for everything it has todo with users, tickets and certificates. To use ovirt, its required to start first ovirt-identity-node to have kerberos tickets and users. Other tools, services and frameworks in this cloude use the same identityinformation. It can be possible to go this way, if we create on ovirt a new user, ovirt is able to request this on the identity node. This node self is directly viewable in ovirt if this ovirt user has enough permission. And the identity node can have the own locale small rails application for create users and groups in general. What you think about this? Thomas From mmcgrath at redhat.com Thu Apr 16 17:42:24 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 16 Apr 2009 12:42:24 -0500 (CDT) Subject: [Ovirt-devel] Outstanding UI bugs Message-ID: Sorry guys, wanted to send this a bit sooner. Just a quick list of some outstanding bugs that I'm seeing (I'll work on actual bugzillas after the meeting) 1) We are seeing lots of things getting left in a pending state. For example after deleting an lvm store, the lvm is stuck in pending_deletion. 2) See - http://mmcgrath.fedorapeople.org/bad.gif I'm not sure if this is one problem or multiple. here's the firebug and rails.log - http://mmcgrath.fedorapeople.org/post.txt 3) libvirt-qpid on the nodes keep dieing. 4) We've got guests that were on a node, libvirt-qpid died, the guests went unavailable. After the host came back the nodes stayed unavailable for a very long time (hours) but now seems to be back. Not sure if a restart of something fixed it while I was debugging something else but it's something to make note of. I'll keep an eye out. Really number 2) seems to be the bigger bug right now. -Mike From mmcgrath at redhat.com Thu Apr 16 18:04:11 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Thu, 16 Apr 2009 13:04:11 -0500 (CDT) Subject: [Ovirt-devel] Outstanding UI bugs In-Reply-To: References: Message-ID: On Thu, 16 Apr 2009, Mike McGrath wrote: > Sorry guys, wanted to send this a bit sooner. Just a quick list of some > outstanding bugs that I'm seeing (I'll work on actual bugzillas after the > meeting) > > 1) We are seeing lots of things getting left in a pending state. For > example after deleting an lvm store, the lvm is stuck in pending_deletion. > > 2) See - http://mmcgrath.fedorapeople.org/bad.gif I'm not sure if this is > one problem or multiple. here's the firebug and rails.log - > http://mmcgrath.fedorapeople.org/post.txt > > 3) libvirt-qpid on the nodes keep dieing. > > > 4) We've got guests that were on a node, libvirt-qpid died, the guests > went unavailable. After the host came back the nodes stayed unavailable > for a very long time (hours) but now seems to be back. Not sure if a > restart of something fixed it while I was debugging something else but > it's something to make note of. I'll keep an eye out. > > Really number 2) seems to be the bigger bug right now. > One other bug (not related to UI) is these packages need to get in Fedora! -Mike From jboggs at redhat.com Thu Apr 16 18:04:49 2009 From: jboggs at redhat.com (Joey Boggs) Date: Thu, 16 Apr 2009 14:04:49 -0400 Subject: [Ovirt-devel] [PATCH server] First step of detail pane UI cleanup. In-Reply-To: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> References: <1239651663-2410-1-git-send-email-jguiditt@redhat.com> Message-ID: <49E77341.3050806@redhat.com> Jason Guiditta wrote: > This patch implements layout fixes to clean up look of the > details pane throughout the site, so it looks more like > the design here: > http://ovirt.org/page/Summary_UX > > Note that this does not include the actual rearrangement of > Hardware Pools summary pages. Best place to see changes is > on the summary for a Resource Pool. > --- > src/app/views/layouts/selection.rhtml | 15 +++++++++------ > src/app/views/resources/quick_summary.rhtml | 6 ++---- > src/public/stylesheets/components.css | 11 +++++++---- > src/public/stylesheets/layout.css | 11 +++-------- > 4 files changed, 21 insertions(+), 22 deletions(-) > > diff --git a/src/app/views/layouts/selection.rhtml b/src/app/views/layouts/selection.rhtml > index e7aefc2..1f313d7 100644 > --- a/src/app/views/layouts/selection.rhtml > +++ b/src/app/views/layouts/selection.rhtml > @@ -1,8 +1,11 @@ > -
    > -
    <%= yield :title -%>
    > +
    <%= yield :title -%>
    > > <% tools = yield :action_links -%> > <% if tools %> > + >
      >
    • > <%= image_tag "icon_separator.png", :style=>"vertical-align: middle;" %> > @@ -11,13 +14,13 @@ >
    > <% end %> >
    > +
    > + <%= yield %> > +
    > > - <%= yield %> > - > -
    > <% right = yield :right -%> > <% if right %> > -
    > +
    > <%= right -%> >
    > <% end %> > diff --git a/src/app/views/resources/quick_summary.rhtml b/src/app/views/resources/quick_summary.rhtml > index 31c4033..0a01105 100644 > --- a/src/app/views/resources/quick_summary.rhtml > +++ b/src/app/views/resources/quick_summary.rhtml > @@ -38,7 +38,6 @@ > }, 'json'); > } > > - > > <% resources = @pool.full_resources %> >
    > @@ -58,7 +57,6 @@ > <%= item[2]%>
    > <% end %> >
    > -
    > -
    > +<%- content_for :right do -%> > <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @pool.id, :target => 'resource' %> > -
    > +<% end -%> > \ No newline at end of file > diff --git a/src/public/stylesheets/components.css b/src/public/stylesheets/components.css > index 2313d1c..708eb0e 100644 > --- a/src/public/stylesheets/components.css > +++ b/src/public/stylesheets/components.css > @@ -208,11 +208,14 @@ > } > > /* snapshot graphs on hardware / resource summary tab */ > -#snapshot_graphs table { > - width: 98%; > -} > #snapshot_graphs th { background: #EEEEEE; text-align: left; padding-left: 10px;border:1px solid #CCCCCC;} > -#snapshot_graphs td { padding-left: 10px; background: #FFFFFF;border:1px solid #CCCCCC;} > +#snapshot_graphs td { > + padding-left: 10px; > + padding-right: 10px; > + white-space: nowrap; > + background: #FFFFFF; > + border:1px solid #CCCCCC; > +} > .snapshot_graph_container{ > width: 180px; > height: 10px; > diff --git a/src/public/stylesheets/layout.css b/src/public/stylesheets/layout.css > index 987462d..981ff22 100644 > --- a/src/public/stylesheets/layout.css > +++ b/src/public/stylesheets/layout.css > @@ -256,13 +256,11 @@ a { color:#000000; text-decoration: none;} > background: #DEE7EB; > border-top: #CCCCCC solid 1px; > overflow: auto; > + padding: 10px 10px 10px 15px; > } > > .selection_left { > - padding: 10px 10px 10px 15px; > - height: 126px; > float:left; > - width: 40%; > } > > .selection_title { > @@ -315,12 +313,9 @@ a { color:#000000; text-decoration: none;} > } > > .selection_right { > - width:55%; > float: right; > - padding-top: 10px; > - /*background: #F0F0F0;*/ > - height: 140px; > - } > + padding-right: 10px; > +} > > .selection_right_title { > padding: 4px 4px 4px 6px; > ack From mmorsi at redhat.com Thu Apr 16 16:53:32 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 16 Apr 2009 12:53:32 -0400 Subject: [Ovirt-devel] [PATCH] populate 'send keys' menu and wire up key sending mechanism Message-ID: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> --- main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 70 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index 390046a..05da700 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ #include #include +#include #include #ifdef HAVE_NETDB_H @@ -60,10 +61,16 @@ gboolean debug = 0; const char *cainfo = CAINFO; gboolean check_cert = TRUE; +/* The WUI thread has updated the vm list. Here in the main thread + * we keep our own copy of the vmlist. + */ +static GSList *vmlist = NULL; + /* Private functions. */ static void start_ui (void); static GtkWidget *menu_item_new (int which_menu); static void connect_to_wui (GtkWidget *, gpointer); +static void send_key_to_vm (GtkWidget *widget, gpointer _keyComboDef); static void login_to_wui (GtkWidget *, gpointer); static gboolean delete_event (GtkWidget *widget, GdkEvent *event, gpointer data); static void destroy (GtkWidget *widget, gpointer data); @@ -78,6 +85,7 @@ static void viewer_initialized (GtkWidget *vnc, GtkWidget *data); static void viewer_disconnected (GtkWidget *vnc); static void viewer_credential (GtkWidget *vnc, GValueArray *credList); static int viewer_open_vnc_socket (const char *vnchost, int vncport); +static void add_vm_to_connectmenu (gpointer _vm, gpointer data); /* For any widgets accessed from multiple functions. */ static GtkWidget *window; @@ -123,6 +131,35 @@ static struct menuItem menuItems[] = { { HELP_MENU, NULL, "_Help", "Help" } }; + +#define MAX_KEY_COMBO 3 + struct keyComboDef { + guint keys[MAX_KEY_COMBO]; + guint nkeys; + const char *label; + }; + +#define NUM_KEY_COMBOS 17 +static struct keyComboDef keyCombos[] = { + { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, + { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, + { {}, 0, "" }, + { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F1"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F2"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F3"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F4"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F5"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F6"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F7"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F8"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F9"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F10"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F11"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F12"}, + { {}, 0, "" }, + { { GDK_Print }, 1, "PrintScreen"}, +}; + /* Window title. */ static const char *title = "oVirt Viewer"; @@ -228,12 +265,14 @@ main (int argc, char *argv[]) static void start_ui (void) { + int i; GtkWidget *vbox; GtkWidget *menubar; GtkWidget *view; GtkWidget *viewmenu; GtkWidget *sendkey; GtkWidget *sendkeymenu; + GtkWidget *sendkeymenuitem; GtkWidget *wind; GtkWidget *windmenu; GtkWidget *help; @@ -302,6 +341,13 @@ start_ui (void) sendkeymenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (sendkey), sendkeymenu); + for(i = 0; i < NUM_KEY_COMBOS; ++i){ + sendkeymenuitem = gtk_menu_item_new_with_label (keyCombos[i].label); + gtk_menu_append (GTK_MENU (sendkeymenu), sendkeymenuitem); + g_signal_connect (G_OBJECT (sendkeymenuitem), "activate", + G_CALLBACK (send_key_to_vm), &(keyCombos[i])); + } + wind = menu_item_new (WINDOW_MENU); windmenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (wind), windmenu); @@ -579,6 +625,30 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) DEBUG ("finished creating new tab"); } + +/* Send key to a virtual machine. This callback is called from the + * send key menu. If finds vm in focus, and sends specified key to it + */ +static void +send_key_to_vm (GtkWidget *widget, gpointer _keyComboDef) +{ + GtkWidget* viewer; + struct keyComboDef* key_combo = (struct keyComboDef*) _keyComboDef; + int c = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); + + if(c < 0){ + return; + } + + viewer = gtk_notebook_get_nth_page(GTK_NOTEBOOK (notebook), c); + if(viewer != NULL){ + DEBUG ("sending keys to vm"); + vnc_display_send_keys(VNC_DISPLAY(viewer), + key_combo->keys, + key_combo->nkeys); + } +} + /* static void viewer_grab(GtkWidget *vnc, GtkWidget *window) { @@ -938,13 +1008,6 @@ main_status_error (gpointer _str) return FALSE; } -/* The WUI thread has updated the vm list. Here in the main thread - * we keep our own copy of the vmlist. - */ -static GSList *vmlist = NULL; - -static void add_vm_to_connectmenu (gpointer _vm, gpointer data); - gboolean main_vmlist_updated (gpointer data) { -- 1.6.0.6 From mmorsi at redhat.com Thu Apr 16 21:03:24 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 16 Apr 2009 17:03:24 -0400 Subject: [Ovirt-devel] Re: [PATCH] populate 'send keys' menu and wire up key sending mechanism In-Reply-To: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> References: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> Message-ID: <49E79D1C.6030209@redhat.com> To clarify this is for the ovirt-viewer project. -Mo From hbrock at redhat.com Thu Apr 16 23:19:12 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 16 Apr 2009 19:19:12 -0400 Subject: [Ovirt-devel] [PATCH] populate 'send keys' menu and wire up key sending mechanism In-Reply-To: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> References: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> Message-ID: <20090416231911.GK10299@redhat.com> On Thu, Apr 16, 2009 at 12:53:32PM -0400, Mohammed Morsi wrote: > --- > main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- > 1 files changed, 70 insertions(+), 7 deletions(-) > > diff --git a/main.c b/main.c > index 390046a..05da700 100644 > --- a/main.c > +++ b/main.c > @@ -25,6 +25,7 @@ > > #include > #include > +#include > #include > > #ifdef HAVE_NETDB_H > @@ -60,10 +61,16 @@ gboolean debug = 0; > const char *cainfo = CAINFO; > gboolean check_cert = TRUE; > > +/* The WUI thread has updated the vm list. Here in the main thread > + * we keep our own copy of the vmlist. > + */ > +static GSList *vmlist = NULL; > + > /* Private functions. */ > static void start_ui (void); > static GtkWidget *menu_item_new (int which_menu); > static void connect_to_wui (GtkWidget *, gpointer); > +static void send_key_to_vm (GtkWidget *widget, gpointer _keyComboDef); > static void login_to_wui (GtkWidget *, gpointer); > static gboolean delete_event (GtkWidget *widget, GdkEvent *event, gpointer data); > static void destroy (GtkWidget *widget, gpointer data); > @@ -78,6 +85,7 @@ static void viewer_initialized (GtkWidget *vnc, GtkWidget *data); > static void viewer_disconnected (GtkWidget *vnc); > static void viewer_credential (GtkWidget *vnc, GValueArray *credList); > static int viewer_open_vnc_socket (const char *vnchost, int vncport); > +static void add_vm_to_connectmenu (gpointer _vm, gpointer data); > > /* For any widgets accessed from multiple functions. */ > static GtkWidget *window; > @@ -123,6 +131,35 @@ static struct menuItem menuItems[] = { > { HELP_MENU, NULL, "_Help", "Help" } > }; > > + > +#define MAX_KEY_COMBO 3 > + struct keyComboDef { > + guint keys[MAX_KEY_COMBO]; > + guint nkeys; > + const char *label; > + }; > + > +#define NUM_KEY_COMBOS 17 > +static struct keyComboDef keyCombos[] = { > + { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, > + { {}, 0, "" }, > + { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F1"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F2"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F3"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F4"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F5"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F6"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F7"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F8"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F9"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F10"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F11"}, > + { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F12"}, > + { {}, 0, "" }, > + { { GDK_Print }, 1, "PrintScreen"}, > +}; > + > /* Window title. */ > static const char *title = "oVirt Viewer"; > > @@ -228,12 +265,14 @@ main (int argc, char *argv[]) > static void > start_ui (void) > { > + int i; > GtkWidget *vbox; > GtkWidget *menubar; > GtkWidget *view; > GtkWidget *viewmenu; > GtkWidget *sendkey; > GtkWidget *sendkeymenu; > + GtkWidget *sendkeymenuitem; > GtkWidget *wind; > GtkWidget *windmenu; > GtkWidget *help; > @@ -302,6 +341,13 @@ start_ui (void) > sendkeymenu = gtk_menu_new (); > gtk_menu_item_set_submenu (GTK_MENU_ITEM (sendkey), sendkeymenu); > > + for(i = 0; i < NUM_KEY_COMBOS; ++i){ > + sendkeymenuitem = gtk_menu_item_new_with_label (keyCombos[i].label); > + gtk_menu_append (GTK_MENU (sendkeymenu), sendkeymenuitem); > + g_signal_connect (G_OBJECT (sendkeymenuitem), "activate", > + G_CALLBACK (send_key_to_vm), &(keyCombos[i])); > + } > + > wind = menu_item_new (WINDOW_MENU); > windmenu = gtk_menu_new (); > gtk_menu_item_set_submenu (GTK_MENU_ITEM (wind), windmenu); > @@ -579,6 +625,30 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) > DEBUG ("finished creating new tab"); > } > > + > +/* Send key to a virtual machine. This callback is called from the > + * send key menu. If finds vm in focus, and sends specified key to it > + */ > +static void > +send_key_to_vm (GtkWidget *widget, gpointer _keyComboDef) > +{ > + GtkWidget* viewer; > + struct keyComboDef* key_combo = (struct keyComboDef*) _keyComboDef; > + int c = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); > + > + if(c < 0){ > + return; > + } > + > + viewer = gtk_notebook_get_nth_page(GTK_NOTEBOOK (notebook), c); > + if(viewer != NULL){ > + DEBUG ("sending keys to vm"); > + vnc_display_send_keys(VNC_DISPLAY(viewer), > + key_combo->keys, > + key_combo->nkeys); > + } > +} > + > /* > static void viewer_grab(GtkWidget *vnc, GtkWidget *window) > { > @@ -938,13 +1008,6 @@ main_status_error (gpointer _str) > return FALSE; > } > > -/* The WUI thread has updated the vm list. Here in the main thread > - * we keep our own copy of the vmlist. > - */ > -static GSList *vmlist = NULL; > - > -static void add_vm_to_connectmenu (gpointer _vm, gpointer data); > - > gboolean > main_vmlist_updated (gpointer data) > { > -- How does virt-viewer currently do this? Should we be using the same mechanism? --Hugh From mmorsi at redhat.com Thu Apr 16 23:26:44 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Thu, 16 Apr 2009 19:26:44 -0400 Subject: [Ovirt-devel] [PATCH] populate 'send keys' menu and wire up key sending mechanism In-Reply-To: <20090416231911.GK10299@redhat.com> References: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> <20090416231911.GK10299@redhat.com> Message-ID: <49E7BEB4.2010602@redhat.com> > > How does virt-viewer currently do this? Should we be using the same mechanism? > > --Hugh > I based this off virt-viewer's implementation with some slight tweaks http://hg.et.redhat.com/cgi-bin/hg-virt.cgi/applications/virt-viewer--devel/file/92da1556bbf9/src/main.c#l1 -Mo From hbrock at redhat.com Thu Apr 16 23:23:46 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Thu, 16 Apr 2009 19:23:46 -0400 Subject: [Ovirt-devel] [PATCH] populate 'send keys' menu and wire up key sending mechanism In-Reply-To: <49E7BEB4.2010602@redhat.com> References: <1239900812-3645-1-git-send-email-mmorsi@redhat.com> <20090416231911.GK10299@redhat.com> <49E7BEB4.2010602@redhat.com> Message-ID: <20090416232345.GL10299@redhat.com> On Thu, Apr 16, 2009 at 07:26:44PM -0400, Mohammed Morsi wrote: > > > > > How does virt-viewer currently do this? Should we be using the same mechanism? > > > > --Hugh > > > > I based this off virt-viewer's implementation with some slight tweaks > > > http://hg.et.redhat.com/cgi-bin/hg-virt.cgi/applications/virt-viewer--devel/file/92da1556bbf9/src/main.c#l1 > > -Mo Never a doubt! Well done then... --Hugh From is at eseco.de Fri Apr 17 08:49:33 2009 From: is at eseco.de (Ingmar Schraub) Date: Fri, 17 Apr 2009 10:49:33 +0200 Subject: [Ovirt-devel] host not shown in default hardware pool Message-ID: <49E8429D.5070105@eseco.de> Hello, I am new to ovirt and please bare with me if my question has been asked before. I googled, studied the wiki and searched the bug list. But I couldn't find anything similar. I've just set up a new server with F10, fully patched and installed ovirt using the Rawhide build instructions. All seems to work nicely, but I am stuck at one point. After 'sudo ovirt-install-node-stateful' followed by a host reboot I started the appliance again. My problem is that the host is not shown at all in the default hardware pool. Any hints what's going wrong here? What could be missing that the appliance doesn't see my host? Networking, bridge, etc. is all ok. I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the ovirt-appliance httpd doesn't start with the config file provided. There is already a ticket open on bugzilla. (#489819). Thanks a lot in advance. regards, Ingmar From is at eseco.de Fri Apr 17 12:26:38 2009 From: is at eseco.de (Ingmar Schraub) Date: Fri, 17 Apr 2009 14:26:38 +0200 Subject: [Ovirt-devel] [Fwd: host not shown in default hardware pool] Message-ID: <49E8757E.5000707@eseco.de> Hello, in addition to my trouble report from this morning, I further noticed in the logs the following: HOST: ----- Apr 17 14:15:25 physical libvirt-qpid: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found) ovirt-appliance: ---------------- Apr 17 14:15:25 management qpidd[2162]: 2009-apr-17 14:15:25 warning Client closed connection with 501: internal-error: Sasl error: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found) (qpid/client/SaslFactory.cpp:226) It seems like the authentication fails and therefore the appliances doesn't 'see' the host. Does anybody know whether this is a libvirt-qpid problem or a qpidd problem or some wrong configuration in ovirt? Is this a known issue or did I hit something new? I am really stuck here... Thanks a lot and best regards, Ingmar -------------- next part -------------- An embedded message was scrubbed... From: Ingmar Schraub Subject: host not shown in default hardware pool Date: Fri, 17 Apr 2009 10:49:33 +0200 Size: 1266 URL: From hbrock at redhat.com Fri Apr 17 13:01:15 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Fri, 17 Apr 2009 09:01:15 -0400 Subject: [Ovirt-devel] host not shown in default hardware pool In-Reply-To: <49E8429D.5070105@eseco.de> References: <49E8429D.5070105@eseco.de> Message-ID: <20090417130115.GM10299@redhat.com> On Fri, Apr 17, 2009 at 10:49:33AM +0200, Ingmar Schraub wrote: > Hello, > > I am new to ovirt and please bare with me if my question has been asked > before. I googled, studied the wiki and searched the bug list. But I > couldn't find anything similar. > > I've just set up a new server with F10, fully patched and installed > ovirt using the Rawhide build instructions. > > All seems to work nicely, but I am stuck at one point. > > After 'sudo ovirt-install-node-stateful' followed by a host reboot I > started the appliance again. My problem is that the host is not shown at > all in the default hardware pool. Any hints what's going wrong here? > What could be missing that the appliance doesn't see my host? > Networking, bridge, etc. is all ok. > > I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the > ovirt-appliance httpd doesn't start with the config file provided. There > is already a ticket open on bugzilla. (#489819). > > Thanks a lot in advance. > > regards, > > Ingmar > Hello there, and thanks for trying oVirt! The Rawhide install instructions are a bit dated now (I need to update them), and in fact I'm not sure they will work at all. The current install instructions are at http://ovirt.org/install-instructions.html, so you might want to read those before going further. Having said that, if you are operating on a single machine, the thing that would prevent your host from showing up at all in the default hardware pool could be two things: 1. a networking failure, or 2. your host has only 1 NIC. We have recently found a bug in which ovirt-identify-node, run from the ovirt-post init script, fails if there is only one NIC on the machine. You might try running ovirt-identify-node from the command line and see if that makes the host show up. Take care, --Hugh From is at eseco.de Fri Apr 17 13:19:00 2009 From: is at eseco.de (Ingmar Schraub) Date: Fri, 17 Apr 2009 15:19:00 +0200 Subject: [Ovirt-devel] host not shown in default hardware pool In-Reply-To: <20090417130115.GM10299@redhat.com> References: <49E8429D.5070105@eseco.de> <20090417130115.GM10299@redhat.com> Message-ID: <49E881C4.8060803@eseco.de> Hugh O. Brock wrote: > On Fri, Apr 17, 2009 at 10:49:33AM +0200, Ingmar Schraub wrote: >> Hello, >> >> I am new to ovirt and please bare with me if my question has been asked >> before. I googled, studied the wiki and searched the bug list. But I >> couldn't find anything similar. >> >> I've just set up a new server with F10, fully patched and installed >> ovirt using the Rawhide build instructions. >> >> All seems to work nicely, but I am stuck at one point. >> >> After 'sudo ovirt-install-node-stateful' followed by a host reboot I >> started the appliance again. My problem is that the host is not shown at >> all in the default hardware pool. Any hints what's going wrong here? >> What could be missing that the appliance doesn't see my host? >> Networking, bridge, etc. is all ok. >> >> I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the >> ovirt-appliance httpd doesn't start with the config file provided. There >> is already a ticket open on bugzilla. (#489819). >> >> Thanks a lot in advance. >> >> regards, >> >> Ingmar >> > > Hello there, and thanks for trying oVirt! > > The Rawhide install instructions are a bit dated now (I need to update > them), and in fact I'm not sure they will work at all. The current > install instructions are at > http://ovirt.org/install-instructions.html, so you might want to read > those before going further. > > Having said that, if you are operating on a single machine, the thing > that would prevent your host from showing up at all in the default > hardware pool could be two things: 1. a networking failure, or 2. your > host has only 1 NIC. We have recently found a bug in which > ovirt-identify-node, run from the ovirt-post init script, fails if > there is only one NIC on the machine. > > You might try running ovirt-identify-node from the command line and > see if that makes the host show up. > > Take care, > --Hugh Hello Hugh, thanks for the hints! I'll try the procedure described in the 'Install Instructions' document as you suggested. My machine comes with 4 network interfaces. ovirt-identify-node needs two parameters: host+port. I assume host is the management (ovirt appliance) machine. Which port must be used? 5762 (qpidd)? Sorry, but couldn't find this information. Maybe you have seen my second e-mail from today which had the log snippets. For me it seems like the rawhide way isn't configuring kerberos completely and therefore the host is not showing up on the managment machine. Thanks a lot, Ingmar From jboggs at redhat.com Fri Apr 17 13:52:04 2009 From: jboggs at redhat.com (Joey Boggs) Date: Fri, 17 Apr 2009 09:52:04 -0400 Subject: [Ovirt-devel] [Fwd: host not shown in default hardware pool] In-Reply-To: <49E8757E.5000707@eseco.de> References: <49E8757E.5000707@eseco.de> Message-ID: <49E88984.1010709@redhat.com> Can you also grab the contents of /var/log/ovirt-server/db-omatic.log from the appliance? Just to make sure, your node is the physical machine running the appliance? Ingmar Schraub wrote: > Hello, > > in addition to my trouble report from this morning, I further noticed in > the logs the following: > > HOST: > ----- > Apr 17 14:15:25 physical libvirt-qpid: GSSAPI Error: Unspecified GSS > failure. Minor code may provide more information (No credentials cache > found) > > ovirt-appliance: > ---------------- > Apr 17 14:15:25 management qpidd[2162]: 2009-apr-17 14:15:25 warning > Client closed connection with 501: internal-error: Sasl error: SASL(-1): > generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may > provide more information (No credentials cache found) > (qpid/client/SaslFactory.cpp:226) > > It seems like the authentication fails and therefore the appliances > doesn't 'see' the host. > > Does anybody know whether this is a libvirt-qpid problem or a qpidd > problem or some wrong configuration in ovirt? Is this a known issue or > did I hit something new? > > I am really stuck here... > > Thanks a lot and best regards, > > Ingmar > > > ------------------------------------------------------------------------ > > Subject: > host not shown in default hardware pool > From: > Ingmar Schraub > Date: > Fri, 17 Apr 2009 10:49:33 +0200 > To: > ovirt-devel at redhat.com > > To: > ovirt-devel at redhat.com > > > Hello, > > I am new to ovirt and please bare with me if my question has been asked > before. I googled, studied the wiki and searched the bug list. But I > couldn't find anything similar. > > I've just set up a new server with F10, fully patched and installed > ovirt using the Rawhide build instructions. > > All seems to work nicely, but I am stuck at one point. > > After 'sudo ovirt-install-node-stateful' followed by a host reboot I > started the appliance again. My problem is that the host is not shown at > all in the default hardware pool. Any hints what's going wrong here? > What could be missing that the appliance doesn't see my host? > Networking, bridge, etc. is all ok. > > I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the > ovirt-appliance httpd doesn't start with the config file provided. There > is already a ticket open on bugzilla. (#489819). > > Thanks a lot in advance. > > regards, > > Ingmar > > > ------------------------------------------------------------------------ > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel > From is at eseco.de Fri Apr 17 14:14:55 2009 From: is at eseco.de (Ingmar Schraub) Date: Fri, 17 Apr 2009 16:14:55 +0200 Subject: [Ovirt-devel] [Fwd: host not shown in default hardware pool] In-Reply-To: <49E88984.1010709@redhat.com> References: <49E8757E.5000707@eseco.de> <49E88984.1010709@redhat.com> Message-ID: <49E88EDF.2010703@eseco.de> Interesting... the host shows now up after running "ovirt-identify-node -v -s 192.168.50.2 -p 12120". It is unavailable though. I shut the appliance down, re-started libvirtd on the host, powered the appliance back on. Host is still unavailable. I ran the test "ruby /usr/share/ovirt-server/qmf-libvirt-example.rb", but this gave me only Connecting to amqp://management.priv.ovirt.org:5672.. ---------------------------- ---------------------------- I believe that the kerberos authentication fails (as the logs I provided indicate). But why? date/time is in sync on host/appliance. /etc/hosts knows about management.priv.ovirt.org and physical.priv.ovirt.org, hostname is set properly, ... I have currently only 1 physical machine (2xIntel Xeon Quadcore, 8GB RAM, 4xnic,...). On this host (ovirtbr0 - 192.168.50.1, eth0 - 192.168.100.3), I have the 'appliance' running which is the 'management' station (eth0 - 192.168.50.2). Here is the log excerpt from db-omatic.log as requested. INFO Fri Apr 17 13:23:26 +0200 2009 (2276) dbomatic started. ERROR Fri Apr 17 13:23:36 +0200 2009 (2276) Unable to determine qpid server fromm DNS SRV record, retrying.. INFO Fri Apr 17 13:23:41 +0200 2009 (2276) Connecting to amqp://management.priv.. ovirt.org:5672 ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) Error in db-omatic: SIGTERM ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) /usr/share/ovirt-server/db-omatic/dbb _omatic.rb:433:in `sleep'/usr/share/ovirt-server/db-omatic/db_omatic.rb:433:in `` check_heartbeats'/usr/share/ovirt-server/db-omatic/db_omatic.rb:470:in `main'/uss r/share/ovirt-server/db-omatic/db_omatic.rb:474 INFO Fri Apr 17 15:45:18 +0200 2009 (2297) dbomatic started. ERROR Fri Apr 17 15:45:28 +0200 2009 (2297) Unable to determine qpid server fromm DNS SRV record, retrying.. INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Connecting to amqp://management.priv.. ovirt.org:5672 INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Marking host physical.priv.ovirt.org unavailable regards, Ingmar Joey Boggs wrote: > > Can you also grab the contents of /var/log/ovirt-server/db-omatic.log > from the appliance? > > Just to make sure, your node is the physical machine running the appliance? > > > > Ingmar Schraub wrote: >> Hello, >> >> in addition to my trouble report from this morning, I further noticed in >> the logs the following: >> >> HOST: >> ----- >> Apr 17 14:15:25 physical libvirt-qpid: GSSAPI Error: Unspecified GSS >> failure. Minor code may provide more information (No credentials cache >> found) >> >> ovirt-appliance: >> ---------------- >> Apr 17 14:15:25 management qpidd[2162]: 2009-apr-17 14:15:25 warning >> Client closed connection with 501: internal-error: Sasl error: SASL(-1): >> generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may >> provide more information (No credentials cache found) >> (qpid/client/SaslFactory.cpp:226) >> >> It seems like the authentication fails and therefore the appliances >> doesn't 'see' the host. >> >> Does anybody know whether this is a libvirt-qpid problem or a qpidd >> problem or some wrong configuration in ovirt? Is this a known issue or >> did I hit something new? >> >> I am really stuck here... >> >> Thanks a lot and best regards, >> >> Ingmar >> >> ------------------------------------------------------------------------ >> >> Subject: >> host not shown in default hardware pool >> From: >> Ingmar Schraub >> Date: >> Fri, 17 Apr 2009 10:49:33 +0200 >> To: >> ovirt-devel at redhat.com >> >> To: >> ovirt-devel at redhat.com >> >> >> Hello, >> >> I am new to ovirt and please bare with me if my question has been asked >> before. I googled, studied the wiki and searched the bug list. But I >> couldn't find anything similar. >> >> I've just set up a new server with F10, fully patched and installed >> ovirt using the Rawhide build instructions. >> >> All seems to work nicely, but I am stuck at one point. >> >> After 'sudo ovirt-install-node-stateful' followed by a host reboot I >> started the appliance again. My problem is that the host is not shown at >> all in the default hardware pool. Any hints what's going wrong here? >> What could be missing that the appliance doesn't see my host? >> Networking, bridge, etc. is all ok. >> >> I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the >> ovirt-appliance httpd doesn't start with the config file provided. There >> is already a ticket open on bugzilla. (#489819). >> >> Thanks a lot in advance. >> >> regards, >> >> Ingmar >> >> >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> Ovirt-devel mailing list >> Ovirt-devel at redhat.com >> https://www.redhat.com/mailman/listinfo/ovirt-devel >> > From jboggs at redhat.com Fri Apr 17 14:23:31 2009 From: jboggs at redhat.com (Joey Boggs) Date: Fri, 17 Apr 2009 10:23:31 -0400 Subject: [Ovirt-devel] [Fwd: host not shown in default hardware pool] In-Reply-To: <49E88EDF.2010703@eseco.de> References: <49E8757E.5000707@eseco.de> <49E88984.1010709@redhat.com> <49E88EDF.2010703@eseco.de> Message-ID: <49E890E3.1020202@redhat.com> On the node try running: dig +short srv _ovirt._tcp.priv.ovirt.org it should return the ip address of your appliance, that could cause the gssapi errors since it's not able to find to the server. Also on the node can you attach /var/log/ovirt.log which will let us know what's going on when the ovirt services start. Ingmar Schraub wrote: > Interesting... the host shows now up after running "ovirt-identify-node > -v -s 192.168.50.2 -p 12120". It is unavailable though. > > I shut the appliance down, re-started libvirtd on the host, powered the > appliance back on. Host is still unavailable. > > I ran the test "ruby /usr/share/ovirt-server/qmf-libvirt-example.rb", > but this gave me only > Connecting to amqp://management.priv.ovirt.org:5672.. > ---------------------------- > ---------------------------- > > I believe that the kerberos authentication fails (as the logs I provided > indicate). But why? date/time is in sync on host/appliance. /etc/hosts > knows about management.priv.ovirt.org and physical.priv.ovirt.org, > hostname is set properly, ... > > I have currently only 1 physical machine (2xIntel Xeon Quadcore, 8GB > RAM, 4xnic,...). On this host (ovirtbr0 - 192.168.50.1, eth0 - > 192.168.100.3), I have the 'appliance' running which is the 'management' > station (eth0 - 192.168.50.2). > > > Here is the log excerpt from db-omatic.log as requested. > > INFO Fri Apr 17 13:23:26 +0200 2009 (2276) dbomatic started. > ERROR Fri Apr 17 13:23:36 +0200 2009 (2276) Unable to determine qpid > server fromm > DNS SRV record, retrying.. > INFO Fri Apr 17 13:23:41 +0200 2009 (2276) Connecting to > amqp://management.priv.. > ovirt.org:5672 > ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) Error in db-omatic: SIGTERM > ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) > /usr/share/ovirt-server/db-omatic/dbb > _omatic.rb:433:in > `sleep'/usr/share/ovirt-server/db-omatic/db_omatic.rb:433:in `` > check_heartbeats'/usr/share/ovirt-server/db-omatic/db_omatic.rb:470:in > `main'/uss > r/share/ovirt-server/db-omatic/db_omatic.rb:474 > INFO Fri Apr 17 15:45:18 +0200 2009 (2297) dbomatic started. > ERROR Fri Apr 17 15:45:28 +0200 2009 (2297) Unable to determine qpid > server fromm > DNS SRV record, retrying.. > INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Connecting to > amqp://management.priv.. > ovirt.org:5672 > INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Marking host > physical.priv.ovirt.org > unavailable > > regards, > > Ingmar > > > Joey Boggs wrote: > >> Can you also grab the contents of /var/log/ovirt-server/db-omatic.log >> from the appliance? >> >> Just to make sure, your node is the physical machine running the appliance? >> >> >> >> Ingmar Schraub wrote: >> >>> Hello, >>> >>> in addition to my trouble report from this morning, I further noticed in >>> the logs the following: >>> >>> HOST: >>> ----- >>> Apr 17 14:15:25 physical libvirt-qpid: GSSAPI Error: Unspecified GSS >>> failure. Minor code may provide more information (No credentials cache >>> found) >>> >>> ovirt-appliance: >>> ---------------- >>> Apr 17 14:15:25 management qpidd[2162]: 2009-apr-17 14:15:25 warning >>> Client closed connection with 501: internal-error: Sasl error: SASL(-1): >>> generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may >>> provide more information (No credentials cache found) >>> (qpid/client/SaslFactory.cpp:226) >>> >>> It seems like the authentication fails and therefore the appliances >>> doesn't 'see' the host. >>> >>> Does anybody know whether this is a libvirt-qpid problem or a qpidd >>> problem or some wrong configuration in ovirt? Is this a known issue or >>> did I hit something new? >>> >>> I am really stuck here... >>> >>> Thanks a lot and best regards, >>> >>> Ingmar >>> >>> ------------------------------------------------------------------------ >>> >>> Subject: >>> host not shown in default hardware pool >>> From: >>> Ingmar Schraub >>> Date: >>> Fri, 17 Apr 2009 10:49:33 +0200 >>> To: >>> ovirt-devel at redhat.com >>> >>> To: >>> ovirt-devel at redhat.com >>> >>> >>> Hello, >>> >>> I am new to ovirt and please bare with me if my question has been asked >>> before. I googled, studied the wiki and searched the bug list. But I >>> couldn't find anything similar. >>> >>> I've just set up a new server with F10, fully patched and installed >>> ovirt using the Rawhide build instructions. >>> >>> All seems to work nicely, but I am stuck at one point. >>> >>> After 'sudo ovirt-install-node-stateful' followed by a host reboot I >>> started the appliance again. My problem is that the host is not shown at >>> all in the default hardware pool. Any hints what's going wrong here? >>> What could be missing that the appliance doesn't see my host? >>> Networking, bridge, etc. is all ok. >>> >>> I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the >>> ovirt-appliance httpd doesn't start with the config file provided. There >>> is already a ticket open on bugzilla. (#489819). >>> >>> Thanks a lot in advance. >>> >>> regards, >>> >>> Ingmar >>> >>> >>> ------------------------------------------------------------------------ >>> >>> _______________________________________________ >>> Ovirt-devel mailing list >>> Ovirt-devel at redhat.com >>> https://www.redhat.com/mailman/listinfo/ovirt-devel >>> >>> From is at eseco.de Fri Apr 17 14:46:23 2009 From: is at eseco.de (Ingmar Schraub) Date: Fri, 17 Apr 2009 16:46:23 +0200 Subject: [Ovirt-devel] [Fwd: host not shown in default hardware pool] In-Reply-To: <49E890E3.1020202@redhat.com> References: <49E8757E.5000707@eseco.de> <49E88984.1010709@redhat.com> <49E88EDF.2010703@eseco.de> <49E890E3.1020202@redhat.com> Message-ID: <49E8963F.7050109@eseco.de> [root at physical log]# dig +short srv _ovirt._tcp.priv.ovirt.org 0 0 80 management.priv.ovirt.org. dns seems to be ok. I verified on host/node + managment that the resolvers point to .50.1 and .50.2. and the srv/a resolves properly. physical keeps saying: Apr 17 16:35:48 physical libvirt-qpid: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found) management keeps saying: Apr 17 16:35:48 management qpidd[2158]: 2009-apr-17 16:35:48 warning Client closed connection with 501: internal-error: Sasl error: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found) (qpid/client/SaslFactory.cpp:226) On physical I do not have a /var/log/ovirt.log (neither on management). I have: [root at management log]# ll ovirt-server/ total 968 -rw-r--r-- 1 ovirt ovirt 6048 2009-04-17 16:32 db-omatic.log -rw-rw-rw- 1 root root 9400 2009-04-17 15:40 host-browser.log -rw-r--r-- 1 ovirt ovirt 5263 2009-04-17 16:32 mongrel.log -rw-r--r-- 1 ovirt ovirt 950770 2009-04-17 16:38 rails.log -rw-r--r-- 1 ovirt ovirt 3783 2009-04-17 16:32 taskomatic.log and [root at physical log]# ll ovirt-host.log -rw-r--r-- 1 root root 0 2009-04-16 16:24 ovirt-host.log Probably most information goes into /var/log/messages? I've been running also the following test: service libvirt-qpid stop export QPID_TRACE=1 libvirt-qpid --broker Please see the output attached as file. Any further ideas? Why is the kerberos failing? The client side gives up. That's what I read from the logs. regards, Ingmar Joey Boggs wrote: > > On the node try running: dig +short srv _ovirt._tcp.priv.ovirt.org > it should return the ip address of your appliance, that could cause the > gssapi errors since it's not able to find to the server. Also on the > node can you attach /var/log/ovirt.log which will let us know what's > going on when the ovirt services start. > > > > Ingmar Schraub wrote: >> Interesting... the host shows now up after running "ovirt-identify-node >> -v -s 192.168.50.2 -p 12120". It is unavailable though. >> >> I shut the appliance down, re-started libvirtd on the host, powered the >> appliance back on. Host is still unavailable. >> >> I ran the test "ruby /usr/share/ovirt-server/qmf-libvirt-example.rb", >> but this gave me only >> Connecting to amqp://management.priv.ovirt.org:5672.. >> ---------------------------- >> ---------------------------- >> >> I believe that the kerberos authentication fails (as the logs I provided >> indicate). But why? date/time is in sync on host/appliance. /etc/hosts >> knows about management.priv.ovirt.org and physical.priv.ovirt.org, >> hostname is set properly, ... >> >> I have currently only 1 physical machine (2xIntel Xeon Quadcore, 8GB >> RAM, 4xnic,...). On this host (ovirtbr0 - 192.168.50.1, eth0 - >> 192.168.100.3), I have the 'appliance' running which is the 'management' >> station (eth0 - 192.168.50.2). >> >> >> Here is the log excerpt from db-omatic.log as requested. >> >> INFO Fri Apr 17 13:23:26 +0200 2009 (2276) dbomatic started. >> ERROR Fri Apr 17 13:23:36 +0200 2009 (2276) Unable to determine qpid >> server fromm >> DNS SRV record, retrying.. >> INFO Fri Apr 17 13:23:41 +0200 2009 (2276) Connecting to >> amqp://management.priv.. >> ovirt.org:5672 >> ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) Error in db-omatic: SIGTERM >> ERROR Fri Apr 17 15:43:26 +0200 2009 (2276) >> /usr/share/ovirt-server/db-omatic/dbb >> _omatic.rb:433:in >> `sleep'/usr/share/ovirt-server/db-omatic/db_omatic.rb:433:in `` >> check_heartbeats'/usr/share/ovirt-server/db-omatic/db_omatic.rb:470:in >> `main'/uss >> r/share/ovirt-server/db-omatic/db_omatic.rb:474 >> INFO Fri Apr 17 15:45:18 +0200 2009 (2297) dbomatic started. >> ERROR Fri Apr 17 15:45:28 +0200 2009 (2297) Unable to determine qpid >> server fromm >> DNS SRV record, retrying.. >> INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Connecting to >> amqp://management.priv.. >> ovirt.org:5672 >> INFO Fri Apr 17 15:45:33 +0200 2009 (2297) Marking host >> physical.priv.ovirt.org >> unavailable >> >> regards, >> >> Ingmar >> >> >> Joey Boggs wrote: >> >>> Can you also grab the contents of /var/log/ovirt-server/db-omatic.log >>> from the appliance? >>> >>> Just to make sure, your node is the physical machine running the >>> appliance? >>> >>> >>> >>> Ingmar Schraub wrote: >>> >>>> Hello, >>>> >>>> in addition to my trouble report from this morning, I further >>>> noticed in >>>> the logs the following: >>>> >>>> HOST: >>>> ----- >>>> Apr 17 14:15:25 physical libvirt-qpid: GSSAPI Error: Unspecified GSS >>>> failure. Minor code may provide more information (No credentials cache >>>> found) >>>> >>>> ovirt-appliance: >>>> ---------------- >>>> Apr 17 14:15:25 management qpidd[2162]: 2009-apr-17 14:15:25 warning >>>> Client closed connection with 501: internal-error: Sasl error: >>>> SASL(-1): >>>> generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may >>>> provide more information (No credentials cache found) >>>> (qpid/client/SaslFactory.cpp:226) >>>> >>>> It seems like the authentication fails and therefore the appliances >>>> doesn't 'see' the host. >>>> >>>> Does anybody know whether this is a libvirt-qpid problem or a qpidd >>>> problem or some wrong configuration in ovirt? Is this a known issue or >>>> did I hit something new? >>>> >>>> I am really stuck here... >>>> >>>> Thanks a lot and best regards, >>>> >>>> Ingmar >>>> >>>> ------------------------------------------------------------------------ >>>> >>>> >>>> Subject: >>>> host not shown in default hardware pool >>>> From: >>>> Ingmar Schraub >>>> Date: >>>> Fri, 17 Apr 2009 10:49:33 +0200 >>>> To: >>>> ovirt-devel at redhat.com >>>> >>>> To: >>>> ovirt-devel at redhat.com >>>> >>>> >>>> Hello, >>>> >>>> I am new to ovirt and please bare with me if my question has been asked >>>> before. I googled, studied the wiki and searched the bug list. But I >>>> couldn't find anything similar. >>>> >>>> I've just set up a new server with F10, fully patched and installed >>>> ovirt using the Rawhide build instructions. >>>> >>>> All seems to work nicely, but I am stuck at one point. >>>> >>>> After 'sudo ovirt-install-node-stateful' followed by a host reboot I >>>> started the appliance again. My problem is that the host is not >>>> shown at >>>> all in the default hardware pool. Any hints what's going wrong here? >>>> What could be missing that the appliance doesn't see my host? >>>> Networking, bridge, etc. is all ok. >>>> >>>> I had also to tweak /etc/httpd/conf.d/ovirt-server.conf because the >>>> ovirt-appliance httpd doesn't start with the config file provided. >>>> There >>>> is already a ticket open on bugzilla. (#489819). >>>> >>>> Thanks a lot in advance. >>>> >>>> regards, >>>> >>>> Ingmar >>>> >>>> >>>> ------------------------------------------------------------------------ >>>> >>>> >>>> _______________________________________________ >>>> Ovirt-devel mailing list >>>> Ovirt-devel at redhat.com >>>> https://www.redhat.com/mailman/listinfo/ovirt-devel >>>> > -------------- next part -------------- A non-text attachment was scrubbed... Name: libvirtqpid.log Type: text/x-log Size: 8982 bytes Desc: not available URL: From mmorsi at redhat.com Mon Apr 20 14:46:46 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Mon, 20 Apr 2009 10:46:46 -0400 Subject: [Ovirt-devel] [PATCH server] fix incorrect forward vnc url in vm details pane Message-ID: <1240238806-3212-1-git-send-email-mmorsi@redhat.com> use javascript to grab the url from the browser and use that instead of generating it server side --- src/app/views/vm/show.rhtml | 13 +++++++++---- src/public/javascripts/ovirt.js | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/app/views/vm/show.rhtml b/src/app/views/vm/show.rhtml index add29b4..dffcb7b 100644 --- a/src/app/views/vm/show.rhtml +++ b/src/app/views/vm/show.rhtml @@ -88,7 +88,8 @@
    Uuid:
    - <%= @vm.forward_vnc ? "VNC uri:
    " : "" %> + <%= @vm.forward_vnc && @vm.state == Vm::STATE_RUNNING ? + "VNC uri:
    " : "" %> Num vcpus allocated:
    Num vcpus used:
    Memory allocated:
    @@ -101,9 +102,13 @@
    <%=h @vm.uuid %>
    - <%= url = request.url - url = request.url[0..(url.index('/', 8) - 1)] + ":" + @vm.forward_vnc_port.to_s - @vm.forward_vnc ? (url + "
    ") : "" %> + <% if @vm.forward_vnc && @vm.state == Vm::STATE_RUNNING %> +
    + + <% end %> <%=h @vm.num_vcpus_allocated %>
    <%=h @vm.num_vcpus_used %>
    <%=h @vm.memory_allocated_in_mb %> MB
    diff --git a/src/public/javascripts/ovirt.js b/src/public/javascripts/ovirt.js index c24df16..b06f33e 100644 --- a/src/public/javascripts/ovirt.js +++ b/src/public/javascripts/ovirt.js @@ -380,4 +380,18 @@ var VmCreator = { VmCreator.recreateTree(storedOptions); VmCreator.clickCheckboxes(); } -} \ No newline at end of file +} + +// retreives server from url +function get_server_from_url() +{ + var regexS = "https.*" + var regex = new RegExp(regexS); + var results = regex.exec( window.location.href ); + var start = 8; + if(results == null){ + start = 7; + } + var end = window.location.href.indexOf('/', 8) - start; + return window.location.href.substr(start, end); +} -- 1.6.0.6 From dpierce at redhat.com Fri Apr 17 19:10:39 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 17 Apr 2009 15:10:39 -0400 Subject: [Ovirt-devel] [PATCH node] Fixed where sending no NICs returned an error result. Message-ID: <1239995439-12072-1-git-send-email-dpierce@redhat.com> If there are no NICs to send, then the result is set to success and then returned. If no NICs were sent due to the only NIC found being ignored, then a default success is returned. Otherwise, processing NICs works as desired. Signed-off-by: Darryl L. Pierce --- ovirt-identify-node/protocol.c | 48 ++++++++++++++++++++++++--------------- 1 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ovirt-identify-node/protocol.c b/ovirt-identify-node/protocol.c index 0382dac..1099ebb 100644 --- a/ovirt-identify-node/protocol.c +++ b/ovirt-identify-node/protocol.c @@ -176,26 +176,36 @@ send_nic_details(void) nic_info_ptr current = nic_info; - while (current != NULL) { - if((!management_interface) || (strcmp(management_interface, current->iface_name))) { - send_text("NIC"); - - if (!(get_text("NICINFO?")) && - (!send_value("MAC", current->mac_address)) && - (!send_value("BANDWIDTH", current->bandwidth)) && - (!send_value("IFACE_NAME", current->iface_name)) && - (!send_value("IP_ADDRESS", current->ip_address)) && - (!send_value("NETMASK", current->netmask)) && - (!send_value("BROADCAST", current->broadcast))) { - send_text("ENDNIC"); - result = get_text("ACK NIC"); - } - - current = current->next; - } else { - current = current->next; + /* only send NIC details if we found NICs to process */ + if(current) { + int sent_count = 0; + while (current != NULL) { + if((!management_interface) || (strcmp(management_interface, current->iface_name))) { + send_text("NIC"); + + if (!(get_text("NICINFO?")) && + (!send_value("MAC", current->mac_address)) && + (!send_value("BANDWIDTH", current->bandwidth)) && + (!send_value("IFACE_NAME", current->iface_name)) && + (!send_value("IP_ADDRESS", current->ip_address)) && + (!send_value("NETMASK", current->netmask)) && + (!send_value("BROADCAST", current->broadcast))) { + send_text("ENDNIC"); + result = get_text("ACK NIC"); + sent_count++; + } + + current = current->next; + } else { + current = current->next; + } } - } + + /* if no nics were sent, then set default success */ + if( sent_count == 0) + result = 0; + + } else { result = 0; } return result; } -- 1.6.0.6 From sseago at redhat.com Mon Apr 20 15:13:13 2009 From: sseago at redhat.com (Scott Seago) Date: Mon, 20 Apr 2009 15:13:13 +0000 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. Message-ID: <1240240393-5759-1-git-send-email-sseago@redhat.com> This code is based on David Lutterkort's proposal outlined in https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html I've included service-layer methods for show, create, update, destroy, vm_action, and cancel_queued_tasks. These are the concrete actions that make sense as part of the API. Most of the remaining vm_controller methods are pure-WUI actions -- for things such as generating the web form for a new VM (the subsequent 'create' action _is_ part of the API). There's a certain amount of temporary code that we need in place while only some of the controllers have been converted, as we still need permissions pre-filters for non-converted create, etc. methods -- but for the converted controllers we don't want to perform actions in before_filters that will be done as part of the services layer. Any temporary methods, etc. that will go away when the last controller is converted have been marked clearly with FIXME comments. Signed-off-by: Scott Seago --- src/app/controllers/application.rb | 113 +++++++---- src/app/controllers/hardware_controller.rb | 3 +- src/app/controllers/host_controller.rb | 4 +- src/app/controllers/nic_controller.rb | 2 +- src/app/controllers/permission_controller.rb | 12 +- src/app/controllers/pool_controller.rb | 2 +- src/app/controllers/quota_controller.rb | 4 +- src/app/controllers/storage_controller.rb | 5 +- src/app/controllers/storage_volume_controller.rb | 6 +- src/app/controllers/task_controller.rb | 9 +- src/app/controllers/vm_controller.rb | 230 +++++----------------- src/app/models/vm.rb | 1 + src/app/services/application_service.rb | 56 ++++++ src/app/services/vm_service.rb | 189 ++++++++++++++++++ src/app/views/vm/_form.rhtml | 3 +- 15 files changed, 394 insertions(+), 245 deletions(-) create mode 100644 src/app/services/application_service.rb create mode 100644 src/app/services/vm_service.rb diff --git a/src/app/controllers/application.rb b/src/app/controllers/application.rb index fa88773..34283ec 100644 --- a/src/app/controllers/application.rb +++ b/src/app/controllers/application.rb @@ -20,19 +20,35 @@ # Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. +# FIXME: once all controller classes include this, remove here +require 'services/vm_service' + class ApplicationController < ActionController::Base + # FIXME: once all controller classes include this, remove here + include ApplicationService + # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_ovirt_session_id' init_gettext "ovirt" layout :choose_layout + # FIXME: once service layer is complete, the following before_filters will be + # removed as their functionality has been moved to the service layer + # pre_create + # pre_edit will remain only for :edit, not :update or :destroy + # pre_show + # authorize_admin will remain only for :new, :edit before_filter :pre_new, :only => [:new] before_filter :pre_create, :only => [:create] - before_filter :pre_edit, :only => [:edit, :update, :destroy] + before_filter :pre_edit, :only => [:edit] + # the following is to facilitate transition to service layer + before_filter :tmp_pre_update, :only => [:update, :destroy] before_filter :pre_show, :only => [:show] - before_filter :authorize_admin, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authorize_admin, :only => [:new, :edit] + before_filter :tmp_authorize_admin, :only => [:create, :update, :destroy] before_filter :is_logged_in, :get_help_section + def choose_layout if(params[:component_layout]) return (ENV["RAILS_ENV"] != "production")?'components/' << params[:component_layout]:'redux' @@ -61,62 +77,66 @@ class ApplicationController < ActionController::Base (ENV["RAILS_ENV"] == "production") ? session[:user] : "ovirtadmin" end - def set_perms(hwpool) - @user = get_login_user - @can_view = hwpool.can_view(@user) - @can_control_vms = hwpool.can_control_vms(@user) - @can_modify = hwpool.can_modify(@user) - @can_view_perms = hwpool.can_view_perms(@user) - @can_set_perms = hwpool.can_set_perms(@user) - end - protected # permissions checking def pre_new end - def pre_create - end def pre_edit end + + # FIXME: remove these when service layer transition is complete + def tmp_pre_update + pre_edit + end + def tmp_authorize_admin + authorize_admin + end + def pre_create + end def pre_show end + def authorize_view(msg=nil) + authorize_action(Privilege::VIEW,msg) + end def authorize_user(msg=nil) - authorize_action(false,msg) + authorize_action(Privilege::VM_CONTROL,msg) end def authorize_admin(msg=nil) - authorize_action(true,msg) - end - def authorize_action(is_modify_action, msg=nil) - msg ||= 'You do not have permission to create or modify this item ' - if @perm_obj - set_perms(@perm_obj) - unless (is_modify_action ? @can_modify : @can_control_vms) - respond_to do |format| - format.html do - @title = "Access denied" - @errmsg = msg - @ajax = params[:ajax] - @nolayout = params[:nolayout] - if @ajax - render :template => 'layouts/popup-error', :layout => 'tabs-and-content' - elsif @nolayout - render :template => 'layouts/popup-error', :layout => 'help-and-content' - else - render :template => 'layouts/popup-error', :layout => 'popup' - end - end - format.json do - @json_hash ||= {} - @json_hash[:success] = false - @json_hash[:alert] = msg - render :json => @json_hash - end - format.xml { head :forbidden } + authorize_action(Privilege::MODIFY,msg) + end + def authorize_action(privilege, msg=nil) + msg ||= 'You have insufficient privileges to perform action.' + unless authorized?(privilege) + handle_auth_error(msg) + false + else + true + end + end + def handle_auth_error(msg) + respond_to do |format| + format.html do + @title = "Access denied" + @errmsg = msg + @ajax = params[:ajax] + @nolayout = params[:nolayout] + if @ajax + render :template => 'layouts/popup-error', :layout => 'tabs-and-content' + elsif @nolayout + render :template => 'layouts/popup-error', :layout => 'help-and-content' + else + render :template => 'layouts/popup-error', :layout => 'popup' end - false end + format.json do + @json_hash ||= {} + @json_hash[:success] = false + @json_hash[:alert] = msg + render :json => @json_hash + end + format.xml { head :forbidden } end end @@ -155,6 +175,11 @@ class ApplicationController < ActionController::Base render :json => json_hash(full_items, attributes, arg_list, find_opts, id_method).to_json end - + def json_error(obj_type, obj, exception) + json_hash = { :object => obj_type, :success => false} + json_hash[:errors] = obj.errors.localize_error_messages.to_a if obj + json_hash[:alert] = exception.message if obj.errors.size == 0 + render :json => json_hash + end end diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb index 726e5bd..5615f6e 100644 --- a/src/app/controllers/hardware_controller.rb +++ b/src/app/controllers/hardware_controller.rb @@ -70,7 +70,8 @@ class HardwareController < PoolController id = params[:id] if id @pool = Pool.find(id) - set_perms(@pool) + @perm_obj = @pool + set_perms unless @pool.has_privilege(@user, privilege) flash[:notice] = 'You do not have permission to access this hardware pool: redirecting to top level' redirect_to :controller => "dashboard" diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb index f0b8c2b..ad3bde4 100644 --- a/src/app/controllers/host_controller.rb +++ b/src/app/controllers/host_controller.rb @@ -53,7 +53,7 @@ class HostController < ApplicationController def show - set_perms(@perm_obj) + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this host: redirecting to top level' #perm errors for ajax should be done differently @@ -68,7 +68,7 @@ class HostController < ApplicationController def quick_summary pre_show - set_perms(@perm_obj) + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this host: redirecting to top level' #perm errors for ajax should be done differently diff --git a/src/app/controllers/nic_controller.rb b/src/app/controllers/nic_controller.rb index 85d4315..6319dbe 100644 --- a/src/app/controllers/nic_controller.rb +++ b/src/app/controllers/nic_controller.rb @@ -23,7 +23,7 @@ class NicController < ApplicationController :redirect_to => { :controller => 'dashboard' } def show - set_perms(@perm_obj) + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this NIC: redirecting to top level' redirect_to :controller => 'pool', :action => 'list' diff --git a/src/app/controllers/permission_controller.rb b/src/app/controllers/permission_controller.rb index 3bfbffa..9914fb7 100644 --- a/src/app/controllers/permission_controller.rb +++ b/src/app/controllers/permission_controller.rb @@ -28,7 +28,8 @@ class PermissionController < ApplicationController def show @permission = Permission.find(params[:id]) - set_perms(@permission.pool) + @perm_obj = @permission.pool + set_perms # admin permission required to view permissions unless @can_view_perms flash[:notice] = 'You do not have permission to view this permission record' @@ -43,7 +44,8 @@ class PermissionController < ApplicationController filter = @pool.permissions.collect{ |permission| permission.uid } @users = Account.names(filter) @roles = Role.find(:all).collect{ |role| [role.name, role.id] } - set_perms(@permission.pool) + @perm_obj = @permission.pool + set_perms # admin permission required to view permissions unless @can_set_perms flash[:notice] = 'You do not have permission to create this permission record' @@ -55,7 +57,8 @@ class PermissionController < ApplicationController def create @permission = Permission.new(params[:permission]) - set_perms(@permission.pool) + @perm_obj = @permission.pool + set_perms unless @can_set_perms # FIXME: need to handle proper error messages w/ ajax flash[:notice] = 'You do not have permission to create this permission record' @@ -117,7 +120,8 @@ class PermissionController < ApplicationController def destroy @permission = Permission.find(params[:id]) - set_perms(@permission.pool) + @perm_obj = @permission.pool + set_perms unless @can_set_perms flash[:notice] = 'You do not have permission to delete this permission record' redirect_to_parent diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb index 22cf1a4..018f2cd 100644 --- a/src/app/controllers/pool_controller.rb +++ b/src/app/controllers/pool_controller.rb @@ -123,7 +123,7 @@ class PoolController < ApplicationController def pre_show @perm_obj = @pool @current_pool_id=@pool.id - set_perms(@perm_obj) + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this pool: redirecting to top level' respond_to do |format| diff --git a/src/app/controllers/quota_controller.rb b/src/app/controllers/quota_controller.rb index 17fdc20..220792b 100644 --- a/src/app/controllers/quota_controller.rb +++ b/src/app/controllers/quota_controller.rb @@ -28,7 +28,7 @@ class QuotaController < ApplicationController def show @quota = Quota.find(params[:id]) - set_perms(@quota.pool) + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this quota: redirecting to top level' @@ -91,7 +91,7 @@ class QuotaController < ApplicationController end def pre_show @quota = Quota.find(params[:id]) - @perm_obj = @quota + @perm_obj = @quota.pool end def pre_edit @quota = Quota.find(params[:id]) diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb index 98ba0f6..2232388 100644 --- a/src/app/controllers/storage_controller.rb +++ b/src/app/controllers/storage_controller.rb @@ -46,7 +46,7 @@ class StorageController < ApplicationController @attach_to_pool=params[:attach_to_pool] if @attach_to_pool pool = HardwarePool.find(@attach_to_pool) - set_perms(pool) + @perm_obj = pool unless @can_view flash[:notice] = 'You do not have permission to view this storage pool list: redirecting to top level' redirect_to :controller => 'dashboard' @@ -70,7 +70,8 @@ class StorageController < ApplicationController def show @storage_pool = StoragePool.find(params[:id]) - set_perms(@storage_pool.hardware_pool) + @perm_obj = @storage_pool.hardware_pool + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this storage pool: redirecting to top level' respond_to do |format| diff --git a/src/app/controllers/storage_volume_controller.rb b/src/app/controllers/storage_volume_controller.rb index 9b0b9e0..f78071f 100644 --- a/src/app/controllers/storage_volume_controller.rb +++ b/src/app/controllers/storage_volume_controller.rb @@ -92,7 +92,8 @@ class StorageVolumeController < ApplicationController def show @storage_volume = StorageVolume.find(params[:id]) - set_perms(@storage_volume.storage_pool.hardware_pool) + @perm_obj = @storage_volume.storage_pool.hardware_pool + set_perms @storage_pool = @storage_volume.storage_pool unless @can_view flash[:notice] = 'You do not have permission to view this storage volume: redirecting to top level' @@ -117,7 +118,8 @@ class StorageVolumeController < ApplicationController def destroy @storage_volume = StorageVolume.find(params[:id]) - set_perms(@storage_volume.storage_pool.hardware_pool) + @perm_obj = @storage_volume.storage_pool.hardware_pool + set_perms unless @can_modify and @storage_volume.storage_pool.user_subdividable respond_to do |format| format.json { render :json => { :object => "storage_volume", diff --git a/src/app/controllers/task_controller.rb b/src/app/controllers/task_controller.rb index 647d69c..618856c 100644 --- a/src/app/controllers/task_controller.rb +++ b/src/app/controllers/task_controller.rb @@ -21,14 +21,15 @@ class TaskController < ApplicationController def show @task = Task.find(params[:id]) if @task[:type] == VmTask.name - set_perms(@task.vm.vm_resource_pool) + @perm_obj = @task.vm.vm_resource_pool elsif @task[:type] == StorageTask.name - set_perms(@task.storage_pool.hardware_pool) + @perm_obj = @task.storage_pool.hardware_pool elsif @task[:type] == StorageVolumeTask.name - set_perms(@task.storage_volume.storage_pool.hardware_pool) + @perm_obj = @task.storage_volume.storage_pool.hardware_pool elsif @task[:type] == HostTask.name - set_perms(@task.host.hardware_pool) + @perm_obj = @task.host.hardware_pool end + set_perms unless @can_view flash[:notice] = 'You do not have permission to view this task: redirecting to top level' redirect_to :controller => 'dashboard' diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb index a81f6b5..fc55d92 100644 --- a/src/app/controllers/vm_controller.rb +++ b/src/app/controllers/vm_controller.rb @@ -17,13 +17,16 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. require 'socket' +require 'services/vm_service' class VmController < ApplicationController + include VmService + # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :controller => 'dashboard' } - before_filter :pre_vm_action, :only => [:vm_action, :cancel_queued_tasks, :console] + before_filter :pre_console, :only => [:console] def index @vms = Vm.find(:all, @@ -38,13 +41,13 @@ class VmController < ApplicationController end def show - set_perms(@perm_obj) - @actions = @vm.get_action_hash(@user) - unless @can_view - flash[:notice] = 'You do not have permission to view this vm: redirecting to top level' - redirect_to :controller => 'resources', :controller => 'dashboard' + begin + svc_show(params[:id]) + @actions = @vm.get_action_hash(@user) + render :layout => 'selection' + rescue PermissionError => perm_error + handle_auth_error(perm_error.message) end - render :layout => 'selection' end def add_to_smart_pool @@ -58,38 +61,15 @@ class VmController < ApplicationController end def create + params[:vm][:forward_vnc] = params[:forward_vnc] begin - Vm.transaction do - @vm.save! - _setup_vm_provision(params) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_CREATE_VM, - :state => Task::STATE_QUEUED}) - @task.save! - end - start_now = params[:start_now] - if (start_now) - if @vm.get_action_list.include?(VmTask::ACTION_START_VM) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - alert = "VM was successfully created. VM Start action queued." - else - alert = "VM was successfully created. Resources are not available to start VM now." - end - else - alert = "VM was successfully created." - end + alert = svc_create(params[:vm], params[:start_now]) render :json => { :object => "vm", :success => true, :alert => alert } + rescue PermissionError => perm_error + handle_auth_error(perm_error.message) rescue Exception => error - # FIXME: need to distinguish vm vs. task save errors (but should mostly be vm) - render :json => { :object => "vm", :success => false, - :errors => @vm.errors.localize_error_messages.to_a } + json_error("vm", @vm, error) end - end def edit @@ -98,58 +78,20 @@ class VmController < ApplicationController end def update + params[:vm][:forward_vnc] = params[:forward_vnc] begin - #needs restart if certain fields are changed (since those will only take effect the next startup) - needs_restart = false - unless @vm.get_pending_state == Vm::STATE_STOPPED - Vm::NEEDS_RESTART_FIELDS.each do |field| - unless @vm[field].to_s == params[:vm][field] - needs_restart = true - break - end - end - current_storage_ids = @vm.storage_volume_ids.sort - new_storage_ids = params[:vm][:storage_volume_ids] - new_storage_ids = [] unless new_storage_ids - new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } - needs_restart = true unless current_storage_ids == new_storage_ids - end - - params[:vm][:forward_vnc] = params[:forward_vnc] - params[:vm][:needs_restart] = 1 if needs_restart - @vm.update_attributes!(params[:vm]) - _setup_vm_provision(params) - - if (params[:start_now] and @vm.get_action_list.include?(VmTask::ACTION_START_VM) ) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - elsif ( params[:restart_now] and @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) ) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_SHUTDOWN_VM, - :state => Task::STATE_QUEUED}) - @task.save! - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - end - - - render :json => { :object => "vm", :success => true, - :alert => 'Vm was successfully updated.' } - rescue + alert = svc_update(params[:id], params[:vm], params[:start_now], + params[:restart_now]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue Exception => error # FIXME: need to distinguish vm vs. task save errors (but should mostly be vm) - render :json => { :object => "vm", :success => false, - :errors => @vm.errors.localize_error_messages.to_a } + json_error("vm", @vm, error) end end #FIXME: we need permissions checks. user must have permission. Also state checks + # this should probably be implemented as an action on the containing VM pool once + # that service module is defined def delete vm_ids_str = params[:vm_ids] vm_ids = vm_ids_str.split(",").collect {|x| x.to_i} @@ -181,15 +123,13 @@ class VmController < ApplicationController end def destroy - vm_resource_pool = @vm.vm_resource_pool_id - if (@vm.is_destroyable?) - destroy_cobbler_system(@vm) - @vm.destroy - render :json => { :object => "vm", :success => true, - :alert => "Virtual Machine was successfully deleted." } - else - render :json => { :object => "vm", :success => false, - :alert => "Vm must be stopped to delete it." } + begin + alert = svc_destroy(params[:id]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue ActionError => error + json_error("vm", @vm, error) + rescue Exception => error + json_error("vm", @vm, error) end end @@ -204,27 +144,23 @@ class VmController < ApplicationController end def vm_action - vm_action = params[:vm_action] - data = params[:vm_action_data] begin - if @vm.queue_action(get_login_user, vm_action, data) - render :json => { :object => "vm", :success => true, :alert => "#{vm_action} was successfully queued." } - else - render :json => { :object => "vm", :success => false, :alert => "#{vm_action} is an invalid action." } - end - rescue - render :json => { :object => "vm", :success => false, :alert => "Error in queueing #{vm_action}." } + alert = svc_vm_action(params[:id], params[:vm_action], + params[:vm_action_data]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue ActionError => error + json_error("vm", @vm, error) + rescue Exception => error + json_error("vm", @vm, error) end end def cancel_queued_tasks begin - Task.transaction do - @vm.tasks.queued.each { |task| task.cancel} - end - render :json => { :object => "vm", :success => true, :alert => "queued tasks were canceled." } - rescue - render :json => { :object => "vm", :success => true, :alert => "queued tasks cancel failed." } + alert = svc_cancel_queued_tasks(params[:id]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue Exception => error + json_error("vm", @vm, error) end end @@ -268,53 +204,10 @@ class VmController < ApplicationController end end - # FIXME: move this to an edit_vm task in taskomatic - def _setup_vm_provision(params) - # spaces are invalid in the cobbler name - name = params[:vm][:uuid] - mac = params[:vm][:vnic_mac_addr] - provision = params[:vm][:provisioning_and_boot_settings] - # determine what type of provisioning was selected for the VM - provisioning_type = :pxe_or_hd_type - provisioning_type = :image_type if provision.index "#{Vm::IMAGE_PREFIX}@#{Vm::COBBLER_PREFIX}" - provisioning_type = :system_type if provision.index "#{Vm::PROFILE_PREFIX}@#{Vm::COBBLER_PREFIX}" - - unless provisioning_type == :pxe_or_hd_type - cobbler_name = provision.slice(/(.*):(.*)/, 2) - system = Cobbler::System.find_one(name) - unless system - nic = Cobbler::NetworkInterface.new({'mac_address' => mac}) - - case provisioning_type - when :image_type: - system = Cobbler::System.new("name" => name, "image" => cobbler_name) - when :system_type: - system = Cobbler::System.new("name" => name, "profile" => cobbler_name) - end - - system.interfaces = [nic] - system.save - end - end - end - def pre_new - # if no vm_resource_pool is passed in, find (or auto-create) it based on hardware_pool_id unless params[:vm_resource_pool_id] - unless params[:hardware_pool_id] - flash[:notice] = "VM Resource Pool or Hardware Pool is required." - redirect_to :controller => 'dashboard' - end - @hardware_pool = HardwarePool.find(params[:hardware_pool_id]) - @user = get_login_user - vm_resource_pool = @hardware_pool.sub_vm_resource_pools.select {|pool| pool.name == @user}.first - if vm_resource_pool - params[:vm_resource_pool_id] = vm_resource_pool.id - else - @vm_resource_pool = VmResourcePool.new({:name => vm_resource_pool}) - @vm_resource_pool.tmp_parent = @hardware_pool - @vm_resource_pool_name = @user - end + flash[:notice] = "VM Resource Pool is required." + redirect_to :controller => 'dashboard' end # random MAC @@ -336,26 +229,6 @@ class VmController < ApplicationController @networks = Network.find(:all).collect{ |net| [net.name, net.id] } _setup_provisioning_options end - def pre_create - params[:vm][:state] = Vm::STATE_PENDING - vm_resource_pool_name = params[:vm_resource_pool_name] - hardware_pool_id = params[:hardware_pool_id] - if vm_resource_pool_name and hardware_pool_id - hardware_pool = HardwarePool.find(hardware_pool_id) - vm_resource_pool = VmResourcePool.new({:name => vm_resource_pool_name}) - vm_resource_pool.create_with_parent(hardware_pool) - params[:vm][:vm_resource_pool_id] = vm_resource_pool.id - end - params[:vm][:forward_vnc] = params[:forward_vnc] - @vm = Vm.new(params[:vm]) - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id - end - def pre_show - @vm = Vm.find(params[:id]) - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id - end def pre_edit @vm = Vm.find(params[:id]) @perm_obj = @vm.vm_resource_pool @@ -363,18 +236,15 @@ class VmController < ApplicationController @networks = Network.find(:all).collect{ |net| [net.name, net.id] } _setup_provisioning_options end - def pre_vm_action + def pre_console pre_edit authorize_user end - - private - - def destroy_cobbler_system(vm) - # Destroy the Cobbler system first if it's defined - if vm.uses_cobbler? - system = Cobbler::System.find_one(vm.cobbler_system_name) - system.remove if system - end + # FIXME: remove these when service transition is complete. these are here + # to keep from running permissions checks and other setup steps twice + def tmp_pre_update + end + def tmp_authorize_admin end + end diff --git a/src/app/models/vm.rb b/src/app/models/vm.rb index c62595a..4c7925c 100644 --- a/src/app/models/vm.rb +++ b/src/app/models/vm.rb @@ -220,6 +220,7 @@ class Vm < ActiveRecord::Base self[:boot_device]= BOOT_DEV_HD self[:provisioning]= nil else + # FIXME: Should this case trigger an error instead? self[:boot_device]= BOOT_DEV_NETWORK self[:provisioning]= settings end diff --git a/src/app/services/application_service.rb b/src/app/services/application_service.rb new file mode 100644 index 0000000..04f5196 --- /dev/null +++ b/src/app/services/application_service.rb @@ -0,0 +1,56 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Written by Scott Seago , +# David Lutterkort +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# +# Common infrastructure for business logic for WUI and QMF +# +# We call objects in the mid-level API 'Service' for lack of a better name. +# The Service layer is all in modules that are included by the classes that +# use them in the WUI and the QMF controllers. They set instance variables, +# which automatically become instance variables on the controllers that use +# the Service modules + +module ApplicationService + class PermissionError < RuntimeError; end + class ActionError < RuntimeError; end + + # Including class must provide a GET_LOGIN_USER + + def set_perms + @user = get_login_user + @can_view = @perm_obj.can_view(@user) + @can_control_vms = @perm_obj.can_control_vms(@user) + @can_modify = @perm_obj.can_modify(@user) + @can_view_perms = @perm_obj.can_view_perms(@user) + @can_set_perms = @perm_obj.can_set_perms(@user) + end + + def authorized?(privilege) + return false unless @perm_obj + set_perms + return @perm_obj.has_privilege(get_login_user, privilege) + end + def authorized!(privilege) + unless authorized?(privilege) + raise PermissionError.new( + 'You have insufficient privileges to perform action.') + end + end + +end diff --git a/src/app/services/vm_service.rb b/src/app/services/vm_service.rb new file mode 100644 index 0000000..0c964de --- /dev/null +++ b/src/app/services/vm_service.rb @@ -0,0 +1,189 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Written by Scott Seago , +# David Lutterkort +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# Mid-level API: Business logic around individual VM's +module VmService + + include ApplicationService + + def svc_show(vm_id) + # from before_filter + @vm = Vm.find(vm_id) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::VIEW) + end + + def svc_create(vm_hash, start_now) + # from before_filter + vm_hash[:state] = Vm::STATE_PENDING + @vm = Vm.new(params[:vm]) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::MODIFY) + + alert = "VM was successfully created." + Vm.transaction do + @vm.save! + vm_provision + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_CREATE_VM, + :state => Task::STATE_QUEUED}) + @task.save! + if start_now + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Start action queued." + else + alert += " Resources are not available to start VM now." + end + end + end + return alert + end + + def svc_update(vm_id, vm_hash, start_now, restart_now) + # from before_filter + @vm = Vm.find(vm_id) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::MODIFY) + + #needs restart if certain fields are changed + # (since those will only take effect the next startup) + needs_restart = false + unless @vm.get_pending_state == Vm::STATE_STOPPED + Vm::NEEDS_RESTART_FIELDS.each do |field| + unless @vm[field].to_s == vm_hash[field] + needs_restart = true + break + end + end + current_storage_ids = @vm.storage_volume_ids.sort + new_storage_ids = vm_hash[:storage_volume_ids] + new_storage_ids = [] unless new_storage_ids + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } + needs_restart = true unless current_storage_ids == new_storage_ids + end + vm_hash[:needs_restart] = 1 if needs_restart + + + alert = "VM was successfully updated." + Vm.transaction do + @vm.update_attributes!(vm_hash) + vm_provision + if start_now + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Start action queued." + else + alert += " Resources are not available to start VM now." + end + elsif restart_now + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_SHUTDOWN_VM, + :state => Task::STATE_QUEUED}) + @task.save! + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Restart action queued." + else + alert += " Restart action was not available." + end + end + end + return alert + end + + def svc_destroy(vm_id) + # from before_filter + @vm = Vm.find(vm_id) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::MODIFY) + + unless @vm.is_destroyable? + raise ActionError.new("Virtual Machine must be stopped to delete it") + end + destroy_cobbler_system(@vm) + @vm.destroy + return "Virtual Machine wa ssuccessfully deleted." + end + + def svc_vm_action(vm_id, vm_action, action_args) + @vm = Vm.find(vm_id) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::MODIFY) + unless @vm.queue_action(@user, vm_action, action_args) + raise ActionError.new("#{vm_action} is an invalid action.") + end + return "#{vm_action} was successfully queued." + end + + def svc_cancel_queued_tasks(vm_id) + @vm = Vm.find(vm_id) + @perm_obj = @vm.vm_resource_pool + @current_pool_id=@perm_obj.id + authorized!(Privilege::MODIFY) + + Task.transaction do + @vm.tasks.queued.each { |task| task.cancel} + end + return "Queued tasks were successfully canceled." + end + + def vm_provision + if @vm.uses_cobbler? + # spaces are invalid in the cobbler name + name = @vm.uuid + system = Cobbler::System.find_one(name) + unless system + system = Cobbler::System.new("name" => name, + @vm.cobbler_type => @vm.cobbler_name) + system.interfaces = [Cobbler::NetworkInterface.new( + {'mac_address' => @vm.vnic_mac_addr})] + system.save + end + end + end + + def destroy_cobbler_system(vm) + # Destroy the Cobbler system first if it's defined + if vm.uses_cobbler? + system = Cobbler::System.find_one(vm.cobbler_system_name) + system.remove if system + end + end + +end diff --git a/src/app/views/vm/_form.rhtml b/src/app/views/vm/_form.rhtml index 58a3d61..610f2bc 100644 --- a/src/app/views/vm/_form.rhtml +++ b/src/app/views/vm/_form.rhtml @@ -3,8 +3,7 @@ <% start_resources = @vm.vm_resource_pool.available_resources_for_vm(@vm) %> -<%= hidden_field 'vm', 'vm_resource_pool_id' unless @vm_resource_pool_name %> -<%= hidden_field_tag 'vm_resource_pool_name', @vm_resource_pool_name if @vm_resource_pool_name %> +<%= hidden_field 'vm', 'vm_resource_pool_id' %> <%= hidden_field_tag 'hardware_pool_id', @hardware_pool.id if @hardware_pool %> <%= text_field_with_label "Name:", "vm", "description", {:style=>"width:250px;"} %> -- 1.6.0.6 From sseago at redhat.com Mon Apr 20 15:22:22 2009 From: sseago at redhat.com (Scott Seago) Date: Mon, 20 Apr 2009 11:22:22 -0400 Subject: [Ovirt-devel] Re: [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240240393-5759-1-git-send-email-sseago@redhat.com> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> Message-ID: <49EC932E.5080304@redhat.com> Scott Seago wrote: > This code is based on David Lutterkort's proposal outlined in > https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html > > I've included service-layer methods for show, create, update, destroy, vm_action, and cancel_queued_tasks. These are the concrete actions that make sense as part of the API. Most of the remaining vm_controller methods are pure-WUI actions -- for things such as generating the web form for a new VM (the subsequent 'create' action _is_ part of the API). > > There's a certain amount of temporary code that we need in place while only some of the controllers have been converted, as we still need permissions pre-filters for non-converted create, etc. methods -- but for the converted controllers we don't want to perform actions in before_filters that will be done as part of the services layer. Any temporary methods, etc. that will go away when the last controller is converted have been marked clearly with FIXME comments. > > Signed-off-by: Scott Seago > --- > src/app/controllers/application.rb | 113 +++++++---- > src/app/controllers/hardware_controller.rb | 3 +- > src/app/controllers/host_controller.rb | 4 +- > src/app/controllers/nic_controller.rb | 2 +- > src/app/controllers/permission_controller.rb | 12 +- > src/app/controllers/pool_controller.rb | 2 +- > src/app/controllers/quota_controller.rb | 4 +- > src/app/controllers/storage_controller.rb | 5 +- > src/app/controllers/storage_volume_controller.rb | 6 +- > src/app/controllers/task_controller.rb | 9 +- > src/app/controllers/vm_controller.rb | 230 +++++----------------- > src/app/models/vm.rb | 1 + > src/app/services/application_service.rb | 56 ++++++ > src/app/services/vm_service.rb | 189 ++++++++++++++++++ > src/app/views/vm/_form.rhtml | 3 +- > 15 files changed, 394 insertions(+), 245 deletions(-) > create mode 100644 src/app/services/application_service.rb > create mode 100644 src/app/services/vm_service.rb > > diff --git a/src/app/controllers/application.rb b/src/app/controllers/application.rb > index fa88773..34283ec 100644 > --- a/src/app/controllers/application.rb > +++ b/src/app/controllers/application.rb > @@ -20,19 +20,35 @@ > # Filters added to this controller apply to all controllers in the application. > # Likewise, all the methods added will be available for all controllers. > > +# FIXME: once all controller classes include this, remove here > +require 'services/vm_service' > + > Oops. that should have been 'application_service' instead of 'vm_service'. Changing that locally now... Scott From dpierce at redhat.com Mon Apr 20 17:41:49 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 20 Apr 2009 13:41:49 -0400 Subject: [Ovirt-devel] [PATCH server] Makes host-browser tolerant of a node that reports no NICs. Message-ID: <1240249309-27856-1-git-send-email-dpierce@redhat.com> Signed-off-by: Darryl L. Pierce --- src/host-browser/host-browser.rb | 1 + src/public/images/icon_start.png | Bin 587 -> 0 bytes 2 files changed, 1 insertions(+), 0 deletions(-) delete mode 100644 src/public/images/icon_start.png diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb index 945b1d2..7e6f62e 100755 --- a/src/host-browser/host-browser.rb +++ b/src/host-browser/host-browser.rb @@ -85,6 +85,7 @@ class HostBrowser result = Hash.new result['HOSTNAME'] = @session.peeraddr[2] result['IPADDR'] = @session.peeraddr[3] + result['NICINFO'] = Hash.new @session.write("INFO?\n") diff --git a/src/public/images/icon_start.png b/src/public/images/icon_start.png deleted file mode 100644 index 6d0fa99563e59ed316dda79097b90525331c2343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmV-R0<`^!P)ckWXt9Q4~kdd-G;GZ7f7Ot*HqX#D%L8#hPLT#eRUg=vwHa3tdPT`4~Y4T=Y|9 z(}i>suuvDt#<&n&xKYSN(@B-4Lo$Ef#6?ZjBnK{B?&Wa#UBMr=s+)O3rsX(Md!w1D z5?80P^04^61yH`(_66UT=ILw{VIf z((;5HYqeKc`i^(9h}T&ricP%EHD0ZM1mNYnRSHXOV*U3QBNRZ}ci4Z_1mOAGBKwao z`WHt>QS` zRmdPT8AKNCu7i}?osiR^sPqQ21brLJNO<<<0hZE4u_BHXLEom=pJg}{l?nM^yVepS zE&1nJegzp!k&wiaBv$+k=JC(72$7bYxwF>P%m>@GhJZq-P4^_oGOAFUu7H9wch;De Z`8W0bsG*n0qL=^x002ovPDHLkV1nH7|55+| -- 1.6.0.6 From dpierce at redhat.com Mon Apr 20 17:49:15 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 20 Apr 2009 13:49:15 -0400 Subject: [Ovirt-devel] Re: [PATCH server] Makes host-browser tolerant of a node that reports no NICs. In-Reply-To: <1240249309-27856-1-git-send-email-dpierce@redhat.com> References: <1240249309-27856-1-git-send-email-dpierce@redhat.com> Message-ID: <20090420174915.GB25174@mcpierce-laptop.rdu.redhat.com> On Mon, Apr 20, 2009 at 01:41:49PM -0400, Darryl L. Pierce wrote: > > Signed-off-by: Darryl L. Pierce > --- > src/host-browser/host-browser.rb | 1 + > src/public/images/icon_start.png | Bin 587 -> 0 bytes > 2 files changed, 1 insertions(+), 0 deletions(-) > delete mode 100644 src/public/images/icon_start.png > > diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb > index 945b1d2..7e6f62e 100755 > --- a/src/host-browser/host-browser.rb > +++ b/src/host-browser/host-browser.rb > @@ -85,6 +85,7 @@ class HostBrowser > result = Hash.new > result['HOSTNAME'] = @session.peeraddr[2] > result['IPADDR'] = @session.peeraddr[3] > + result['NICINFO'] = Hash.new > > @session.write("INFO?\n") > > diff --git a/src/public/images/icon_start.png b/src/public/images/icon_start.png > deleted file mode 100644 > index 6d0fa99563e59ed316dda79097b90525331c2343..0000000000000000000000000000000000000000 > GIT binary patch > literal 0 > HcmV?d00001 > > literal 587 > zcmV-R0<`^!P) zd zcW-iQb09-gGnm#!0{{R36m&&cbVG7wVRUJ4ZXi@?ZDjy9FE%eQI4if6pa1{?rAb6V > zR49>ckWXt9Q4~kdd-G;GZ7f7Ot*HqX#D%L8#hPLT#eRUg=vwHa3tdPT`4~Y4T=Y|9 > z(}i>suuvDt#<&n&xKYSN(@B-4Lo$Ef#6?ZjBnK{B?&Wa#UBMr=s+)O3rsX(Md!w1D > z5?80P^04^61yH`( z`rX@~{}TbOWcsWu|3Ifk{kVB2&lu7WX*suWifx4?T9PD+L at T^bj>_66UT=ILw{VIf > z((;5HYqeKc`i^(9h}T&ricP%EHD0ZM1mNYnRSHXOV*U3QBNRZ}ci4Z_1mOAGBKwao > z`WHt>QS` > zRmdPT8AKNCu7i}?osiR^sPqQ21brLJNO<<<0hZE4u_BHXLEom=pJg}{l?nM^yVepS > zE&1nJegzp!k&wiaBv$+k=JC(72$7bYxwF>P%m>@GhJZq-P4^_oGOAFUu7H9wch;De > Z`8W0bsG*n0qL=^x002ovPDHLkV1nH7|55+| hrmmmm, didn't see this in the commit. I'll resend a patch without this file change. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Mon Apr 20 17:55:11 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 20 Apr 2009 13:55:11 -0400 Subject: [Ovirt-devel] Overrides the previous patch Message-ID: <1240250112-28677-1-git-send-email-dpierce@redhat.com> Somehow the patch I sent previously included deleting the src/public/images/icon_start.png file. Dunno how that crept in there, but this patch fixes that. From dpierce at redhat.com Mon Apr 20 17:55:12 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 20 Apr 2009 13:55:12 -0400 Subject: [Ovirt-devel] [PATCH server] Makes host-browser tolerant of a node that reports no NICs. In-Reply-To: <1240250112-28677-1-git-send-email-dpierce@redhat.com> References: <1240250112-28677-1-git-send-email-dpierce@redhat.com> Message-ID: <1240250112-28677-2-git-send-email-dpierce@redhat.com> Signed-off-by: Darryl L. Pierce --- src/host-browser/host-browser.rb | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb index 945b1d2..7e6f62e 100755 --- a/src/host-browser/host-browser.rb +++ b/src/host-browser/host-browser.rb @@ -85,6 +85,7 @@ class HostBrowser result = Hash.new result['HOSTNAME'] = @session.peeraddr[2] result['IPADDR'] = @session.peeraddr[3] + result['NICINFO'] = Hash.new @session.write("INFO?\n") -- 1.6.0.6 From sseago at redhat.com Mon Apr 20 20:26:39 2009 From: sseago at redhat.com (Scott Seago) Date: Mon, 20 Apr 2009 20:26:39 +0000 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. Message-ID: <1240259199-10088-1-git-send-email-sseago@redhat.com> This code is based on David Lutterkort's proposal outlined in https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html I've included service-layer methods for show, create, update, destroy, vm_action, and cancel_queued_tasks. These are the concrete actions that make sense as part of the API. Most of the remaining vm_controller methods are pure-WUI actions -- for things such as generating the web form for a new VM (the subsequent 'create' action _is_ part of the API). There's a certain amount of temporary code that we need in place while only some of the controllers have been converted, as we still need permissions pre-filters for non-converted create, etc. methods -- but for the converted controllers we don't want to perform actions in before_filters that will be done as part of the services layer. Any temporary methods, etc. that will go away when the last controller is converted have been marked clearly with FIXME comments. Revised version passes perm_obj arg into set_perms -- and always uses this method to set @perm_obj rather than setting it directly. I've also cleaned the permission-setting calls in general, removing more of the no-longer-valid redirects, etc. Signed-off-by: Scott Seago --- src/app/controllers/application.rb | 113 ++++++---- src/app/controllers/hardware_controller.rb | 8 +- src/app/controllers/host_controller.rb | 23 +-- src/app/controllers/network_controller.rb | 2 +- src/app/controllers/nic_controller.rb | 8 +- src/app/controllers/permission_controller.rb | 22 +-- src/app/controllers/pool_controller.rb | 16 +- src/app/controllers/quota_controller.rb | 16 +- src/app/controllers/resources_controller.rb | 4 +- src/app/controllers/smart_pools_controller.rb | 6 +- src/app/controllers/storage_controller.rb | 21 +-- src/app/controllers/storage_volume_controller.rb | 24 +-- src/app/controllers/task_controller.rb | 5 +- src/app/controllers/vm_controller.rb | 241 +++++----------------- src/app/models/vm.rb | 1 + src/app/services/application_service.rb | 57 +++++ src/app/services/vm_service.rb | 183 ++++++++++++++++ src/app/views/vm/_form.rhtml | 3 +- 18 files changed, 409 insertions(+), 344 deletions(-) create mode 100644 src/app/services/application_service.rb create mode 100644 src/app/services/vm_service.rb diff --git a/src/app/controllers/application.rb b/src/app/controllers/application.rb index fa88773..e5f4d4b 100644 --- a/src/app/controllers/application.rb +++ b/src/app/controllers/application.rb @@ -20,19 +20,35 @@ # Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. +# FIXME: once all controller classes include this, remove here +require 'services/application_service' + class ApplicationController < ActionController::Base + # FIXME: once all controller classes include this, remove here + include ApplicationService + # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_ovirt_session_id' init_gettext "ovirt" layout :choose_layout + # FIXME: once service layer is complete, the following before_filters will be + # removed as their functionality has been moved to the service layer + # pre_create + # pre_edit will remain only for :edit, not :update or :destroy + # pre_show + # authorize_admin will remain only for :new, :edit before_filter :pre_new, :only => [:new] before_filter :pre_create, :only => [:create] - before_filter :pre_edit, :only => [:edit, :update, :destroy] + before_filter :pre_edit, :only => [:edit] + # the following is to facilitate transition to service layer + before_filter :tmp_pre_update, :only => [:update, :destroy] before_filter :pre_show, :only => [:show] - before_filter :authorize_admin, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authorize_admin, :only => [:new, :edit] + before_filter :tmp_authorize_admin, :only => [:create, :update, :destroy] before_filter :is_logged_in, :get_help_section + def choose_layout if(params[:component_layout]) return (ENV["RAILS_ENV"] != "production")?'components/' << params[:component_layout]:'redux' @@ -61,62 +77,66 @@ class ApplicationController < ActionController::Base (ENV["RAILS_ENV"] == "production") ? session[:user] : "ovirtadmin" end - def set_perms(hwpool) - @user = get_login_user - @can_view = hwpool.can_view(@user) - @can_control_vms = hwpool.can_control_vms(@user) - @can_modify = hwpool.can_modify(@user) - @can_view_perms = hwpool.can_view_perms(@user) - @can_set_perms = hwpool.can_set_perms(@user) - end - protected # permissions checking def pre_new end - def pre_create - end def pre_edit end + + # FIXME: remove these when service layer transition is complete + def tmp_pre_update + pre_edit + end + def tmp_authorize_admin + authorize_admin + end + def pre_create + end def pre_show end + def authorize_view(msg=nil) + authorize_action(Privilege::VIEW,msg) + end def authorize_user(msg=nil) - authorize_action(false,msg) + authorize_action(Privilege::VM_CONTROL,msg) end def authorize_admin(msg=nil) - authorize_action(true,msg) - end - def authorize_action(is_modify_action, msg=nil) - msg ||= 'You do not have permission to create or modify this item ' - if @perm_obj - set_perms(@perm_obj) - unless (is_modify_action ? @can_modify : @can_control_vms) - respond_to do |format| - format.html do - @title = "Access denied" - @errmsg = msg - @ajax = params[:ajax] - @nolayout = params[:nolayout] - if @ajax - render :template => 'layouts/popup-error', :layout => 'tabs-and-content' - elsif @nolayout - render :template => 'layouts/popup-error', :layout => 'help-and-content' - else - render :template => 'layouts/popup-error', :layout => 'popup' - end - end - format.json do - @json_hash ||= {} - @json_hash[:success] = false - @json_hash[:alert] = msg - render :json => @json_hash - end - format.xml { head :forbidden } + authorize_action(Privilege::MODIFY,msg) + end + def authorize_action(privilege, msg=nil) + msg ||= 'You have insufficient privileges to perform action.' + unless authorized?(privilege) + handle_auth_error(msg) + false + else + true + end + end + def handle_auth_error(msg) + respond_to do |format| + format.html do + @title = "Access denied" + @errmsg = msg + @ajax = params[:ajax] + @nolayout = params[:nolayout] + if @ajax + render :template => 'layouts/popup-error', :layout => 'tabs-and-content' + elsif @nolayout + render :template => 'layouts/popup-error', :layout => 'help-and-content' + else + render :template => 'layouts/popup-error', :layout => 'popup' end - false end + format.json do + @json_hash ||= {} + @json_hash[:success] = false + @json_hash[:alert] = msg + render :json => @json_hash + end + format.xml { head :forbidden } end end @@ -155,6 +175,11 @@ class ApplicationController < ActionController::Base render :json => json_hash(full_items, attributes, arg_list, find_opts, id_method).to_json end - + def json_error(obj_type, obj, exception) + json_hash = { :object => obj_type, :success => false} + json_hash[:errors] = obj.errors.localize_error_messages.to_a if obj + json_hash[:alert] = exception.message if obj.errors.size == 0 + render :json => json_hash + end end diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb index 726e5bd..094eef0 100644 --- a/src/app/controllers/hardware_controller.rb +++ b/src/app/controllers/hardware_controller.rb @@ -71,11 +71,7 @@ class HardwareController < PoolController if id @pool = Pool.find(id) set_perms(@pool) - unless @pool.has_privilege(@user, privilege) - flash[:notice] = 'You do not have permission to access this hardware pool: redirecting to top level' - redirect_to :controller => "dashboard" - return - end + return unless authorize_action(privilege) end if @pool pools = @pool.children @@ -386,7 +382,7 @@ class HardwareController < PoolController def pre_edit @pool = HardwarePool.find(params[:id]) @parent = @pool.parent - @perm_obj = @pool + set_perms(@pool) @current_pool_id=@pool.id end def pre_show diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb index f0b8c2b..7f808dc 100644 --- a/src/app/controllers/host_controller.rb +++ b/src/app/controllers/host_controller.rb @@ -53,12 +53,7 @@ class HostController < ApplicationController def show - set_perms(@perm_obj) - unless @can_view - flash[:notice] = 'You do not have permission to view this host: redirecting to top level' - #perm errors for ajax should be done differently - redirect_to :controller => 'dashboard', :action => 'list' - else + if authorize_view respond_to do |format| format.html { render :layout => 'selection' } format.xml { render :xml => @host.to_xml(:include => [ :cpus ] ) } @@ -68,13 +63,9 @@ class HostController < ApplicationController def quick_summary pre_show - set_perms(@perm_obj) - unless @can_view - flash[:notice] = 'You do not have permission to view this host: redirecting to top level' - #perm errors for ajax should be done differently - redirect_to :controller => 'dashboard', :action => 'list' + if authorize_view + render :layout => false end - render :layout => false end # retrieves data used by snapshot graphs @@ -89,7 +80,7 @@ class HostController < ApplicationController def pre_addhost @pool = Pool.find(params[:hardware_pool_id]) @parent = @pool.parent - @perm_obj = @pool + set_perms(@pool) @current_pool_id=@pool.id authorize_admin end @@ -192,14 +183,14 @@ class HostController < ApplicationController end def pre_action @host = Host.find(params[:id]) - @perm_obj = @host.hardware_pool + set_perms(@host.hardware_pool) @json_hash = { :object => :host } authorize_admin end def pre_show @host = Host.find(params[:id]) - @perm_obj = @host.hardware_pool - @current_pool_id=@perm_obj.id + set_perms(@host.hardware_pool) + @current_pool_id=@host.hardware_pool.id end diff --git a/src/app/controllers/network_controller.rb b/src/app/controllers/network_controller.rb index a99cf8d..244d041 100644 --- a/src/app/controllers/network_controller.rb +++ b/src/app/controllers/network_controller.rb @@ -28,7 +28,7 @@ class NetworkController < ApplicationController # or by extending permission model to accomodate # any object @default_pool = HardwarePool.get_default_pool - @perm_obj=@default_pool + set_perms(@default_pool) super('You do not have permission to access networks') end diff --git a/src/app/controllers/nic_controller.rb b/src/app/controllers/nic_controller.rb index 85d4315..fdbda06 100644 --- a/src/app/controllers/nic_controller.rb +++ b/src/app/controllers/nic_controller.rb @@ -23,11 +23,7 @@ class NicController < ApplicationController :redirect_to => { :controller => 'dashboard' } def show - set_perms(@perm_obj) - unless @can_view - flash[:notice] = 'You do not have permission to view this NIC: redirecting to top level' - redirect_to :controller => 'pool', :action => 'list' - end + authorize_view end def new @@ -62,7 +58,7 @@ class NicController < ApplicationController end def pre_show @nic = Nic.find(params[:id]) - @perm_obj = @nic.host.hardware_pool + set_perms(@nic.host.hardware_pool) end end diff --git a/src/app/controllers/permission_controller.rb b/src/app/controllers/permission_controller.rb index 3bfbffa..d4c3fb5 100644 --- a/src/app/controllers/permission_controller.rb +++ b/src/app/controllers/permission_controller.rb @@ -29,11 +29,7 @@ class PermissionController < ApplicationController def show @permission = Permission.find(params[:id]) set_perms(@permission.pool) - # admin permission required to view permissions - unless @can_view_perms - flash[:notice] = 'You do not have permission to view this permission record' - redirect_to_parent - end + authorize_action(Privilege::PERM_VIEW) end def new @@ -45,10 +41,7 @@ class PermissionController < ApplicationController @roles = Role.find(:all).collect{ |role| [role.name, role.id] } set_perms(@permission.pool) # admin permission required to view permissions - unless @can_set_perms - flash[:notice] = 'You do not have permission to create this permission record' - redirect_to_parent - else + if authorize_action(Privilege::PERM_SET) render :layout => 'popup' end end @@ -56,11 +49,7 @@ class PermissionController < ApplicationController def create @permission = Permission.new(params[:permission]) set_perms(@permission.pool) - unless @can_set_perms - # FIXME: need to handle proper error messages w/ ajax - flash[:notice] = 'You do not have permission to create this permission record' - redirect_to_parent - else + if authorize_action(Privilege::PERM_SET) begin @permission.save_with_new_children render :json => { :object => "permission", :success => true, @@ -118,10 +107,7 @@ class PermissionController < ApplicationController def destroy @permission = Permission.find(params[:id]) set_perms(@permission.pool) - unless @can_set_perms - flash[:notice] = 'You do not have permission to delete this permission record' - redirect_to_parent - else + if authorize_action(Privilege::PERM_SET) pool = @permission.pool if @permission.destroy if pool diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb index 22cf1a4..4d83bbe 100644 --- a/src/app/controllers/pool_controller.rb +++ b/src/app/controllers/pool_controller.rb @@ -104,7 +104,7 @@ class PoolController < ApplicationController protected def pre_new @parent = Pool.find(params[:parent_id]) - @perm_obj = @parent + set_perms(@parent) @current_pool_id=@parent.id end def pre_create @@ -114,24 +114,16 @@ class PoolController < ApplicationController else @parent = Pool.find(params[:parent_id]) end - @perm_obj = @parent + set_perms(@parent) @current_pool_id=@parent.id end def pre_show_pool pre_show end def pre_show - @perm_obj = @pool + set_perms(@pool) @current_pool_id=@pool.id - set_perms(@perm_obj) - unless @can_view - flash[:notice] = 'You do not have permission to view this pool: redirecting to top level' - respond_to do |format| - format.html { redirect_to :controller => "dashboard" } - format.xml { head :forbidden } - end - return - end + authorize_view end end diff --git a/src/app/controllers/quota_controller.rb b/src/app/controllers/quota_controller.rb index 17fdc20..d4fbcd0 100644 --- a/src/app/controllers/quota_controller.rb +++ b/src/app/controllers/quota_controller.rb @@ -28,13 +28,7 @@ class QuotaController < ApplicationController def show @quota = Quota.find(params[:id]) - set_perms(@quota.pool) - - unless @can_view - flash[:notice] = 'You do not have permission to view this quota: redirecting to top level' - redirect_to_parent - end - + authorize_view end def new @@ -83,19 +77,19 @@ class QuotaController < ApplicationController protected def pre_new @quota = Quota.new( { :pool_id => params[:pool_id]}) - @perm_obj = @quota.pool + set_perms(@quota.pool) end def pre_create @quota = Quota.new(params[:quota]) - @perm_obj = @quota.pool + set_perms(@quota.pool) end def pre_show @quota = Quota.find(params[:id]) - @perm_obj = @quota + set_perms(@quota.pool) end def pre_edit @quota = Quota.find(params[:id]) - @perm_obj = @quota.pool + set_perms(@quota.pool) end end diff --git a/src/app/controllers/resources_controller.rb b/src/app/controllers/resources_controller.rb index b57fae6..6b61439 100644 --- a/src/app/controllers/resources_controller.rb +++ b/src/app/controllers/resources_controller.rb @@ -166,7 +166,7 @@ class ResourcesController < PoolController def pre_edit @pool = VmResourcePool.find(params[:id]) @parent = @pool.parent - @perm_obj = @pool.parent + set_perms(@pool.parent) @current_pool_id=@pool.id end def pre_show @@ -177,7 +177,7 @@ class ResourcesController < PoolController def pre_vm_actions @pool = VmResourcePool.find(params[:id]) @parent = @pool.parent - @perm_obj = @pool + set_perms(@pool) authorize_user end diff --git a/src/app/controllers/smart_pools_controller.rb b/src/app/controllers/smart_pools_controller.rb index f5f3c9d..93c81ee 100644 --- a/src/app/controllers/smart_pools_controller.rb +++ b/src/app/controllers/smart_pools_controller.rb @@ -199,19 +199,19 @@ class SmartPoolsController < PoolController def pre_new @pool = SmartPool.new @parent = DirectoryPool.get_or_create_user_root(get_login_user) - @perm_obj = @parent + set_perms(@parent) @current_pool_id=@parent.id end def pre_create @pool = SmartPool.new(params[:smart_pool]) @parent = DirectoryPool.get_or_create_user_root(get_login_user) - @perm_obj = @parent + set_perms(@parent) @current_pool_id=@parent.id end def pre_edit @pool = SmartPool.find(params[:id]) @parent = @pool.parent - @perm_obj = @pool + set_perms(@pool) @current_pool_id=@pool.id end def pre_show diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb index 98ba0f6..2cb5464 100644 --- a/src/app/controllers/storage_controller.rb +++ b/src/app/controllers/storage_controller.rb @@ -47,10 +47,7 @@ class StorageController < ApplicationController if @attach_to_pool pool = HardwarePool.find(@attach_to_pool) set_perms(pool) - unless @can_view - flash[:notice] = 'You do not have permission to view this storage pool list: redirecting to top level' - redirect_to :controller => 'dashboard' - else + if authorize_view conditions = "hardware_pool_id is null" conditions += " or hardware_pool_id=#{pool.parent_id}" if pool.parent @storage_pools = StoragePool.find(:all, :conditions => conditions) @@ -71,13 +68,7 @@ class StorageController < ApplicationController def show @storage_pool = StoragePool.find(params[:id]) set_perms(@storage_pool.hardware_pool) - unless @can_view - flash[:notice] = 'You do not have permission to view this storage pool: redirecting to top level' - respond_to do |format| - format.html { redirect_to :controller => 'dashboard' } - format.xml { head :forbidden } - end - else + if authorize_view respond_to do |format| format.html { render :layout => 'selection' } format.xml { @@ -234,7 +225,7 @@ class StorageController < ApplicationController def pre_new @hardware_pool = HardwarePool.find(params[:hardware_pool_id]) - @perm_obj = @hardware_pool + set_perms(@hardware_pool) authorize_admin @storage_pools = @hardware_pool.storage_volumes @storage_types = StoragePool::STORAGE_TYPE_PICKLIST @@ -250,7 +241,7 @@ class StorageController < ApplicationController new_params[:port] = 3260 end @storage_pool = StoragePool.factory(params[:storage_type], new_params) - @perm_obj = @storage_pool.hardware_pool + set_perms(@storage_pool.hardware_pool) authorize_admin end def pre_create @@ -259,11 +250,11 @@ class StorageController < ApplicationController type = pool.delete(:storage_type) end @storage_pool = StoragePool.factory(type, pool) - @perm_obj = @storage_pool.hardware_pool + set_perms(@storage_pool.hardware_pool) end def pre_edit @storage_pool = StoragePool.find(params[:id]) - @perm_obj = @storage_pool.hardware_pool + set_perms(@storage_pool.hardware_pool) end def pre_pool_admin pre_edit diff --git a/src/app/controllers/storage_volume_controller.rb b/src/app/controllers/storage_volume_controller.rb index 9b0b9e0..b6b0593 100644 --- a/src/app/controllers/storage_volume_controller.rb +++ b/src/app/controllers/storage_volume_controller.rb @@ -94,19 +94,12 @@ class StorageVolumeController < ApplicationController @storage_volume = StorageVolume.find(params[:id]) set_perms(@storage_volume.storage_pool.hardware_pool) @storage_pool = @storage_volume.storage_pool - unless @can_view - flash[:notice] = 'You do not have permission to view this storage volume: redirecting to top level' - respond_to do |format| - format.html { redirect_to :controller => 'dashboard' } - format.json { redirect_to :controller => 'dashboard' } - format.xml { head :forbidden } - end - else + if authorize_view respond_to do |format| format.html { render :layout => 'selection' } format.json do attr_list = [] - attr_list << :id if (@storage_pool.user_subdividable and @can_modify) + attr_list << :id if (@storage_pool.user_subdividable and authorized?(Privilege::MODIFY) attr_list += [:display_name, :size_in_gb, :get_type_label] json_list(@storage_pool.storage_volumes, attr_list) end @@ -118,13 +111,8 @@ class StorageVolumeController < ApplicationController def destroy @storage_volume = StorageVolume.find(params[:id]) set_perms(@storage_volume.storage_pool.hardware_pool) - unless @can_modify and @storage_volume.storage_pool.user_subdividable - respond_to do |format| - format.json { render :json => { :object => "storage_volume", - :success => false, - :alert => "You do not have permission to delete this storage volume." } } - format.xml { head :forbidden } - end + unless authorized?(Privilege::MODIFY) and @storage_volume.storage_pool.user_subdividable + handle_auth_error("You do not have permission to delete this storage volume.") else alert, success = delete_volume_internal(@storage_volume) respond_to do |format| @@ -141,14 +129,14 @@ class StorageVolumeController < ApplicationController type = volume.delete(:storage_type) end @storage_volume = StorageVolume.factory(type, volume) - @perm_obj = @storage_volume.storage_pool.hardware_pool + set_perms(@storage_volume.storage_pool.hardware_pool) authorize_admin end private def new_volume_internal(storage_pool, new_params) @storage_volume = StorageVolume.factory(storage_pool.get_type_label, new_params) - @perm_obj = @storage_volume.storage_pool.hardware_pool + set_perms(@storage_volume.storage_pool.hardware_pool) authorize_admin end diff --git a/src/app/controllers/task_controller.rb b/src/app/controllers/task_controller.rb index 647d69c..9756f79 100644 --- a/src/app/controllers/task_controller.rb +++ b/src/app/controllers/task_controller.rb @@ -29,10 +29,7 @@ class TaskController < ApplicationController elsif @task[:type] == HostTask.name set_perms(@task.host.hardware_pool) end - unless @can_view - flash[:notice] = 'You do not have permission to view this task: redirecting to top level' - redirect_to :controller => 'dashboard' - end + authorize_view end diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb index a81f6b5..e3dc9ef 100644 --- a/src/app/controllers/vm_controller.rb +++ b/src/app/controllers/vm_controller.rb @@ -17,13 +17,16 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. require 'socket' +require 'services/vm_service' class VmController < ApplicationController + include VmService + # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :controller => 'dashboard' } - before_filter :pre_vm_action, :only => [:vm_action, :cancel_queued_tasks, :console] + before_filter :pre_console, :only => [:console] def index @vms = Vm.find(:all, @@ -38,13 +41,13 @@ class VmController < ApplicationController end def show - set_perms(@perm_obj) - @actions = @vm.get_action_hash(@user) - unless @can_view - flash[:notice] = 'You do not have permission to view this vm: redirecting to top level' - redirect_to :controller => 'resources', :controller => 'dashboard' + begin + svc_show(params[:id]) + @actions = @vm.get_action_hash(@user) + render :layout => 'selection' + rescue PermissionError => perm_error + handle_auth_error(perm_error.message) end - render :layout => 'selection' end def add_to_smart_pool @@ -58,38 +61,15 @@ class VmController < ApplicationController end def create + params[:vm][:forward_vnc] = params[:forward_vnc] begin - Vm.transaction do - @vm.save! - _setup_vm_provision(params) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_CREATE_VM, - :state => Task::STATE_QUEUED}) - @task.save! - end - start_now = params[:start_now] - if (start_now) - if @vm.get_action_list.include?(VmTask::ACTION_START_VM) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - alert = "VM was successfully created. VM Start action queued." - else - alert = "VM was successfully created. Resources are not available to start VM now." - end - else - alert = "VM was successfully created." - end + alert = svc_create(params[:vm], params[:start_now]) render :json => { :object => "vm", :success => true, :alert => alert } + rescue PermissionError => perm_error + handle_auth_error(perm_error.message) rescue Exception => error - # FIXME: need to distinguish vm vs. task save errors (but should mostly be vm) - render :json => { :object => "vm", :success => false, - :errors => @vm.errors.localize_error_messages.to_a } + json_error("vm", @vm, error) end - end def edit @@ -98,58 +78,20 @@ class VmController < ApplicationController end def update + params[:vm][:forward_vnc] = params[:forward_vnc] begin - #needs restart if certain fields are changed (since those will only take effect the next startup) - needs_restart = false - unless @vm.get_pending_state == Vm::STATE_STOPPED - Vm::NEEDS_RESTART_FIELDS.each do |field| - unless @vm[field].to_s == params[:vm][field] - needs_restart = true - break - end - end - current_storage_ids = @vm.storage_volume_ids.sort - new_storage_ids = params[:vm][:storage_volume_ids] - new_storage_ids = [] unless new_storage_ids - new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } - needs_restart = true unless current_storage_ids == new_storage_ids - end - - params[:vm][:forward_vnc] = params[:forward_vnc] - params[:vm][:needs_restart] = 1 if needs_restart - @vm.update_attributes!(params[:vm]) - _setup_vm_provision(params) - - if (params[:start_now] and @vm.get_action_list.include?(VmTask::ACTION_START_VM) ) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - elsif ( params[:restart_now] and @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) ) - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_SHUTDOWN_VM, - :state => Task::STATE_QUEUED}) - @task.save! - @task = VmTask.new({ :user => @user, - :task_target => @vm, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) - @task.save! - end - - - render :json => { :object => "vm", :success => true, - :alert => 'Vm was successfully updated.' } - rescue + alert = svc_update(params[:id], params[:vm], params[:start_now], + params[:restart_now]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue Exception => error # FIXME: need to distinguish vm vs. task save errors (but should mostly be vm) - render :json => { :object => "vm", :success => false, - :errors => @vm.errors.localize_error_messages.to_a } + json_error("vm", @vm, error) end end #FIXME: we need permissions checks. user must have permission. Also state checks + # this should probably be implemented as an action on the containing VM pool once + # that service module is defined def delete vm_ids_str = params[:vm_ids] vm_ids = vm_ids_str.split(",").collect {|x| x.to_i} @@ -181,15 +123,13 @@ class VmController < ApplicationController end def destroy - vm_resource_pool = @vm.vm_resource_pool_id - if (@vm.is_destroyable?) - destroy_cobbler_system(@vm) - @vm.destroy - render :json => { :object => "vm", :success => true, - :alert => "Virtual Machine was successfully deleted." } - else - render :json => { :object => "vm", :success => false, - :alert => "Vm must be stopped to delete it." } + begin + alert = svc_destroy(params[:id]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue ActionError => error + json_error("vm", @vm, error) + rescue Exception => error + json_error("vm", @vm, error) end end @@ -204,34 +144,29 @@ class VmController < ApplicationController end def vm_action - vm_action = params[:vm_action] - data = params[:vm_action_data] begin - if @vm.queue_action(get_login_user, vm_action, data) - render :json => { :object => "vm", :success => true, :alert => "#{vm_action} was successfully queued." } - else - render :json => { :object => "vm", :success => false, :alert => "#{vm_action} is an invalid action." } - end - rescue - render :json => { :object => "vm", :success => false, :alert => "Error in queueing #{vm_action}." } + alert = svc_vm_action(params[:id], params[:vm_action], + params[:vm_action_data]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue ActionError => error + json_error("vm", @vm, error) + rescue Exception => error + json_error("vm", @vm, error) end end def cancel_queued_tasks begin - Task.transaction do - @vm.tasks.queued.each { |task| task.cancel} - end - render :json => { :object => "vm", :success => true, :alert => "queued tasks were canceled." } - rescue - render :json => { :object => "vm", :success => true, :alert => "queued tasks cancel failed." } + alert = svc_cancel_queued_tasks(params[:id]) + render :json => { :object => "vm", :success => true, :alert => alert } + rescue Exception => error + json_error("vm", @vm, error) end end def migrate @vm = Vm.find(params[:id]) - @perm_obj = @vm.get_hardware_pool - @redir_obj = @vm + set_perms(@vm.get_hardware_pool) @current_pool_id=@vm.vm_resource_pool.id authorize_admin render :layout => 'popup' @@ -268,53 +203,10 @@ class VmController < ApplicationController end end - # FIXME: move this to an edit_vm task in taskomatic - def _setup_vm_provision(params) - # spaces are invalid in the cobbler name - name = params[:vm][:uuid] - mac = params[:vm][:vnic_mac_addr] - provision = params[:vm][:provisioning_and_boot_settings] - # determine what type of provisioning was selected for the VM - provisioning_type = :pxe_or_hd_type - provisioning_type = :image_type if provision.index "#{Vm::IMAGE_PREFIX}@#{Vm::COBBLER_PREFIX}" - provisioning_type = :system_type if provision.index "#{Vm::PROFILE_PREFIX}@#{Vm::COBBLER_PREFIX}" - - unless provisioning_type == :pxe_or_hd_type - cobbler_name = provision.slice(/(.*):(.*)/, 2) - system = Cobbler::System.find_one(name) - unless system - nic = Cobbler::NetworkInterface.new({'mac_address' => mac}) - - case provisioning_type - when :image_type: - system = Cobbler::System.new("name" => name, "image" => cobbler_name) - when :system_type: - system = Cobbler::System.new("name" => name, "profile" => cobbler_name) - end - - system.interfaces = [nic] - system.save - end - end - end - def pre_new - # if no vm_resource_pool is passed in, find (or auto-create) it based on hardware_pool_id unless params[:vm_resource_pool_id] - unless params[:hardware_pool_id] - flash[:notice] = "VM Resource Pool or Hardware Pool is required." - redirect_to :controller => 'dashboard' - end - @hardware_pool = HardwarePool.find(params[:hardware_pool_id]) - @user = get_login_user - vm_resource_pool = @hardware_pool.sub_vm_resource_pools.select {|pool| pool.name == @user}.first - if vm_resource_pool - params[:vm_resource_pool_id] = vm_resource_pool.id - else - @vm_resource_pool = VmResourcePool.new({:name => vm_resource_pool}) - @vm_resource_pool.tmp_parent = @hardware_pool - @vm_resource_pool_name = @user - end + flash[:notice] = "VM Resource Pool is required." + redirect_to :controller => 'dashboard' end # random MAC @@ -331,50 +223,27 @@ class VmController < ApplicationController unless params[:vm_resource_pool_id] @vm.vm_resource_pool = @vm_resource_pool end - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id + set_perms(@vm.vm_resource_pool) + @current_pool_id=@vm.vm_resource_pool.id @networks = Network.find(:all).collect{ |net| [net.name, net.id] } _setup_provisioning_options end - def pre_create - params[:vm][:state] = Vm::STATE_PENDING - vm_resource_pool_name = params[:vm_resource_pool_name] - hardware_pool_id = params[:hardware_pool_id] - if vm_resource_pool_name and hardware_pool_id - hardware_pool = HardwarePool.find(hardware_pool_id) - vm_resource_pool = VmResourcePool.new({:name => vm_resource_pool_name}) - vm_resource_pool.create_with_parent(hardware_pool) - params[:vm][:vm_resource_pool_id] = vm_resource_pool.id - end - params[:vm][:forward_vnc] = params[:forward_vnc] - @vm = Vm.new(params[:vm]) - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id - end - def pre_show - @vm = Vm.find(params[:id]) - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id - end def pre_edit @vm = Vm.find(params[:id]) - @perm_obj = @vm.vm_resource_pool - @current_pool_id=@perm_obj.id + set_perms(@vm.vm_resource_pool) + @current_pool_id=@vm.vm_resource_pool.id @networks = Network.find(:all).collect{ |net| [net.name, net.id] } _setup_provisioning_options end - def pre_vm_action + def pre_console pre_edit authorize_user end - - private - - def destroy_cobbler_system(vm) - # Destroy the Cobbler system first if it's defined - if vm.uses_cobbler? - system = Cobbler::System.find_one(vm.cobbler_system_name) - system.remove if system - end + # FIXME: remove these when service transition is complete. these are here + # to keep from running permissions checks and other setup steps twice + def tmp_pre_update + end + def tmp_authorize_admin end + end diff --git a/src/app/models/vm.rb b/src/app/models/vm.rb index c62595a..4c7925c 100644 --- a/src/app/models/vm.rb +++ b/src/app/models/vm.rb @@ -220,6 +220,7 @@ class Vm < ActiveRecord::Base self[:boot_device]= BOOT_DEV_HD self[:provisioning]= nil else + # FIXME: Should this case trigger an error instead? self[:boot_device]= BOOT_DEV_NETWORK self[:provisioning]= settings end diff --git a/src/app/services/application_service.rb b/src/app/services/application_service.rb new file mode 100644 index 0000000..e2d0d38 --- /dev/null +++ b/src/app/services/application_service.rb @@ -0,0 +1,57 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Written by Scott Seago , +# David Lutterkort +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# +# Common infrastructure for business logic for WUI and QMF +# +# We call objects in the mid-level API 'Service' for lack of a better name. +# The Service layer is all in modules that are included by the classes that +# use them in the WUI and the QMF controllers. They set instance variables, +# which automatically become instance variables on the controllers that use +# the Service modules + +module ApplicationService + class PermissionError < RuntimeError; end + class ActionError < RuntimeError; end + + # Including class must provide a GET_LOGIN_USER + + def set_perms(perm_obj) + @perm_obj = perm_obj + @user = get_login_user + @can_view = @perm_obj.can_view(@user) + @can_control_vms = @perm_obj.can_control_vms(@user) + @can_modify = @perm_obj.can_modify(@user) + @can_view_perms = @perm_obj.can_view_perms(@user) + @can_set_perms = @perm_obj.can_set_perms(@user) + end + + def authorized?(privilege, perm_obj=nil) + set_perms(perm_obj) if perm_obj + return false unless @perm_obj + return @perm_obj.has_privilege(@user, privilege) + end + def authorized!(privilege, perm_obj=nil) + unless authorized?(privilege, perm_obj) + raise PermissionError.new( + 'You have insufficient privileges to perform action.') + end + end + +end diff --git a/src/app/services/vm_service.rb b/src/app/services/vm_service.rb new file mode 100644 index 0000000..c44afb7 --- /dev/null +++ b/src/app/services/vm_service.rb @@ -0,0 +1,183 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Written by Scott Seago , +# David Lutterkort +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# Mid-level API: Business logic around individual VM's +module VmService + + include ApplicationService + + def svc_show(vm_id) + # from before_filter + @vm = Vm.find(vm_id) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::VIEW, at vm.vm_resource_pool) + end + + def svc_create(vm_hash, start_now) + # from before_filter + vm_hash[:state] = Vm::STATE_PENDING + @vm = Vm.new(params[:vm]) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::MODIFY, at vm.vm_resource_pool) + + alert = "VM was successfully created." + Vm.transaction do + @vm.save! + vm_provision + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_CREATE_VM, + :state => Task::STATE_QUEUED}) + @task.save! + if start_now + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Start action queued." + else + alert += " Resources are not available to start VM now." + end + end + end + return alert + end + + def svc_update(vm_id, vm_hash, start_now, restart_now) + # from before_filter + @vm = Vm.find(vm_id) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) + + #needs restart if certain fields are changed + # (since those will only take effect the next startup) + needs_restart = false + unless @vm.get_pending_state == Vm::STATE_STOPPED + Vm::NEEDS_RESTART_FIELDS.each do |field| + unless @vm[field].to_s == vm_hash[field] + needs_restart = true + break + end + end + current_storage_ids = @vm.storage_volume_ids.sort + new_storage_ids = vm_hash[:storage_volume_ids] + new_storage_ids = [] unless new_storage_ids + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } + needs_restart = true unless current_storage_ids == new_storage_ids + end + vm_hash[:needs_restart] = 1 if needs_restart + + + alert = "VM was successfully updated." + Vm.transaction do + @vm.update_attributes!(vm_hash) + vm_provision + if start_now + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Start action queued." + else + alert += " Resources are not available to start VM now." + end + elsif restart_now + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_SHUTDOWN_VM, + :state => Task::STATE_QUEUED}) + @task.save! + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) + @task.save! + alert += " VM Restart action queued." + else + alert += " Restart action was not available." + end + end + end + return alert + end + + def svc_destroy(vm_id) + # from before_filter + @vm = Vm.find(vm_id) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) + + unless @vm.is_destroyable? + raise ActionError.new("Virtual Machine must be stopped to delete it") + end + destroy_cobbler_system(@vm) + @vm.destroy + return "Virtual Machine wa ssuccessfully deleted." + end + + def svc_vm_action(vm_id, vm_action, action_args) + @vm = Vm.find(vm_id) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) + unless @vm.queue_action(@user, vm_action, action_args) + raise ActionError.new("#{vm_action} is an invalid action.") + end + return "#{vm_action} was successfully queued." + end + + def svc_cancel_queued_tasks(vm_id) + @vm = Vm.find(vm_id) + @current_pool_id=@vm.vm_resource_pool.id + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) + + Task.transaction do + @vm.tasks.queued.each { |task| task.cancel} + end + return "Queued tasks were successfully canceled." + end + + def vm_provision + if @vm.uses_cobbler? + # spaces are invalid in the cobbler name + name = @vm.uuid + system = Cobbler::System.find_one(name) + unless system + system = Cobbler::System.new("name" => name, + @vm.cobbler_type => @vm.cobbler_name) + system.interfaces = [Cobbler::NetworkInterface.new( + {'mac_address' => @vm.vnic_mac_addr})] + system.save + end + end + end + + def destroy_cobbler_system(vm) + # Destroy the Cobbler system first if it's defined + if vm.uses_cobbler? + system = Cobbler::System.find_one(vm.cobbler_system_name) + system.remove if system + end + end + +end diff --git a/src/app/views/vm/_form.rhtml b/src/app/views/vm/_form.rhtml index 58a3d61..610f2bc 100644 --- a/src/app/views/vm/_form.rhtml +++ b/src/app/views/vm/_form.rhtml @@ -3,8 +3,7 @@ <% start_resources = @vm.vm_resource_pool.available_resources_for_vm(@vm) %> -<%= hidden_field 'vm', 'vm_resource_pool_id' unless @vm_resource_pool_name %> -<%= hidden_field_tag 'vm_resource_pool_name', @vm_resource_pool_name if @vm_resource_pool_name %> +<%= hidden_field 'vm', 'vm_resource_pool_id' %> <%= hidden_field_tag 'hardware_pool_id', @hardware_pool.id if @hardware_pool %> <%= text_field_with_label "Name:", "vm", "description", {:style=>"width:250px;"} %> -- 1.6.0.6 From imain at redhat.com Mon Apr 20 22:13:47 2009 From: imain at redhat.com (Ian Main) Date: Mon, 20 Apr 2009 15:13:47 -0700 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240240393-5759-1-git-send-email-sseago@redhat.com> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> Message-ID: <20090420151347.48b7e0af@tp.mains.net> On Mon, 20 Apr 2009 15:13:13 +0000 Scott Seago wrote: > This code is based on David Lutterkort's proposal outlined in > https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html [SNIP] > + def svc_create(vm_hash, start_now) > + # from before_filter > + vm_hash[:state] = Vm::STATE_PENDING > + @vm = Vm.new(params[:vm]) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + > + alert = "VM was successfully created." > + Vm.transaction do > + @vm.save! > + vm_provision > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_CREATE_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + if start_now > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! I can see this is a bit odd.. if we're calling this from QMF then there's going to be issues here.. In the current API I don't have create VM returning a task, which is kind of beside the point, but if it did then we would have to have a QMF object of this task figured out when the command returned (there are other APIs that do return tasks like start_vm). I'm not entirely sure how that would work using this API right now.. we'd have to somehow figure out which task it was that was put in the DB.. I wonder if there is a better way to approach this? I'm not going to argue this hard here because I know this is a first cut and just a refactoring but I do think there should be no tasks associated with creating a VM definition for the API. I think we've talked about this before.. not a big deal, just wanted to bring it up for future reference :). Ian From imain at redhat.com Mon Apr 20 22:22:12 2009 From: imain at redhat.com (Ian Main) Date: Mon, 20 Apr 2009 15:22:12 -0700 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240240393-5759-1-git-send-email-sseago@redhat.com> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> Message-ID: <20090420152212.53ec57c5@tp.mains.net> On Mon, 20 Apr 2009 15:13:13 +0000 Scott Seago wrote: > This code is based on David Lutterkort's proposal outlined in > https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html > [SNIP] > + > + def svc_create(vm_hash, start_now) > + # from before_filter > + vm_hash[:state] = Vm::STATE_PENDING > + @vm = Vm.new(params[:vm]) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + > + alert = "VM was successfully created." > + Vm.transaction do > + @vm.save! > + vm_provision > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_CREATE_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + if start_now > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Start action queued." > + else > + alert += " Resources are not available to start VM now." > + end > + end > + end > + return alert > + end I also just realized that we return the newly created VM definition in the QMF API too.. so again we'd have to somehow figure out which new VM was created when making this call.. I think it would be good to return the VM ID? Isn't this some kind of odd design where you have all these side effects from calling a single method? > + def svc_update(vm_id, vm_hash, start_now, restart_now) > + # from before_filter > + @vm = Vm.find(vm_id) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + > + #needs restart if certain fields are changed > + # (since those will only take effect the next startup) > + needs_restart = false > + unless @vm.get_pending_state == Vm::STATE_STOPPED > + Vm::NEEDS_RESTART_FIELDS.each do |field| > + unless @vm[field].to_s == vm_hash[field] > + needs_restart = true > + break > + end > + end > + current_storage_ids = @vm.storage_volume_ids.sort > + new_storage_ids = vm_hash[:storage_volume_ids] > + new_storage_ids = [] unless new_storage_ids > + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } > + needs_restart = true unless current_storage_ids == new_storage_ids > + end > + vm_hash[:needs_restart] = 1 if needs_restart > + > + > + alert = "VM was successfully updated." > + Vm.transaction do > + @vm.update_attributes!(vm_hash) > + vm_provision > + if start_now > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Start action queued." > + else > + alert += " Resources are not available to start VM now." > + end > + elsif restart_now > + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_SHUTDOWN_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Restart action queued." > + else > + alert += " Restart action was not available." > + end > + end > + end > + return alert > + end Is this something we want in the API? It seems a little odd to me from a usage standpoint for the QMF implementation. It will require that we map the info from the active record into a hash, then pass it to this method with the property changed, and then deal with side effects from tasks starting? > + def svc_destroy(vm_id) > + # from before_filter > + @vm = Vm.find(vm_id) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + > + unless @vm.is_destroyable? > + raise ActionError.new("Virtual Machine must be stopped to delete it") > + end > + destroy_cobbler_system(@vm) > + @vm.destroy > + return "Virtual Machine wa ssuccessfully deleted." > + end > + > + def svc_vm_action(vm_id, vm_action, action_args) > + @vm = Vm.find(vm_id) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + unless @vm.queue_action(@user, vm_action, action_args) > + raise ActionError.new("#{vm_action} is an invalid action.") > + end > + return "#{vm_action} was successfully queued." > + end > + > + def svc_cancel_queued_tasks(vm_id) > + @vm = Vm.find(vm_id) > + @perm_obj = @vm.vm_resource_pool > + @current_pool_id=@perm_obj.id > + authorized!(Privilege::MODIFY) > + > + Task.transaction do > + @vm.tasks.queued.each { |task| task.cancel} > + end > + return "Queued tasks were successfully canceled." > + end So I'm guessing things like this we would just ignore? I'm thinking we may end up using only a portion of the calls here.. In QMF I would think you would just do a search of open tasks where the target is the VM in question and then call cancel on them. > + > + def vm_provision > + if @vm.uses_cobbler? > + # spaces are invalid in the cobbler name > + name = @vm.uuid > + system = Cobbler::System.find_one(name) > + unless system > + system = Cobbler::System.new("name" => name, > + @vm.cobbler_type => @vm.cobbler_name) > + system.interfaces = [Cobbler::NetworkInterface.new( > + {'mac_address' => @vm.vnic_mac_addr})] > + system.save > + end > + end > + end I'm not sure how these fit in either.. > + def destroy_cobbler_system(vm) > + # Destroy the Cobbler system first if it's defined > + if vm.uses_cobbler? > + system = Cobbler::System.find_one(vm.cobbler_system_name) > + system.remove if system > + end > + end Ian From lutter at redhat.com Mon Apr 20 22:30:06 2009 From: lutter at redhat.com (David Lutterkort) Date: Mon, 20 Apr 2009 22:30:06 +0000 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090420151347.48b7e0af@tp.mains.net> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> <20090420151347.48b7e0af@tp.mains.net> Message-ID: <1240266606.12933.51.camel@avon.watzmann.net> On Mon, 2009-04-20 at 15:13 -0700, Ian Main wrote: > > + def svc_create(vm_hash, start_now) > > + # from before_filter > > + vm_hash[:state] = Vm::STATE_PENDING > > + @vm = Vm.new(params[:vm]) > > + @perm_obj = @vm.vm_resource_pool > > + @current_pool_id=@perm_obj.id > > + authorized!(Privilege::MODIFY) > > + > > + alert = "VM was successfully created." > > + Vm.transaction do > > + @vm.save! > > + vm_provision > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_CREATE_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + if start_now > > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_START_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > I can see this is a bit odd.. if we're calling this from QMF then > there's going to be issues here.. In the current API I don't have > create VM returning a task, which is kind of beside the point, but if > it did then we would have to have a QMF object of this task figured > out when the command returned (there are other APIs that do return > tasks like start_vm). I'm not entirely sure how that would work using > this API right now.. we'd have to somehow figure out which task it was > that was put in the DB.. I wonder if there is a better way to approach > this? It depends on which task the QMF API would return, but in general the last task created by this method would be available in the QMF agent as @task. If you needed something else, we could change the above code to remember it somewhere else - these are all internal API's, and we can change things around as we go along. I expect that once we start implementing the QMF agent, we'll discover lots of places where things need to be changed to be more convenient for QMF purposes. > I'm not going to argue this hard here because I know this is a first cut > and just a refactoring but I do think there should be no tasks > associated with creating a VM definition for the API. I think we've > talked about this before.. not a big deal, just wanted to bring it up > for future reference :). Yeah, I think we should see if we can kill the CREATE_VM task altogether, but as you said, it's a little besides the point, since it's orthogonal to the refactoring happening right now. David From lutter at redhat.com Mon Apr 20 22:37:34 2009 From: lutter at redhat.com (David Lutterkort) Date: Mon, 20 Apr 2009 15:37:34 -0700 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090420152212.53ec57c5@tp.mains.net> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> <20090420152212.53ec57c5@tp.mains.net> Message-ID: <1240267054.12933.59.camel@avon.watzmann.net> On Mon, 2009-04-20 at 15:22 -0700, Ian Main wrote: > On Mon, 20 Apr 2009 15:13:13 +0000 > Scott Seago wrote: > > + > > + def svc_create(vm_hash, start_now) > > + # from before_filter > > + vm_hash[:state] = Vm::STATE_PENDING > > + @vm = Vm.new(params[:vm]) > > + @perm_obj = @vm.vm_resource_pool > > + @current_pool_id=@perm_obj.id > > + authorized!(Privilege::MODIFY) > > + > > + alert = "VM was successfully created." > > + Vm.transaction do > > + @vm.save! > > + vm_provision > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_CREATE_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + if start_now > > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_START_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + alert += " VM Start action queued." > > + else > > + alert += " Resources are not available to start VM now." > > + end > > + end > > + end > > + return alert > > + end > > > I also just realized that we return the newly created VM definition in > the QMF API too.. so again we'd have to somehow figure out which new VM > was created when making this call.. I think it would be good to return > the VM ID? Isn't this some kind of odd design where you have all these > side effects from calling a single method? That's the strange beauty of using modules here .. you can access the newly created VM as @vm in whatever class includes that module - it works well for the Rails code, so I'd hope it will also work for the QMF agent; if it starts to get too confusing, we can think about changing either the return type, e.g. to [alert, @vm], or document these sideeffects more clearly. > > + def svc_update(vm_id, vm_hash, start_now, restart_now) > > + # from before_filter > > + @vm = Vm.find(vm_id) > > + @perm_obj = @vm.vm_resource_pool > > + @current_pool_id=@perm_obj.id > > + authorized!(Privilege::MODIFY) > > + > > + #needs restart if certain fields are changed > > + # (since those will only take effect the next startup) > > + needs_restart = false > > + unless @vm.get_pending_state == Vm::STATE_STOPPED > > + Vm::NEEDS_RESTART_FIELDS.each do |field| > > + unless @vm[field].to_s == vm_hash[field] > > + needs_restart = true > > + break > > + end > > + end > > + current_storage_ids = @vm.storage_volume_ids.sort > > + new_storage_ids = vm_hash[:storage_volume_ids] > > + new_storage_ids = [] unless new_storage_ids > > + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } > > + needs_restart = true unless current_storage_ids == new_storage_ids > > + end > > + vm_hash[:needs_restart] = 1 if needs_restart > > + > > + > > + alert = "VM was successfully updated." > > + Vm.transaction do > > + @vm.update_attributes!(vm_hash) > > + vm_provision > > + if start_now > > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_START_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + alert += " VM Start action queued." > > + else > > + alert += " Resources are not available to start VM now." > > + end > > + elsif restart_now > > + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_SHUTDOWN_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + @task = VmTask.new({ :user => @user, > > + :task_target => @vm, > > + :action => VmTask::ACTION_START_VM, > > + :state => Task::STATE_QUEUED}) > > + @task.save! > > + alert += " VM Restart action queued." > > + else > > + alert += " Restart action was not available." > > + end > > + end > > + end > > + return alert > > + end > > Is this something we want in the API? It seems a little odd to me from > a usage standpoint for the QMF implementation. It will require that we > map the info from the active record into a hash, then pass it to this > method with the property changed, and then deal with side effects from > tasks starting? Not sure I understand - do you mean that you'd like to have a more direct way to start/stop/etc. a VM for QMF ? I agree that that should be the case, and we should have such methods in the service layer - we definitely will need further changes to accomodate QMF. For now the focus is more on separating presentation logic from core business logic - restructuring the business logic to better fit QMF will be the next step. > > + def svc_cancel_queued_tasks(vm_id) > > + @vm = Vm.find(vm_id) > > + @perm_obj = @vm.vm_resource_pool > > + @current_pool_id=@perm_obj.id > > + authorized!(Privilege::MODIFY) > > + > > + Task.transaction do > > + @vm.tasks.queued.each { |task| task.cancel} > > + end > > + return "Queued tasks were successfully canceled." > > + end > > So I'm guessing things like this we would just ignore? I'm thinking we > may end up using only a portion of the calls here.. In QMF I would > think you would just do a search of open tasks where the target is the > VM in question and then call cancel on them. Sure .. we'd only use the above from the QMF agent if we needed to support a 'cancel all tasks' API call. David From sseago at redhat.com Tue Apr 21 02:00:03 2009 From: sseago at redhat.com (Scott Seago) Date: Mon, 20 Apr 2009 22:00:03 -0400 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240266606.12933.51.camel@avon.watzmann.net> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> <20090420151347.48b7e0af@tp.mains.net> <1240266606.12933.51.camel@avon.watzmann.net> Message-ID: <49ED28A3.5060009@redhat.com> David Lutterkort wrote: > On Mon, 2009-04-20 at 15:13 -0700, Ian Main wrote: > >>> + def svc_create(vm_hash, start_now) >>> + # from before_filter >>> + vm_hash[:state] = Vm::STATE_PENDING >>> + @vm = Vm.new(params[:vm]) >>> + @perm_obj = @vm.vm_resource_pool >>> + @current_pool_id=@perm_obj.id >>> + authorized!(Privilege::MODIFY) >>> + >>> + alert = "VM was successfully created." >>> + Vm.transaction do >>> + @vm.save! >>> + vm_provision >>> + @task = VmTask.new({ :user => @user, >>> + :task_target => @vm, >>> + :action => VmTask::ACTION_CREATE_VM, >>> + :state => Task::STATE_QUEUED}) >>> + @task.save! >>> + if start_now >>> + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) >>> + @task = VmTask.new({ :user => @user, >>> + :task_target => @vm, >>> + :action => VmTask::ACTION_START_VM, >>> + :state => Task::STATE_QUEUED}) >>> + @task.save! >>> >> I can see this is a bit odd.. if we're calling this from QMF then >> there's going to be issues here.. In the current API I don't have >> create VM returning a task, which is kind of beside the point, but if >> it did then we would have to have a QMF object of this task figured >> out when the command returned (there are other APIs that do return >> tasks like start_vm). I'm not entirely sure how that would work using >> this API right now.. we'd have to somehow figure out which task it was >> that was put in the DB.. I wonder if there is a better way to approach >> this? >> > > It depends on which task the QMF API would return, but in general the > last task created by this method would be available in the QMF agent as > @task. > > If you needed something else, we could change the above code to remember > it somewhere else - these are all internal API's, and we can change > things around as we go along. I expect that once we start implementing > the QMF agent, we'll discover lots of places where things need to be > changed to be more convenient for QMF purposes. > > >> I'm not going to argue this hard here because I know this is a first cut >> and just a refactoring but I do think there should be no tasks >> associated with creating a VM definition for the API. I think we've >> talked about this before.. not a big deal, just wanted to bring it up >> for future reference :). >> > > Yeah, I think we should see if we can kill the CREATE_VM task > altogether, but as you said, it's a little besides the point, since it's > orthogonal to the refactoring happening right now. > > David > Yes, the create_vm task is definitely an issue to discuss. It's completely orthogonal to the refactoring and the QMF API, but it's still something we need to nail down. At the moment the create_vm task doesn't really do anything, and we don't even have a modify_vm task. At one point the cobbler system creation was in the create_vm task, as the original goal was to isolate the WUI from making external calls as much as possible. We ended up having to pull it back into the WUI when we added cobbler functionality into the modify VM form, but we had discussed eventually pulling out all cobbler system creation/modification bits _back_ into the create_vm task as well as a not-yet-created modify_vm task. At the time clalance and I were thinking that pulling it into taskomatic would be a cleaner way of handling this code. The idea was to avoid doing anything from the WUI that could potentially block. Is there any reason why doing this in taskomatic would be a bad thing? Scott From sseago at redhat.com Tue Apr 21 02:09:02 2009 From: sseago at redhat.com (Scott Seago) Date: Mon, 20 Apr 2009 22:09:02 -0400 Subject: [Ovirt-devel] [PATCH server] First attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090420152212.53ec57c5@tp.mains.net> References: <1240240393-5759-1-git-send-email-sseago@redhat.com> <20090420152212.53ec57c5@tp.mains.net> Message-ID: <49ED2ABE.5000407@redhat.com> Ian Main wrote: > On Mon, 20 Apr 2009 15:13:13 +0000 > Scott Seago wrote: > > >> This code is based on David Lutterkort's proposal outlined in >> https://www.redhat.com/archives/ovirt-devel/2009-April/msg00086.html >> >> > [SNIP] > > >> + >> + def svc_create(vm_hash, start_now) >> + # from before_filter >> + vm_hash[:state] = Vm::STATE_PENDING >> + @vm = Vm.new(params[:vm]) >> + @perm_obj = @vm.vm_resource_pool >> + @current_pool_id=@perm_obj.id >> + authorized!(Privilege::MODIFY) >> + >> + alert = "VM was successfully created." >> + Vm.transaction do >> + @vm.save! >> + vm_provision >> + @task = VmTask.new({ :user => @user, >> + :task_target => @vm, >> + :action => VmTask::ACTION_CREATE_VM, >> + :state => Task::STATE_QUEUED}) >> + @task.save! >> + if start_now >> + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) >> + @task = VmTask.new({ :user => @user, >> + :task_target => @vm, >> + :action => VmTask::ACTION_START_VM, >> + :state => Task::STATE_QUEUED}) >> + @task.save! >> + alert += " VM Start action queued." >> + else >> + alert += " Resources are not available to start VM now." >> + end >> + end >> + end >> + return alert >> + end >> > > > I also just realized that we return the newly created VM definition in > the QMF API too.. so again we'd have to somehow figure out which new VM > was created when making this call.. I think it would be good to return > the VM ID? Isn't this some kind of odd design where you have all these > side effects from calling a single method? > > Yeah as David said we are "returning" it by setting the @vm instance variable. (and the @task variable too). I don't really see these so much as side effects than as the primary effect of calling this method. svc_create is responsible for all business logic associated with creating a new VM -- which includes the VM description record in the DB _and_ any required tasks. This includes the create task (if we end up keeping it long-term) and the start task -- since from a usability point of view we definitely want to give the user the chance to start the newly-created VM as part of the single logical creation action. >> + def svc_update(vm_id, vm_hash, start_now, restart_now) >> + # from before_filter >> + @vm = Vm.find(vm_id) >> + @perm_obj = @vm.vm_resource_pool >> + @current_pool_id=@perm_obj.id >> + authorized!(Privilege::MODIFY) >> + >> + #needs restart if certain fields are changed >> + # (since those will only take effect the next startup) >> + needs_restart = false >> + unless @vm.get_pending_state == Vm::STATE_STOPPED >> + Vm::NEEDS_RESTART_FIELDS.each do |field| >> + unless @vm[field].to_s == vm_hash[field] >> + needs_restart = true >> + break >> + end >> + end >> + current_storage_ids = @vm.storage_volume_ids.sort >> + new_storage_ids = vm_hash[:storage_volume_ids] >> + new_storage_ids = [] unless new_storage_ids >> + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } >> + needs_restart = true unless current_storage_ids == new_storage_ids >> + end >> + vm_hash[:needs_restart] = 1 if needs_restart >> + >> + >> + alert = "VM was successfully updated." >> + Vm.transaction do >> + @vm.update_attributes!(vm_hash) >> + vm_provision >> + if start_now >> + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) >> + @task = VmTask.new({ :user => @user, >> + :task_target => @vm, >> + :action => VmTask::ACTION_START_VM, >> + :state => Task::STATE_QUEUED}) >> + @task.save! >> + alert += " VM Start action queued." >> + else >> + alert += " Resources are not available to start VM now." >> + end >> + elsif restart_now >> + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) >> + @task = VmTask.new({ :user => @user, >> + :task_target => @vm, >> + :action => VmTask::ACTION_SHUTDOWN_VM, >> + :state => Task::STATE_QUEUED}) >> + @task.save! >> + @task = VmTask.new({ :user => @user, >> + :task_target => @vm, >> + :action => VmTask::ACTION_START_VM, >> + :state => Task::STATE_QUEUED}) >> + @task.save! >> + alert += " VM Restart action queued." >> + else >> + alert += " Restart action was not available." >> + end >> + end >> + end >> + return alert >> + end >> > > Is this something we want in the API? It seems a little odd to me from > a usage standpoint for the QMF implementation. It will require that we > map the info from the active record into a hash, then pass it to this > method with the property changed, and then deal with side effects from > tasks starting? > > Most of this stuff is done as a hash since on the web side we already get a hash from the form submission _and_ AR expects a hash to come in to define the new VM. I'd expect the public QMF API wouldn't get a hash -- we'd pass in explicit parameters, and the QMF implementation (the class that includes the vm_service module) would take those params and generate the hash to pass into svc_create, scv_update, etc. The task bits are parallel to the 'new VM' case -- since some VM characteristics require a restart to take effect, we want to give the user the opportunity to trigger a restart as part of the update action. It may be that for QMF we _don't_ want to include restart as an option for the modify task -- that's OK -- we just wouldn't expose the start_now, restart_now attributes in the API. >> + def svc_destroy(vm_id) >> + # from before_filter >> + @vm = Vm.find(vm_id) >> + @perm_obj = @vm.vm_resource_pool >> + @current_pool_id=@perm_obj.id >> + authorized!(Privilege::MODIFY) >> + >> + unless @vm.is_destroyable? >> + raise ActionError.new("Virtual Machine must be stopped to delete it") >> + end >> + destroy_cobbler_system(@vm) >> + @vm.destroy >> + return "Virtual Machine wa ssuccessfully deleted." >> + end >> + >> + def svc_vm_action(vm_id, vm_action, action_args) >> + @vm = Vm.find(vm_id) >> + @perm_obj = @vm.vm_resource_pool >> + @current_pool_id=@perm_obj.id >> + authorized!(Privilege::MODIFY) >> + unless @vm.queue_action(@user, vm_action, action_args) >> + raise ActionError.new("#{vm_action} is an invalid action.") >> + end >> + return "#{vm_action} was successfully queued." >> + end >> + >> + def svc_cancel_queued_tasks(vm_id) >> + @vm = Vm.find(vm_id) >> + @perm_obj = @vm.vm_resource_pool >> + @current_pool_id=@perm_obj.id >> + authorized!(Privilege::MODIFY) >> + >> + Task.transaction do >> + @vm.tasks.queued.each { |task| task.cancel} >> + end >> + return "Queued tasks were successfully canceled." >> + end >> > > So I'm guessing things like this we would just ignore? I'm thinking we > may end up using only a portion of the calls here.. In QMF I would > think you would just do a search of open tasks where the target is the > VM in question and then call cancel on them. > > Sure -- and if there was _no_ reason for a cancel_queued_tasks_for_vm action in the API I could even pull this method back into the controller. We don't need _all_ methods going through the service layer -- only those that are useful for both WUI and QMF. >> + >> + def vm_provision >> + if @vm.uses_cobbler? >> + # spaces are invalid in the cobbler name >> + name = @vm.uuid >> + system = Cobbler::System.find_one(name) >> + unless system >> + system = Cobbler::System.new("name" => name, >> + @vm.cobbler_type => @vm.cobbler_name) >> + system.interfaces = [Cobbler::NetworkInterface.new( >> + {'mac_address' => @vm.vnic_mac_addr})] >> + system.save >> + end >> + end >> + end >> > > I'm not sure how these fit in either.. > > This is just an internal method called by svc_create and svc_update -- this is the bit that could be pulled into the start_vm (and not-currently-created modify_vm) tasks in the future. It won't be part of the API. Scott >> + def destroy_cobbler_system(vm) >> + # Destroy the Cobbler system first if it's defined >> + if vm.uses_cobbler? >> + system = Cobbler::System.find_one(vm.cobbler_system_name) >> + system.remove if system >> + end >> + end >> > > Ian > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel > From idol.levy at gmail.com Tue Apr 21 09:13:40 2009 From: idol.levy at gmail.com (Ido Levy) Date: Tue, 21 Apr 2009 12:13:40 +0300 Subject: [Ovirt-devel] Installing Ovirt Message-ID: <74f065630904210213r3bfcbbbg82557a08bc40f837@mail.gmail.com> Hello All, We have tried to install an oVirt server using the following link - http://ovirt.org/install-instructions.html We used the latest RPMs from oVirt repo ( 04/07/09 ). All stages went fine until we have executed the install command - ace -d -l ovirt-install-log install ovirt Log File Output: Tue Apr 21 11:47:11 +0300 2009 executing puppet -d -v --detailed-exitcodes --templatedir=/usr/share/ace/appliances/ovirt/templates --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances --factpath=/usr/share/ace/facts --logdest=ovirt-install-log /usr/share/ace/manifests/pre_install.pp Tue Apr 21 11:47:14 +0300 2009 executing puppet -d -v --detailed-exitcodes --templatedir=/usr/share/ace/appliances/ovirt/templates --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances --factpath=/usr/share/ace/facts --logdest=ovirt-install-log /usr/share/ace/appliances/ovirt/ovirt.pp Screen Output is attached. Any advice would be appreciated Thanks Ido & Oshrit -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: screen-out Type: application/octet-stream Size: 22642 bytes Desc: not available URL: From sseago at redhat.com Tue Apr 21 14:01:05 2009 From: sseago at redhat.com (Scott Seago) Date: Tue, 21 Apr 2009 14:01:05 +0000 Subject: [Ovirt-devel] [PATCH server] Taskomatic wasn't catching exceptions extending Exception or errors raised while saving the task. Message-ID: <1240322465-16480-1-git-send-email-sseago@redhat.com> Signed-off-by: Scott Seago --- src/task-omatic/taskomatic.rb | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/task-omatic/taskomatic.rb b/src/task-omatic/taskomatic.rb index f852c32..850701f 100755 --- a/src/task-omatic/taskomatic.rb +++ b/src/task-omatic/taskomatic.rb @@ -859,7 +859,7 @@ class TaskOmatic state = Task::STATE_FAILED task.message = "Unknown task type" end - rescue => ex + rescue Exception => ex @logger.error "Task action processing failed: #{ex.class}: #{ex.message}" @logger.error ex.backtrace state = Task::STATE_FAILED @@ -868,7 +868,12 @@ class TaskOmatic task.state = state task.time_ended = Time.now - task.save! + begin + task.save! + rescue Exception => ex + @logger.error "Error saving task state for task #{task.id}: #{ex.class}: #{ex.message}" + @logger.error ex.backtrace + end @logger.info "done" end # FIXME: here, we clean up "orphaned" tasks. These are tasks -- 1.6.0.6 From dpierce at redhat.com Tue Apr 21 14:57:51 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 10:57:51 -0400 Subject: [Ovirt-devel] Array, not Hash Message-ID: <1240325872-20011-1-git-send-email-dpierce@redhat.com> Overrides previous patch, which set nic_info to be a Hash rather than an Array. From dpierce at redhat.com Tue Apr 21 14:57:52 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 10:57:52 -0400 Subject: [Ovirt-devel] [PATCH server] Makes host-browser tolerant of a node that reports no NICs. In-Reply-To: <1240325872-20011-1-git-send-email-dpierce@redhat.com> References: <1240325872-20011-1-git-send-email-dpierce@redhat.com> Message-ID: <1240325872-20011-2-git-send-email-dpierce@redhat.com> Signed-off-by: Darryl L. Pierce --- src/host-browser/host-browser.rb | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb index 945b1d2..13b2ac4 100755 --- a/src/host-browser/host-browser.rb +++ b/src/host-browser/host-browser.rb @@ -85,6 +85,7 @@ class HostBrowser result = Hash.new result['HOSTNAME'] = @session.peeraddr[2] result['IPADDR'] = @session.peeraddr[3] + result['NICINFO'] = Array.new @session.write("INFO?\n") -- 1.6.0.6 From slinabery at redhat.com Tue Apr 21 15:20:00 2009 From: slinabery at redhat.com (Steve Linabery) Date: Tue, 21 Apr 2009 10:20:00 -0500 Subject: [Ovirt-devel] [PATCH server] Makes host-browser tolerant of a node that reports no NICs. In-Reply-To: <1240325872-20011-2-git-send-email-dpierce@redhat.com> References: <1240325872-20011-1-git-send-email-dpierce@redhat.com> <1240325872-20011-2-git-send-email-dpierce@redhat.com> Message-ID: <20090421151958.GF17184@redhat.com> On Tue, Apr 21, 2009 at 10:57:52AM -0400, Darryl L. Pierce wrote: > > Signed-off-by: Darryl L. Pierce > --- > src/host-browser/host-browser.rb | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb > index 945b1d2..13b2ac4 100755 > --- a/src/host-browser/host-browser.rb > +++ b/src/host-browser/host-browser.rb > @@ -85,6 +85,7 @@ class HostBrowser > result = Hash.new > result['HOSTNAME'] = @session.peeraddr[2] > result['IPADDR'] = @session.peeraddr[3] > + result['NICINFO'] = Array.new > > @session.write("INFO?\n") > > -- > 1.6.0.6 > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel ACK ACK! From slinabery at redhat.com Tue Apr 21 15:20:29 2009 From: slinabery at redhat.com (Steve Linabery) Date: Tue, 21 Apr 2009 10:20:29 -0500 Subject: [Ovirt-devel] [PATCH node] Fixed where sending no NICs returned an error result. In-Reply-To: <1239995439-12072-1-git-send-email-dpierce@redhat.com> References: <1239995439-12072-1-git-send-email-dpierce@redhat.com> Message-ID: <20090421152028.GG17184@redhat.com> On Fri, Apr 17, 2009 at 03:10:39PM -0400, Darryl L. Pierce wrote: > If there are no NICs to send, then the result is set to success and then > returned. > > If no NICs were sent due to the only NIC found being ignored, then a > default success is returned. > > Otherwise, processing NICs works as desired. > > Signed-off-by: Darryl L. Pierce > --- > ovirt-identify-node/protocol.c | 48 ++++++++++++++++++++++++--------------- > 1 files changed, 29 insertions(+), 19 deletions(-) > > diff --git a/ovirt-identify-node/protocol.c b/ovirt-identify-node/protocol.c > index 0382dac..1099ebb 100644 > --- a/ovirt-identify-node/protocol.c > +++ b/ovirt-identify-node/protocol.c > @@ -176,26 +176,36 @@ send_nic_details(void) > > nic_info_ptr current = nic_info; > > - while (current != NULL) { > - if((!management_interface) || (strcmp(management_interface, current->iface_name))) { > - send_text("NIC"); > - > - if (!(get_text("NICINFO?")) && > - (!send_value("MAC", current->mac_address)) && > - (!send_value("BANDWIDTH", current->bandwidth)) && > - (!send_value("IFACE_NAME", current->iface_name)) && > - (!send_value("IP_ADDRESS", current->ip_address)) && > - (!send_value("NETMASK", current->netmask)) && > - (!send_value("BROADCAST", current->broadcast))) { > - send_text("ENDNIC"); > - result = get_text("ACK NIC"); > - } > - > - current = current->next; > - } else { > - current = current->next; > + /* only send NIC details if we found NICs to process */ > + if(current) { > + int sent_count = 0; > + while (current != NULL) { > + if((!management_interface) || (strcmp(management_interface, current->iface_name))) { > + send_text("NIC"); > + > + if (!(get_text("NICINFO?")) && > + (!send_value("MAC", current->mac_address)) && > + (!send_value("BANDWIDTH", current->bandwidth)) && > + (!send_value("IFACE_NAME", current->iface_name)) && > + (!send_value("IP_ADDRESS", current->ip_address)) && > + (!send_value("NETMASK", current->netmask)) && > + (!send_value("BROADCAST", current->broadcast))) { > + send_text("ENDNIC"); > + result = get_text("ACK NIC"); > + sent_count++; > + } > + > + current = current->next; > + } else { > + current = current->next; > + } > } > - } > + > + /* if no nics were sent, then set default success */ > + if( sent_count == 0) > + result = 0; > + > + } else { result = 0; } > > return result; > } > -- > 1.6.0.6 > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel ACK! From dpierce at redhat.com Tue Apr 21 15:31:39 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 11:31:39 -0400 Subject: [Ovirt-devel] [PATCH server] Makes host-browser tolerant of a node that reports no NICs. In-Reply-To: <20090421151958.GF17184@redhat.com> References: <1240325872-20011-1-git-send-email-dpierce@redhat.com> <1240325872-20011-2-git-send-email-dpierce@redhat.com> <20090421151958.GF17184@redhat.com> Message-ID: <20090421153139.GE3958@mcpierce-laptop.rdu.redhat.com> On Tue, Apr 21, 2009 at 10:20:00AM -0500, Steve Linabery wrote: > On Tue, Apr 21, 2009 at 10:57:52AM -0400, Darryl L. Pierce wrote: > > > > Signed-off-by: Darryl L. Pierce > > --- > > src/host-browser/host-browser.rb | 1 + > > 1 files changed, 1 insertions(+), 0 deletions(-) > > > > diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb > > index 945b1d2..13b2ac4 100755 > > --- a/src/host-browser/host-browser.rb > > +++ b/src/host-browser/host-browser.rb > > @@ -85,6 +85,7 @@ class HostBrowser > > result = Hash.new > > result['HOSTNAME'] = @session.peeraddr[2] > > result['IPADDR'] = @session.peeraddr[3] > > + result['NICINFO'] = Array.new > > > > @session.write("INFO?\n") > > > > -- > > 1.6.0.6 > > > > _______________________________________________ > > Ovirt-devel mailing list > > Ovirt-devel at redhat.com > > https://www.redhat.com/mailman/listinfo/ovirt-devel > > ACK ACK! Thanks. Pushed now. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Tue Apr 21 15:32:58 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 11:32:58 -0400 Subject: [Ovirt-devel] [PATCH node] Fixed where sending no NICs returned an error result. In-Reply-To: <20090421152028.GG17184@redhat.com> References: <1239995439-12072-1-git-send-email-dpierce@redhat.com> <20090421152028.GG17184@redhat.com> Message-ID: <20090421153258.GF3958@mcpierce-laptop.rdu.redhat.com> On Tue, Apr 21, 2009 at 10:20:29AM -0500, Steve Linabery wrote: > On Fri, Apr 17, 2009 at 03:10:39PM -0400, Darryl L. Pierce wrote: > > If there are no NICs to send, then the result is set to success and then > > returned. > > > > If no NICs were sent due to the only NIC found being ignored, then a > > default success is returned. > > > > Otherwise, processing NICs works as desired. > > > > Signed-off-by: Darryl L. Pierce > > --- > > ovirt-identify-node/protocol.c | 48 ++++++++++++++++++++++++--------------- > > 1 files changed, 29 insertions(+), 19 deletions(-) > > > > diff --git a/ovirt-identify-node/protocol.c b/ovirt-identify-node/protocol.c > > index 0382dac..1099ebb 100644 > > --- a/ovirt-identify-node/protocol.c > > +++ b/ovirt-identify-node/protocol.c > > @@ -176,26 +176,36 @@ send_nic_details(void) > > > > nic_info_ptr current = nic_info; > > > > - while (current != NULL) { > > - if((!management_interface) || (strcmp(management_interface, current->iface_name))) { > > - send_text("NIC"); > > - > > - if (!(get_text("NICINFO?")) && > > - (!send_value("MAC", current->mac_address)) && > > - (!send_value("BANDWIDTH", current->bandwidth)) && > > - (!send_value("IFACE_NAME", current->iface_name)) && > > - (!send_value("IP_ADDRESS", current->ip_address)) && > > - (!send_value("NETMASK", current->netmask)) && > > - (!send_value("BROADCAST", current->broadcast))) { > > - send_text("ENDNIC"); > > - result = get_text("ACK NIC"); > > - } > > - > > - current = current->next; > > - } else { > > - current = current->next; > > + /* only send NIC details if we found NICs to process */ > > + if(current) { > > + int sent_count = 0; > > + while (current != NULL) { > > + if((!management_interface) || (strcmp(management_interface, current->iface_name))) { > > + send_text("NIC"); > > + > > + if (!(get_text("NICINFO?")) && > > + (!send_value("MAC", current->mac_address)) && > > + (!send_value("BANDWIDTH", current->bandwidth)) && > > + (!send_value("IFACE_NAME", current->iface_name)) && > > + (!send_value("IP_ADDRESS", current->ip_address)) && > > + (!send_value("NETMASK", current->netmask)) && > > + (!send_value("BROADCAST", current->broadcast))) { > > + send_text("ENDNIC"); > > + result = get_text("ACK NIC"); > > + sent_count++; > > + } > > + > > + current = current->next; > > + } else { > > + current = current->next; > > + } > > } > > - } > > + > > + /* if no nics were sent, then set default success */ > > + if( sent_count == 0) > > + result = 0; > > + > > + } else { result = 0; } > > > > return result; > > } > > -- > > 1.6.0.6 > > > > _______________________________________________ > > Ovirt-devel mailing list > > Ovirt-devel at redhat.com > > https://www.redhat.com/mailman/listinfo/ovirt-devel > > ACK! Thanks. This is pushed as well. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From dpierce at redhat.com Tue Apr 21 15:51:37 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 11:51:37 -0400 Subject: [Ovirt-devel] Problems with autotest on Fedora... Message-ID: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> I'm refactoring and extending the autotesting suite for ovirt-node-image. But, in trying to run them on Fedora rather than RHEL, the PXE booting never seems to successfully complete. I can see the virtual bridge created, dnsmasq starts properly, and the VM is defined to use the bridge and to boot from the network. I watch it start to boot, but then never seems to finish. Instead, it sits at: Loading 192.168.136.1:tftpboot/pxelinux.0 ...... The dots come up every few minutes, but only gets to about six of them and then just stops. Any suggestions on what to look for to fix this? -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From mmcgrath at redhat.com Tue Apr 21 16:26:00 2009 From: mmcgrath at redhat.com (Mike McGrath) Date: Tue, 21 Apr 2009 11:26:00 -0500 (CDT) Subject: [Ovirt-devel] Problems with autotest on Fedora... In-Reply-To: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> References: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> Message-ID: On Tue, 21 Apr 2009, Darryl L. Pierce wrote: > I'm refactoring and extending the autotesting suite for > ovirt-node-image. But, in trying to run them on Fedora rather than RHEL, > the PXE booting never seems to successfully complete. > > I can see the virtual bridge created, dnsmasq starts properly, and the > VM is defined to use the bridge and to boot from the network. I watch it > start to boot, but then never seems to finish. Instead, it sits at: > > Loading 192.168.136.1:tftpboot/pxelinux.0 ...... > > The dots come up every few minutes, but only gets to about six of them > and then just stops. > > Any suggestions on what to look for to fix this? > Not sure what the physical setup of this box is but I noticed that fedora sees the nics in a different order then RHEL. -Mike From dpierce at redhat.com Tue Apr 21 16:46:55 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 12:46:55 -0400 Subject: [Ovirt-devel] Problems with autotest on Fedora... In-Reply-To: References: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> Message-ID: <20090421164655.GA3860@mcpierce-laptop.mcpierce.org> On Tue, Apr 21, 2009 at 11:26:00AM -0500, Mike McGrath wrote: > Not sure what the physical setup of this box is but I noticed that fedora > sees the nics in a different order then RHEL. In this case, I think NIC ordering's not a factor: I can see in virt-viewer that the VM has connected to the instance of dnsmasq and has both been assigned an IP address via dhcp and has started downloading the node image. However, it only gets to a point then I can't tell if it's still downloading but not updating the viewer or if it's stopped entirely. The node XML follows: stateless-pxe 524288 1 hvm destroy restart restart /usr/bin/qemu-kvm And the configuration for my pxeboot is: DEFAULT pxeboot TIMEOUT 20 PROMPT 0 LABEL pxeboot KERNEL vmlinuz0 APPEND rootflags=loop initrd=initrd0.img root=/ovirt-node-image.iso rootfstype=auto ro liveimg console=tty0 console=ttyS0,115200n8 rhgb check rootfstype=iso9660 ONERROR LOCALBOOT 0 I trimmed off extra args (such as ovirt_standalone) to try and eliminate them as problems for booting. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From jboggs at redhat.com Tue Apr 21 17:01:31 2009 From: jboggs at redhat.com (Joey Boggs) Date: Tue, 21 Apr 2009 13:01:31 -0400 Subject: [Ovirt-devel] Installing Ovirt In-Reply-To: <74f065630904210213r3bfcbbbg82557a08bc40f837@mail.gmail.com> References: <74f065630904210213r3bfcbbbg82557a08bc40f837@mail.gmail.com> Message-ID: <49EDFBEB.303@redhat.com> It's actually a bug, it's caused when using an external dns server rather than choosing the bundled dnsmasq setup. Does your dns server already contain your machines and node A records? If not you will need to choose N on option for use this system's dns servers, that question can be misleading and will be updated. If your dns setup is correct we can provide a workaround. Ido Levy wrote: > Hello All, > > We have tried to install an oVirt server using the following link - > http://ovirt.org/install-instructions.html > We used the latest RPMs from oVirt repo ( 04/07/09 ). > > All stages went fine until we have executed the install command - ace > -d -l ovirt-install-log install ovirt > > Log File Output: > > Tue Apr 21 11:47:11 +0300 2009 executing puppet -d -v > --detailed-exitcodes > --templatedir=/usr/share/ace/appliances/ovirt/templates > --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances > --factpath=/usr/share/ace/facts --logdest=ovirt-install-log > /usr/share/ace/manifests/pre_install.pp > Tue Apr 21 11:47:14 +0300 2009 executing puppet -d -v > --detailed-exitcodes > --templatedir=/usr/share/ace/appliances/ovirt/templates > --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances > --factpath=/usr/share/ace/facts --logdest=ovirt-install-log > /usr/share/ace/appliances/ovirt/ovirt.pp > > Screen Output is attached. > > Any advice would be appreciated > > Thanks > > Ido & Oshrit > > > ------------------------------------------------------------------------ > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel > From dpierce at redhat.com Tue Apr 21 19:44:25 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 21 Apr 2009 15:44:25 -0400 Subject: [Ovirt-devel] Problems with autotest on Fedora... In-Reply-To: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> References: <20090421155137.GG3958@mcpierce-laptop.rdu.redhat.com> Message-ID: <20090421194425.GB3860@mcpierce-laptop.mcpierce.org> On Tue, Apr 21, 2009 at 11:51:37AM -0400, Darryl L. Pierce wrote: > I'm refactoring and extending the autotesting suite for > ovirt-node-image. But, in trying to run them on Fedora rather than RHEL, > the PXE booting never seems to successfully complete. > > I can see the virtual bridge created, dnsmasq starts properly, and the > VM is defined to use the bridge and to boot from the network. I watch it > start to boot, but then never seems to finish. Instead, it sits at: > > Loading 192.168.136.1:tftpboot/pxelinux.0 ...... > > The dots come up every few minutes, but only gets to about six of them > and then just stops. > > Any suggestions on what to look for to fix this? The problem was iptables related: port 69 was not open for tftp. Once I opened that, things started working as normal. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Virtual Machine Management - http://www.ovirt.org/ Is fearr Gaeilge bhriste n? B?arla cliste. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: From mmorsi at redhat.com Tue Apr 21 19:47:53 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 21 Apr 2009 15:47:53 -0400 Subject: [Ovirt-devel] (no subject) Message-ID: <1240343276-3514-1-git-send-email-mmorsi@redhat.com> Updated patchset integrating anyterm into ovirt. These changes now work with the anyterm rpm hosted in the public ovirt repository. Simply build the server, node, and node-image rpms with these patches included, update the server with the new server, node-image, and node-image-pxe rpms, and pxe boot a node off it. You will then be able to access the terminal via the vm's details pane. From mmorsi at redhat.com Tue Apr 21 19:47:54 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 21 Apr 2009 15:47:54 -0400 Subject: [Ovirt-devel] [PATCH node-image] unblacklist gconv as needed by anyterm and open anyterm port In-Reply-To: <1240343276-3514-1-git-send-email-mmorsi@redhat.com> References: <1240343276-3514-1-git-send-email-mmorsi@redhat.com> Message-ID: <1240343276-3514-2-git-send-email-mmorsi@redhat.com> --- common-blacklist.ks | 4 ++-- common-post.ks | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common-blacklist.ks b/common-blacklist.ks index 9127219..fe6c107 100644 --- a/common-blacklist.ks +++ b/common-blacklist.ks @@ -88,8 +88,8 @@ blacklist="/boot /etc/alsa /etc/pki /usr/share/hwdata/MonitorsDB \ /usr/share/tc /usr/share/emacs /usr/share/info \ /usr/src /usr/etc /usr/games /usr/include /usr/local \ /usr/sbin/{dell*,sasldblistusers2,build-locale-archive,glibc_post_upgrade.*}" -blacklist_lib="/usr/lib{,64}/gconv \ - /usr/{,lib64}/tc /usr/lib{,64}/tls /usr/lib{,64}/sse2 \ +blacklist_lib="/usr/{,lib64}/tc \ + /usr/lib{,64}/tls /usr/lib{,64}/sse2 \ /usr/lib{,64}/pkgconfig /usr/lib{,64}/nss \ /usr/lib{,64}/games /usr/lib{,64}/alsa-lib /usr/lib{,64}/fs/reiserfs \ /usr/lib{,64}/krb5 /usr/lib{,64}/hal /usr/lib{,64}/gio \ diff --git a/common-post.ks b/common-post.ks index b4efb73..2734004 100644 --- a/common-post.ks +++ b/common-post.ks @@ -70,6 +70,8 @@ cat > /etc/sysconfig/iptables << \EOF -A INPUT -p tcp --dport 16509 -j ACCEPT # SSH -A INPUT -p tcp --dport 22 -j ACCEPT +# anyterm +-A INPUT -p tcp --dport 81 -j ACCEPT # guest consoles -A INPUT -p tcp -m multiport --dports 5800:6000 -j ACCEPT # migration -- 1.6.0.6 From mmorsi at redhat.com Tue Apr 21 19:47:55 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 21 Apr 2009 15:47:55 -0400 Subject: [Ovirt-devel] [PATCH node] add anyterm to node requirements and setup on startup In-Reply-To: <1240343276-3514-2-git-send-email-mmorsi@redhat.com> References: <1240343276-3514-1-git-send-email-mmorsi@redhat.com> <1240343276-3514-2-git-send-email-mmorsi@redhat.com> Message-ID: <1240343276-3514-3-git-send-email-mmorsi@redhat.com> adds anyterm rpm dependency to ovirt node spec and sets up anyterm on node instantation by setting the service to start by default and making the necessary anyterm sysconfig changes --- ovirt-node.spec.in | 1 + scripts/ovirt-functions | 8 ++++++++ scripts/ovirt-install-node-stateful | 2 ++ scripts/ovirt-install-node-stateless | 2 ++ 4 files changed, 13 insertions(+), 0 deletions(-) diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in index 1a73066..1b847c5 100644 --- a/ovirt-node.spec.in +++ b/ovirt-node.spec.in @@ -42,6 +42,7 @@ Requires: qemu-img Requires: nc Requires: grub Requires: /usr/sbin/crond +Requires: anyterm ExclusiveArch: %{ix86} x86_64 %define app_root %{_datadir}/%{name} diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index e89898d..524cd7a 100755 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -201,6 +201,14 @@ ovirt_setup_libvirtd() { fi } +ovirt_setup_anyterm() { + sed -i -e 's/^# ANYTERM_CMD=\/usr\/bin\/anyterm-cmd/ANYTERM_CMD="virsh console %p"/' \ + /etc/sysconfig/anyterm + + sed -i -e 's/^# ANYTERM_LOCAL_ONLY=true/ANYTERM_LOCAL_ONLY=false/' \ + /etc/sysconfig/anyterm +} + md5() { md5sum $1 2>/dev/null | (read MD5 filename; echo $MD5) } diff --git a/scripts/ovirt-install-node-stateful b/scripts/ovirt-install-node-stateful index 3ec1c29..9426c81 100755 --- a/scripts/ovirt-install-node-stateful +++ b/scripts/ovirt-install-node-stateful @@ -75,6 +75,7 @@ chkconfig libvirt-qpid on chkconfig iptables on chkconfig ntpdate on chkconfig ntpd on +chkconfig anyterm on backup_file /etc/sysconfig/libvirtd backup_file /etc/libvirt/qemu.conf @@ -82,6 +83,7 @@ backup_file /etc/libvirt/libvirtd.conf backup_file /etc/sasl2/libvirt.conf backup_file /etc/krb5.conf ovirt_setup_libvirtd +ovirt_setup_anyterm backup_file /etc/sysconfig/iptables # We open up anything coming from ovirtbr0 to this node, since it diff --git a/scripts/ovirt-install-node-stateless b/scripts/ovirt-install-node-stateless index 705c491..cceb048 100755 --- a/scripts/ovirt-install-node-stateless +++ b/scripts/ovirt-install-node-stateless @@ -20,8 +20,10 @@ chkconfig --level 3 ovirt-early on chkconfig --level 3 ovirt on chkconfig --level 3 ovirt-post on chkconfig --level 3 collectd on +chkconfig --level 3 anyterm on ovirt_setup_libvirtd +ovirt_setup_anyterm # make sure we don't autostart virbr0 on libvirtd startup rm -f /etc/libvirt/qemu/networks/autostart/default.xml -- 1.6.0.6 From mmorsi at redhat.com Tue Apr 21 19:47:56 2009 From: mmorsi at redhat.com (Mohammed Morsi) Date: Tue, 21 Apr 2009 15:47:56 -0400 Subject: [Ovirt-devel] [PATCH server] integrate anyterm into ovirt web interface In-Reply-To: <1240343276-3514-3-git-send-email-mmorsi@redhat.com> References: <1240343276-3514-1-git-send-email-mmorsi@redhat.com> <1240343276-3514-2-git-send-email-mmorsi@redhat.com> <1240343276-3514-3-git-send-email-mmorsi@redhat.com> Message-ID: <1240343276-3514-4-git-send-email-mmorsi@redhat.com> this patch adds the necessary components to forward vm web terminal requests from the local apache server to the node which the vm is running on (httpd configuration and vm2node lookup scripts) as well as changes to the wui to allow users to access this functionality --- conf/ovirt-server.conf | 6 +++++ ovirt-server.spec.in | 2 + scripts/ovirt-vm2node | 35 ++++++++++++++++++++++++++++++++++ src/app/controllers/vm_controller.rb | 10 ++++++++- src/app/views/vm/show.rhtml | 27 +++++++++++++++++++------ src/public/javascripts/ovirt.js | 15 +++++++++++++- 6 files changed, 86 insertions(+), 9 deletions(-) create mode 100755 scripts/ovirt-vm2node diff --git a/conf/ovirt-server.conf b/conf/ovirt-server.conf index bab6f1a..36564ed 100644 --- a/conf/ovirt-server.conf +++ b/conf/ovirt-server.conf @@ -21,6 +21,12 @@ NameVirtualHost AdminNetIpAddress:80 TransferLog /etc/httpd/logs/access_log LogLevel warn + RewriteEngine On + RewriteMap vmnodes prg:/usr/bin/ovirt-vm2node + RewriteRule ^/terminal/(.*\.(js|css|gif)|proxy/anyterm-module)$ http://${vmnodes:anyterm}:81/$1 [P] + RewriteRule ^/terminal/(.*)$ http://${vmnodes:$1}:81/anyterm.html?param=$1 [P,NE] + + ProxyPass /ovirt http://AdminNodeFQDN/ovirt ProxyPassReverse /ovirt http://AdminNodeFQDN/ovirt diff --git a/ovirt-server.spec.in b/ovirt-server.spec.in index 6da7297..b4f7454 100644 --- a/ovirt-server.spec.in +++ b/ovirt-server.spec.in @@ -130,6 +130,7 @@ touch %{buildroot}%{_localstatedir}/log/%{name}/db-omatic.log %{__rm} -f %{buildroot}%{app_root}/task-omatic/.gitignore %{__cp} -a %{pbuild}/scripts/ovirt-add-host %{buildroot}%{_bindir} +%{__cp} -a %{pbuild}/scripts/ovirt-vm2node %{buildroot}%{_bindir} %{__cp} -a %{pbuild}/scripts/ovirt-reindex-search %{buildroot}%{_sbindir} %{__cp} -a %{pbuild}/scripts/ovirt-update-search %{buildroot}%{_sbindir} %{__rm} -rf %{buildroot}%{app_root}/tmp @@ -199,6 +200,7 @@ fi %{_sbindir}/ovirt-reindex-search %{_sbindir}/ovirt-update-search %{_bindir}/ovirt-add-host +%{_bindir}/ovirt-vm2node %{_initrddir}/ovirt-host-browser %{_initrddir}/ovirt-db-omatic %{_initrddir}/ovirt-host-collect diff --git a/scripts/ovirt-vm2node b/scripts/ovirt-vm2node new file mode 100755 index 0000000..ef81df1 --- /dev/null +++ b/scripts/ovirt-vm2node @@ -0,0 +1,35 @@ +#!/usr/bin/ruby + +############################ Initialize active record +require 'rubygems' +require 'active_record' +require 'yaml' + +dbconfig = YAML::load(File.open('/usr/share/ovirt-server/config/database.yml')) +ActiveRecord::Base.establish_connection(dbconfig['production']) + + +########################### Initlialize vm / host classes +class Host < ActiveRecord::Base + has_many :vms +end + +class Vm < ActiveRecord::Base + belongs_to :host +end + +########################## retreive host from vm w/ specified name +$stdin.each{ |vmname| # get vm name from stdin + vmname.chomp! # remove the newline + + # specially handle 'anyterm' to just return + # first host (for css/js/etc which aren't + # vm dependent) + if vmname == 'anyterm' + puts Host.find(:first, :conditions => "state = 'available'").hostname + else + puts Vm.find(:first, :conditions => ['description = ?', vmname]).host.hostname + end + + $stdout.flush +} diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb index a81f6b5..82a78b0 100644 --- a/src/app/controllers/vm_controller.rb +++ b/src/app/controllers/vm_controller.rb @@ -23,7 +23,7 @@ class VmController < ApplicationController verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :controller => 'dashboard' } - before_filter :pre_vm_action, :only => [:vm_action, :cancel_queued_tasks, :console] + before_filter :pre_vm_action, :only => [:vm_action, :cancel_queued_tasks, :console, :terminal] def index @vms = Vm.find(:all, @@ -37,6 +37,14 @@ class VmController < ApplicationController end end + def terminal + # optionally add rows and columns params to url here + # eg ?param=vmname&rows=30&columns=100 + redirect_to "https://" + params[:host] + + "/terminal/" + @vm.description + + "?param=" + @vm.description + end + def show set_perms(@perm_obj) @actions = @vm.get_action_hash(@user) diff --git a/src/app/views/vm/show.rhtml b/src/app/views/vm/show.rhtml index add29b4..a73f505 100644 --- a/src/app/views/vm/show.rhtml +++ b/src/app/views/vm/show.rhtml @@ -3,16 +3,29 @@ <%- end -%> <%- content_for :action_links do -%> - <%if @can_control_vms and @vm.has_console -%> - <%= link_to image_tag("icon_x.png") + " Open Console", - {:controller => 'vm', :action => 'console', :id => @vm}, - :id=>"vnc_console_link" %> + <%if @can_control_vms -%> + <%if @vm.has_console -%> + <%= link_to image_tag("icon_x.png") + " Open Console", + {:controller => 'vm', :action => 'console', :id => @vm}, + :id=>"vnc_console_link" %> + + <% end -%> + + <%= link_to image_tag("icon_x.png") + " Open Terminal", + {:controller => 'vm', :action => 'terminal', :id => @vm}, + :id=> "vm_terminal_link"%> <% end -%> + <%if @can_modify -%> <%= link_to image_tag("icon_edit.png") + " Edit", {:controller => 'vm', :action => 'edit', :id => @vm}, diff --git a/src/public/javascripts/ovirt.js b/src/public/javascripts/ovirt.js index c24df16..2754817 100644 --- a/src/public/javascripts/ovirt.js +++ b/src/public/javascripts/ovirt.js @@ -380,4 +380,17 @@ var VmCreator = { VmCreator.recreateTree(storedOptions); VmCreator.clickCheckboxes(); } -} \ No newline at end of file +} + +function get_server_from_url() +{ + var regexS = "https.*" + var regex = new RegExp(regexS); + var results = regex.exec( window.location.href ); + var start = 8; + if(results == null){ + start = 7; + } + var end = window.location.href.indexOf('/', 8) - start; + return window.location.href.substr(start, end); +} -- 1.6.0.6 From imain at redhat.com Tue Apr 21 20:14:06 2009 From: imain at redhat.com (Ian Main) Date: Tue, 21 Apr 2009 13:14:06 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240259199-10088-1-git-send-email-sseago@redhat.com> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> Message-ID: <20090421131406.70b7a092@tp.mains.net> So with this service layer.. with it being included and setting local properties of the object, will that be thread safe? Or will we have to do locking around each call? I'm not sure yet if the agent will be threaded.. but it certainly could have a thread per method invocation.. Ian > +module VmService > + > + include ApplicationService > + > + def svc_show(vm_id) > + # from before_filter > + @vm = Vm.find(vm_id) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::VIEW, at vm.vm_resource_pool) > + end > + > + def svc_create(vm_hash, start_now) > + # from before_filter > + vm_hash[:state] = Vm::STATE_PENDING > + @vm = Vm.new(params[:vm]) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::MODIFY, at vm.vm_resource_pool) > + > + alert = "VM was successfully created." > + Vm.transaction do > + @vm.save! > + vm_provision > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_CREATE_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + if start_now > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Start action queued." > + else > + alert += " Resources are not available to start VM now." > + end > + end > + end > + return alert > + end > + > + def svc_update(vm_id, vm_hash, start_now, restart_now) > + # from before_filter > + @vm = Vm.find(vm_id) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) > + > + #needs restart if certain fields are changed > + # (since those will only take effect the next startup) > + needs_restart = false > + unless @vm.get_pending_state == Vm::STATE_STOPPED > + Vm::NEEDS_RESTART_FIELDS.each do |field| > + unless @vm[field].to_s == vm_hash[field] > + needs_restart = true > + break > + end > + end > + current_storage_ids = @vm.storage_volume_ids.sort > + new_storage_ids = vm_hash[:storage_volume_ids] > + new_storage_ids = [] unless new_storage_ids > + new_storage_ids = new_storage_ids.sort.collect {|x| x.to_i } > + needs_restart = true unless current_storage_ids == new_storage_ids > + end > + vm_hash[:needs_restart] = 1 if needs_restart > + > + > + alert = "VM was successfully updated." > + Vm.transaction do > + @vm.update_attributes!(vm_hash) > + vm_provision > + if start_now > + if @vm.get_action_list.include?(VmTask::ACTION_START_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Start action queued." > + else > + alert += " Resources are not available to start VM now." > + end > + elsif restart_now > + if @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_SHUTDOWN_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + @task = VmTask.new({ :user => @user, > + :task_target => @vm, > + :action => VmTask::ACTION_START_VM, > + :state => Task::STATE_QUEUED}) > + @task.save! > + alert += " VM Restart action queued." > + else > + alert += " Restart action was not available." > + end > + end > + end > + return alert > + end > + > + def svc_destroy(vm_id) > + # from before_filter > + @vm = Vm.find(vm_id) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) > + > + unless @vm.is_destroyable? > + raise ActionError.new("Virtual Machine must be stopped to delete it") > + end > + destroy_cobbler_system(@vm) > + @vm.destroy > + return "Virtual Machine wa ssuccessfully deleted." > + end > + > + def svc_vm_action(vm_id, vm_action, action_args) > + @vm = Vm.find(vm_id) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) > + unless @vm.queue_action(@user, vm_action, action_args) > + raise ActionError.new("#{vm_action} is an invalid action.") > + end > + return "#{vm_action} was successfully queued." > + end > + > + def svc_cancel_queued_tasks(vm_id) > + @vm = Vm.find(vm_id) > + @current_pool_id=@vm.vm_resource_pool.id > + authorized!(Privilege::MODIFY, @vm.vm_resource_pool) > + > + Task.transaction do > + @vm.tasks.queued.each { |task| task.cancel} > + end > + return "Queued tasks were successfully canceled." > + end > + > + def vm_provision > + if @vm.uses_cobbler? > + # spaces are invalid in the cobbler name > + name = @vm.uuid > + system = Cobbler::System.find_one(name) > + unless system > + system = Cobbler::System.new("name" => name, > + @vm.cobbler_type => @vm.cobbler_name) > + system.interfaces = [Cobbler::NetworkInterface.new( > + {'mac_address' => @vm.vnic_mac_addr})] > + system.save > + end > + end > + end > + > + def destroy_cobbler_system(vm) > + # Destroy the Cobbler system first if it's defined > + if vm.uses_cobbler? > + system = Cobbler::System.find_one(vm.cobbler_system_name) > + system.remove if system > + end > + end > + > +end > diff --git a/src/app/views/vm/_form.rhtml b/src/app/views/vm/_form.rhtml > index 58a3d61..610f2bc 100644 > --- a/src/app/views/vm/_form.rhtml > +++ b/src/app/views/vm/_form.rhtml > @@ -3,8 +3,7 @@ > <% start_resources = @vm.vm_resource_pool.available_resources_for_vm(@vm) %> > > > -<%= hidden_field 'vm', 'vm_resource_pool_id' unless @vm_resource_pool_name %> > -<%= hidden_field_tag 'vm_resource_pool_name', @vm_resource_pool_name if @vm_resource_pool_name %> > +<%= hidden_field 'vm', 'vm_resource_pool_id' %> > <%= hidden_field_tag 'hardware_pool_id', @hardware_pool.id if @hardware_pool %> > > <%= text_field_with_label "Name:", "vm", "description", {:style=>"width:250px;"} %> > -- > 1.6.0.6 > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From sseago at redhat.com Tue Apr 21 20:25:48 2009 From: sseago at redhat.com (Scott Seago) Date: Tue, 21 Apr 2009 16:25:48 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090421131406.70b7a092@tp.mains.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> Message-ID: <49EE2BCC.9050101@redhat.com> Ian Main wrote: > So with this service layer.. with it being included and setting local properties of the object, will that be thread safe? Or will we have to do locking around each call? > > I'm not sure yet if the agent will be threaded.. but it certainly could have a thread per method invocation.. > > Ian > This question also gets at what David and I were discussing last week about the scope of the service objects. On the WUI side, a controller object only exists for the duration of a single web request -- when we set @vm in the VmController object (via the VmService module) that instance variable will only ever be accessed by a single thread. If we're following something similar on the QMF side, then it's not so much a question of locking as it is making sure each API call gets its own service object. Scott From jboggs at redhat.com Tue Apr 21 20:52:50 2009 From: jboggs at redhat.com (Joey Boggs) Date: Tue, 21 Apr 2009 16:52:50 -0400 Subject: [Ovirt-devel] [PATCH server] add dns setup clarification in installer Message-ID: <1240347170-5843-1-git-send-email-jboggs@redhat.com> This clarifies the dns setup section in the installer and notifies to use the bundled dns setup if the management server is not in the upstream dns already --- installer/bin/ovirt-installer | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/installer/bin/ovirt-installer b/installer/bin/ovirt-installer index 2d88886..862c5e2 100755 --- a/installer/bin/ovirt-installer +++ b/installer/bin/ovirt-installer @@ -183,6 +183,8 @@ File.open('/etc/resolv.conf').each_line{ |line| line = line.chomp puts line if line =~ /nameserver/ } + at cli.say("<%= color('\nIf your above dns servers contain the A records for your management server select \"y\" +otherwise select \"n\" and a dns server will be configured during the install', RED) %>") dns_servers = prompt_yes_no("Use this systems's dns servers?") guest_httpd_ipaddr = interfaces[guest_httpd_dev] -- 1.6.0.6 From lutter at redhat.com Tue Apr 21 21:49:15 2009 From: lutter at redhat.com (David Lutterkort) Date: Tue, 21 Apr 2009 21:49:15 +0000 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090421131406.70b7a092@tp.mains.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> Message-ID: <1240350555.18022.32.camel@avon.watzmann.net> On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: > So with this service layer.. with it being included and setting local > properties of the object, will that be thread safe? Or will we have > to do locking around each call? > > I'm not sure yet if the agent will be threaded.. but it certainly > could have a thread per method invocation.. To echo what Scott said: I would prefer if we followed the rails model fairly closely, with some sort of notion of a 'QMF controller', and instantiate one for every method call from the QMF agent. Given that we want to minimize the amount of things we keep in memory (mostly to avoid cache coherency issues between memory and DB), we want the QMF API to be as statefree as possible. David From hbrock at redhat.com Wed Apr 22 00:48:19 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Tue, 21 Apr 2009 20:48:19 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240350555.18022.32.camel@avon.watzmann.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> Message-ID: <20090422004818.GQ10299@redhat.com> On Tue, Apr 21, 2009 at 09:49:15PM +0000, David Lutterkort wrote: > On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: > > So with this service layer.. with it being included and setting local > > properties of the object, will that be thread safe? Or will we have > > to do locking around each call? > > > > I'm not sure yet if the agent will be threaded.. but it certainly > > could have a thread per method invocation.. > > To echo what Scott said: I would prefer if we followed the rails model > fairly closely, with some sort of notion of a 'QMF controller', and > instantiate one for every method call from the QMF agent. > > Given that we want to minimize the amount of things we keep in memory > (mostly to avoid cache coherency issues between memory and DB), we want > the QMF API to be as statefree as possible. Yeah this is clearly the right way to do things... i.e. we already have lots of code dedicated to handling simultaneous HTTP requests and even multi-request sessions, why reinvent that for handling simultaneous QMF sessions? Seems like a fairly straightforward analogy... with the annoying exception perhaps that a QMF session might be rather longer lived than an http request and therefore the locking issues might be more serious. But I still think all of this is manageable. --H From is at eseco.de Wed Apr 22 13:47:22 2009 From: is at eseco.de (Ingmar Schraub) Date: Wed, 22 Apr 2009 15:47:22 +0200 Subject: [Ovirt-devel] ovirt - web gui Message-ID: <49EF1FEA.1020209@eseco.de> Hello, last week I had an issue with the Kerberos authentication. Since then I have tested a lot, deleted the whole thing, re-started, etc. Made some progress, the Kerberos issue is gone. I'd like to document this and share the info here. But first I want to be sure, I can reproduce it again and see if my local change really works all the time. Today I faced a new problem. When I connect with the web browser to http://management.priv.ovirt.org/ovirt, login in, I see the dashboard. So far so good. However, when I click on "default", I get re-directed to the dashboard, the "default" icon+text as well as the "Smart Pools" icon+text disappears. Clicking again on Dashboard, gives me the icons back. Interestingly the "Smart Pools" menu works. I can add another smart pool, click on "Add Host" and I can add my node (physical..). This time it is shown as "available(enabled)". Clicking on this host after having it added to my Smart Pool, gives me a "404 Not Found" pop-up. Does anybody have an idea why the 'default' pool disappears/never shows when clicking on the link? Last week when I had the Kerberos problem, the "default" pool worked without problems. I hope that you don't mind that I ask here on this list. I know it is a devel list not a users list. But I hope that some users feedback is useful for you as well. Thanks a lot and regards, Ingmar From hbrock at redhat.com Wed Apr 22 14:42:31 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Wed, 22 Apr 2009 10:42:31 -0400 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <49EF1FEA.1020209@eseco.de> References: <49EF1FEA.1020209@eseco.de> Message-ID: <20090422144231.GZ10299@redhat.com> On Wed, Apr 22, 2009 at 03:47:22PM +0200, Ingmar Schraub wrote: > Hello, > > last week I had an issue with the Kerberos authentication. Since then I > have tested a lot, deleted the whole thing, re-started, etc. Made some > progress, the Kerberos issue is gone. I'd like to document this and > share the info here. But first I want to be sure, I can reproduce it > again and see if my local change really works all the time. > > Today I faced a new problem. > > When I connect with the web browser to > http://management.priv.ovirt.org/ovirt, login in, I see the dashboard. > So far so good. However, when I click on "default", I get re-directed to > the dashboard, the "default" icon+text as well as the "Smart Pools" > icon+text disappears. Clicking again on Dashboard, gives me the icons back. > > Interestingly the "Smart Pools" menu works. I can add another smart > pool, click on "Add Host" and I can add my node (physical..). This time > it is shown as "available(enabled)". > > Clicking on this host after having it added to my Smart Pool, gives me a > "404 Not Found" pop-up. > > Does anybody have an idea why the 'default' pool disappears/never shows > when clicking on the link? > > Last week when I had the Kerberos problem, the "default" pool worked > without problems. > > I hope that you don't mind that I ask here on this list. I know it is a > devel list not a users list. But I hope that some users feedback is > useful for you as well. > > Thanks a lot and regards, > > Ingmar Hi Ingmar, please feel free to post user questions here as we have no users list at the moment (hmm, I should add one). By default with ovirt-0.98, you have to use https to access the UI, and there is an automatic redirect from http:///ovirt to https:///ovirt/login. It's possible that is the problem you are having. Is it possible your apache isn't configured correctly for ssl? Take care, --Hugh From kc at cobradevil.org Wed Apr 22 14:52:19 2009 From: kc at cobradevil.org (kc at cobradevil.org) Date: Wed, 22 Apr 2009 16:52:19 +0200 (CEST) Subject: [Ovirt-devel] ovirt - web gui Message-ID: <60730.217.169.229.153.1240411939.squirrel@webmail.spothost.nl> Hello Ingmar i wasn't subscribed so i hope it will continue on the thread. Are you trying to login with admin? Try to login with ovirtadmin same password as admin if you have followed the install instructions. As admin you do not see everything. I had the same problem end it took me 2 hours to find that! With kind regards William ak cobradevil From is at eseco.de Wed Apr 22 14:59:33 2009 From: is at eseco.de (Ingmar Schraub) Date: Wed, 22 Apr 2009 16:59:33 +0200 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <20090422144231.GZ10299@redhat.com> References: <49EF1FEA.1020209@eseco.de> <20090422144231.GZ10299@redhat.com> Message-ID: <49EF30D5.30909@eseco.de> Hugh O. Brock wrote: > On Wed, Apr 22, 2009 at 03:47:22PM +0200, Ingmar Schraub wrote: >> Hello, >> >> last week I had an issue with the Kerberos authentication. Since then I >> have tested a lot, deleted the whole thing, re-started, etc. Made some >> progress, the Kerberos issue is gone. I'd like to document this and >> share the info here. But first I want to be sure, I can reproduce it >> again and see if my local change really works all the time. >> >> Today I faced a new problem. >> >> When I connect with the web browser to >> http://management.priv.ovirt.org/ovirt, login in, I see the dashboard. >> So far so good. However, when I click on "default", I get re-directed to >> the dashboard, the "default" icon+text as well as the "Smart Pools" >> icon+text disappears. Clicking again on Dashboard, gives me the icons back. >> >> Interestingly the "Smart Pools" menu works. I can add another smart >> pool, click on "Add Host" and I can add my node (physical..). This time >> it is shown as "available(enabled)". >> >> Clicking on this host after having it added to my Smart Pool, gives me a >> "404 Not Found" pop-up. >> >> Does anybody have an idea why the 'default' pool disappears/never shows >> when clicking on the link? >> >> Last week when I had the Kerberos problem, the "default" pool worked >> without problems. >> >> I hope that you don't mind that I ask here on this list. I know it is a >> devel list not a users list. But I hope that some users feedback is >> useful for you as well. >> >> Thanks a lot and regards, >> >> Ingmar > > Hi Ingmar, please feel free to post user questions here as we have no > users list at the moment (hmm, I should add one). > > By default with ovirt-0.98, you have to use https to access the UI, > and there is an automatic redirect from > http:///ovirt to > https:///ovirt/login. It's possible that is the > problem you are having. Is it possible your apache isn't configured > correctly for ssl? Hello Hugh, thanks for your help!! Well, I am still on rawhide and probably you blame me now for this... I have the following rpm's installed on my management system: ovirt-release-0.99-0.fc10.20090422120055gitf5ff067.noarch ovirt-server-installer-0.99-0.fc10.20090422120059git3ef3335.noarch ovirt-docs-0.99-0.fc10.20090422120538gitb7cd200.noarch ovirt-node-image-1.0.1-0.fc10.20090422120528git0fa11eb.x86_64 ovirt-server-0.99-0.fc10.20090422120059git3ef3335.noarch Note: the /etc/httpd/conf.d/ovirt-server.conf file which comes with the rpm is wrong. The httpd daemon does not start at all. I have attached it to this e-mail, that you can have a look. I 'fixed' (better hacked) it by making the following changes: NameVirtualHost :80 -> NameVirtualHost _default:80 -> NameVirtualHost :443 -> NameVirtualHost _default_:443 -> With these changes, httpd starts and I have plain http, can login in and see the dashboard. If I replace _default_ with 192.168.50.2, I get re-directed to https, but then after login in, the browser tells me "Redirect Loop Firefox has detected that the server is redirecting the request for this address in a way that will never complete." So that is one issue. On the other hand, my problem I described in my previous e-mail seems not to be related to this one here. Thanks, Ingmar > Take care, > --Hugh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ovirt-server.conf URL: From is at eseco.de Wed Apr 22 15:13:40 2009 From: is at eseco.de (Ingmar Schraub) Date: Wed, 22 Apr 2009 17:13:40 +0200 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <60730.217.169.229.153.1240411939.squirrel@webmail.spothost.nl> References: <60730.217.169.229.153.1240411939.squirrel@webmail.spothost.nl> Message-ID: <49EF3424.3070208@eseco.de> Hello William, thanks for helping!! I used all the time 'ovirtadmin'. Now I tested with 'admin' to check if this makes a difference (since you are saying 'admin' sees less), but the screen looks the same to me and I have with both logins the same problem that clicking on 'default' removes this menu entry and also 'Smart Pools'. I have already re-installed the whole management system (yes, from rawhide, because it is the most convenient way... and yes, I followed the instructions and read it many times). I could install a new F10 image on kvm and install 0.98 in there. Is there anybody out there who had recently done a fresh install on a fully patched F10 system going the rawhide path? And was it successful? That would be very interesting to know. Thanks, Ingmar kc at cobradevil.org wrote: > Hello Ingmar > > i wasn't subscribed so i hope it will continue on the thread. > > Are you trying to login with admin? > Try to login with ovirtadmin same password as admin if you have followed > the install instructions. > > As admin you do not see everything. > > I had the same problem end it took me 2 hours to find that! > > With kind regards > > William ak cobradevil > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From Ingmar.Schraub at eseco.de Wed Apr 22 15:11:13 2009 From: Ingmar.Schraub at eseco.de (Ingmar Schraub) Date: Wed, 22 Apr 2009 17:11:13 +0200 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <60730.217.169.229.153.1240411939.squirrel@webmail.spothost.nl> References: <60730.217.169.229.153.1240411939.squirrel@webmail.spothost.nl> Message-ID: <49EF3391.9020805@eseco.de> Hello William, thanks for helping!! I used all the time 'ovirtadmin'. Now I tested with 'admin' to check if this makes a difference (since you are saying 'admin' sees less), but the screen looks the same to me and I have with both logins the same problem that clicking on 'default' removes this menu entry and also 'Smart Pools'. I have already re-installed the whole management system (yes, from rawhide, because it is the most convenient way... and yes, I followed the instructions and read it many times). I could install a new F10 image on kvm and install 0.98 in there. Is there anybody out there who had recently done a fresh install on a fully patched F10 system going the rawhide path? And was it successful? That would be very interesting to know. Thanks, Ingmar kc at cobradevil.org wrote: > Hello Ingmar > > i wasn't subscribed so i hope it will continue on the thread. > > Are you trying to login with admin? > Try to login with ovirtadmin same password as admin if you have followed > the install instructions. > > As admin you do not see everything. > > I had the same problem end it took me 2 hours to find that! > > With kind regards > > William ak cobradevil > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel -- Bye, Ingmar Schraub e-mail : Ingmar.Schraub at eseco.de eseco GmbH & Co. KG Web : http://www.eseco.de Herrnwaldstr. 6 phone : +49 6251 702988 0 D-64625 Bensheim fax : +49 6251 58360 83 Germany mobile : +49 173 6711767 Skype : ischraub Registergericht: Darmstadt, HRA 40930 Gesch?ftsf?hrer: Ingmar Schraub Hauptsitz: Herrnwaldstr. 6, D-64625 Bensheim From jboggs at redhat.com Wed Apr 22 15:40:33 2009 From: jboggs at redhat.com (Joey Boggs) Date: Wed, 22 Apr 2009 11:40:33 -0400 Subject: [Ovirt-devel] Installing Ovirt In-Reply-To: References: Message-ID: <49EF3A71.2040900@redhat.com> Oshrit, For ease of tracking could you be sure all replies are cc'ed to ovirt-devel at redhat.com or select reply all Does the management machine only have one nic in it? The lines commented out should work fine in a machine with 2 nics though. Updated instructions will be out shortly the current set are at: http://ovirt.org/docs/Using_the_oVirt_Server_Suite_User_Interface/ You will need to setup your nodes using pxe and they will appear in the management console http://$managementserver/ovirt your login is ovirtadmin and the password is the one set for freeipa in the installer. Here's some cobbler setup steps that will help you provision virtual machines once your nodes are up and running You will need an Fedora 10 install cd can be either 32/64 bit we'll use x86_64 bit in the example Make a temporary directory /media/f10dvd If using a physical cd Mount the install cd: mount /dev/cdrom /tmp/f10dvd If using an iso file Mount the install cd: mount -o loop $filename /tmp/f10dvd cobbler import --mirror=/tmp/f10dvd --name=Fedora10 ----------------------------- Optional (add a Fedora updates repo) 12GB or so of data to sync and will take a few hours, can be added later - Get a mirror url from: http://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f10&arch=x86_64 - Goto the cobbler web ui add another repo, set the name: Fedora10-x86_64-updates and the mirror location to one from the above list check mirror locally and keep updated - In the web ui click on the Fedora10-x86_64 profile go down to the repo section and add the repo just created - Click sync on the left corner ----------------------------- A simple kickstart is provided for the Fedora10-x86_64 profile and can be customized for your setup. You can now pxe boot or provision virtual machines to the ovirt nodes from the web management console Oshrit Feder wrote: > > Thanks Joey. We ran the installation again, this time answered N for > the dns prompt and were managed to get to a point where after a few > changes to the /etc/https/conf.d/ovirt-server.conf file the cobbler > web page was accessable. > > (Had to comment a few lines so the apche could start > > # NSSEngine on > # NSSCipherSuite > +rsa_rc4_128_md5,+rsa_rc4_128_sha,+rsa_3des_sha,-rsa_des_sha,-rsa_rc4_40_md5,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_null_sha,+fips_3des_sha,-fips_des_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-rsa_des_56_sha,-rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha > # NSSProtocol SSLv3,TLSv1 > # NSSNickname Server-Cert > # NSSCertificateDatabase /etc/httpd/alias > > > ) > > So, Now we are able to explore the cobbler web page, and from the > cobbler/webui/wui.html we can see the _oVirt-Node-x86_64_ > > profile. The instruction page doesnt provide more details from this > point - How to deploy it and start the oVirt webGui? > > Thanks for the help > > ____________________________ > > It's actually a bug, it's caused when using an external dns server > rather than choosing the bundled dnsmasq setup. Does your dns server > already contain your machines and node A records? If not you will need > to choose N on option for use this system's dns servers, that question > can be misleading and will be updated. If your dns setup is correct we > can provide a workaround. > > > > Ido Levy wrote: > > Hello All, > > > > We have tried to install an oVirt server using the following link - > > http://ovirt.org/install-instructions.html > > We used the latest RPMs from oVirt repo ( 04/07/09 ). > > > > All stages went fine until we have executed the install command - ace > > -d -l ovirt-install-log install ovirt > > > > Log File Output: > > > > Tue Apr 21 11:47:11 +0300 2009 executing puppet -d -v > > --detailed-exitcodes > > --templatedir=/usr/share/ace/appliances/ovirt/templates > > --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances > > --factpath=/usr/share/ace/facts --logdest=ovirt-install-log > > /usr/share/ace/manifests/pre_install.pp > > Tue Apr 21 11:47:14 +0300 2009 executing puppet -d -v > > --detailed-exitcodes > > --templatedir=/usr/share/ace/appliances/ovirt/templates > > --modulepath=/usr/share/ace/modules:/usr/share/ace/appliances > > --factpath=/usr/share/ace/facts --logdest=ovirt-install-log > > /usr/share/ace/appliances/ovirt/ovirt.pp > > > > Screen Output is attached. > > > > Any advice would be appreciated > > > > Thanks > > > > Ido & Oshrit > > > > > > ------------------------------------------------------------------------ > > > > _______________________________________________ > > Ovirt-devel mailing list > > Ovirt-devel at redhat.com > > https://www.redhat.com/mailman/listinfo/ovirt-devel > > > From imain at redhat.com Wed Apr 22 16:08:06 2009 From: imain at redhat.com (Ian Main) Date: Wed, 22 Apr 2009 09:08:06 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240350555.18022.32.camel@avon.watzmann.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> Message-ID: <20090422090806.4eeeaa33@tp.mains.net> On Tue, 21 Apr 2009 21:49:15 +0000 David Lutterkort wrote: > On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: > > So with this service layer.. with it being included and setting local > > properties of the object, will that be thread safe? Or will we have > > to do locking around each call? > > > > I'm not sure yet if the agent will be threaded.. but it certainly > > could have a thread per method invocation.. > > To echo what Scott said: I would prefer if we followed the rails model > fairly closely, with some sort of notion of a 'QMF controller', and > instantiate one for every method call from the QMF agent. > > Given that we want to minimize the amount of things we keep in memory > (mostly to avoid cache coherency issues between memory and DB), we want > the QMF API to be as statefree as possible. Yeah that makes sense.. the only place where it might be a little odd is in setting properties. When properties are set it seems the way to do it is to load the vm properties hash from an active record and then call update() to have everything verified the same way as in rails? I'm not sure if there's any other way to verify the contents of various fields using the active record directly? Either way it seems we need direct acccess to it as well.. is that a problem? Ian From sseago at redhat.com Wed Apr 22 16:35:55 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 22 Apr 2009 12:35:55 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090422090806.4eeeaa33@tp.mains.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> Message-ID: <49EF476B.7060801@redhat.com> Ian Main wrote: > On Tue, 21 Apr 2009 21:49:15 +0000 > David Lutterkort wrote: > > >> On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: >> >>> So with this service layer.. with it being included and setting local >>> properties of the object, will that be thread safe? Or will we have >>> to do locking around each call? >>> >>> I'm not sure yet if the agent will be threaded.. but it certainly >>> could have a thread per method invocation.. >>> >> To echo what Scott said: I would prefer if we followed the rails model >> fairly closely, with some sort of notion of a 'QMF controller', and >> instantiate one for every method call from the QMF agent. >> >> Given that we want to minimize the amount of things we keep in memory >> (mostly to avoid cache coherency issues between memory and DB), we want >> the QMF API to be as statefree as possible. >> > > Yeah that makes sense.. the only place where it might be a little odd is > in setting properties. When properties are set it seems the way to do it > is to load the vm properties hash from an active record and then call > update() to have everything verified the same way as in rails? > > I'm not sure if there's any other way to verify the contents of various > fields using the active record directly? Either way it seems we need > direct acccess to it as well.. is that a problem? > > Ian > > Yes, to make persistent changes to VM properties here you would need to use the svc_update call. Or are you saying you also want to make changes to activerecord objects outside the service API layer? This would certainly be possible -- and if you call save! then any validation errors will raise exceptions just like they do in the svc method, although you'd lose the permission checks and any other business logic that is in the service layer. Scott From sseago at redhat.com Wed Apr 22 17:21:20 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 22 Apr 2009 17:21:20 +0000 Subject: [Ovirt-devel] [PATCH server] fixed attribute bug in grant_admin_privileges Message-ID: <1240420880-26010-1-git-send-email-sseago@redhat.com> Signed-off-by: Scott Seago --- src/script/grant_admin_privileges | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/script/grant_admin_privileges b/src/script/grant_admin_privileges index 231b1f8..cdf36e7 100755 --- a/src/script/grant_admin_privileges +++ b/src/script/grant_admin_privileges @@ -14,7 +14,7 @@ ActiveLdap::Base.establish_connection :base => base, :host => host, :try_sasl => if Account.exists?("uid=#{uid}") puts "Creating an admin account for #{uid}..." $pool = DirectoryPool.get_directory_root - permission = Permission.new(:user_role => Role.find_by_name(Role::SUPER_ADMIN).id, + permission = Permission.new(:role_id => Role.find_by_name(Role::SUPER_ADMIN).id, :uid => uid, :pool_id => $pool.id) permission.save_with_new_children -- 1.6.0.6 From jboggs at redhat.com Wed Apr 22 17:23:56 2009 From: jboggs at redhat.com (Joey Boggs) Date: Wed, 22 Apr 2009 13:23:56 -0400 Subject: [Ovirt-devel] [PATCH server] fixed attribute bug in grant_admin_privileges In-Reply-To: <1240420880-26010-1-git-send-email-sseago@redhat.com> References: <1240420880-26010-1-git-send-email-sseago@redhat.com> Message-ID: <49EF52AC.6050800@redhat.com> ack Scott Seago wrote: > Signed-off-by: Scott Seago > --- > src/script/grant_admin_privileges | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/src/script/grant_admin_privileges b/src/script/grant_admin_privileges > index 231b1f8..cdf36e7 100755 > --- a/src/script/grant_admin_privileges > +++ b/src/script/grant_admin_privileges > @@ -14,7 +14,7 @@ ActiveLdap::Base.establish_connection :base => base, :host => host, :try_sasl => > if Account.exists?("uid=#{uid}") > puts "Creating an admin account for #{uid}..." > $pool = DirectoryPool.get_directory_root > - permission = Permission.new(:user_role => Role.find_by_name(Role::SUPER_ADMIN).id, > + permission = Permission.new(:role_id => Role.find_by_name(Role::SUPER_ADMIN).id, > :uid => uid, > :pool_id => $pool.id) > permission.save_with_new_children > From jboggs at redhat.com Wed Apr 22 17:29:35 2009 From: jboggs at redhat.com (Joey Boggs) Date: Wed, 22 Apr 2009 13:29:35 -0400 Subject: [Ovirt-devel] [PATCH server] cleanup cobbler and put all cobbler traffic on the admin network Message-ID: <1240421375-9335-1-git-send-email-jboggs@redhat.com> This set the cobbler modules dns/dhcp to dnsmasq, removes a duplicate ip replacement in /etc/cobbler/settings, and sets the ip address to the admin network instead of the guest networkwhere it should've been in the first place. --- installer/modules/ovirt/files/modules.conf | 4 ++-- installer/modules/ovirt/manifests/cobbler.pp | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/installer/modules/ovirt/files/modules.conf b/installer/modules/ovirt/files/modules.conf index 236ef4c..7bfc2f8 100644 --- a/installer/modules/ovirt/files/modules.conf +++ b/installer/modules/ovirt/files/modules.conf @@ -74,7 +74,7 @@ module = authz_allowall # https://fedorahosted.org/cobbler/wiki/ManageDns [dns] -module = manage_bind +module = manage_dnsmasq # chooses the DHCP management engine if manage_dhcp is enabled # in /etc/cobbler/settings, which is off by default. @@ -89,7 +89,7 @@ module = manage_bind # https://fedorahosted.org/cobbler/wiki/ManageDhcp [dhcp] -module = manage_isc +module = manage_dnsmasq diff --git a/installer/modules/ovirt/manifests/cobbler.pp b/installer/modules/ovirt/manifests/cobbler.pp index e9c239e..811a0ee 100644 --- a/installer/modules/ovirt/manifests/cobbler.pp +++ b/installer/modules/ovirt/manifests/cobbler.pp @@ -80,26 +80,18 @@ class cobbler::bundled { require => Package[cobbler] } - file_replacement{"settings_ip_address": - file => "/etc/cobbler/settings", - pattern => "127.0.0.1", - replacement => $ipaddress, - notify => Service[cobblerd], - require => Package[cobbler] - } - file_replacement{"settings_xml_rpc": file => "/etc/cobbler/settings", pattern => "xmlrpc_rw_enabled: 0", replacement => "xmlrpc_rw_enabled: 1", - require => File_replacement[settings_ip_address], + require => [File_replacement[settings_next_server],File_replacement[settings_server]], notify=> Service[cobblerd] } service {"cobblerd" : ensure => running, enable => true, - require => File_replacement[settings_ip_address] + require => [File_replacement[settings_next_server],File_replacement[settings_server]], } file {"/etc/cobbler/modules.conf": @@ -132,7 +124,7 @@ class cobbler::bundled { file_replacement{"settings_server": file => "/etc/cobbler/settings", pattern => "server: 127.0.0.1", - replacement => "server: $guest_ipaddr", + replacement => "server: $admin_ipaddr", require => Package[cobbler], notify => Service[cobblerd] } @@ -140,7 +132,7 @@ class cobbler::bundled { file_replacement{"settings_next_server": file => "/etc/cobbler/settings", pattern => "next_server: 127.0.0.1", - replacement => "next_server: $guest_ipaddr", + replacement => "next_server: $admin_ipaddr", require => Package[cobbler], notify => Service[cobblerd] } -- 1.6.0.6 From imain at redhat.com Wed Apr 22 18:06:17 2009 From: imain at redhat.com (Ian Main) Date: Wed, 22 Apr 2009 11:06:17 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <49EF476B.7060801@redhat.com> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> Message-ID: <20090422110617.47cc5bd1@tp.mains.net> On Wed, 22 Apr 2009 12:35:55 -0400 Scott Seago wrote: > Ian Main wrote: > > On Tue, 21 Apr 2009 21:49:15 +0000 > > David Lutterkort wrote: > > > > > >> On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: > >> > >>> So with this service layer.. with it being included and setting local > >>> properties of the object, will that be thread safe? Or will we have > >>> to do locking around each call? > >>> > >>> I'm not sure yet if the agent will be threaded.. but it certainly > >>> could have a thread per method invocation.. > >>> > >> To echo what Scott said: I would prefer if we followed the rails model > >> fairly closely, with some sort of notion of a 'QMF controller', and > >> instantiate one for every method call from the QMF agent. > >> > >> Given that we want to minimize the amount of things we keep in memory > >> (mostly to avoid cache coherency issues between memory and DB), we want > >> the QMF API to be as statefree as possible. > >> > > > > Yeah that makes sense.. the only place where it might be a little odd is > > in setting properties. When properties are set it seems the way to do it > > is to load the vm properties hash from an active record and then call > > update() to have everything verified the same way as in rails? > > > > I'm not sure if there's any other way to verify the contents of various > > fields using the active record directly? Either way it seems we need > > direct acccess to it as well.. is that a problem? > > > > Ian > > > > > Yes, to make persistent changes to VM properties here you would need to > use the svc_update call. Or are you saying you also want to make changes > to activerecord objects outside the service API layer? This would > certainly be possible -- and if you call save! then any validation > errors will raise exceptions just like they do in the svc method, > although you'd lose the permission checks and any other business logic > that is in the service layer. I think in many instances it would be easier to simply change the active record directly. If you think about something like.. vm = ovirt.create_vm_def(...) vm.description = 'changed description' in the backend there will be a call to the 'description' method of a VmDef object. So in ruby we'll have eg: class VmDef def description(new_desc) vm = vm_ar.reload vm.description = new_desc vm.save! end ... Otherwise you have to load the VM active record and make a hash from it (?? maybe that's easy?) and then call svc_update() with the new hash.. maybe it would be possible to just have the permission check callable directly? Not sure what is best.. Ian From sseago at redhat.com Wed Apr 22 18:19:11 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 22 Apr 2009 14:19:11 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090422110617.47cc5bd1@tp.mains.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> Message-ID: <49EF5F9F.6070507@redhat.com> Ian Main wrote: > On Wed, 22 Apr 2009 12:35:55 -0400 > Scott Seago wrote: > > >> Ian Main wrote: >> >>> On Tue, 21 Apr 2009 21:49:15 +0000 >>> David Lutterkort wrote: >>> >>> >>> >>>> On Tue, 2009-04-21 at 13:14 -0700, Ian Main wrote: >>>> >>>> >>>>> So with this service layer.. with it being included and setting local >>>>> properties of the object, will that be thread safe? Or will we have >>>>> to do locking around each call? >>>>> >>>>> I'm not sure yet if the agent will be threaded.. but it certainly >>>>> could have a thread per method invocation.. >>>>> >>>>> >>>> To echo what Scott said: I would prefer if we followed the rails model >>>> fairly closely, with some sort of notion of a 'QMF controller', and >>>> instantiate one for every method call from the QMF agent. >>>> >>>> Given that we want to minimize the amount of things we keep in memory >>>> (mostly to avoid cache coherency issues between memory and DB), we want >>>> the QMF API to be as statefree as possible. >>>> >>>> >>> Yeah that makes sense.. the only place where it might be a little odd is >>> in setting properties. When properties are set it seems the way to do it >>> is to load the vm properties hash from an active record and then call >>> update() to have everything verified the same way as in rails? >>> >>> I'm not sure if there's any other way to verify the contents of various >>> fields using the active record directly? Either way it seems we need >>> direct acccess to it as well.. is that a problem? >>> >>> Ian >>> >>> >>> >> Yes, to make persistent changes to VM properties here you would need to >> use the svc_update call. Or are you saying you also want to make changes >> to activerecord objects outside the service API layer? This would >> certainly be possible -- and if you call save! then any validation >> errors will raise exceptions just like they do in the svc method, >> although you'd lose the permission checks and any other business logic >> that is in the service layer. >> > > I think in many instances it would be easier to simply change the active record directly. If you think about something like.. > > vm = ovirt.create_vm_def(...) > vm.description = 'changed description' > > in the backend there will be a call to the 'description' method of a > VmDef object. So in ruby we'll have eg: > > class VmDef > > def description(new_desc) > vm = vm_ar.reload > vm.description = new_desc > vm.save! > end > > ... > > Otherwise you have to load the VM active record and make a hash from it > (?? maybe that's easy?) and then call svc_update() with the new hash.. > maybe it would be possible to just have the permission check callable > directly? Not sure what is best.. > > Ian > > For edits you only need to include changed attributes in the hash. So you could call svc_obj.svc_update(vm_id, {:description => 'changed description'}). I'm still slightly confused on how VmDef relates to the service classes. Is VmDef the class that includes the VmService module? Or is VmDef something longer-lived and more related to the activerecord stuff directly? In any case whatever class includes VmService will have access to the activerecord VM ID somehow so it could call svc_update(vm_id, {:description => 'changed description'}) if all you want to do is change the description. Something like this: def description(new_desc) #svc_update handles saving here begin # replace vm_ar.id with whatever means we have to get the id for the current object. svc_update(vm_ar.id,:description => new_desc) rescue # error handling here end end The biggest sticking point here would probably not be the mechanics of what methods we implement, etc -- but the fact that the expected scope of any object including VmService is handling a single user request. If we need a single in-memory object to span multiple requests you'd probably need to go to the activerecord model directly (and then have to deal with the various synchronization/threading/locking issues). Scott > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel > From lutter at redhat.com Wed Apr 22 18:21:03 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 22 Apr 2009 11:21:03 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <20090422110617.47cc5bd1@tp.mains.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> Message-ID: <1240424463.8789.3.camel@avon.watzmann.net> On Wed, 2009-04-22 at 11:06 -0700, Ian Main wrote: > Otherwise you have to load the VM active record and make a hash from it > (?? maybe that's easy?) and then call svc_update() with the new hash.. > maybe it would be possible to just have the permission check callable > directly? Not sure what is best.. Yeah, for single-property updates we want some more generic way to do that, on the ovirt agent side, I'd think something like def description(new_desc) ar_id = ... from QMF objectID ... user = ... QMF user ... svc_property!(user, ar_id, :description, new_desc) end and have svc_property! do the permission check, load the AR model, change its description attribute, and save! it back. Given how that is just a lot of boilerplate, I'd imagine that with a tiny bit of metaprogramming, we can reduce that to property_setter :description David From lutter at redhat.com Wed Apr 22 18:24:00 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 22 Apr 2009 11:24:00 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <49EF5F9F.6070507@redhat.com> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> <49EF5F9F.6070507@redhat.com> Message-ID: <1240424640.8789.5.camel@avon.watzmann.net> On Wed, 2009-04-22 at 14:19 -0400, Scott Seago wrote: > For edits you only need to include changed attributes in the hash. So > you could call svc_obj.svc_update(vm_id, {:description => 'changed > description'}). Yeah, that makes much more sense than my implict assumption that we have a special method to modify single properties. > I'm still slightly confused on how VmDef relates to the service classes. > Is VmDef the class that includes the VmService module? Or is VmDef > something longer-lived and more related to the activerecord stuff directly? IIRC VmDef is the QMF object that is exposed for a Vm, i.e. the QMF 'view' of a virtual machine, not the controller. David From sseago at redhat.com Wed Apr 22 18:24:56 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 22 Apr 2009 14:24:56 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240424463.8789.3.camel@avon.watzmann.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> <1240424463.8789.3.camel@avon.watzmann.net> Message-ID: <49EF60F8.2070702@redhat.com> David Lutterkort wrote: > On Wed, 2009-04-22 at 11:06 -0700, Ian Main wrote: > >> Otherwise you have to load the VM active record and make a hash from it >> (?? maybe that's easy?) and then call svc_update() with the new hash.. >> maybe it would be possible to just have the permission check callable >> directly? Not sure what is best.. >> > > Yeah, for single-property updates we want some more generic way to do > that, on the ovirt agent side, I'd think something like > > def description(new_desc) > ar_id = ... from QMF objectID ... > user = ... QMF user ... > svc_property!(user, ar_id, :description, new_desc) > end > > and have svc_property! do the permission check, load the AR model, > change its description attribute, and save! it back. > > Given how that is just a lot of boilerplate, I'd imagine that with a > tiny bit of metaprogramming, we can reduce that to > > property_setter :description > > David > > Yeah I'm unclear on exactly what metaprogramming we need for property_setter, but svc_property itself can be based off the existing svc_update: def svc_property!(ar_id, property, value) svc_update(ar_id, {property => value}) end Note we don't need to pass in user since the svc_foo methods all call get_login_user for that. Scott From sseago at redhat.com Wed Apr 22 18:26:49 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 22 Apr 2009 14:26:49 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240424640.8789.5.camel@avon.watzmann.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> <49EF5F9F.6070507@redhat.com> <1240424640.8789.5.camel@avon.watzmann.net> Message-ID: <49EF6169.1040406@redhat.com> David Lutterkort wrote: > On Wed, 2009-04-22 at 14:19 -0400, Scott Seago wrote: > >> For edits you only need to include changed attributes in the hash. So >> you could call svc_obj.svc_update(vm_id, {:description => 'changed >> description'}). >> > > Yeah, that makes much more sense than my implict assumption that we have > a special method to modify single properties. > > Maybe there's value for the single property version -- I"m not sure. >> I'm still slightly confused on how VmDef relates to the service classes. >> Is VmDef the class that includes the VmService module? Or is VmDef >> something longer-lived and more related to the activerecord stuff directly? >> > > IIRC VmDef is the QMF object that is exposed for a Vm, i.e. the QMF > 'view' of a virtual machine, not the controller. > > David > > So we have two different QMF objects for each AR type? i.e. for Foo we have FooDef which maps to AR and FooService which maps to the service/controller layer? Does it matter that FooService ignores FooDef and uses the AR Foo class directly? Scott From lutter at redhat.com Wed Apr 22 18:31:02 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 22 Apr 2009 11:31:02 -0700 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <49EF6169.1040406@redhat.com> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> <49EF5F9F.6070507@redhat.com> <1240424640.8789.5.camel@avon.watzmann.net> <49EF6169.1040406@redhat.com> Message-ID: <1240425062.8789.13.camel@avon.watzmann.net> On Wed, 2009-04-22 at 14:26 -0400, Scott Seago wrote: > So we have two different QMF objects for each AR type? i.e. for Foo we > have FooDef which maps to AR and FooService which maps to the > service/controller layer? Does it matter that FooService ignores FooDef > and uses the AR Foo class directly? I am actually not sure what a VmDef object looks like agent side - I've been thinking of them as little more than hashes of the properties we expose over QMF; I don't think there's much point in having separate classes for those, since all their behavior is handled by the QMF 'controller'. David From hbrock at redhat.com Wed Apr 22 18:31:12 2009 From: hbrock at redhat.com (Hugh O. Brock) Date: Wed, 22 Apr 2009 14:31:12 -0400 Subject: [Ovirt-devel] [PATCH server] Revised attempt at refactoring the vm_controller using the service layer. In-Reply-To: <1240424463.8789.3.camel@avon.watzmann.net> References: <1240259199-10088-1-git-send-email-sseago@redhat.com> <20090421131406.70b7a092@tp.mains.net> <1240350555.18022.32.camel@avon.watzmann.net> <20090422090806.4eeeaa33@tp.mains.net> <49EF476B.7060801@redhat.com> <20090422110617.47cc5bd1@tp.mains.net> <1240424463.8789.3.camel@avon.watzmann.net> Message-ID: <20090422183111.GD10299@redhat.com> On Wed, Apr 22, 2009 at 11:21:03AM -0700, David Lutterkort wrote: > On Wed, 2009-04-22 at 11:06 -0700, Ian Main wrote: > > Otherwise you have to load the VM active record and make a hash from it > > (?? maybe that's easy?) and then call svc_update() with the new hash.. > > maybe it would be possible to just have the permission check callable > > directly? Not sure what is best.. > > Yeah, for single-property updates we want some more generic way to do > that, on the ovirt agent side, I'd think something like > > def description(new_desc) > ar_id = ... from QMF objectID ... > user = ... QMF user ... > svc_property!(user, ar_id, :description, new_desc) > end > > and have svc_property! do the permission check, load the AR model, > change its description attribute, and save! it back. > > Given how that is just a lot of boilerplate, I'd imagine that with a > tiny bit of metaprogramming, we can reduce that to > > property_setter :description > > David Paging Dr. Jones... Dr. Jones, please bring your camel to the operating room... --Hugh From lutter at redhat.com Wed Apr 22 18:41:27 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 22 Apr 2009 11:41:27 -0700 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <49EF30D5.30909@eseco.de> References: <49EF1FEA.1020209@eseco.de> <20090422144231.GZ10299@redhat.com> <49EF30D5.30909@eseco.de> Message-ID: <1240425687.8789.24.camel@avon.watzmann.net> On Wed, 2009-04-22 at 16:59 +0200, Ingmar Schraub wrote: > Note: the /etc/httpd/conf.d/ovirt-server.conf file which comes with the > rpm is wrong. The httpd daemon does not start at all. I have attached it > to this e-mail, that you can have a look. > > I 'fixed' (better hacked) it by making the following changes: > NameVirtualHost :80 -> NameVirtualHost _default:80 > -> > NameVirtualHost :443 -> NameVirtualHost _default_:443 > -> > > With these changes, httpd starts and I have plain http, can login in and > see the dashboard. > > If I replace _default_ with 192.168.50.2, I get re-directed to https, > but then after login in, the browser tells me "Redirect Loop > Firefox has detected that the server is redirecting the request for this > address in a way that will never complete." I encountered that yesterday, too; if you only have one NIC on your ovirt server (and that should certainly be supported), the httpd config tells Apache to rewrite http: requests to https:, and the :443 vhost wants to ProxyPass back to http: Should be easy to fix, though I am not sure how since I don't know what lead to the initial overt-server.conf. David From lutter at redhat.com Wed Apr 22 18:53:27 2009 From: lutter at redhat.com (David Lutterkort) Date: Wed, 22 Apr 2009 11:53:27 -0700 Subject: [Ovirt-devel] ovirt - web gui In-Reply-To: <49EF30D5.30909@eseco.de> References: <49EF1FEA.1020209@eseco.de> <20090422144231.GZ10299@redhat.com> <49EF30D5.30909@eseco.de> Message-ID: <1240426407.8789.29.camel@avon.watzmann.net> Forgot to mention in my previous reply: On Wed, 2009-04-22 at 16:59 +0200, Ingmar Schraub wrote: > NameVirtualHost :80 > > > RewriteEngine on > RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L] > > As a workaround, if you comment this block out, things work (without the http -> https redirect, of course) - Scott says that the real fix will be coming forth shortly (i.e., feel free to preempt us with a patch) ;) David From kc at cobradevil.org Wed Apr 22 19:42:59 2009 From: kc at cobradevil.org (william) Date: Wed, 22 Apr 2009 21:42:59 +0200 Subject: [Ovirt-devel] [PATCH server webui] Change the "Edit virtual machine" to "Save settings" button] Message-ID: <1240429379.11522.5.camel@RIC.kc.mindef.nl> A small change in the Web UI edit virtual machine. --- app/views/vm/edit.rhtml.orig 2009-04-22 21:18:50.000000000 +0200 +++ app/views/vm/edit.rhtml 2009-04-22 21:19:11.000000000 +0200 @@ -11,7 +11,7 @@ <%= render :partial => 'form', :locals => { :create => false } %>
    - <%= popup_footer("$('#vm_form').submit()", "Edit Virtual Machine") %> + <%= popup_footer("$('#vm_form').submit()", "Save settings") %>