mobilis 0.0.3 → 0.0.4

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: 3cd47dc94e879a945b060720f6ee453228b266749ebab21264f8a03c1af833ef
4
- data.tar.gz: 22c7ce3af384fc3bda6b19790ea086919341466b8d37310d1c5b68fe5c169c6d
3
+ metadata.gz: a79181b97bf2572ac73e8dce659320884665aa649e955970d95bda0251c295dc
4
+ data.tar.gz: 303979cb4e400a188c6ca99d75f8c8857b4926661287e485b0999f0341f30611
5
5
  SHA512:
6
- metadata.gz: 8e9064d8564ee716bc4d4dcf0806638ca3ce16036b6e3225593bf07a470a2fca3bb42da8a7bc63996b2fcf7aefa502b9311f53fbbe5a4434216cfe700c218eaf
7
- data.tar.gz: a6f42ea29dd0b3605b3df3fe79bb768252bbc570cb5afdcb8a0c3245907af95bb8d7f5faefa687e057b4adf1feb686b60b66bfb7cfbc8f10f39649aed48598ba
6
+ metadata.gz: 561a375e73c458745e72415ab88ee6e19d7fe7b299a576ee2a619bc5e66e45ff4f25d763f8a58a2d8465661c6f861b6e5e1642c2e3f2da7084c57a5c5dbe2b2a
7
+ data.tar.gz: 02aabfdd670aeb2d7138b3507d36f15e4c2009656430ac9ec73c6829627f0e87f52949e8b9ce0d911786c24ed685e2ee1396a97a4cb98bb60fc829e2a0f26940
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.4] - 2022-09-11
4
+
5
+ - Added command line options load and build
6
+ - Added wait-until to rails w/postgresql or mysql to wait for the db to be ready before starting rails
7
+ - Fixed per-state display not working
8
+ - Use table_print to display some information such as linked projects
9
+
3
10
  ## [0.0.1] - 2022-06-26
4
11
 
5
12
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,9 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mobilis (0.1.0)
4
+ mobilis (0.0.4)
5
5
  awesome_print
6
+ optimist
7
+ pry
6
8
  state_machine
9
+ table_print
7
10
  tty-prompt
8
11
 
9
12
  GEM
@@ -41,6 +44,7 @@ GEM
41
44
  attr_extras (>= 6.2.4)
42
45
  diff-lcs
43
46
  patience_diff
47
+ table_print (1.5.7)
44
48
  tty-color (0.6.0)
45
49
  tty-cursor (0.7.1)
46
50
  tty-prompt (0.23.1)
data/README.md CHANGED
@@ -1,22 +1,44 @@
1
1
  # Mobilis
