avm 0.6.1 → 0.7.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.
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