faastruby 0.4.18 → 0.5.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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -3
  3. data/Gemfile.lock +28 -4
  4. data/README.md +63 -5
  5. data/faastruby.gemspec +5 -1
  6. data/lib/faastruby.rb +1 -0
  7. data/lib/faastruby/api.rb +154 -6
  8. data/lib/faastruby/base.rb +3 -9
  9. data/lib/faastruby/cli.rb +39 -12
  10. data/lib/faastruby/cli/base_command.rb +66 -0
  11. data/lib/faastruby/cli/commands.rb +122 -59
  12. data/lib/faastruby/cli/commands/account/base_command.rb +10 -0
  13. data/lib/faastruby/cli/commands/account/confirm.rb +94 -0
  14. data/lib/faastruby/cli/commands/account/login.rb +86 -0
  15. data/lib/faastruby/cli/commands/account/logout.rb +59 -0
  16. data/lib/faastruby/cli/commands/account/signup.rb +76 -0
  17. data/lib/faastruby/cli/commands/{function.rb → function/base_command.rb} +2 -11
  18. data/lib/faastruby/cli/commands/function/build.rb +18 -11
  19. data/lib/faastruby/cli/commands/function/deploy_to.rb +100 -37
  20. data/lib/faastruby/cli/commands/function/new.rb +89 -36
  21. data/lib/faastruby/cli/commands/function/remove_from.rb +21 -6
  22. data/lib/faastruby/cli/commands/function/run.rb +15 -15
  23. data/lib/faastruby/cli/commands/function/test.rb +5 -4
  24. data/lib/faastruby/cli/commands/function/update_context.rb +10 -3
  25. data/lib/faastruby/cli/commands/function/upgrade.rb +62 -61
  26. data/lib/faastruby/cli/commands/help.rb +33 -20
  27. data/lib/faastruby/cli/commands/project/base_command.rb +14 -0
  28. data/lib/faastruby/cli/commands/project/deploy.rb +114 -0
  29. data/lib/faastruby/cli/commands/project/down.rb +58 -0
  30. data/lib/faastruby/cli/commands/project/new.rb +237 -0
  31. data/lib/faastruby/cli/commands/workspace/cp.rb +107 -0
  32. data/lib/faastruby/cli/commands/workspace/create.rb +35 -27
  33. data/lib/faastruby/cli/commands/workspace/destroy.rb +14 -7
  34. data/lib/faastruby/cli/commands/workspace/list.rb +15 -6
  35. data/lib/faastruby/cli/commands/workspace/migrate.rb +93 -0
  36. data/lib/faastruby/cli/commands/workspace/rm.rb +81 -0
  37. data/lib/faastruby/cli/commands/workspace/update.rb +62 -0
  38. data/lib/faastruby/cli/credentials.rb +58 -57
  39. data/lib/faastruby/cli/new_credentials.rb +63 -0
  40. data/lib/faastruby/cli/package.rb +1 -0
  41. data/lib/faastruby/cli/template.rb +7 -7
  42. data/lib/faastruby/local.rb +188 -0
  43. data/lib/faastruby/local/crystal_runtime.cr +170 -0
  44. data/lib/faastruby/local/functions.rb +7 -0
  45. data/lib/faastruby/local/functions/crystal.rb +64 -0
  46. data/lib/faastruby/local/functions/function.rb +173 -0
  47. data/lib/faastruby/local/functions/ruby.rb +28 -0
  48. data/lib/faastruby/local/listeners.rb +5 -0
  49. data/lib/faastruby/local/listeners/listener.rb +104 -0
  50. data/lib/faastruby/local/logger.rb +37 -0
  51. data/lib/faastruby/local/monkey_patch.rb +38 -0
  52. data/lib/faastruby/local/processors.rb +7 -0
  53. data/lib/faastruby/local/processors/function.rb +151 -0
  54. data/lib/faastruby/local/processors/processor.rb +116 -0
  55. data/lib/faastruby/local/processors/static_file.rb +48 -0
  56. data/lib/faastruby/local/static_files.rb +5 -0
  57. data/lib/faastruby/local/static_files/static_file.rb +59 -0
  58. data/lib/faastruby/server.rb +44 -3
  59. data/lib/faastruby/server/app.rb +107 -0
  60. data/lib/faastruby/server/concurrency_controller.rb +50 -50
  61. data/lib/faastruby/server/config.ru +2 -0
  62. data/lib/faastruby/server/event.rb +3 -0
  63. data/lib/faastruby/server/event_hub.rb +7 -6
  64. data/lib/faastruby/server/local.rb +22 -0
  65. data/lib/faastruby/server/logger.rb +50 -0
  66. data/lib/faastruby/server/project_config.rb +44 -0
  67. data/lib/faastruby/server/puma.rb +4 -0
  68. data/lib/faastruby/server/response.rb +40 -0
  69. data/lib/faastruby/server/runner.rb +116 -21
  70. data/lib/faastruby/server/runner_methods.rb +17 -16
  71. data/lib/faastruby/server/sentinel.rb +496 -0
  72. data/lib/faastruby/supported_runtimes.rb +8 -0
  73. data/lib/faastruby/user.rb +77 -0
  74. data/lib/faastruby/version.rb +1 -1
  75. data/lib/faastruby/workspace.rb +36 -3
  76. data/templates/crystal/example-blank/handler.cr +3 -0
  77. data/templates/crystal/example/spec/handler_spec.cr +11 -6
  78. data/templates/public-web/assets/images/background.png +0 -0
  79. data/templates/public-web/assets/images/ruby.png +0 -0
  80. data/templates/public-web/assets/javascripts/main.js +1 -0
  81. data/templates/public-web/assets/stylesheets/main.css +70 -0
  82. data/templates/public-web/favicon.ico +0 -0
  83. data/templates/ruby/api-404/handler.rb +6 -0
  84. data/templates/ruby/api-root/handler.rb +6 -0
  85. data/templates/ruby/example-blank/handler.rb +0 -23
  86. data/templates/ruby/web-404/404.html +36 -0
  87. data/templates/ruby/web-404/handler.rb +3 -0
  88. data/templates/ruby/web-root/handler.rb +10 -0
  89. data/templates/ruby/web-root/index.html.erb +37 -0
  90. data/templates/ruby/web-root/template.rb +13 -0
  91. metadata +102 -21
  92. data/exe/faastruby-server +0 -76
  93. data/lib/faastruby/cli/commands/credentials.rb +0 -11
  94. data/lib/faastruby/cli/commands/credentials/add.rb +0 -58
  95. data/lib/faastruby/cli/commands/credentials/list.rb +0 -58
  96. data/lib/faastruby/cli/commands/workspace.rb +0 -13
  97. data/lib/faastruby/cli/commands/workspace/deploy.rb +0 -50
  98. data/templates/crystal/example-blank/README.md +0 -22
  99. data/templates/crystal/example-blank/spec/handler_spec.cr +0 -8
  100. data/templates/crystal/example-blank/spec/spec_helper.cr +0 -4
  101. data/templates/crystal/example-blank/src/handler.cr +0 -25
  102. data/templates/ruby/example-blank/Gemfile +0 -7
  103. data/templates/ruby/example-blank/README.md +0 -22
  104. data/templates/ruby/example-blank/spec/handler_spec.rb +0 -16
  105. data/templates/ruby/example-blank/spec/spec_helper.rb +0 -3
