avm 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a8d74639333b0b7c2b8f8e171c22dd6184ec276653bfe46ac84cbddfdf05d0c
4
- data.tar.gz: f897626773b7aa103b80347a7b41740c6a5c66c3aee68e7834ee80e44263fc3a
3
+ metadata.gz: 3be29c02f4be9deec23c40452cf17ad0ce0478c6ae32508690d0a54bc9c4987a
4
+ data.tar.gz: e63f5d086715190a1803f4289a48f9e25e56094d570d62f6ed5c22b0ceeb6084
5
5
  SHA512:
6
- metadata.gz: 9122946512714522606f24e5e3c79f64b773a7f4229ed25cb8c3a7e2e82b62e86a3ec4354230fdb2bce366bb36ad0e27593cd42e3e9380ab5eb82854eafbff55
7
- data.tar.gz: 71b9e84a0416b0bcefccbbd283d78b5da476e1d5e366746e245eb75eb6c5f22752ef3871a4f571363554f0f99354c366823193dd6a84d3f92faa981b82299d52
6
+ metadata.gz: 372b53edca7fe1187fa0faa39e145437779a3608b7ce7d248b2d5fe753520079c0542dda99a80b4936f09438f6bda1fceebdb78ce1b741e14854f10160468085
7
+ data.tar.gz: 02bd6cdb0cdb4f02e7a202d69de40ca2c5f1c981af6198e8ce1e93b36380b0d39a436d36a358e58856675df9e040080ad6879367e013228cd6bfa3efb3e66735
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'avm/tools/core_ext'
4
- require 'avm/files/rotate'
3
+ require 'avm/data/rotate'
4
+ require 'eac_ruby_utils/core_ext'
5
5
  require 'minitar'
6
6
 
7
7
  module Avm
@@ -88,7 +88,7 @@ module Avm
88
88
  return unless existing == EXISTING_ROTATE
89
89
 
90
90
  infom "Rotating \"#{data_file_path}\"..."
91
- ::Avm::Files::Rotate.new(data_file_path).run
91
+ ::Avm::Data::Rotate.new(data_file_path).run
92
92
  end
93
93
 
94
94
  def new_build_path
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'eac_ruby_utils/simple_cache'
5
+
6
+ module Avm
7
+ module Data
8
+ class Rotate
9
+ include ::EacRubyUtils::SimpleCache
10
+
11
+ attr_reader :options, :source_path
12
+
13
+ def initialize(source_path, options = {})
14
+ @source_path = source_path
15
+ @options = options
16
+ end
17
+
18
+ def run
19
+ validate_msg = validate
20
+ return validate_msg if validate_msg.present?
21
+
22
+ ::FileUtils.mv(source_path, target_path)
23
+ check_space_limit
24
+ nil
25
+ end
26
+
27
+ def space_limit
28
+ r = options[:space_limit].try(:to_i)
29
+ return r if r.present? && r.positive?
30
+
31
+ r
32
+ end
33
+
34
+ def space_used
35
+ rotated_files.inject(0) { |a, e| a + ::File.size(e) }
36
+ end
37
+
38
+ def rotated_files
39
+ ::Dir["#{dirname}/#{source_basename_without_extension}*#{source_extension}"]
40
+ end
41
+
42
+ def oldest_rotated_file
43
+ rotated_files.min_by { |file| [::File.mtime(file)] }
44
+ end
45
+
46
+ private
47
+
48
+ def check_space_limit
49
+ return unless space_limit
50
+
51
+ while space_used > space_limit
52
+ file = oldest_rotated_file
53
+ unless file
54
+ raise 'oldest_rotated_file returned nil ' \
55
+ "(Limit: #{space_limit}, used: #{space_used})"
56
+ end
57
+ ::File.delete(file)
58
+ end
59
+ end
60
+
61
+ def validate
62
+ return "Source file \"#{source_path}\" does not exist" unless ::File.exist?(source_path)
63
+ return "File \"#{source_path}\" is already rotated" if source_rotated?
64
+
65
+ nil
66
+ end
67
+
68
+ def source_rotated?
69
+ source_basename_without_extension.match(/[PN]\d{4}\z/)
70
+ end
71
+
72
+ def source_extension_uncached
73
+ file_extension(::File.basename(source_path))
74
+ end
75
+
76
+ def source_basename_without_extension
77
+ ::File.basename(source_path, source_extension)
78
+ end
79
+
80
+ def target_path_uncached
81
+ ::File.join(dirname, target_basename)
82
+ end
83
+
84
+ def dirname
85
+ ::File.dirname(source_path)
86
+ end
87
+
88
+ def target_basename
89
+ source_basename_without_extension + target_suffix + source_extension
90
+ end
91
+
92
+ def target_suffix
93
+ return '_UNKNOWN_MTIME' unless ::File.exist?(source_path)
94
+
95
+ t = ::File.mtime(source_path)
96
+ t.strftime('_%Y-%m-%d_%H-%M-%S_') + t.strftime('%z').gsub(/\A\+/, 'P').gsub(/\A\-/, 'N')
97
+ end
98
+
99
+ def file_extension(basename)
100
+ extension = ::File.extname(basename)
101
+ return '' if extension.blank?
102
+
103
+ file_extension(::File.basename(basename, extension)) + extension
104
+ end
105
+ end
106
+ end
107
+ end
@@ -13,6 +13,7 @@ module Avm
13
13
 
