From bad908991b10231fbc95c5f24f1c0fe2b223b930 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 14:50:58 -0700 Subject: [PATCH 1/8] Add elecksee dep for local servers --- miasma-local.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/miasma-local.gemspec b/miasma-local.gemspec index 68f0ee6..e0989af 100644 --- a/miasma-local.gemspec +++ b/miasma-local.gemspec @@ -10,6 +10,7 @@ Gem::Specification.new do |s| s.description = 'Smoggy local API' s.license = 'Apache 2.0' s.require_path = 'lib' + s.add_runtime_dependency 'elecksee' s.add_development_dependency 'miasma', '>= 0.2.12' s.add_development_dependency 'pry' s.add_development_dependency 'minitest' From c3ca827eba3ce6eb7ccb8c5e85c11f5cea43a3e5 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 14:52:19 -0700 Subject: [PATCH 2/8] Add initial compute implementation on local --- lib/miasma/contrib/local.rb | 2 + lib/miasma/contrib/local/compute.rb | 62 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 lib/miasma/contrib/local/compute.rb diff --git a/lib/miasma/contrib/local.rb b/lib/miasma/contrib/local.rb index c74ed94..be7a150 100644 --- a/lib/miasma/contrib/local.rb +++ b/lib/miasma/contrib/local.rb @@ -15,6 +15,7 @@ module ApiCommon def self.included(klass) klass.class_eval do attribute :object_store_root, String + attribute :container_root, String, :default => '/var/lib/lxc' end end @@ -23,5 +24,6 @@ def self.included(klass) end end + Models::Compute.autoload :Local, 'miasma/contrib/local/compute' Models::Storage.autoload :Local, 'miasma/contrib/local/storage' end diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb new file mode 100644 index 0000000..0e91c81 --- /dev/null +++ b/lib/miasma/contrib/local/compute.rb @@ -0,0 +1,62 @@ +require 'miasma' +require 'miasma/contrib/local' +require 'elecksee' + +module Miasma + module Models + class Compute + class Local < Compute + + include Contrib::LocalApiCore::ApiCommon + + # Provide full list of server instances + # + # @return [Array] + def server_all + c_roots = Dir.glob( + File.join(container_root, '*') + ).find_all do |g_path| + File.directory?(g_path) + end + c_roots.map do |c_path| + lxc = Lxc.new( + File.basename(c_path), + :base_path => File.dirname(c_path) + ) + Server.new( + self, + :id => lxc.path.to_s, + :name => lxc.name, + :state => lxc.state, + :image_id => 'unknown', + :flavor_id => 'unknown', + :addresses_public => lxc.running? ? [ + Server::Address.new( + :version => 4, + :address => lxc.container_ip + ) + ] : [], + :addresses_private => [], + :status => lxc.state.to_s + ).valid_state + end + end + + # Reload the server data + # + # @param server [Miasma::Models::Compute::Server] + # @return [Miasma::Models::Compute::Server] + def server_save(server) + + end + + def server_reload(obj) + end + + def server_destroy(obj) + end + + end + end + end +end From 8e200e0f7862cf7c4e5f88553b9022ac9afe8033 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 15:34:36 -0700 Subject: [PATCH 3/8] Implement server type things (except save) --- lib/miasma/contrib/local/compute.rb | 88 ++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb index 0e91c81..be9fb52 100644 --- a/lib/miasma/contrib/local/compute.rb +++ b/lib/miasma/contrib/local/compute.rb @@ -25,6 +25,69 @@ def server_all ) Server.new( self, + server_info(lxc) + ).valid_state + end + end + + # Save/create the server + # + # @param server [Miasma::Models::Compute::Server] + # @return [Miasma::Models::Compute::Server] + def server_save(server) + + end + + # Reload the server data + # + # @param server [Miasma::Models::Compute::Server] + # @return [Miasma::Models::Compute::Server] + def server_reload(server) + if(server.persisted?) + lxc = Lxc.new( + server.name, + :base_path => File.dirname(server.id) + ) + server.load_data( + server_info(lxc) + ).valid_state + server + else + server + end + end + + # Destroy the server + # + # @param server [Miasma::Models::Compute::Server] + # @return [TrueClass, FalseClass] + def server_destroy(server) + if(server.persisted?) + lxc = Lxc.new( + server.name, + :base_path => File.dirname(server.id) + ) + if(lxc.exists?) + if(lxc.running?) + lxc.stop + end + lxc.destroy + end + true + else + false + end + end + + protected + + # Generate model attributes from container + # + # @param lxc [Lxc] + # @return [Smash] + def server_info(lxc) + if(lxc.exists?) + Smash.new( :id => lxc.path.to_s, :name => lxc.name, :state => lxc.state, @@ -38,24 +101,19 @@ def server_all ] : [], :addresses_private => [], :status => lxc.state.to_s - ).valid_state + ) + else + Smash.new( + :id => lxc.path.to_s, + :name => lxc.name, + :state => :terminated, + :addresses_public => [], + :addresses_private => [], + :status => 'Destroyed' + ) end end - # Reload the server data - # - # @param server [Miasma::Models::Compute::Server] - # @return [Miasma::Models::Compute::Server] - def server_save(server) - - end - - def server_reload(obj) - end - - def server_destroy(obj) - end - end end end From 0a1fa57050059e1b8316f1f84050bb034c92cd7f Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 16:08:48 -0700 Subject: [PATCH 4/8] Provide junky image ID to simply provide distro + version details --- lib/miasma/contrib/local/compute.rb | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb index be9fb52..6f78825 100644 --- a/lib/miasma/contrib/local/compute.rb +++ b/lib/miasma/contrib/local/compute.rb @@ -35,7 +35,11 @@ def server_all # @param server [Miasma::Models::Compute::Server] # @return [Miasma::Models::Compute::Server] def server_save(server) + if(server.persisted?) + raise "What do we do?" + else + end end # Reload the server data @@ -87,11 +91,29 @@ def server_destroy(server) # @return [Smash] def server_info(lxc) if(lxc.exists?) + info_path = lxc.rootfs.join('etc/os-release').to_s + if(File.exists?(info_path)) + sys_info = Smash[ + File.read(info_path).split("\n").map do |line| + line.split('=', 2).map do |item| + item.gsub(/(^"|"$)/, '') + end + end + ] + image_id = [ + sys_info.fetch('ID', 'unknown-system'), + sys_info.fetch('VERSION_ID', 'unknown-version') + ].join('_') + else + sys_info = Smash.new + image_id = 'unknown' + end + Smash.new( :id => lxc.path.to_s, :name => lxc.name, :state => lxc.state, - :image_id => 'unknown', + :image_id => image_id, :flavor_id => 'unknown', :addresses_public => lxc.running? ? [ Server::Address.new( From 3386d134ceea410c39d307ba9b3e4557fc33e4e9 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 16:52:39 -0700 Subject: [PATCH 5/8] Add basic support for save implementation --- lib/miasma/contrib/local/compute.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb index 6f78825..940e793 100644 --- a/lib/miasma/contrib/local/compute.rb +++ b/lib/miasma/contrib/local/compute.rb @@ -38,7 +38,14 @@ def server_save(server) if(server.persisted?) raise "What do we do?" else - + lxc = Lxc::Clone.new( + :original => server.image_id, + :new_name => server.name + ).clone! + lxc.start + server.load_data( + server_info(lxc) + ).valid_state end end @@ -103,7 +110,7 @@ def server_info(lxc) image_id = [ sys_info.fetch('ID', 'unknown-system'), sys_info.fetch('VERSION_ID', 'unknown-version') - ].join('_') + ].join('_').tr('.', '') else sys_info = Smash.new image_id = 'unknown' From 899f57f08519843151d12c7237a63a8f99421b65 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Jun 2015 16:53:06 -0700 Subject: [PATCH 6/8] Use updated elecksee for testing --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index fa75df1..576d003 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ source 'https://rubygems.org' +gem 'elecksee', :git => 'git://github.com/chrisroberts/elecksee', :branch => 'develop' + gemspec From 86ca8544ec788c482dc8fb11598f1923c51e705f Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Thu, 18 Jun 2015 07:13:25 -0700 Subject: [PATCH 7/8] Include optional support for ephemerals --- lib/miasma/contrib/local/compute.rb | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb index 940e793..fad02ef 100644 --- a/lib/miasma/contrib/local/compute.rb +++ b/lib/miasma/contrib/local/compute.rb @@ -38,10 +38,21 @@ def server_save(server) if(server.persisted?) raise "What do we do?" else - lxc = Lxc::Clone.new( - :original => server.image_id, - :new_name => server.name - ).clone! + if(server.metadata && server.metadata[:ephemeral]) + elxc = Lxc::Ephemeral.new( + :original => server.image_id, + :daemon => true, + :new_name => server.name + ) + elxc.create! + elxc.start!(:detach) + lxc = elxc.lxc + else + lxc = Lxc::Clone.new( + :original => server.image_id, + :new_name => server.name + ).clone! + end lxc.start server.load_data( server_info(lxc) From 893867137f4c2829cf7e512044c2be1fb20d9207 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Thu, 18 Jun 2015 07:44:16 -0700 Subject: [PATCH 8/8] Write metadata on save. Isolate name from ID. --- lib/miasma/contrib/local/compute.rb | 77 ++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/lib/miasma/contrib/local/compute.rb b/lib/miasma/contrib/local/compute.rb index fad02ef..923f812 100644 --- a/lib/miasma/contrib/local/compute.rb +++ b/lib/miasma/contrib/local/compute.rb @@ -1,6 +1,7 @@ require 'miasma' require 'miasma/contrib/local' require 'elecksee' +require 'tempfile' module Miasma module Models @@ -54,6 +55,26 @@ def server_save(server) ).clone! end lxc.start + m_data = Smash.new( + :name => server.name, + :ephemeral => server.metadata[:ephemeral], + :image_id => server.image_id, + :flavor_id => server.flavor_id + ) + m_data_path = lxc.path.join('miasma.json').to_s + if(File.writable?(File.dirname(m_data_path))) + File.open(m_data_path, 'w') do |file| + file.write MultiJson.dump(m_data) + end + else + t_file = Tempfile.new('miasma-local-compute') + t_file.write MultiJson.dump(m_data) + t_file.close + lxc.run_command( + "mv #{t_file.path} #{m_data_path}", + :sudo => true + ) + end server.load_data( server_info(lxc) ).valid_state @@ -67,7 +88,7 @@ def server_save(server) def server_reload(server) if(server.persisted?) lxc = Lxc.new( - server.name, + File.basename(server.id), :base_path => File.dirname(server.id) ) server.load_data( @@ -86,14 +107,16 @@ def server_reload(server) def server_destroy(server) if(server.persisted?) lxc = Lxc.new( - server.name, + File.basename(server.id), :base_path => File.dirname(server.id) ) if(lxc.exists?) if(lxc.running?) lxc.stop end - lxc.destroy + if(lxc.exists?) # ephemeral self-clean + lxc.destroy + end end true else @@ -109,30 +132,35 @@ def server_destroy(server) # @return [Smash] def server_info(lxc) if(lxc.exists?) - info_path = lxc.rootfs.join('etc/os-release').to_s - if(File.exists?(info_path)) - sys_info = Smash[ - File.read(info_path).split("\n").map do |line| - line.split('=', 2).map do |item| - item.gsub(/(^"|"$)/, '') - end - end - ] - image_id = [ - sys_info.fetch('ID', 'unknown-system'), - sys_info.fetch('VERSION_ID', 'unknown-version') - ].join('_').tr('.', '') + meta_path = lxc.path.join('miasma.json').to_s + if(File.exists?(meta_path)) + sys_info = MultiJson.load(File.read(meta_path)).to_smash else - sys_info = Smash.new - image_id = 'unknown' + info_path = lxc.rootfs.join('etc/os-release').to_s + if(File.exists?(info_path)) + sys_info = Smash[ + File.read(info_path).split("\n").map do |line| + line.split('=', 2).map do |item| + item.gsub(/(^"|"$)/, '') + end + end + ] + sys_info[:image_id] = [ + sys_info.fetch('ID', 'unknown-system'), + sys_info.fetch('VERSION_ID', 'unknown-version') + ].join('_').tr('.', '') + sys_info[:name] = lxc.name + else + sys_info = Smash.new + end end Smash.new( :id => lxc.path.to_s, - :name => lxc.name, + :name => sys_info[:name], :state => lxc.state, - :image_id => image_id, - :flavor_id => 'unknown', + :image_id => sys_info.fetch(:image_id, 'unknown'), + :flavor_id => sys_info.fetch(:flavor_id, 'unknown'), :addresses_public => lxc.running? ? [ Server::Address.new( :version => 4, @@ -140,12 +168,17 @@ def server_info(lxc) ) ] : [], :addresses_private => [], - :status => lxc.state.to_s + :status => lxc.state.to_s, + :metadata => Smash.new( + :ephemeral => sys_info[:ephemeral] + ) ) else Smash.new( :id => lxc.path.to_s, :name => lxc.name, + :image_id => 'unknown', + :flavor_id => 'unknown', :state => :terminated, :addresses_public => [], :addresses_private => [],