@@ -0,0 +1,7 @@
1
+ module FaaStRuby
2
+ module Local
3
+ require 'faastruby/local/processors/processor'
4
+ require 'faastruby/local/processors/function'
5
+ require 'faastruby/local/processors/static_file'
6
+ end
7
+ end
@@ -0,0 +1,151 @@
1
+ module FaaStRuby
2
+ module Local
3
+ class FunctionProcessor < Processor
4
+
5
+ def should_ignore?(event)
6
+ debug "should_ignore?(#{event.inspect})"
7
+ if present_in_ignore_list?(event.dirname)
8
+ debug "SKIP #{event}"
9
+ return true
10
+ end
11
+ if is_a_crystal_function?(event.dirname) && is_crystal_handler_binary?(event.filename)
12
+ debug "ignoring #{event.filename}"
13
+ return true
14
+ end
15
+ return false
16
+ end
17
+
18
+ def is_crystal_handler_binary?(filename)
19
+ debug "is_crystal_handler_binary?(#{filename.inspect})"
20
+ filename == 'handler' || filename == 'handler.dwarf'
21
+ end
22
+
23
+ def is_a_crystal_function?(directory)
24
+ debug "is_a_crystal_function?(#{directory.inspect})"
25
+ File.file?("#{directory}/handler.cr") || File.file?("#{directory}/src/handler.cr")
26
+ end
27
+
28
+ def added(event)
29
+ debug "added(#{event.inspect})"
30
+ # This should trigger
31
+ # - Initialize function
32
+ # - Deploy
33
+ if event.function_created?
34
+ debug "added: a handler file was added"
35
+ return new_function(event)
36
+ end
37
+ unless event.file_is_a_function_config?
38
+ debug "added: a file was added"
39
+ deploy(event)
40
+ end
41
+ end
42
+
43
+ def modified(event)
44
+ debug "modified(#{event.inspect})"
45
+ # This should trigger
46
+ # - Compile
47
+ # - Deploy
48
+ compile_function(event)
49
+ deploy(event)
50
+ end
51
+
52
+ def removed(event)
53
+ debug "removed(#{event.inspect})"
54
+ # This should trigger
55
+ # - Compile
56
+ # - Deploy
57
+ # - Remove from workspace
58
+ if event.file_is_a_function_config?
59
+ debug "removed: the file is a function_config"
60
+ function_name = event.relative_path
61
+ puts "Function '#{function_name}' was removed."
62
+ return remove_from_workspace(event)
63
+ end
64
+ if !event.file_is_a_handler?
65
+ debug "removed: the file is NOT a function config"
66
+ compile_function(event)
67
+ deploy(event)
68
+ return true
69
+ end
70
+ rescue FaaStRuby::Local::MissingConfigurationFileError
71
+ nil
72
+ end
73
+
74
+ def compile_function(event)
75
+ debug "compile_function(#{event.inspect})"
76
+ # This should run if:
77
+ # - Modified any file
78
+ # - Removed any file but handler
79
+ # - Language is cristal
80
+ function = Local::Function.that_has_file(event.full_path, event.type)
81
+ if function.is_a?(Local::CrystalFunction)
82
+ run(function.name, 'compile') do
83
+ debug "+ IGNORE #{function.absolute_folder}"
84
+ add_ignore(function.absolute_folder)
85
+ function.compile
86
+ debug "- IGNORE #{function.absolute_folder}"
87
+ remove_ignore(function.absolute_folder)
88
+ end
89
+ end
90
+ end
91
+
92
+ def new_function(event)
93
+ debug "new_function(#{event.inspect})"
94
+ # This should run if:
95
+ # - Handler file is added to a folder
96
+ object = function_object_for_handler(event.filename)
97
+ function = object.new(
98
+ absolute_folder: event.dirname,
99
+ name: File.dirname(event.relative_path),
100
+ )
101
+ run(function.name, 'new_function') do
102
+ debug "+ IGNORE #{event.dirname}"
103
+ add_ignore(event.dirname)
104
+ function.initialize_new_function
105
+ # Needs improvement. We need to wait a bit so it won't try
106
+ # to deploy or compile newly added functions
107
+ sleep 1.5
108
+ debug "- IGNORE #{event.dirname}"
109
+ remove_ignore(event.dirname)
110
+ end
111
+ end
112
+
113
+ def function_object_for_handler(filename)
114
+ debug "function_object_for_handler(#{filename.inspect})"
115
+ case filename
116
+ when 'handler.rb'
117
+ Local::RubyFunction
118
+ when 'handler.cr'
119
+ Local::CrystalFunction
120
+ end
121
+ end
122
+
123
+ def deploy(event)
124
+ debug "deploy(#{event.inspect})"
125
+ return false unless SYNC_ENABLED
126
+ # This should run when sync is enabled and:
127
+ # - added any file but handler
128
+ # - modified any file
129
+ # - removed any file but handler
130
+ function = Local::Function.that_has_file(event.full_path, event.type)
131
+ run(function.name, 'deploy') do
132
+ debug "+ IGNORE #{function.absolute_folder}"
133
+ add_ignore(function.absolute_folder)
134
+ function.deploy
135
+ debug "- IGNORE #{function.absolute_folder}"
136
+ remove_ignore(function.absolute_folder)
137
+ end
138
+ end
139
+
140
+ def remove_from_workspace(event)
141
+ debug "remove_from_workspace(#{event.inspect})"
142
+ return false unless SYNC_ENABLED
143
+ # This should run when sync is enabled and:
144
+ # - removed handler
145
+ function = Local::Function.that_has_file(event.full_path, event.type)
146
+ run(function.name, 'remove_from_workspace') {function.remove_from_workspace}
147
+ end
148
+
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,116 @@
1
+ module FaaStRuby
2
+ module Local
3
+ class Processor
4
+ include Local::Logger
5
+ attr_accessor :queue, :thread
6
+ def initialize(queue)
7
+ debug "initialize(#{queue.inspect})"
8
+ @queue = queue
9
+ @ignore = {}
10
+ @mutex = Mutex.new
11
+ @threads_mutex = Mutex.new
12
+ @threads = {}
13
+ end
14
+
15
+ def start
16
+ debug "start"
17
+ thread = Thread.new do
18
+ loop do
19
+ begin
20
+ event = queue.pop
21
+ next if should_ignore?(event)
22
+ send(event.type, event)
23
+ rescue StandardError => e
24
+ String.disable_colorization = true
25
+ STDOUT.puts e.full_message
26
+ String.disable_colorization = false
27
+ next
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def should_ignore?(event)
34
+ debug "should_ignore?(#{event.inspect})"
35
+ if present_in_ignore_list?(event.dirname)
36
+ debug "SKIP #{event}"
37
+ return true
38
+ end
39
+ return false
40
+ end
41
+
42
+ def add_ignore(entry)
43
+ debug "add_ignore(#{entry})"
44
+ @mutex.synchronize do
45
+ @ignore[entry] = true
46
+ debug "Added #{@ignore[entry]}"
47
+ end
48
+ end
49
+
50
+ def present_in_ignore_list?(entry)
51
+ debug "present_in_ignore_list(#{entry})"
52
+ @mutex.synchronize do
53
+ @ignore[entry] ? debug(true) : debug(false)
54
+ @ignore[entry]
55
+ end
56
+ end
57
+
58
+ def remove_ignore(entry)
59
+ debug "remove_ignore(#{entry})"
60
+ @mutex.synchronize do
61
+ @ignore.delete(entry)
62
+ debug "Removed: is nil? #{@ignore[entry].nil?}"
63
+ end
64
+ end
65
+
66
+ def run(name, action, &block)
67
+ debug __method__
68
+ kill_thread(name, action)
69
+ add_thread(name, action, &block)
70
+ end
71
+
72
+ def add_thread(name, action, &block)
73
+ debug __method__
74
+ @threads_mutex.synchronize do
75
+ @threads[name] = {action => start_thread(name, action, &block)}
76
+ end
77
+ end
78
+
79
+ def start_thread(name, action, &block)
80
+ debug __method__
81
+ Thread.new do
82
+ Thread.report_on_exception = false
83
+ yield
84
+ remove_thread_record(name, action)
85
+ end
86
+ end
87
+
88
+ def get_thread(name, action)
89
+ debug __method__
90
+ @threads_mutex.synchronize do
91
+ return
92
+ return nil
93
+ end
94
+ end
95
+
96
+ def remove_thread_record(name, action)
97
+ @threads_mutex.synchronize do
98
+ if @threads[name] && @threads[name][action]
99
+ @threads[name].delete(action)
100
+ end
101
+ end
102
+ end
103
+
104
+ def kill_thread(name, action)
105
+ debug __method__
106
+ @threads_mutex.synchronize do
107
+ if @threads[name] && @threads[name][action]
108
+ puts "Killing previous '#{action}' action for '#{name}'."
109
+ Thread.kill @threads[name][action]
110
+ @threads[name].delete(action)
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,48 @@
1
+ module FaaStRuby
2
+ module Local
3
+ class StaticFileProcessor < Processor
4
+
5
+ def added(event)
6
+ debug "added(#{event.inspect})"
7
+ # This should trigger
8
+ # - Copy to workspace
9
+ deploy(event)
10
+ end
11
+
12
+ def modified(event)
13
+ debug "modified(#{event.inspect})"
14
+ # This should trigger
15
+ # - Copy to workspace
16
+ deploy(event)
17
+ end
18
+
19
+ def removed(event)
20
+ debug "removed(#{event.inspect})"
21
+ # This should trigger
22
+ # - Remove from workspace
23
+ remove_from_workspace(event)
24
+ end
25
+
26
+ def deploy(event)
27
+ static_file = StaticFile.new(
28
+ full_path: event.full_path,
29
+ relative_path: event.relative_path,
30
+ filename: event.filename,
31
+ dirname: event.dirname
32
+ )
33
+ run(event.relative_path, 'deploy') {static_file.deploy}
34
+ end
35
+
36
+ def remove_from_workspace(event)
37
+ static_file = StaticFile.new(
38
+ full_path: event.full_path,
39
+ relative_path: event.relative_path,
40
+ filename: event.filename,
41
+ dirname: event.dirname
42
+ )
43
+ run(event.relative_path, 'remove_from_workspace') {static_file.remove_from_workspace}
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ module FaaStRuby
2
+ module Local
3
+ require 'faastruby/local/static_files/static_file'
4
+ end
5
+ end
@@ -0,0 +1,59 @@
1
+ module FaaStRuby
2
+ module Local
3
+ class StaticFile
4
+ include Local::Logger
5
+
6
+ def self.full_sync
7
+ cmd = "faastruby deploy-to #{Local.workspace} -f #{Local.public_dir}"
8
+ output, status = Open3.capture2e(cmd)
9
+ String.disable_colorization = true
10
+ if status.exitstatus == 0
11
+ output.split("\n").each {|o| puts "#{Time.now} | #{o}" unless o == '---'}
12
+ puts '---'
13
+ else
14
+ STDERR.puts output
15
+ end
16
+ String.disable_colorization = false
17
+ end
18
+
19
+ def initialize(full_path:, relative_path:, filename:, dirname:)
20
+ @full_path = full_path
21
+ @relative_path = relative_path
22
+ @filename = filename
23
+ @dirname = dirname
24
+ @config = YAML.load(File.read("#{Local.public_dir}/faastruby.yml"))
25
+ @before_build = @config['before_build'] || []
26
+ end
27
+
28
+ def deploy
29
+ path = "public/#{@relative_path}"
30
+ cmd = "faastruby cp #{path} #{Local.workspace}:/#{@relative_path}"
31
+ puts "Running: #{cmd}"
32
+ output, status = Open3.capture2e(cmd)
33
+ String.disable_colorization = true
34
+ if status.exitstatus == 0
35
+ output.split("\n").each {|o| puts o unless o == '---' || o == "" || o.match(/Copying file to/)}
36
+ else
37
+ puts "* [#{path}] Error uploading static file '#{path}' to cloud workspace '#{Local.workspace}':"
38
+ STDERR.puts output
39
+ end
40
+ String.disable_colorization = false
41
+ end
42
+
43
+ def remove_from_workspace
44
+ path = "public/#{@relative_path}"
45
+ cmd = "faastruby rm #{Local.workspace}:/#{@relative_path}"
46
+ puts "Running: #{cmd}"
47
+ output, status = Open3.capture2e(cmd)
48
+ String.disable_colorization = true
49
+ if status.exitstatus == 0
50
+ output.split("\n").each {|o| puts o unless o == '---'}
51
+ else
52
+ puts "* [#{path}] Error removing static file '#{path}' from cloud workspace '#{Local.workspace}':"
53
+ STDERR.puts output
54
+ end
55
+ String.disable_colorization = false
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,13 +1,54 @@
1
+ require 'yaml'
1
2
  module FaaStRuby
