cove 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b00339b694d9feceadf96e0d59a116c954100fc7f7c775d90fc4f9ea9c02d8ae
4
+ data.tar.gz: d4c62d73422bb3b52e05544b0959216eef51c75c3cc63e9234b34250b5911de9
5
+ SHA512:
6
+ metadata.gz: dd6e29d6394c24b55b3bc291e0bda88003f671c71faf972e88a9805d05c980fc55fb692503e905788a814710950af2424e80364dd2c0eb4189711512b39fd420
7
+ data.tar.gz: 10777000027cffa657c78c9bfbfcb01b5825195b73dae7305a7be8663307f7c901d4e415408550fc9b64e8dd2bfa0ac1abff14cfe3568dcaa1042b9324e602b6
data/.env ADDED
@@ -0,0 +1 @@
1
+ FLOTTE_CONFIG_DIR=spec/fixtures/configs/basic/
data/.projections.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "lib/*.rb": {
3
+ "type": "implementation",
4
+ "alternate": "spec/{}_spec.rb"
5
+ },
6
+ "spec/*_spec.rb": {
7
+ "type": "spec",
8
+ "alternate": "lib/{}.rb"
9
+ }
10
+
11
+ }
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.solargraph.yml ADDED
@@ -0,0 +1,14 @@
1
+ ---
2
+ include:
3
+ - "**/*.rb"
4
+ exclude:
5
+ - spec/**/*
6
+ - vendor/**/*
7
+ - ".bundle/**/*"
8
+ require: []
9
+ domains: []
10
+ reporters:
11
+ - require_not_found
12
+ formatter: []
13
+ require_paths: []
14
+ max_files: 5000
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/testdouble/standard
3
+ ruby_version: 2.6
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.2.2
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in flotte.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "standard", "~> 1.3"
13
+
14
+ gem "solargraph"
15
+
16
+ gem "byebug"
data/Gemfile.lock ADDED
@@ -0,0 +1,127 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flotte (0.1.0)
5
+ activesupport (~> 7.0)
6
+ bcrypt_pbkdf (~> 1.1)
7
+ dotenv (~> 2.8)
8
+ ed25519 (>= 1.2, < 2.0)
9
+ sshkit (~> 1.21)
10
+ thor (~> 1.2)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activesupport (7.0.4.3)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 1.6, < 2)
18
+ minitest (>= 5.1)
19
+ tzinfo (~> 2.0)
20
+ ast (2.4.2)
21
+ backport (1.2.0)
22
+ bcrypt_pbkdf (1.1.0)
23
+ benchmark (0.2.1)
24
+ byebug (11.1.3)
25
+ concurrent-ruby (1.2.2)
26
+ diff-lcs (1.5.0)
27
+ dotenv (2.8.1)
28
+ e2mmap (0.1.0)
29
+ ed25519 (1.3.0)
30
+ i18n (1.12.0)
31
+ concurrent-ruby (~> 1.0)
32
+ jaro_winkler (1.5.4)
33
+ json (2.6.3)
34
+ kramdown (2.4.0)
35
+ rexml
36
+ kramdown-parser-gfm (1.1.0)
37
+ kramdown (~> 2.0)
38
+ language_server-protocol (3.17.0.3)
39
+ minitest (5.18.0)
40
+ net-scp (4.0.0)
41
+ net-ssh (>= 2.6.5, < 8.0.0)
42
+ net-ssh (7.1.0)
43
+ nokogiri (1.14.3-x86_64-darwin)
44
+ racc (~> 1.4)
45
+ parallel (1.22.1)
46
+ parser (3.2.2.0)
47
+ ast (~> 2.4.1)
48
+ racc (1.6.2)
49
+ rainbow (3.1.1)
50
+ rake (13.0.6)
51
+ rbs (2.8.4)
52
+ regexp_parser (2.7.0)
53
+ reverse_markdown (2.1.1)
54
+ nokogiri
55
+ rexml (3.2.5)
56
+ rspec (3.12.0)
57
+ rspec-core (~> 3.12.0)
58
+ rspec-expectations (~> 3.12.0)
59
+ rspec-mocks (~> 3.12.0)
60
+ rspec-core (3.12.1)
61
+ rspec-support (~> 3.12.0)
62
+ rspec-expectations (3.12.2)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.12.0)
65
+ rspec-mocks (3.12.5)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.12.0)
68
+ rspec-support (3.12.0)
69
+ rubocop (1.48.1)
70
+ json (~> 2.3)
71
+ parallel (~> 1.10)
72
+ parser (>= 3.2.0.0)
73
+ rainbow (>= 2.2.2, < 4.0)
74
+ regexp_parser (>= 1.8, < 3.0)
75
+ rexml (>= 3.2.5, < 4.0)
76
+ rubocop-ast (>= 1.26.0, < 2.0)
77
+ ruby-progressbar (~> 1.7)
78
+ unicode-display_width (>= 2.4.0, < 3.0)
79
+ rubocop-ast (1.28.0)
80
+ parser (>= 3.2.1.0)
81
+ rubocop-performance (1.16.0)
82
+ rubocop (>= 1.7.0, < 2.0)
83
+ rubocop-ast (>= 0.4.0)
84
+ ruby-progressbar (1.13.0)
85
+ solargraph (0.49.0)
86
+ backport (~> 1.2)
87
+ benchmark
88
+ bundler (~> 2.0)
89
+ diff-lcs (~> 1.4)
90
+ e2mmap
91
+ jaro_winkler (~> 1.5)
92
+ kramdown (~> 2.3)
93
+ kramdown-parser-gfm (~> 1.1)
94
+ parser (~> 3.0)
95
+ rbs (~> 2.0)
96
+ reverse_markdown (~> 2.0)
97
+ rubocop (~> 1.38)
98
+ thor (~> 1.0)
99
+ tilt (~> 2.0)
100
+ yard (~> 0.9, >= 0.9.24)
101
+ sshkit (1.21.4)
102
+ net-scp (>= 1.1.2)
103
+ net-ssh (>= 2.8.0)
104
+ standard (1.26.0)
105
+ language_server-protocol (~> 3.17.0.2)
106
+ rubocop (~> 1.48.1)
107
+ rubocop-performance (~> 1.16.0)
108
+ thor (1.2.1)
109
+ tilt (2.1.0)
110
+ tzinfo (2.0.6)
111
+ concurrent-ruby (~> 1.0)
112
+ unicode-display_width (2.4.2)
113
+ yard (0.9.34)
114
+
115
+ PLATFORMS
116
+ x86_64-darwin-21
117
+
118
+ DEPENDENCIES
119
+ byebug
120
+ flotte!
121
+ rake (~> 13.0)
122
+ rspec (~> 3.0)
123
+ solargraph
124
+ standard (~> 1.3)
125
+
126
+ BUNDLED WITH
127
+ 2.4.12
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Julian Fahrer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Flotte
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/flotte`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+
11
+ $ bundle add flotte
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ $ gem install flotte
16
+
17
+ ## Usage
18
+
19
+ TODO: Write usage instructions here
20
+
21
+ ## Development
22
+
23
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
+
25
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
+
27
+ ## Contributing
28
+
29
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/flotte.
30
+
31
+ ## License
32
+
33
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
data/flotte.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/flotte/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "flotte"
7
+ spec.version = Flotte::VERSION
8
+ spec.authors = ["Julian Fahrer"]
9
+ spec.email = ["julian@fahrer.net"]
10
+
11
+ spec.summary = "Manage containers with easy"
12
+ spec.description = ""
13
+ spec.homepage = "https://codetales.io/flotte"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/codetales/flotte"
19
+ spec.metadata["changelog_uri"] = "https://github.com/codetales/flotte"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
+ end
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ # Uncomment to register a new dependency of your gem
33
+ spec.add_dependency "activesupport", "~> 7.0"
34
+ spec.add_dependency "dotenv", "~> 2.8"
35
+ spec.add_dependency "sshkit", "~> 1.21"
36
+ spec.add_dependency "thor", "~> 1.2"
37
+ spec.add_dependency "bcrypt_pbkdf", "~> 1.1"
38
+ spec.add_dependency "ed25519", ">= 1.2", "< 2.0"
39
+
40
+ # For more information and examples about making a new gem, check out our
41
+ # guide at: https://bundler.io/guides/creating_gem.html
42
+ end
@@ -0,0 +1,24 @@
1
+ module Flotte
2
+ module CLI
3
+ class Host < Thor
4
+ include SSHKit::DSL
5
+
6
+ desc "list", "List hosts"
7
+ def list
8
+ Flotte.registry.hosts.each do |host|
9
+ Flotte.output.puts host.name
10
+ end
11
+ end
12
+
13
+ desc "ssh HOST", "Connec to HOST via SSH"
14
+ def ssh(host)
15
+ host = Flotte.registry.hosts[host]
16
+ command = ["ssh", "-t", host.ssh_destination_string]
17
+ run_locally do
18
+ info "Connecting to host #{host.name} via #{command.join(" ")}"
19
+ Kernel.exec(*command)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ module Flotte
2
+ module CLI
3
+ class Main < Thor
4
+ include SSHKit::DSL
5
+
6
+ def self.exit_on_failure?
7
+ true
8
+ end
9
+
10
+ desc "version", "Print the installed version of Flotte"
11
+ def version
12
+ Flotte.output.puts Flotte::VERSION
13
+ end
14
+
15
+ desc "runit", "Run a command"
16
+ def runit
17
+ captured = {}
18
+ image = "alpine"
19
+ container_name = "test-#{SecureRandom.alphanumeric(5)}"
20
+ host = "root@test"
21
+ on(host) do |host|
22
+ output = capture(*Command::Docker::Container::Run.build(image: image, name: container_name, remove: false, interactive: true), {verbosity: Logger::INFO})
23
+
24
+ captured[host] = output
25
+ end
26
+
27
+ run_locally do
28
+ command = Flotte::Command::SSH.wrap(host, [:docker, :container, :attach, container_name, ";", "echo", "'42424242'"])
29
+ info "Running #{command.join(" ")}"
30
+ Kernel.exec(*command)
31
+ end
32
+ end
33
+
34
+ desc "logs", "Tail logs"
35
+ def logs
36
+ host = "root@test"
37
+ on([host]) do |host|
38
+ SSHKit.config.output_verbosity = Logger::DEBUG
39
+ execute :docker, "logs", "-f", "goofy_meitner"
40
+ end
41
+ end
42
+
43
+ desc "host", "Host specific commands"
44
+ subcommand "host", Flotte::CLI::Host
45
+
46
+ desc "service", "Service specific commands"
47
+ subcommand "service", Flotte::CLI::Service
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,28 @@
1
+ module Flotte
2
+ module CLI
3
+ class Service < Thor
4
+ include SSHKit::DSL
5
+
6
+ desc "list", "List hosts"
7
+ def list
8
+ Flotte.registry.services.each do |service|
9
+ Flotte.output.puts service.name
10
+ end
11
+ end
12
+
13
+ desc "hosts SERVICE", "List all roles within the service"
14
+ def hosts(service_name)
15
+ service = Flotte.registry.services[service_name]
16
+ Flotte.registry.roles.select { |role| role.service == service }.flat_map(&:hosts).uniq.each do |host|
17
+ Flotte.output.puts host.name
18
+ end
19
+ end
20
+
21
+ desc "up SERVICE", "Ensure SERVICE is up and running"
22
+ def up(service_name)
23
+ service = Flotte.registry.services[service_name]
24
+ Flotte::Invocation::ServiceUp.new(service).invoke
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/flotte/cli.rb ADDED
@@ -0,0 +1,8 @@
1
+ require_relative "cli/host"
2
+ require_relative "cli/service"
3
+ require_relative "cli/main"
4
+
5
+ module Flotte
6
+ module CLI
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ module Flotte
2
+ module Command
3
+ module Docker
4
+ module Container
5
+ class Run
6
+ def self.build(image:, name: nil, remove: false, detach: true, interactive: false, command: [], ports: [], extra_arguments: [])
7
+ builder = [:docker, "container", "run"]
8
+
9
+ builder += ["--name", name] if name.present?
10
+
11
+ Array(ports).each do |port_mapping|
12
+ builder += ["--publish", port_mapping]
13
+ end
14
+
15
+ builder << "--detach" if detach
16
+ builder << "--rm" if remove
17
+ builder << "-it" if interactive
18
+
19
+ builder += Array(extra_arguments)
20
+
21
+ builder << image
22
+ builder += Array(command)
23
+
24
+ builder
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,2 @@
1
+ require_relative "container/run"
2
+ require_relative "container/list"
@@ -0,0 +1,9 @@
1
+ module Flotte
2
+ module Command
3
+ class SSH
4
+ def self.wrap(host, command)
5
+ ["ssh", "-t", host] << Array(command).map(&:to_s).join(" ")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "command/docker/container"
2
+ require_relative "command/ssh"
3
+ require_relative "command/builder"
4
+
5
+ module Flotte
6
+ module Command
7
+ # @type [Array<Flotte::Host>]
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ require "yaml"
2
+ require "flotte/host"
3
+
4
+ module Flotte
5
+ module Configuration
6
+ class Hosts
7
+ ALLOWED_DEFAULT_KEYS = ["user"]
8
+
9
+ def initialize(config_file)
10
+ @config_file = config_file
11
+ end
12
+
13
+ def all
14
+ load_config
15
+
16
+ @raw_host_config["hosts"].map do |entry|
17
+ parse(entry)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def parse(entry)
24
+ if Hash === entry
25
+ Host.new(**defaults.merge(entry.symbolize_keys))
26
+ else
27
+ Host.new(**defaults.merge(name: entry))
28
+ end
29
+ end
30
+
31
+ def defaults
32
+ @raw_host_config["defaults"].slice(*ALLOWED_DEFAULT_KEYS).symbolize_keys
33
+ end
34
+
35
+ def load_config
36
+ @raw_host_config ||= YAML.safe_load(ERB.new(contents).result)
37
+ end
38
+
39
+ def contents
40
+ File.read(@config_file)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,50 @@
1
+ module Flotte
2
+ module Configuration
3
+ class Service
4
+ def initialize(config_file, host_registry)
5
+ @config_file = config_file
6
+ @host_registry = host_registry
7
+ end
8
+
9
+ def build
10
+ self
11
+ end
12
+
13
+ def service
14
+ @service ||= Service.new(name: service_name, image: image, default_environment: service_environment)
15
+ end
16
+
17
+ def roles
18
+ @roles ||= config["roles"].map do |role_name, role_config|
19
+ role_environment = service_environment.merge(role_config["environment"] || {})
20
+ Role.new(
21
+ name: role_name,
22
+ service: service,
23
+ environment: role_environment,
24
+ hosts: role_config["hosts"].map { |host_id| @host_registry[host_id] }
25
+ )
26
+ end
27
+ end
28
+
29
+ def service_name
30
+ config["name"]
31
+ end
32
+
33
+ def image
34
+ config["image"]
35
+ end
36
+
37
+ def service_environment
38
+ config["environment"] || {}
39
+ end
40
+
41
+ def config
42
+ @raw_service_config ||= YAML.safe_load(ERB.new(contents).result)
43
+ end
44
+
45
+ def contents
46
+ File.read(@config_file)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ require_relative "configuration/hosts"
2
+ require_relative "configuration/service"
3
+
4
+ module Flotte
5
+ module Configuration
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ module Flotte
2
+ class Host
3
+ # @return [String]
4
+ attr_reader :name, :user
5
+
6
+ # @param [String] name
7
+ # @param [String] hostname
8
+ # @param [String] user
9
+ def initialize(name:, hostname: nil, user: nil)
10
+ @name = name
11
+ @hostname = hostname
12
+ @user = user
13
+ end
14
+
15
+ # @return [String]
16
+ def id
17
+ name
18
+ end
19
+
20
+ # @return [SSHKit::Host]
21
+ def sshkit_host
22
+ @sshkit_host ||= SSHKit::Host.new(ssh_destination_string)
23
+ end
24
+
25
+ # @return [String]
26
+ def ssh_destination_string
27
+ [user, hostname].compact.join("@")
28
+ end
29
+
30
+ # @return [String]
31
+ def hostname
32
+ @hostname || name
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ module Flotte
2
+ class Initialization
3
+ # @return [Flotte::Registry]
4
+ attr_reader :registry
5
+ # @return [String]
6
+ attr_reader :config_path
7
+
8
+ # @param config_path [String]
9
+ # @param registry [Flotte::Registry]
10
+ def initialize(config_path, registry)
11
+ @config_path = config_path
12
+ @registry = registry
13
+ end
14
+
15
+ def perform
16
+ init_hosts
17
+ init_services
18
+ end
19
+
20
+ private
21
+
22
+ def init_hosts
23
+ host_config = Configuration::Hosts.new(File.join(config_path, "hosts.yml"))
24
+ host_config.all.each do |host|
25
+ registry.hosts.add(host)
26
+ end
27
+ end
28
+
29
+ def init_services
30
+ service_dirs = Dir[File.join(config_path, "services", "*/")]
31
+
32
+ service_dirs.map do |service_dir|
33
+ Configuration::Service.new(File.join(service_dir, "service.yml"), registry.hosts).build
34
+ end.each do |service_config|
35
+ registry.services.add(service_config.service)
36
+ service_config.roles.each do |role|
37
+ registry.roles.add(role)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ module Flotte
2
+ class Registry
3
+ class Base
4
+ include Enumerable
5
+
6
+ delegate :size, :each, to: :all
7
+
8
+ def initialize(entities = [])
9
+ @entities_by_id = {}
10
+ Array(entities).each do |entity|
11
+ add(entity)
12
+ end
13
+ end
14
+
15
+ def add(entity)
16
+ Array(entity).each do |entity|
17
+ @entities_by_id[entity.id] = entity
18
+ end
19
+ end
20
+
21
+ def all
22
+ @entities_by_id.values
23
+ end
24
+
25
+ def [](id)
26
+ @entities_by_id[id]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module Flotte
2
+ class Registry
3
+ class Host < Base
4
+ # @param name [String]
5
+ # @return [Flotte::Host]
6
+ def [](name)
7
+ super
8
+ end
9
+
10
+ # @return [Array<Flotte::Host>]
11
+ def all
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Flotte
2
+ class Registry
3
+ class Role < Base
4
+ # @param name [String]
5
+ # @return [Flotte::Role]
6
+ def [](name)
7
+ super
8
+ end
9
+
10
+ # @return [Array<Flotte::Role>]
11
+ def all
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Flotte
2
+ class Registry
3
+ class Service < Base
4
+ # @param name [String]
5
+ # @return [Flotte::Service]
6
+ def [](name)
7
+ super
8
+ end
9
+
10
+ # @return [Array<Flotte::Service>]
11
+ def all
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "registry/base"
2
+ require_relative "registry/host"
3
+ require_relative "registry/service"
4
+ require_relative "registry/role"
5
+
6
+ module Flotte
7
+ class Registry
8
+ def self.build(hosts: [], services: [], roles: [])
9
+ registry = new
10
+ registry.hosts.add(hosts)
11
+ registry.services.add(services)
12
+ registry.roles.add(roles)
13
+ registry
14
+ end
15
+
16
+ # @return [Flotte::Registry::Host]
17
+ def hosts
18
+ @hosts_registry ||= Flotte::Registry::Host.new
19
+ end
20
+
21
+ # @return [Flotte::Registry::Service]
22
+ def services
23
+ @services_registry ||= Flotte::Registry::Service.new
24
+ end
25
+
26
+ # @return [Flotte::Registry::Role]
27
+ def roles
28
+ @roles_registry ||= Flotte::Registry::Role.new
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Flotte
2
+ class Role
3
+ # @return [String]
4
+ attr_reader :name, :environment
5
+ # @return [Flotte::Service]
6
+ attr_reader :service
7
+ # @return [Array<Flotte::Host>]
8
+ attr_reader :hosts
9
+ # @return [Array<String>]
10
+ attr_reader :command
11
+ # @return [String]
12
+ delegate :image, to: :service
13
+
14
+ def initialize(name:, service:, hosts:, command: [], environment: {})
15
+ @name = name
16
+ @service = service
17
+ @hosts = hosts
18
+ @command = command
19
+ @environment = environment
20
+ end
21
+
22
+ # @return [String]
23
+ def id
24
+ "#{service.name}.#{name}"
25
+ end
26
+
27
+ def name_for_container
28
+ id
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ module Flotte
2
+ class Service
3
+ # @return [String]
4
+ attr_reader :name, :image
5
+ # @return [Hash]
6
+ attr_reader :default_environment
7
+
8
+ # @param [String] name
9
+ # @param [String] image
10
+ # @param [Hash] default_environment
11
+ def initialize(name:, image:, default_environment: {})
12
+ @name = name
13
+ @image = image
14
+ @default_environment = default_environment
15
+ end
16
+
17
+ # @return [String]
18
+ def id
19
+ name
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flotte
4
+ VERSION = "0.1.0"
5
+ end
data/lib/flotte.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/all"
4
+ require "dotenv/load"
5
+ require "thor"
6
+ require "sshkit"
7
+ require "sshkit/dsl"
8
+ require "yaml"
9
+ require_relative "flotte/version"
10
+ require_relative "flotte/registry"
11
+ require_relative "flotte/host"
12
+ require_relative "flotte/service"
13
+ require_relative "flotte/role"
14
+ require_relative "flotte/configuration"
15
+ require_relative "flotte/command"
16
+ require_relative "flotte/cli"
17
+ require_relative "flotte/initialization"
18
+ require_relative "flotte/invocation/service_up"
19
+
20
+ module Flotte
21
+ class Error < StandardError; end
22
+
23
+ def self.output=(output)
24
+ @output = output
25
+ end
26
+
27
+ def self.output
28
+ @output || $stdout
29
+ end
30
+
31
+ def self.init(config:)
32
+ @registry = nil
33
+ Initialization.new(config, registry).perform
34
+ end
35
+
36
+ def self.registry
37
+ @registry ||= Registry.new
38
+ end
39
+ end
data/sig/flotte.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Flotte
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cove
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Julian Fahrer
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-04-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sshkit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.21'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.21'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bcrypt_pbkdf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ed25519
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '2.0'
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '1.2'
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ description: ''
104
+ email:
105
+ - julian@fahrer.net
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".env"
111
+ - ".projections.json"
112
+ - ".rspec"
113
+ - ".solargraph.yml"
114
+ - ".standard.yml"
115
+ - ".tool-versions"
116
+ - Gemfile
117
+ - Gemfile.lock
118
+ - LICENSE.txt
119
+ - README.md
120
+ - Rakefile
121
+ - flotte.gemspec
122
+ - lib/flotte.rb
123
+ - lib/flotte/cli.rb
124
+ - lib/flotte/cli/host.rb
125
+ - lib/flotte/cli/main.rb
126
+ - lib/flotte/cli/service.rb
127
+ - lib/flotte/command.rb
128
+ - lib/flotte/command/docker/container.rb
129
+ - lib/flotte/command/docker/container/run.rb
130
+ - lib/flotte/command/ssh.rb
131
+ - lib/flotte/configuration.rb
132
+ - lib/flotte/configuration/hosts.rb
133
+ - lib/flotte/configuration/service.rb
134
+ - lib/flotte/host.rb
135
+ - lib/flotte/initialization.rb
136
+ - lib/flotte/registry.rb
137
+ - lib/flotte/registry/base.rb
138
+ - lib/flotte/registry/host.rb
139
+ - lib/flotte/registry/role.rb
140
+ - lib/flotte/registry/service.rb
141
+ - lib/flotte/role.rb
142
+ - lib/flotte/service.rb
143
+ - lib/flotte/version.rb
144
+ - sig/flotte.rbs
145
+ homepage: https://codetales.io/cove
146
+ licenses:
147
+ - MIT
148
+ metadata:
149
+ homepage_uri: https://codetales.io/cove
150
+ source_code_uri: https://github.com/codetales/cove
151
+ changelog_uri: https://github.com/codetales/cove
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 2.6.0
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubygems_version: 3.4.10
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: Manage containers with easy
171
+ test_files: []