14
14
  runner_with :help do
15
15
  desc 'Manipulate Docker images.'
16
+ bool_opt '-I', '--image-name', 'Output image name.'
16
17
  arg_opt '-n', '--registry-name', 'Docker registry\'s name.'
17
18
  bool_opt '-p', '--push', 'Push the image to Docker registry.'
18
19
  bool_opt '-r', '--run', 'Run or start a container with builded image.'
@@ -27,6 +28,7 @@ module Avm
27
28
  setup
28
29
  banner
29
30
  build
31
+ output_image_name
30
32
  push
31
33
  container_run
32
34
  end
@@ -84,6 +86,12 @@ module Avm
84
86
  )
85
87
  end
86
88
 
89
+ def output_image_name
90
+ return unless parsed.image_name
91
+
92
+ out(docker_image.tag.to_s.strip + "\n")
93
+ end
94
+
87
95
  def registry_uncached
88
96
  registry_from_option || registry_from_instance || registry_from_default ||
89
97
  fatal_error('No registry defined')
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/instances/entries'
4
+
5
+ module Avm
6
+ module Instances
7
+ class Application
8
+ include ::Avm::Instances::Entries
9
+
10
+ attr_reader :id
11
+
12
+ def initialize(id)
13
+ @id = id.to_s
14
+ end
15
+
16
+ def to_s
17
+ id
18
+ end
19
+
20
+ def instance(suffix)
21
+ ::Avm::Instances::Base.new(self, suffix)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ class Base
6
+ module AutoValues
7
+ module Access
8
+ def auto_access
9
+ read_entry_optional('ssh.url').present? ? 'ssh' : 'local'
10
+ end
11
+
12
+ def auto_ssh_hostname
13
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'ssh.hostname')
14
+ end
15
+
16
+ def auto_ssh_port
17
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'ssh.port') || 22
18
+ end
19
+
20
+ def auto_ssh_username
21
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'ssh.username')
22
+ end
23
+
24
+ def auto_ssh_url
25
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'ssh.url') ||
26
+ auto_ssh_url_by_parts
27
+ end
28
+
29
+ def auto_ssh_url_by_parts
30
+ read_entry_optional('ssh.hostname').if_present do |a|
31
+ a = read_entry_optional('ssh.username').if_present(a) { |v| "#{v}@#{a}" }
32
+ a = read_entry_optional('ssh.port').if_present(a) { |v| "#{a}:#{v}" }
33
+ "ssh://#{a}"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ class Base
6
+ module AutoValues
7
+ module Admin
8
+ def auto_admin_email
9
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'admin.email')
10
+ end
11
+
12
+ def auto_admin_name
13
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'admin.name')
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/data/package/dump'
4
+ require 'avm/self/instance'
5
+
6
+ module Avm
7
+ module Instances
8
+ class Base
9
+ module AutoValues
10
+ module Data
11
+ def auto_data_default_dump_path
12
+ ::Avm::Self
13
+ .instance
14
+ .read_entry_optional(::Avm::Self::Instance::EntryKeys::DATA_DEFAULT_PATH)
15
+ .if_present do |v|
16
+ ::File.join(
17
+ v,
18
+ "#{id}#{::Avm::Data::Instance::Package::Dump::DEFAULT_FILE_EXTENSION}"
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/instances/entry_keys'
4
+
5
+ module Avm
6
+ module Instances
7
+ class Base
8
+ module AutoValues
9
+ module Database
10
+ DEFAULT_HOSTNAME = '127.0.0.1'
11
+ DEFAULT_LIMIT = 5
12
+ DEFAULT_PORTS = {
13
+ 'postgresql' => 5432,
14
+ 'mysql' => 3306,
15
+ 'oracle' => 1521,
16
+ 'sqlserver' => 1433
17
+ }.freeze
18
+ DEFAULT_SYSTEM = 'postgresql'
19
+ DEFAULT_TIMEOUT = 5000
20
+
21
+ def auto_database_name
22
+ inherited_entry_value(::Avm::Instances::EntryKeys::DATABASE_ID,
23
+ ::Avm::Instances::EntryKeys::DATABASE_NAME) || id
24
+ end
25
+
26
+ def auto_database_hostname
27
+ database_auto_common('hostname') || DEFAULT_HOSTNAME
28
+ end
29
+
30
+ def auto_database_limit
31
+ database_auto_common('limit') || DEFAULT_LIMIT
32
+ end
33
+
34
+ def auto_database_password
35
+ database_auto_common('password')
36
+ end
37
+
38
+ def auto_database_port
39
+ database_auto_common('port') || database_port_by_system
40
+ end
41
+
42
+ def auto_database_username
43
+ database_auto_common('username')
44
+ end
45
+
46
+ def auto_database_system
47
+ database_auto_common('system') || DEFAULT_SYSTEM
48
+ end
49
+
50
+ def auto_database_timeout
51
+ database_auto_common('timeout') || DEFAULT_TIMEOUT
52
+ end
53
+
54
+ private
55
+
56
+ def database_auto_common(suffix)
57
+ database_key = ::Avm::Instances::EntryKeys.const_get("database_#{suffix}".upcase)
58
+ inherited_entry_value(::Avm::Instances::EntryKeys::DATABASE_ID, database_key) ||
59
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, database_key)
60
+ end
61
+
62
+ def database_port_by_system
63
+ read_entry_optional(::Avm::Instances::EntryKeys::DATABASE_SYSTEM).if_present do |v|
64
+ DEFAULT_PORTS.fetch(v)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ class Base
6
+ module AutoValues
7
+ module Filesystem
8
+ FS_PATH_KEY = :fs_path
9
+
10
+ def auto_fs_path
11
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, FS_PATH_KEY) do |v|
12
+ v + '/' + id
13
+ end
14
+ end
15
+
16
+ def auto_data_fs_path
17
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, :data_fs_path) do |v|
18
+ v + '/' + id
19
+ end
20
+ end
21
+
22
+ def auto_fs_url
23
+ auto_fs_url_with_ssh || auto_fs_url_without_ssh
24
+ end
25
+
26
+ def auto_fs_url_with_ssh
27
+ read_entry_optional('ssh.url').if_present do |ssh_url|
28
+ read_entry_optional('fs_path').if_present do |fs_path|
29
+ "#{ssh_url}#{fs_path}"
30
+ end
31
+ end
32
+ end
33
+
34
+ def auto_fs_url_without_ssh
35
+ return nil if read_entry_optional('ssh.url').present?
36
+
37
+ read_entry_optional('fs_path').if_present do |fs_path|
38
+ "file://#{fs_path}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/instances/entry'
4
+ require 'avm/instances/entry_keys'
5
+
6
+ module Avm
7
+ module Instances
8
+ class Base
9
+ module AutoValues
10
+ module Mailer
11
+ ::Avm::Instances::EntryKeys.all.select { |c| c.to_s.start_with?('mailer.') }
12
+ .reject { |c| c == ::Avm::Instances::EntryKeys::MAILER_ID }
13
+ .each do |mailer_key|
14
+ define_method ::Avm::Instances::Entry.auto_value_method_name(mailer_key) do
15
+ mailer_auto_common(mailer_key)
16
+ end
17
+ end
18
+
19
+ def auto_mailer_id
20
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID,
21
+ ::Avm::Instances::EntryKeys::MAILER_ID) ||
22
+ read_entry_optional(::Avm::Instances::EntryKeys::HOST_ID)
23
+ end
24
+
25
+ private
26
+
27
+ def mailer_auto_common(mailer_key)
28
+ inherited_entry_value(::Avm::Instances::EntryKeys::MAILER_ID, mailer_key)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ class Base
6
+ module AutoValues
7
+ module Ruby
8
+ def auto_ruby_version
9
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'ruby.version')
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ class Base
6
+ module AutoValues
7
+ module Source
8
+ def auto_source_instance_id
9
+ "#{application.id}_dev"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'addressable'
4
+
5
+ module Avm
6
+ module Instances
7
+ class Base
8
+ module AutoValues
9
+ module System
10
+ def auto_system_username
11
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'system.username') ||
12
+ read_entry_optional('ssh.username')
13
+ end
14
+
15
+ def auto_system_groupname
16
+ inherited_entry_value(::Avm::Instances::EntryKeys::HOST_ID, 'system.groupname') ||
17
+ read_entry_optional('system.username')
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'addressable'
4
+ require 'avm/instances/entry_keys'
5
+
6
+ module Avm
7
+ module Instances
8
+ class Base
9
+ module AutoValues
10
+ module Web
11
+ def auto_web_authority
12
+ web_url_as_uri(&:authority)
13
+ end
14
+
15
+ def auto_web_hostname
16
+ web_url_as_uri(&:host)
17
+ end
18
+
19
+ def auto_web_path
20
+ web_url_as_uri(&:path)
21
+ end
22
+
23
+ def auto_web_port
24
+ web_url_as_uri(&:port)
25
+ end
26
+
27
+ def auto_web_scheme
28
+ web_url_as_uri(&:scheme)
29
+ end
30
+
31
+ def auto_web_userinfo
32
+ web_url_as_uri(&:userinfo)
33
+ end
34
+
35
+ private
36
+
37
+ def web_url_as_uri
38
+ read_entry_optional(::Avm::Instances::EntryKeys::WEB_URL).if_present do |v|
39
+ yield(::Addressable::URI.parse(v))
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/require_sub'
4
+ ::EacRubyUtils.require_sub(__FILE__)
5
+
6
+ module Avm
7
+ module Instances
8
+ class Base
9
+ module AutoValues
10
+ extend ::ActiveSupport::Concern
11
+
12
+ included do
13
+ %w[Access Admin Data Database Filesystem Mailer Ruby Source System Web]
14
+ .each do |class_name|
15
+ include const_get(class_name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_docker/executables'
4
+ require 'eac_ruby_utils/core_ext'
5
+ require 'avm/docker/container'
6
+
7
+ module Avm
8
+ module Instances
9
+ class Base
10
+ module Dockerizable
11
+ enable_simple_cache
12
+ attr_reader :docker_image_options
13
+
14
+ def docker_image_options=(options)
15
+ @docker_image_options = ::ActiveSupport::HashWithIndifferentAccess.new(options)
16
+ reset_cache
17
+ end
18
+
19
+ def docker_container_exist?
20
+ ::EacDocker::Executables.docker.command.append(
21
+ ['ps', '-qaf', "name=#{docker_container_name}"]
22
+ ).execute!.present?
23
+ end
24
+
25
+ def docker_container_name
26
+ id
27
+ end
28
+
29
+ private
30
+
31
+ def docker_container_uncached
32
+ ::Avm::Docker::Container.new(self)
33
+ end
34
+
35
+ def docker_image_uncached
36
+ r = docker_image_class.new(docker_image_options.fetch(:registry))
37
+ r.instance = self if r.respond_to?(:instance)
38
+ r.version = docker_image_options[:version] if docker_image_options.key?(:version)
39
+ r.snapshot = docker_image_options[:snapshot] if docker_image_options.key?(:snapshot)
40
+ r
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/instances/entry_keys'
4
+
5
+ module Avm
6
+ module Instances
7
+ class Base
8
+ module EntryKeys
9
+ ::Avm::Instances::EntryKeys.all.each do |key|
10
+ method_name = key.to_s.variableize
11
+ define_method method_name do
12
+ read_entry(key)
13
+ end
14
+
15
+ define_method "#{method_name}_optional" do
16
+ read_entry(key, required: false)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/require_sub'
4
+ require 'eac_ruby_utils/simple_cache'
5
+ require 'avm/instances/entries'
6
+
7
+ module Avm
8
+ module Instances
9
+ class Base
10
+ enable_listable
11
+ enable_simple_cache
12
+ require_sub __FILE__, include_modules: true
13
+ include ::Avm::Instances::Entries
14
+
15
+ lists.add_string :access, :local, :ssh
16
+
17
+ ID_PATTERN = /\A([a-z0-9]+(?:\-[a-z0-9]+)*)_(.+)\z/.freeze
18
+
19
+ class << self
20
+ def by_id(id)
21
+ application_id, suffix = parse_id(id)
22
+ require 'avm/instances/application'
23
+ new(::Avm::Instances::Application.new(application_id), suffix)
24
+ end
25
+
26
+ private
27
+
28
+ def parse_id(id)
29
+ m = ID_PATTERN.match(id)
30
+ return [m[1], m[2]] if m
31
+
32
+ raise "ID Pattern no matched: \"#{id}\""
33
+ end
34
+ end
35
+
36
+ common_constructor :application, :suffix do
37
+ self.suffix = suffix.to_s
38
+ end
39
+
40
+ def id
41
+ "#{application.id}_#{suffix}"
42
+ end
43
+
44
+ def to_s
45
+ id
46
+ end
47
+
48
+ def host_env_uncached
49
+ access = read_entry(:access, list: ::Avm::Instances::Base.lists.access.values)
50
+ case access
51
+ when 'local' then ::EacRubyUtils::Envs.local
52
+ when 'ssh' then ::EacRubyUtils::Envs.ssh(read_entry('ssh.url'))
53
+ else raise("Unmapped access value: \"#{access}\"")
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def source_instance_uncached
60
+ ::Avm::Instances::Base.by_id(source_instance_id)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'avm/instances/entry'
5
+
6
+ module Avm
7
+ module Instances
8
+ module Entries
9
+ def entry(suffix, options = {})
10
+ ::Avm::Instances::Entry.new(self, suffix, options)
11
+ end
12
+
13
+ def path_prefix
14
+ @path_prefix ||= [id].freeze
15
+ end
16
+
17
+ def read_entry(entry_suffix, options = {})
18
+ entry(entry_suffix, options).value
19
+ end
20
+
21
+ def read_entry_optional(entry_suffix, options = {})
22
+ entry(entry_suffix, options).optional_value
23
+ end
24
+
25
+ def full_entry_path(entry_suffix)
26
+ unless entry_suffix.is_a?(::Array)
27
+ entry_suffix = ::EacConfig::PathsHash.parse_entry_key(entry_suffix.to_s)
28
+ end
29
+ (path_prefix + entry_suffix).join('.')
30
+ end
31
+
32
+ def inherited_entry_value(source_entry_suffix, target_entry_suffix, &block)
33
+ read_entry_optional(source_entry_suffix).if_present do |instance_id|
34
+ other_entry_value(instance_id, target_entry_suffix).if_present(&block)
35
+ end
36
+ end
37
+
38
+ def other_entry_value(instance_id, entry_suffix)
39
+ ::Avm::Instances::Base.by_id(instance_id).read_entry_optional(entry_suffix)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_config/node'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module Instances
8
+ class Entry
9
+ class << self
10
+ def auto_value_method_name(suffix)
11
+ "auto_#{suffix.to_s.gsub('.', '_')}"
12
+ end
13
+ end
14
+
15
+ common_constructor :parent, :suffix, :options
16
+
17
+ def auto_value
18
+ parent.respond_to?(auto_value_method, true) ? parent.send(auto_value_method) : nil
19
+ end
20
+
21
+ def auto_value_method
22
+ self.class.auto_value_method_name(suffix)
23
+ end
24
+
25
+ def full_path
26
+ (parent.path_prefix + suffix_as_array).join('.')
27
+ end
28
+
29
+ def optional_value
30
+ read(required: false, noinput: true) || auto_value
31
+ end
32
+
33
+ def read(extra_options = {})
34
+ ::EacConfig::Node.context.current.entry(full_path, options.merge(extra_options)).value
35
+ end
36
+
37
+ def suffix_as_array
38
+ if suffix.is_a?(::Array)
39
+ suffix.dup
40
+ else
41
+ ::EacConfig::PathsHash.parse_entry_key(suffix.to_s)
42
+ end
43
+ end
44
+
45
+ def value
46
+ optional_value || read
47
+ end
48
+
49
+ def write(value)
50
+ ::EacConfig::Node.context.current.entry(full_path).value = value
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module Instances
7
+ module EntryKeys
8
+ class << self
9
+ def all
10
+ all_keys.to_a
11
+ end
12
+
13
+ def keys_consts_set(prefix, suffixes)
14
+ if suffixes.is_a?(::Hash)
15
+ keys_consts_set_from_hash(prefix, suffixes)
16
+ elsif suffixes.is_a?(::Enumerable)
17
+ keys_consts_set_from_enum(prefix, suffixes)
18
+ else
19
+ raise "Unmapped suffixes class: #{suffixes.class}"
20
+ end
21
+ end
22
+
23
+ def key_const_set(prefix, suffix)
24
+ key = [prefix, suffix].reject(&:blank?).join('.')
25
+ const_set(key.gsub('.', '_').upcase, key)
26
+ all_keys << key
27
+ end
28
+
29
+ private
30
+
31
+ def all_keys
32
+ @all_keys ||= ::Set.new
33
+ end
34
+
35
+ def keys_consts_set_from_enum(prefix, suffixes)
36
+ suffixes.each { |suffix| key_const_set(prefix, suffix) }
37
+ end
38
+
39
+ def keys_consts_set_from_hash(prefix, suffixes)
40
+ suffixes.each { |k, v| keys_consts_set(prefix.to_s + (k.blank? ? '' : ".#{k}"), v) }
41
+ end
42
+ end
43
+
44
+ {
45
+ '' => %w[fs_path host_id source_instance_id],
46
+ database: %w[id hostname limit name password port system timeout username],
47
+ docker: %w[registry],
48
+ mailer: {
49
+ '' => %w[id from reply_to],
50
+ smtp: %w[address port domain username password authentication starttls_auto]
51
+ },
52
+ ssh: %w[hostname port url username],
53
+ web: %w[authority hostname path port scheme url userinfo]
54
+ }.each { |prefix, suffixes| keys_consts_set(prefix, suffixes) }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/core_ext'
4
+
5
+ module Avm
6
+ module Instances
7
+ class Runner
8
+ class << self
9
+ def instance_class
10
+ ::Avm.const_get(stereotype_name).const_get('Instance')
11
+ end
12
+
13
+ def stereotype_module
14
+ ::Avm.const_get(stereotype_name)
15
+ end
16
+
17
+ def stereotype_name
18
+ name.demodulize
19
+ end
20
+ end
21
+
22
+ description = "Utilities for #{stereotype_name} instances."
23
+ runner_with :help, :subcommands do
24
+ desc description
25
+ pos_arg 'instance-id'
26
+ subcommands
27
+ end
28
+
29
+ delegate :instance_class, :stereotype_module, :stereotype_name, to: :class
30
+
31
+ private
32
+
33
+ def instance_uncached
34
+ self.class.instance_class.by_id(parsed.instance_id)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Instances
5
+ require 'avm/instances/application'
6
+ require 'avm/instances/entries'
7
+ end
8
+ end
data/lib/avm/registry.rb CHANGED
@@ -7,7 +7,7 @@ module Avm
7
7
  module Registry
8
8
  require_sub __FILE__
9
9
  enable_listable
10
- lists.add_symbol :category, :instance_stereotypes, :scms, :source_stereotypes
10
+ lists.add_symbol :category, :instance_stereotypes, :runners, :scms, :source_stereotypes
11
11
 
12
12
  class << self
13
13
  enable_simple_cache
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/core_ext'
4
+
5
+ module Avm
6
+ module Runners
7
+ class Base
8
+ enable_abstract_methods
9
+
10
+ class << self
11
+ def command_argument
12
+ stereotype_name.underscore.dasherize
13
+ end
14
+
15
+ def stereotype_name
16
+ name.split('::')[-3]
17
+ end
18
+ end
19
+
20
+ delegate :command_argument, :stereotype_name, to: :class
21
+
22
+ runner_with :help, :subcommands do
23
+ subcommands
24
+ end
25
+
26
+ def to_s
27
+ stereotype_name
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'avm/docker/image'
5
+
6
+ module Avm
7
+ module Self
8
+ class DockerImage < ::Avm::Docker::Image
9
+ def stereotype_tag
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module Self
5
+ class Instance < ::Avm::Instances::Base
6
+ module EntryKeys
7
+ DATA_DEFAULT_PATH = 'data.default_path'
8
+ DOCKER_REGISTRY_NAME = 'docker.registry.name'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/instances/base'
4
+ require 'avm/self/docker_image'
5
+ require 'avm/self/instance/entry_keys'
6
+ require 'avm/eac_ubuntu_base0/docker_image'
7
+
8
+ module Avm
9
+ module Self
10
+ class Instance < ::Avm::Instances::Base
11
+ def docker_image_class
12
+ ::Avm::Self::DockerImage
13
+ end
14
+
15
+ def docker_registry
16
+ read_entry(::Avm::Self::Instance::EntryKeys::DOCKER_REGISTRY_NAME)
17
+ end
18
+
19
+ def docker_run_arguments
20
+ ['-e', "LOCAL_USER_ID=#{::Process.uid}"]
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/avm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Avm
4
- VERSION = '0.6.1'
4
+ VERSION = '0.7.0'
5
5
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo H. Bogoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-17 00:00:00.000000000 Z
11
+ date: 2021-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eac_cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.23'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.23.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.23'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.23.1
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: eac_docker
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -168,13 +188,34 @@ files:
168
188
  - lib/avm/data/package.rb
169
189
  - lib/avm/data/package/dump.rb
170
190
  - lib/avm/data/package/load.rb
191
+ - lib/avm/data/rotate.rb
171
192
  - lib/avm/data/unit.rb
172
193
  - lib/avm/docker.rb
173
194
  - lib/avm/docker/container.rb
174
195
  - lib/avm/docker/image.rb
175
196
  - lib/avm/docker/runner.rb
176
197
  - lib/avm/executables.rb
198
+ - lib/avm/instances.rb
199
+ - lib/avm/instances/application.rb
200
+ - lib/avm/instances/base.rb
201
+ - lib/avm/instances/base/auto_values.rb
202
+ - lib/avm/instances/base/auto_values/access.rb
203
+ - lib/avm/instances/base/auto_values/admin.rb
204
+ - lib/avm/instances/base/auto_values/data.rb
205
+ - lib/avm/instances/base/auto_values/database.rb
206
+ - lib/avm/instances/base/auto_values/filesystem.rb
207
+ - lib/avm/instances/base/auto_values/mailer.rb
208
+ - lib/avm/instances/base/auto_values/ruby.rb
209
+ - lib/avm/instances/base/auto_values/source.rb
210
+ - lib/avm/instances/base/auto_values/system.rb
211
+ - lib/avm/instances/base/auto_values/web.rb
212
+ - lib/avm/instances/base/dockerizable.rb
213
+ - lib/avm/instances/base/entry_keys.rb
177
214
  - lib/avm/instances/docker_image.rb
215
+ - lib/avm/instances/entries.rb
216
+ - lib/avm/instances/entry.rb
217
+ - lib/avm/instances/entry_keys.rb
218
+ - lib/avm/instances/runner.rb
178
219
  - lib/avm/jobs.rb
179
220
  - lib/avm/jobs/base.rb
180
221
  - lib/avm/jobs/variables_source.rb
@@ -186,8 +227,12 @@ files:
186
227
  - lib/avm/rspec/setup.rb
187
228
  - lib/avm/rspec/shared_examples/in_avm_registry.rb
188
229
  - lib/avm/rspec/shared_examples/not_in_avm_registry.rb
230
+ - lib/avm/runners/base.rb
189
231
  - lib/avm/scms/base.rb
190
232
  - lib/avm/scms/commit.rb
233
+ - lib/avm/self/docker_image.rb
234
+ - lib/avm/self/instance.rb
235
+ - lib/avm/self/instance/entry_keys.rb
191
236
  - lib/avm/source_stereotypes/base.rb
192
237
  - lib/avm/sources.rb
193
238
  - lib/avm/sources/base.rb