2
- PROJECT_ROOT = Dir.pwd
3
- require 'faastruby/server/concurrency_controller'
3
+ require 'faastruby/version'
4
+ require 'faastruby/supported_runtimes'
5
+
6
+ def self.get_crystal_version
7
+ ver = `crystal -v|head -n1|cut -f2 -d' ' 2>/dev/null`&.chomp
8
+ ver == '' ? CRYSTAL_LATEST : ver
9
+ end
10
+
11
+ def self.crystal_present_and_supported?
12
+ system("which crystal >/dev/null") && SUPPORTED_CRYSTAL.include?(get_crystal_version)
13
+ end
14
+
15
+ def self.ruby_present_and_supported?
16
+ system("which ruby >/dev/null") && SUPPORTED_RUBY.include?(RUBY_VERSION)
17
+ end
18
+
19
+ CRYSTAL_ENABLED = crystal_present_and_supported?
20
+ RUBY_ENABLED = ruby_present_and_supported?
21
+ unless RUBY_ENABLED || CRYSTAL_ENABLED
22
+ puts "\n[ERROR] You need to have one of the following language:version pairs in order to use FaaStRuby Local."
23
+ puts SUPPORTED_RUNTIMES.join(', ') + "\n"*2
24
+ exit 1
25
+ end
26
+ SERVER_ROOT = Dir.pwd
27
+ PROJECT_YAML_FILE = ENV['FAASTRUBY_PROJECT_CONFIG_FILE'] || "#{SERVER_ROOT}/project.yml"
28
+ SECRETS_FILE = ENV['FAASTRUBY_PROJECT_SECRETS_FILE'] || "#{SERVER_ROOT}/secrets.yml"
29
+ PROJECT_NAME = YAML.load(File.read(PROJECT_YAML_FILE))['project']['name']
30
+ SYNC_ENABLED = ENV['FAASTRUBY_PROJECT_SYNC_ENABLED']
31
+ DEPLOY_ENVIRONMENT = ENV['FAASTRUBY_PROJECT_DEPLOY_ENVIRONMENT'] || 'stage'
32
+ WORKSPACE_NAME = "#{PROJECT_NAME}-#{DEPLOY_ENVIRONMENT}"
33
+ CHDIR_MUTEX = Mutex.new
34
+ CRYSTAL_VERSION = get_crystal_version.freeze
35
+ DEFAULT_CRYSTAL_RUNTIME = "crystal:#{CRYSTAL_VERSION}".freeze
36
+ DEFAULT_RUBY_RUNTIME = "ruby:#{RUBY_VERSION}".freeze
37
+ require 'faastruby/server/logger'
38
+ require 'faastruby/server/project_config'
39
+ require 'faastruby/server/local'
40
+ FaaStRuby::Local.start!(deploy_env: DEPLOY_ENVIRONMENT, sync: SYNC_ENABLED, debug: ENV['DEBUG'])
41
+
42
+ # require 'faastruby/server/concurrency_controller'
4
43
  require 'faastruby/server/errors'
5
44
  require 'faastruby/server/event_channel'
6
45
  require 'faastruby/server/subscriber'
7
- require 'faastruby/server/event_hub'
46
+ # require 'faastruby/server/event_hub'
8
47
  require 'faastruby/server/runner_methods'
9
48
  require 'faastruby/server/function_object'
10
49
  require 'faastruby/server/runner'
11
50
  require 'faastruby/server/event'
12
51
  require 'faastruby/server/response'
52
+ # FaaStRuby::EventHub.listen_for_events!
53
+ require 'faastruby/server/app'
13
54
  end