2
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/mobilis`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Mobilis is a ruby app for generating linked sets of docker containers, for rapid
4
+ prototyping of arbitrary project architecture.
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ It has some smarts built in to make common things simple, and will allow you to
7
+ further customize the output for more complex needs.
6
8
 
7
9
  ## Installation
8
10
 
9
- Install the gem and add to the application's Gemfile by executing:
11
+ $ gem install mobilis
10
12
 
11
- $ bundle add mobilis
13
+ ## Usage
12
14
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
15
+ $ mobilis
14
16
 
15
- $ gem install mobilis
17
+ This will start the console based user interface.
16
18
 
17
- ## Usage
19
+ Add projects of the various kinds. The input doesn't save you from mistakes
20
+ like entering spaces for service names, so don't do it.
21
+
22
+ If you need any containers to connect to other containers via the internal
23
+ names, you will want to add a link from the project that is connecting to the
24
+ project that is being connected to.
25
+
26
+ When configured to your liking, select the generate option to generate the
27
+ projects. This will *DESTROY* any data in an existing 'generate' directory.
18
28
 
19
- TODO: Write usage instructions here
29
+ ## Special Rails support
30
+ If a Ruby on Rails project is linked to a postgres or mysql instance, it will
31
+ be setup with a DATABASE_URL environment variable that has the connection
32
+ information.
33
+
34
+ In addition, the database instance will receive a environment variable with the
35
+ name of the default production database that is based on the rails project's name
36
+
37
+ ## Security
38
+ The generated projects are insecure, because of credential handling details.
39
+
40
+ If you want to deploy the projects into a production environment, you are
41
+ responsible for secrets management.
20
42
 
21
43
  ## Development
22
44
 
@@ -26,4 +48,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
26
48
 
27
49
  ## Contributing
28
50
 
29
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mobilis.
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Meleneth/mobilis.
52
+
53
+ ## Plans
54
+
55
+ Adding more project types + smart integrations
56
+ Instrumenting generated projects with New Relic
57
+ Smoothing out the flow of the UI
58
+ Be able to load a previous configured set of projects for further editing
59
+ ~~Make generated rails projects wait at startup until the database is usable~~
60
+ More details in TODO.md
data/TODO.md ADDED
@@ -0,0 +1,18 @@
1
+ make links look better ( table_print )
2
+ make link flow not redirect back to main menu
3
+ write down every time a flow feels bad
4
+ fix NR integration
5
+ ~~fix having to restart several times to go through db create, db migrate, start service loop~~
6
+ add flask app
7
+ rails: add interactive service designer (models / controllers)
8
+ add a rack service wrapper that deploys as a sidecar (*handwave*)
9
+ use graphviz to show a diagram for current metaproject
10
+ ~~give some documentation for expected usage / security concerns~~
11
+ rails: add multi-db-at-once support
12
+ add docker registry support (i.e. the docker container to host a docker registry)
13
+ no matter if you create a db or a rails project first, the flow should be easy and obvious to add the other, associated with whatever you made first
14
+ add ability to re-load old configuration
15
+ if generate/data exists already with data, have an option to keep or wipe the data
16
+ fix git integration so we have proper commit points between each step
17
+ add command line builder, so you can generate a tree based on an existing config
18
+ in a complex config, it feels bad when the config gets big
data/exe/mobilis CHANGED
@@ -5,9 +5,11 @@ require 'pry'
5
5
  require "mobilis/command_line"
6
6
  require "mobilis/interactive_designer"
7
7
 
8
- # options parsing is TODO
9
- #options = Mobilis::CommandLine.parse_args(ARGV)
8
+ options = Mobilis::CommandLine.parse_args(ARGV)
10
9
  program = Mobilis::InteractiveDesigner.new
10
+ if options[:subcommand] == :load
11
+ program.load_from_file options[:filename]
12
+ end
11
13
  program.go_main_menu
12
14
 
13
15
  loop do
@@ -5,37 +5,23 @@ module Mobilis
5
5
  def self.parse_args(args)
6
6
  options = {}
7
7
  Optimist.options(args) do
8
- banner "checklist code janitor"
9
- stop_on ["new", "check", "add"]
8
+ banner "multi-project codebase generation toolkit"
9
+ stop_on ["load", "build", "help"]
10
10
  end
11
- if args.length == 0
12
- options[:subcommand] = :help
11
+ if args == []
12
+ options[:subcommand] = :interactive
13
13
  return options
14
14
  end
15
15
  options[:subcommand] = args.shift.to_sym
16
16
  case options[:subcommand]
17
- when :new
18
- Optimist.options(args) do
19
- stop_on ["gem", "railsapp", "railsapi"]
20
- end
21
- options[:new_type] = args.shift.to_sym
22
- options[:name] = case options[:new_type]
23
- when :gem
24
- args.shift
25
- when :railsapp
26
- args.shift
27
- when :railsapi
28
- args.shift
29
- end
30
- when :add
31
- Optimist.options(args) do
32
- stop_on ["gem", "docker"]
33
- end
34
- options[:add_type] = args.shift.to_sym
35
- case options[:add_type]
36
- when :gem
37
- options[:name] = args.shift
38
- end
17
+ when :load
18
+ options[:filename] = args.shift
19
+ when :build
20
+ options[:filename] = args.shift
21
+ when :help
22
+ puts "I think we'd all like a little help."
23
+ else
24
+ Optimist::die "unknown subcommand #{cmd.inspect}"
39
25
  end
40
26
  options
41
27
  end
@@ -73,10 +73,7 @@ def postgresql_service service
73
73
  {
74
74
  "image" => "postgres:14.1-alpine",
75
75
  "restart" => "always",
76
- "environment" => [
77
- "POSTGRES_USER=#{ service.name }",
78
- "POSTGRES_PASSWORD=#{ service.password }"
79
- ],
76
+ "environment" => service.env_vars,
80
77
  "ports" => ["#{ attributes[keyname] }:5432"],
81
78
  "volumes" => [
82
79
  "#{ service.data_dir }:/var/lib/postgresql/data"
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'state_machine'
4
- require 'tty-prompt'
5
3
  require 'awesome_print'
6
4
  require 'forwardable'
5
+ require 'state_machine'
6
+ require 'table_print'
7
+ require 'tty-prompt'
7
8
 
8
9
  require 'mobilis/logger'
9
10
  require 'mobilis/project'
@@ -16,7 +17,7 @@ extend Forwardable
16
17
  attr_accessor :project
17
18
  attr_reader :prompt
18
19
 
19
- def_delegators :@project, :projects, :display
20
+ def_delegators :@project, :projects, :load_from_file
20
21
 
21
22
  state_machine :state, initial: :intialize do
22
23
 
@@ -44,6 +45,11 @@ state_machine :state, initial: :intialize do
44
45
  transition [:main_menu] => :add_redis_instance
45
46
  end
46
47
 
48
+ event :go_back do
49
+ transition [:edit_rails_project] => :main_menu
50
+ transition [:edit_generic_project] => :main_menu
51
+ end
52
+
47
53
  event :go_add_rack_project do
48
54
  transition [:main_menu] => :add_rack_project
49
55
  end
@@ -107,7 +113,10 @@ state_machine :state, initial: :intialize do
107
113
 
108
114
  state :main_menu do
109
115
  def display
110
- project.display
116
+ puts
117
+ tp.set :max_width, 160
118
+ tp projects, 'name', 'type', 'options': lambda {|p| p.options.join ", "}
119
+ puts
111
120
  end
112
121
  def choices
113
122
  project_choices = projects.map do |project|
@@ -141,12 +150,18 @@ state_machine :state, initial: :intialize do
141
150
  end
142
151
 
143
152
  state :edit_links_select_project do
144
- def display = false
153
+ def display
154
+ puts
155
+ tp.set :max_width, 160
156
+ tp projects, 'name', 'type', 'links': lambda {|p| p.links.join ", "}
157
+ puts
158
+ end
145
159
  def choices
146
160
  [
147
161
  {name: "return to Main Menu", value: -> { go_main_menu }},
148
162
  *( projects.map do |project|
149
- { name: "Edit '#{ project.name }' links", value: -> { @selected_project = project ; go_edit_links } }
163
+ links_txt = project.links.join ", "
164
+ { name: "Edit '#{ project.name }' links (#{ links_txt })", value: -> { @selected_project = project ; go_edit_links } }
150
165
  end)
151
166
  ]
152
167
  end
@@ -274,7 +289,7 @@ state_machine :state, initial: :intialize do
274
289
 
275
290
  state :toggle_rails_api_mode do
276
291
  def display
277
- Mobilis.logger.info "Toggled rails API mode for '#{@selected_rails_project.name}'"
292
+ Mobilis.logger.info "Toggled rails API mode for '#{ @selected_rails_project.name }'"
278
293
  end
279
294
  def choices = false
280
295
  def action
@@ -347,10 +362,10 @@ def initialize
347
362
  @project = Project.new
348
363
  end
349
364
 
350
-
365
+ ##
366
+ # display, choices, and action methods all change per-state
351
367
  def choose_destination
352
368
  Mobilis.logger.info "#choose_destination"
353
-
354
369
  blank_space
355
370
  spacer
356
371
  display
@@ -13,6 +13,17 @@ def child_env_vars
13
13
  [ ]
14
14
  end
15
15
 
16
+ def env_vars
17
+ vars = []
18
+ if linked_to_rails_project
19
+ vars << "POSTGRES_DB=#{ linked_to_rails_project.name }_production"
20
+ end
21
+ vars.concat [
22
+ "POSTGRES_USER=#{ name }",
23
+ "POSTGRES_PASSWORD=#{ password }"
24
+ ]
25
+ end
26
+
16
27
  def data_dir
17
28
  "./data/#{ name }"
18
29
  end
@@ -159,6 +159,11 @@ def build_rails_builder
159
159
  run_docker "build -t #{ rails_builder_image } ."
160
160
  end
161
161
 
162
+ def load_from_file filename
163
+ data = File.read filename
164
+ @data = JSON.parse data, {:symbolize_names => true}
165
+ end
166
+
162
167
  def save_project
163
168
  File.open("mproj.json", "w") do |f|
164
169
  f.write(JSON.pretty_generate(@data))
@@ -181,7 +186,7 @@ def projects
181
186
  redis: RedisInstance,
182
187
  rack: RackProject
183
188
  }
184
- @data[:projects].map {|p| mapping[p[:type]].new p, self}
189
+ @data[:projects].map {|p| mapping[p[:type].to_sym].new p, self}
185
190
  end
186
191
 
187
192
  def project_by_name name
@@ -21,7 +21,8 @@ def generate
21
21
  end
22
22
 
23
23
  def generate_config_ru
24
- set_file_contents "config.ru", '# config.ru
24
+ set_file_contents "config.ru", <<CONFIG_RU
25
+ # config.ru
25
26
  app = Proc.new {
26
27
  [
27
28
  200,
@@ -30,11 +31,12 @@ app = Proc.new {
30
31
  ]
31
32
  }
32
33
  run app
33
- '
34
+ CONFIG_RU
34
35
  end
35
36
 
36
37
  def generate_Gemfile
37
- set_file_contents "Gemfile", '# frozen_string_literal: true
38
+ set_file_contents "Gemfile", <<GEMFILE
39
+ # frozen_string_literal: true
38
40
 
39
41
  source "https://rubygems.org"
40
42
 
@@ -43,11 +45,12 @@ source "https://rubygems.org"
43
45
  gem "rack", "= 3.0.0.beta1"
44
46
 
45
47
  gem "rackup", "~> 0.2.2"
46
- '
48
+ GEMFILE
47
49
  end
48
50
 
49
51
  def generate_Gemfile_lock
50
- set_file_contents "Gemfile.lock", 'GEM
52
+ set_file_contents "Gemfile.lock", <<GEMFILE_LOCK
53
+ GEM
51
54
  remote: https://rubygems.org/
52
55
  specs:
53
56
  rack (3.0.0.beta1)
@@ -65,11 +68,11 @@ DEPENDENCIES
65
68
 
66
69
  BUNDLED WITH
67
70
  2.3.16
68
- '
71
+ GEMFILE_LOCK
69
72
  end
70
73
 
71
74
  def generate_Dockerfile
72
- set_file_contents "Dockerfile", '
75
+ set_file_contents "Dockerfile", <<DOCKER_END
73
76
  FROM ruby:latest
74
77
  RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
75
78
  WORKDIR /myapp
@@ -79,10 +82,9 @@ RUN bundle install
79
82
  COPY . /myapp
80
83
 
81
84
  # Add a script to be executed every time the container starts.
82
- ENTRYPOINT ["rackup"]
85
+ ENTRYPOINT ["rackup", "-o", "#{ name }"]
83
86
  EXPOSE 9292
84
-
85
- '
87
+ DOCKER_END
86
88
  end
87
89
 
88
90
  end
@@ -81,6 +81,7 @@ def generate
81
81
  install_rspec if options.include? :rspec
82
82
  install_factory_bot if options.include? :factory_bot
83
83
  git_commit_all "add Gems"
84
+ generate_wait_until
84
85
  generate_Dockerfile
85
86
  generate_entrypoint_sh
86
87
  generate_build_sh
@@ -96,10 +97,36 @@ def rails_master_key
96
97
  @data[:attributes][:rails_master_key]
97
98
  end
98
99
 
100
+ def generate_wait_until
101
+ set_file_contents 'wait-until', <<WAITUNTIL
102
+ #!/usr/bin/env bash
103
+ # https://github.com/nickjj/wait-until under MIT license
104
+
105
+ command="${1}"
106
+ timeout="${2:-30}"
107
+
108
+ i=1
109
+ until eval "${command}"
110
+ do
111
+ ((i++))
112
+
113
+ if [ "${i}" -gt "${timeout}" ]; then
114
+ echo "command was never successful, aborting due to ${timeout}s timeout!"
115
+ exit 1
116
+ fi
117
+
118
+ sleep 1
119
+ done
120
+ WAITUNTIL
121
+ end
122
+
123
+
99
124
  def generate_Dockerfile
100
- set_file_contents "Dockerfile", 'FROM ruby:latest
101
- RUN apt-get update -qq && apt-get install -y nodejs postgresql-client dos2unix
125
+ set_file_contents "Dockerfile", <<DOCKER_END
126
+ FROM ruby:latest
127
+ RUN apt-get update -qq && apt-get install -y nodejs postgresql-client default-mysql-client dos2unix
102
128
  WORKDIR /myapp
129
+ COPY wait-until /myapp/wait-until
103
130
  COPY Gemfile /myapp/Gemfile
104
131
  COPY Gemfile.lock /myapp/Gemfile.lock
105
132
  RUN bundle install
@@ -113,11 +140,12 @@ RUN dos2unix /myapp/entrypoint.sh
113
140
 
114
141
  # Configure the main process to run when running the image
115
142
  CMD ["rails", "server", "-b", "0.0.0.0"]
116
- '
143
+ DOCKER_END
117
144
  end
118
145
 
119
146
  def generate_entrypoint_sh
120
- set_file_contents "entrypoint.sh", "#!/bin/sh
147
+ set_file_contents "entrypoint.sh", <<ENTRYPOINT_SH
148
+ #!/bin/sh
121
149
 
122
150
  # https://stackoverflow.com/a/38732187/1935918
123
151
  set -e
@@ -125,11 +153,25 @@ set -e
125
153
  if [ -f /app/tmp/pids/server.pid ]; then
126
154
  rm /app/tmp/pids/server.pid
127
155
  fi
128
-
156
+ #{ wait_until_line }
129
157
  bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
130
158
 
131
- exec bundle exec \"$@\"
132
- "
159
+ exec bundle exec "$@"
160
+ ENTRYPOINT_SH
161
+ end
162
+
163
+ def wait_until_line
164
+ if database.instance_of? Mobilis::PostgresqlInstance
165
+ return <<POSTGRES_LINE
166
+ /myapp/wait-until "psql postgres://#{ database.username }:#{ database.password }@#{ database.name }/#{ name }_production -c 'select 1'"
167
+ POSTGRES_LINE
168
+ end
169
+ # instance_of? is a code smell - maybe this should be database.wait_until_line ?
170
+ if database.instance_of? Mobilis::MysqlInstance
171
+ return <<MYSQL_LINE
172
+ /myapp/wait-until "mysql -D #{ name }_production -h #{ database.name } -u #{ database.username } -p#{ database.password } -e 'select 1'"
173
+ MYSQL_LINE
174
+ end
133
175
  end
134
176
 
135
177
  def install_rspec
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mobilis
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.4"
5
5
  end
data/lib/mobilis.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "mobilis/version"
4
+ require_relative "mobilis/command_line"
4
5
  require_relative "mobilis/project"
5
6
  require_relative "mobilis/docker_compose_projector"
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobilis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meleneth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-20 00:00:00.000000000 Z
11
+ date: 2022-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: state_machine
28
+ name: optimist
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: tty-prompt
42
+ name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry
56
+ name: state_machine
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,21 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: optimist
70
+ name: table_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: tty-prompt
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -109,6 +123,7 @@ files:
109
123
  - Gemfile.lock
110
124
  - README.md
111
125
  - Rakefile
126
+ - TODO.md
112
127
  - exe/mobilis
113
128
  - lib/mobilis.rb
114
129
  - lib/mobilis/actions_projects_take.rb