networkmanager-dbus 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Guardfile +5 -1
- data/README.md +20 -2
- data/Rakefile +13 -1
- data/TODO.md +3 -3
- data/examples/change_ip.rb +17 -0
- data/examples/connectivity.rb +1 -1
- data/lib/dbus_interface.rb +14 -5
- data/lib/dbus_interface/class.rb +28 -4
- data/lib/dbus_interface/connection.rb +58 -0
- data/lib/dbus_interface/object.rb +15 -7
- data/lib/network_manager.rb +3 -2
- data/lib/network_manager/dbus.rb +2 -0
- data/lib/network_manager/dbus/device.rb +9 -7
- data/lib/network_manager/dbus/root.rb +8 -4
- data/lib/network_manager/dbus/settings.rb +18 -5
- data/lib/network_manager/dbus/settings_connection.rb +86 -0
- data/lib/network_manager/ip4_config.rb +33 -0
- data/lib/network_manager/version.rb +1 -1
- data/lib/networkmanager-dbus.rb +1 -1
- data/networkmanager-dbus.gemspec +4 -0
- data/script/console +7 -0
- data/script/spec_server +1 -0
- data/spec/fixtures/active_connections.yml +10 -0
- data/spec/fixtures/devices.yml +18 -37
- data/spec/fixtures/dhcp4_configs.yml +17 -0
- data/spec/fixtures/ip4_configs.yml +7 -0
- data/spec/fixtures/settings.yml +4 -14
- data/spec/fixtures/settings_connections.yml +10 -0
- data/spec/lib/dbus_interface/class_spec.rb +31 -0
- data/spec/lib/dbus_interface/object_spec.rb +32 -0
- data/spec/{network_manager → lib/network_manager}/dbus/active_connection_spec.rb +6 -6
- data/spec/lib/network_manager/dbus/device_spec.rb +58 -0
- data/spec/lib/network_manager/dbus/dhcp4_config_spec.rb +19 -0
- data/spec/lib/network_manager/dbus/ethernet_device_spec.rb +14 -0
- data/spec/lib/network_manager/dbus/ip4_config_spec.rb +19 -0
- data/spec/lib/network_manager/dbus/root_spec.rb +38 -0
- data/spec/lib/network_manager/dbus/settings_connection_spec.rb +69 -0
- data/spec/lib/network_manager/dbus/settings_spec.rb +53 -0
- data/spec/lib/network_manager/ip4_config_spec.rb +27 -0
- data/spec/{network_manager_spec.rb → lib/network_manager_spec.rb} +2 -0
- data/spec/mocks/dbus/ethernet_device_mock.rb +5 -0
- data/spec/mocks/dbus/root_mock.rb +14 -0
- data/spec/mocks/dbus/settings_connection_mock.rb +21 -0
- data/spec/mocks/dbus/settings_mock.rb +9 -0
- data/spec/mocks/dbus_mock.rb +33 -0
- data/spec/mocks/init.rb +18 -0
- data/spec/mocks/system_bus_mock.rb +5 -0
- data/spec/mocks/system_bus_service_mock.rb +9 -0
- data/spec/spec_helper.rb +22 -3
- data/spec/support/fixture_helper.rb +21 -4
- metadata +96 -28
- data/lib/network_manager/ip4_helper.rb +0 -14
- data/spec/network_manager/dbus/device_spec.rb +0 -36
- data/spec/network_manager/dbus/dhcp4_config_spec.rb +0 -14
- data/spec/network_manager/dbus/ethernet_device_spec.rb +0 -21
- data/spec/network_manager/dbus/ip4_config_spec.rb +0 -14
- data/spec/network_manager/dbus/root_spec.rb +0 -22
- data/spec/network_manager/dbus/settings_connection_spec.rb +0 -13
- data/spec/network_manager/dbus/settings_spec.rb +0 -30
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,18 @@
|
|
1
|
+
THIS IS ALPHA STUFF :)
|
2
|
+
|
3
|
+
see [TODOs](TODO.md)
|
4
|
+
|
5
|
+
[](https://secure.travis-ci.org/dpree/networkmanager-dbus)
|
6
|
+
|
1
7
|
# NetworkManager-Ruby
|
2
8
|
|
3
9
|
This library provides a Ruby API to NetworkManager using its DBus Interface.
|
4
10
|
|
11
|
+
Written using the NetworkManager DBus API Documentation v0.9
|
12
|
+
|
13
|
+
* [General API](http://projects.gnome.org/NetworkManager/developers/api/09/spec.html)
|
14
|
+
* [Details](http://projects.gnome.org/NetworkManager/developers/api/09/ref-settings.html)
|
15
|
+
|
5
16
|
## Installation
|
6
17
|
|
7
18
|
Please make sure that you have `dbus` and `networkmanager` installed on the machine
|
@@ -22,7 +33,7 @@ please have a look at the `examples` folder and the `specs`.
|
|
22
33
|
|
23
34
|
Development currently happens from my OSX machine where no dbus/networkmanager
|
24
35
|
is running. Therefore, i hacked some scripts together to be able to run rspec
|
25
|
-
over the wire
|
36
|
+
over the wire.
|
26
37
|
|
27
38
|
On the remote-machine (linux, dbus, networkmanager)
|
28
39
|
|
@@ -32,6 +43,13 @@ On the local-machine (osx)
|
|
32
43
|
|
33
44
|
`guard`
|
34
45
|
|
46
|
+
# Thanks
|
47
|
+
|
48
|
+
to the guys from IRC channel #nm at irc.freenode.net
|
49
|
+
|
50
|
+
* dbcw
|
51
|
+
* jklimes
|
52
|
+
|
35
53
|
# License
|
36
54
|
|
37
|
-
|
55
|
+
Copyright 2011 Jens Bissinger. All rights reserved. [MIT-LICENSE](MIT-LICENSE)
|
data/Rakefile
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require :development
|
5
|
+
|
3
6
|
def pump_dumps(dumps)
|
4
7
|
dumps.each do |obj|
|
5
8
|
case obj['action']
|
@@ -40,7 +43,7 @@ namespace :spec do
|
|
40
43
|
desc 'run specs on a remote server (script/spec_server)'
|
41
44
|
task :remote do
|
42
45
|
begin
|
43
|
-
client = MarilynRPC::NativeClient.connect_tcp('192.168.56.101', 8483)
|
46
|
+
client = ::MarilynRPC::NativeClient.connect_tcp('192.168.56.101', 8483)
|
44
47
|
runner = client.for :rspec
|
45
48
|
json = runner.run
|
46
49
|
begin
|
@@ -63,3 +66,12 @@ namespace :spec do
|
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
69
|
+
require 'rspec/core/rake_task'
|
70
|
+
desc 'Default: run specs.'
|
71
|
+
desc "Run specs"
|
72
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
73
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
74
|
+
# Put spec opts in a file named .rspec in root
|
75
|
+
end
|
76
|
+
task :default => :spec
|
77
|
+
|
data/TODO.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# TODOs
|
2
2
|
|
3
3
|
* more specs :)
|
4
|
-
*
|
5
|
-
*
|
6
|
-
*
|
4
|
+
* cleanup specs
|
5
|
+
* better mocking
|
6
|
+
* refactor integration specs
|
7
7
|
* add missing interfaces
|
8
8
|
* different device types
|
9
9
|
* vpn
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/network_manager')
|
2
|
+
|
3
|
+
# the first setting (hopefully a eth0 default foo)
|
4
|
+
con = NetworkManager::DBus::Settings.connections.first
|
5
|
+
|
6
|
+
# new ip4 config
|
7
|
+
# ip + netmask + gateway
|
8
|
+
ip4 = NetworkManager::Ip4Config.from_dot_notation '192.168.10.100', '255.255.255.0', '192.168.10.1'
|
9
|
+
|
10
|
+
# change the settings obj
|
11
|
+
con.ip4_manual = ip4
|
12
|
+
|
13
|
+
# take minor important device no.2 :)
|
14
|
+
dev = NetworkManager.devices[1]
|
15
|
+
|
16
|
+
# apply the settings obj to the dev
|
17
|
+
NetworkManager::DBus::Root.activate_connection con, dev
|
data/examples/connectivity.rb
CHANGED
@@ -3,5 +3,5 @@ require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/network_mana
|
|
3
3
|
puts "Internet Connection: #{NetworkManager.internet_connection? ? 'yes' : 'no'}"
|
4
4
|
|
5
5
|
puts "States are described as NM_STATE_... in NetworkManager::DBus::Root"
|
6
|
-
puts "State is == #{NetworkManager::DBus::Root.instance.
|
6
|
+
puts "State is == #{NetworkManager::DBus::Root.instance.call('state'}"
|
7
7
|
|
data/lib/dbus_interface.rb
CHANGED
@@ -1,21 +1,30 @@
|
|
1
1
|
module DBusInterface
|
2
|
+
class UnavailableError < StandardError; end
|
3
|
+
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :interface
|
6
|
+
end
|
7
|
+
|
2
8
|
require 'dbus'
|
9
|
+
require File.join(File.dirname(__FILE__), 'dbus_interface/connection')
|
3
10
|
require File.join(File.dirname(__FILE__), 'dbus_interface/class')
|
4
11
|
require File.join(File.dirname(__FILE__), 'dbus_interface/object')
|
5
12
|
|
6
13
|
def self.system_bus
|
7
14
|
::DBus::SystemBus.instance
|
15
|
+
rescue Errno::ENOENT => e
|
16
|
+
raise UnavailableError.new "DBus SystemBus not available! (#{e})"
|
8
17
|
end
|
9
18
|
|
10
19
|
def self.service
|
11
|
-
@@service
|
20
|
+
@@service ||= system_bus.service config.interface
|
12
21
|
end
|
13
22
|
|
14
|
-
def self.
|
15
|
-
|
23
|
+
def self.configure(&block)
|
24
|
+
yield config
|
16
25
|
end
|
17
26
|
|
18
|
-
def self.
|
19
|
-
|
27
|
+
def self.config
|
28
|
+
@@config ||= Configuration.new
|
20
29
|
end
|
21
30
|
end
|
data/lib/dbus_interface/class.rb
CHANGED
@@ -2,14 +2,22 @@ module DBusInterface::Class
|
|
2
2
|
def map_dbus(conf)
|
3
3
|
@dbus ||= begin
|
4
4
|
# ensure hash
|
5
|
-
raise ArgumentError.new "
|
5
|
+
raise ArgumentError.new "map_dbus must receive a Hash instead of "\
|
6
6
|
"#{conf.class}" unless conf.is_a? Hash
|
7
7
|
# ensure :default_iface is set
|
8
|
-
raise ArgumentError.new "
|
8
|
+
raise ArgumentError.new "map_dbus must specify at least :default_iface"\
|
9
9
|
unless conf.has_key? :default_iface
|
10
10
|
conf
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
def no_properties!
|
15
|
+
@no_properties = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_properties?
|
19
|
+
defined?(@no_properties) && @no_properties ? true : false
|
20
|
+
end
|
13
21
|
|
14
22
|
def default_iface
|
15
23
|
dbus[:default_iface]
|
@@ -23,10 +31,26 @@ module DBusInterface::Class
|
|
23
31
|
def instance
|
24
32
|
@instance ||= new
|
25
33
|
end
|
26
|
-
|
34
|
+
|
35
|
+
def property(name, type = :string)
|
36
|
+
underscored = underscore(name)
|
37
|
+
define_method underscored do self[name] end
|
38
|
+
if type == :boolean
|
39
|
+
define_method "#{underscored}?" do self[name] ? true : false end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
27
43
|
private
|
28
44
|
|
29
45
|
def dbus
|
30
46
|
@dbus
|
31
47
|
end
|
32
|
-
|
48
|
+
|
49
|
+
def underscore(camel_cased_word)
|
50
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
51
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
52
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
53
|
+
tr("-", "_").
|
54
|
+
downcase
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class DBusInterface::Connection
|
2
|
+
attr_reader :default_iface, :object_path
|
3
|
+
|
4
|
+
def initialize(default_iface, object_path)
|
5
|
+
@default_iface = default_iface
|
6
|
+
@object_path = object_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.clear!
|
10
|
+
connections.clear
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.connections
|
14
|
+
@@connections ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.add_connection(con)
|
18
|
+
@@connections[con.key] = con
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.instance_for(default_iface, object_path)
|
22
|
+
con_key = connection_key(default_iface, object_path)
|
23
|
+
if connections[con_key]
|
24
|
+
connections[con_key]
|
25
|
+
else
|
26
|
+
new_con = new(default_iface, object_path)
|
27
|
+
add_connection(new_con)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.connection_key(default_iface, object_path)
|
32
|
+
[default_iface,object_path].join
|
33
|
+
end
|
34
|
+
|
35
|
+
def key
|
36
|
+
self.class.connection_key(default_iface, object_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.call(default_iface, object_path, method, *args)
|
40
|
+
con = instance_for(default_iface, object_path)
|
41
|
+
con.call(method, *args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def call(method, *args)
|
45
|
+
dbus.send(method, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def dbus
|
51
|
+
@dbus ||= begin
|
52
|
+
d = DBusInterface.service.object(object_path)
|
53
|
+
d.default_iface = default_iface
|
54
|
+
d.introspect
|
55
|
+
d
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -3,17 +3,20 @@ module DBusInterface::Object
|
|
3
3
|
some_base.extend(DBusInterface::Class)
|
4
4
|
end
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
object
|
6
|
+
def call(method, *args)
|
7
|
+
if object_path == nil || object_path == '/'
|
8
|
+
nil
|
9
|
+
else
|
10
|
+
DBusInterface::Connection.call(self.class.default_iface, object_path, method, *args)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
15
14
|
def properties
|
16
|
-
|
15
|
+
if self.class.no_properties?
|
16
|
+
nil
|
17
|
+
else
|
18
|
+
call('all_properties')
|
19
|
+
end
|
17
20
|
end
|
18
21
|
|
19
22
|
def initialize(object_path = nil)
|
@@ -32,4 +35,9 @@ module DBusInterface::Object
|
|
32
35
|
def [](key)
|
33
36
|
properties[key]
|
34
37
|
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"#{self.class} #{properties}"
|
41
|
+
end
|
42
|
+
|
35
43
|
end
|
data/lib/network_manager.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# This Library provides an API based on the specs for network manager dbus api
|
2
2
|
# found here: http://projects.gnome.org/NetworkManager/developers/api/09/spec.html
|
3
|
+
require 'ipaddress'
|
3
4
|
module NetworkManager
|
4
5
|
# generic dbus api
|
5
6
|
require File.join(File.dirname(__FILE__), 'dbus_interface')
|
@@ -8,7 +9,7 @@ module NetworkManager
|
|
8
9
|
require File.join(File.dirname(__FILE__), 'network_manager/version')
|
9
10
|
|
10
11
|
# helper
|
11
|
-
require File.join(File.dirname(__FILE__), 'network_manager/
|
12
|
+
require File.join(File.dirname(__FILE__), 'network_manager/ip4_config')
|
12
13
|
|
13
14
|
# network manager dbus api
|
14
15
|
require File.join(File.dirname(__FILE__), 'network_manager/dbus')
|
@@ -23,6 +24,6 @@ module NetworkManager
|
|
23
24
|
end
|
24
25
|
|
25
26
|
DBusInterface.configure do |config|
|
26
|
-
config.
|
27
|
+
config.interface = 'org.freedesktop.NetworkManager'
|
27
28
|
end
|
28
29
|
end
|
data/lib/network_manager/dbus.rb
CHANGED
@@ -24,26 +24,28 @@ class NetworkManager::DBus::Device
|
|
24
24
|
# or LTE standards to access a cellular or wireline data network.
|
25
25
|
NM_DEVICE_TYPE_MODEM = 8
|
26
26
|
|
27
|
-
def to_s
|
28
|
-
"#{self.class} #{properties}"
|
29
|
-
end
|
30
|
-
|
31
27
|
def ip4_address
|
32
28
|
@ip_addr ||= begin
|
33
29
|
ip4_int = self['Ip4Address']
|
34
|
-
NetworkManager::
|
30
|
+
i = NetworkManager::Ip4Config.from_nm_au ip4_int
|
31
|
+
i.address
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
38
35
|
# @return [NetworkManager::DBus::Ip4Config] conf
|
39
36
|
def ip4_config
|
40
|
-
@ip4_config ||= NetworkManager::DBus::Ip4Config.new
|
37
|
+
@ip4_config ||= NetworkManager::DBus::Ip4Config.new self['Ip4Config']
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [NetworkManager::DBus::Ip4Config] conf
|
41
|
+
def dhcp4_config
|
42
|
+
@dhcp4_config ||= NetworkManager::DBus::Dhcp4Config.new self['Dhcp4Config']
|
41
43
|
end
|
42
44
|
|
43
45
|
# @return [NetworkManager::DBus::ActiveConnection] con
|
44
46
|
def active_connection
|
45
47
|
@active_connection ||=
|
46
|
-
NetworkManager::DBus::ActiveConnection.new
|
48
|
+
NetworkManager::DBus::ActiveConnection.new self['ActiveConnection']
|
47
49
|
end
|
48
50
|
|
49
51
|
#
|
@@ -2,7 +2,7 @@ class NetworkManager::DBus::Root
|
|
2
2
|
include DBusInterface::Object
|
3
3
|
map_dbus :default_iface => 'org.freedesktop.NetworkManager',
|
4
4
|
:object_path => '/org/freedesktop/NetworkManager'
|
5
|
-
|
5
|
+
|
6
6
|
# Networking state is unknown.
|
7
7
|
NM_STATE_UNKNOWN = 0
|
8
8
|
# Networking is inactive and all devices are disabled.
|
@@ -22,20 +22,24 @@ class NetworkManager::DBus::Root
|
|
22
22
|
|
23
23
|
# @return [Array<NetworkManager::DBus::Device>]] devices
|
24
24
|
def self.devices
|
25
|
-
instance.
|
25
|
+
instance.call('GetDevices').map do |list|
|
26
26
|
list.map do |object_path|
|
27
27
|
new_device(object_path)
|
28
28
|
end
|
29
29
|
end.flatten
|
30
30
|
end
|
31
31
|
|
32
|
+
def self.activate_connection(con, dev, optional = NetworkManager::DBus::NULL_OBJECT)
|
33
|
+
instance.call('ActivateConnection', con.object_path, dev.object_path, optional)
|
34
|
+
end
|
35
|
+
|
32
36
|
def self.device_by_interface(interface)
|
33
|
-
paths = instance.
|
37
|
+
paths = instance.call('GetDeviceByIpIface', interface)
|
34
38
|
paths.empty? ? nil : new_device(paths.first)
|
35
39
|
end
|
36
40
|
|
37
41
|
def self.internet_connection?
|
38
|
-
instance.
|
42
|
+
instance.call('state').first == NM_STATE_CONNECTED_GLOBAL
|
39
43
|
end
|
40
44
|
|
41
45
|
private
|
@@ -3,19 +3,32 @@ class NetworkManager::DBus::Settings
|
|
3
3
|
map_dbus :default_iface => 'org.freedesktop.NetworkManager.Settings',
|
4
4
|
:object_path => '/org/freedesktop/NetworkManager/Settings'
|
5
5
|
|
6
|
+
# TODO methods
|
7
|
+
# GetConnectionByUuid
|
8
|
+
|
9
|
+
# TODO signals
|
10
|
+
# PropertiesChanged
|
11
|
+
|
12
|
+
property 'Hostname'
|
13
|
+
property 'CanModify', :boolean
|
14
|
+
|
6
15
|
def self.connections
|
7
|
-
instance.
|
16
|
+
instance.connections
|
17
|
+
end
|
18
|
+
|
19
|
+
def connections
|
20
|
+
call('ListConnections').map do |list|
|
8
21
|
list.map do |object_path|
|
9
22
|
::NetworkManager::DBus::SettingsConnection.new(object_path)
|
10
23
|
end
|
11
24
|
end.flatten
|
12
25
|
end
|
13
26
|
|
14
|
-
def
|
15
|
-
|
27
|
+
def add_connection(connection_hash)
|
28
|
+
call('AddConnection', connection_hash)
|
16
29
|
end
|
17
30
|
|
18
|
-
def hostname
|
19
|
-
|
31
|
+
def hostname=(new_name)
|
32
|
+
call('SaveHostname', new_name)
|
20
33
|
end
|
21
34
|
end
|