zillabyte-cli 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/zillabyte-cli/version.rb +1 -1
- data/lib/zillabyte/api/apps.rb +4 -17
- data/lib/zillabyte/api/components.rb +0 -18
- data/lib/zillabyte/api/flows.rb +72 -0
- data/lib/zillabyte/auth.rb +37 -1
- data/lib/zillabyte/cli/apps.rb +11 -22
- data/lib/zillabyte/cli/components.rb +167 -39
- data/lib/zillabyte/cli/flows.rb +129 -21
- data/lib/zillabyte/cli/git.rb +6 -9
- data/lib/zillabyte/cli/templates/apps/ruby/{app.rb → app.rb.erb} +0 -0
- data/lib/zillabyte/cli/templates/components/js/simple_function.js +38 -0
- data/lib/zillabyte/cli/templates/components/js/zillabyte.conf.yaml +2 -0
- data/lib/zillabyte/cli/templates/components/python/component.py +17 -0
- data/lib/zillabyte/cli/templates/components/python/requirements.txt +7 -0
- data/lib/zillabyte/cli/templates/components/python/zillabyte.conf.yaml +4 -0
- data/lib/zillabyte/cli/templates/components/ruby/Gemfile +3 -0
- data/lib/zillabyte/cli/templates/components/ruby/component.rb.erb +20 -0
- data/lib/zillabyte/cli/templates/components/ruby/zillabyte.conf.yaml +5 -0
- data/lib/zillabyte/helpers.rb +41 -1
- data/lib/zillabyte/runner/app_runner.rb +8 -19
- data/lib/zillabyte/runner/component_operation.rb +124 -68
- data/lib/zillabyte/runner/component_runner.rb +25 -31
- data/lib/zillabyte/runner/multilang_operation.rb +11 -4
- metadata +11 -4
- data/lib/zillabyte/cli/executes.rb +0 -180
data/lib/zillabyte/cli/flows.rb
CHANGED
@@ -15,6 +15,9 @@ require "zillabyte/runner/app_runner"
|
|
15
15
|
# HIDDEN: superclass for components and apps
|
16
16
|
#
|
17
17
|
class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
18
|
+
|
19
|
+
MAX_POLL_SECONDS = 60 * 15
|
20
|
+
POLL_SLEEP = 2.0
|
18
21
|
|
19
22
|
# flows:status [DIR]
|
20
23
|
#
|
@@ -95,7 +98,7 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
95
98
|
if type == "json"
|
96
99
|
display "{}"
|
97
100
|
else
|
98
|
-
display "
|
101
|
+
display "Flow ##{res['id']} pulled to #{dir}"
|
99
102
|
end
|
100
103
|
end
|
101
104
|
|
@@ -333,12 +336,12 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
333
336
|
# --output_type OUTPUT_TYPE # specify an output type i.e. json
|
334
337
|
#
|
335
338
|
def delete
|
336
|
-
|
339
|
+
id = options[:id] || shift_argument
|
337
340
|
|
338
|
-
if
|
339
|
-
|
341
|
+
if id.nil?
|
342
|
+
id = read_name_from_conf(options)
|
340
343
|
options[:is_name] = true
|
341
|
-
elsif !(
|
344
|
+
elsif !(id =~ /^\d*$/)
|
342
345
|
options[:is_name] = true
|
343
346
|
end
|
344
347
|
forced = options[:force]
|
@@ -362,12 +365,48 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
362
365
|
confirmed = forced || confirm == "yes"
|
363
366
|
|
364
367
|
if confirmed
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
+
display "Destroying flow ##{id}...please wait..." if type.nil?
|
369
|
+
response = api.flows.create_delete(id, options)
|
370
|
+
|
371
|
+
if response["job_id"]
|
372
|
+
options[:job_id] = response["job_id"]
|
373
|
+
flow_id = response["flow_id"]
|
374
|
+
options.delete :is_name
|
375
|
+
|
376
|
+
start = Time.now.utc
|
377
|
+
display "Destroy request sent. Please wait..." if type.nil?
|
378
|
+
|
379
|
+
while(Time.now.utc < start + MAX_POLL_SECONDS) do
|
380
|
+
|
381
|
+
# Poll
|
382
|
+
res = self.api.flows.poll_delete(flow_id, options)
|
383
|
+
|
384
|
+
case res['status']
|
385
|
+
when 'completed'
|
386
|
+
if res['return']
|
387
|
+
if type == "json"
|
388
|
+
display "{}"
|
389
|
+
else
|
390
|
+
display "Flow ##{id} destroyed"
|
391
|
+
end
|
392
|
+
else
|
393
|
+
throw "something is wrong: #{res}"
|
394
|
+
end
|
395
|
+
# success! continue below
|
396
|
+
break
|
397
|
+
when 'running'
|
398
|
+
sleep(POLL_SLEEP)
|
399
|
+
else
|
400
|
+
throw "unknown status: #{res}"
|
401
|
+
end
|
402
|
+
|
403
|
+
end
|
404
|
+
elsif response["error"]
|
405
|
+
error(response["error"], type)
|
368
406
|
else
|
369
|
-
|
407
|
+
error("remote server error (f413)", type)
|
370
408
|
end
|
409
|
+
|
371
410
|
end
|
372
411
|
|
373
412
|
end
|
@@ -428,7 +467,7 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
428
467
|
# --input INPUT_FILE # writes sink output to a file
|
429
468
|
# --output OUTPUT_FILE # writes sink output to a file
|
430
469
|
# --cycles CYCLES # number of cycles to emit (default 1)
|
431
|
-
# --directory DIR #
|
470
|
+
# --directory DIR # flow directory
|
432
471
|
# -i, --interactive # allow user to control input and read output
|
433
472
|
#
|
434
473
|
def test
|
@@ -440,11 +479,23 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
440
479
|
end
|
441
480
|
options[:directory] = dir
|
442
481
|
|
482
|
+
# Get the flow_type
|
483
|
+
meta = Zillabyte::API::Flows.get_rich_meta_info_from_script(dir, session, {:test => true})
|
484
|
+
if meta.nil? || meta["nodes"].nil?
|
485
|
+
error "this is not a valid zillabyte app directory"
|
486
|
+
exit
|
487
|
+
end
|
443
488
|
|
444
|
-
#
|
445
|
-
|
489
|
+
# Check that multilang version is atleast 0.1.0
|
490
|
+
version = meta["multilang_version"] || "0.0.0"
|
491
|
+
version_arr = version.split('.').map {|v| v.to_i}
|
492
|
+
if version_arr.empty? || (version_arr[0] == 0 && version_arr[1] < 1)
|
493
|
+
display "The version of zillabyte used in your application is outdated."
|
494
|
+
display "Please use upgrade your zillabyte gem via 'bundle update zillabyte; gem cleanup zillabyte'"
|
495
|
+
return
|
496
|
+
end
|
446
497
|
|
447
|
-
case
|
498
|
+
case meta["flow_type"]
|
448
499
|
when "component"
|
449
500
|
runner = Zillabyte::Runner::ComponentRunner.new()
|
450
501
|
when "app"
|
@@ -455,12 +506,76 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
455
506
|
end
|
456
507
|
|
457
508
|
# Start Runner
|
458
|
-
runner.run(dir, self, options)
|
509
|
+
runner.run(meta, dir, self, options)
|
459
510
|
|
460
511
|
end
|
461
512
|
alias_command "test", "flows:test"
|
462
513
|
|
463
514
|
|
515
|
+
# flows:kill ID
|
516
|
+
#
|
517
|
+
# kills the given flow
|
518
|
+
#
|
519
|
+
# --config CONFIG_FILE # use the given config file
|
520
|
+
# --output_type OUTPUT_TYPE # specify an output type i.e. json
|
521
|
+
#
|
522
|
+
def kill
|
523
|
+
id = options[:id] || shift_argument
|
524
|
+
type = options[:output_type]
|
525
|
+
|
526
|
+
if id.nil?
|
527
|
+
id = read_name_from_conf(options)
|
528
|
+
options[:is_name] = true
|
529
|
+
elsif !(id =~ /^\d*$/)
|
530
|
+
options[:is_name] = true
|
531
|
+
end
|
532
|
+
|
533
|
+
display "Killing flow ##{id}...please wait..." if type.nil?
|
534
|
+
response = api.flows.create_kill(id, options)
|
535
|
+
|
536
|
+
if response["job_id"]
|
537
|
+
options[:job_id] = response["job_id"]
|
538
|
+
flow_id = response["flow_id"]
|
539
|
+
options.delete :is_name
|
540
|
+
|
541
|
+
start = Time.now.utc
|
542
|
+
display "Kill request sent. Please wait..." if type.nil?
|
543
|
+
|
544
|
+
while(Time.now.utc < start + MAX_POLL_SECONDS) do
|
545
|
+
|
546
|
+
# Poll
|
547
|
+
res = self.api.flows.poll_kill(flow_id, options)
|
548
|
+
|
549
|
+
case res['status']
|
550
|
+
when 'completed'
|
551
|
+
if res['return']
|
552
|
+
if type == "json"
|
553
|
+
display "{}"
|
554
|
+
else
|
555
|
+
display "Flow ##{id} killed"
|
556
|
+
end
|
557
|
+
else
|
558
|
+
throw "something is wrong: #{res}"
|
559
|
+
end
|
560
|
+
# success! continue below
|
561
|
+
break
|
562
|
+
when 'running'
|
563
|
+
sleep(POLL_SLEEP)
|
564
|
+
# display ".", false
|
565
|
+
else
|
566
|
+
throw "unknown status: #{res}"
|
567
|
+
end
|
568
|
+
|
569
|
+
end
|
570
|
+
elsif response["error"]
|
571
|
+
error(response["error"], type)
|
572
|
+
else
|
573
|
+
error("remote server error (f569)", type)
|
574
|
+
end
|
575
|
+
|
576
|
+
end
|
577
|
+
|
578
|
+
|
464
579
|
private
|
465
580
|
|
466
581
|
#
|
@@ -506,13 +621,6 @@ class Zillabyte::Command::Flows < Zillabyte::Command::Base
|
|
506
621
|
hash["name"]
|
507
622
|
end
|
508
623
|
|
509
|
-
def read_class_from_conf(options = {})
|
510
|
-
type = options[:output_type]
|
511
|
-
hash = Zillabyte::API::Apps.get_rich_meta_info_from_script Dir.pwd, options
|
512
|
-
error("No id given and current directory does not contain a valid Zillabyte configuration file. Please specify a flow id or run command from the directory containing the flow.",type) if hash["error"]
|
513
|
-
hash["class"]
|
514
|
-
end
|
515
|
-
|
516
624
|
def fetch_logs(hash, operation=nil, exit_on=nil)
|
517
625
|
def color_for(operation_name)
|
518
626
|
@color_map[operation_name] ||= @all_colors[ @color_map.size % @all_colors.size ]
|
data/lib/zillabyte/cli/git.rb
CHANGED
@@ -22,17 +22,14 @@ class Zillabyte::Command::Git < Zillabyte::Command::Base
|
|
22
22
|
# ! Git remote zillabyte already exists
|
23
23
|
#
|
24
24
|
def remote
|
25
|
+
|
25
26
|
git_options = args.join(" ")
|
26
27
|
remote = options[:remote] || 'zillabyte'
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
git_url = "git@#{Zillabyte::Auth.git_host}:#{Zillabyte::Auth.user}/#{app_name}"
|
35
|
-
create_git_remote(remote, git_url)
|
28
|
+
name = options[:name] || get_flow_name()
|
29
|
+
error "could not infer app name" if name.nil?
|
30
|
+
|
31
|
+
add_git_remote(name, remote)
|
32
|
+
|
36
33
|
end
|
37
34
|
|
38
35
|
end
|
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
var zillabyte = require('zillabyte');
|
2
|
+
|
3
|
+
function prep(controller) {
|
4
|
+
}
|
5
|
+
|
6
|
+
/**
|
7
|
+
* This is the heart of your algorithm. It's processed on every
|
8
|
+
* web page. This algorithm is run in parallel on possibly hundreds
|
9
|
+
* of machines.
|
10
|
+
*/
|
11
|
+
function exec(controller, tuple) {
|
12
|
+
if(tuple["html"].indexOf("hello world") !== -1) {
|
13
|
+
controller.emit("has_hello_world",{"url":tuple["url"]});
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
zillabyte.simple_function({
|
18
|
+
/**
|
19
|
+
* This specifies the function's name and is mandatory.
|
20
|
+
*/
|
21
|
+
name: "simple_function",
|
22
|
+
|
23
|
+
/**
|
24
|
+
* This directive instructs zillabyte to give your function every
|
25
|
+
* web page in our known universe. Your function will have access
|
26
|
+
* to two fields: URL and HTML
|
27
|
+
*/
|
28
|
+
matches: "select * from web_pages",
|
29
|
+
|
30
|
+
/**
|
31
|
+
* This directive tells Zillabyte what kind of data your function
|
32
|
+
* produces. In this case, we're saying we will emit a tuple that
|
33
|
+
* is one-column wide and contains the field 'URL'
|
34
|
+
*/
|
35
|
+
emits: [["has_hello_world", [{"url":"string"}]]],
|
36
|
+
prepare: prep,
|
37
|
+
execute: exec
|
38
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import zillabyte
|
2
|
+
|
3
|
+
# This function takes a tuple and emits its url field
|
4
|
+
def execute(controller, tuple):
|
5
|
+
controller.emit("urls",{"url":tuple["url"]})
|
6
|
+
|
7
|
+
component = zillabyte.component(name = "hello_world")
|
8
|
+
|
9
|
+
|
10
|
+
# Declare the schema for inputs to the component
|
11
|
+
input_stream = component.inputs(name = "url_stream", fields = [{"url" : "string", "html" : "string"}])
|
12
|
+
|
13
|
+
# Extract urls from the input_stream
|
14
|
+
url_stream = input_stream.each(execute = execute)
|
15
|
+
|
16
|
+
# Declare the output schema of the component
|
17
|
+
url_stream.outputs(name = "urls", fields = [{"url":"string"}])
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Indicate any required libraries here
|
2
|
+
# Default libraries installed:
|
3
|
+
# - numpy 1.8.0
|
4
|
+
# - scipy 0.13.0
|
5
|
+
# For all other libraries, enter one per line in the following format: LIBRARY==VERSION, e.g. numpy==1.8.0
|
6
|
+
# MAKE SURE LIBRARY DEPENDENCIES ARE ALSO INCLUDED, FOR EXAMPLE IF YOUR LIBRARY NEEDS MATPLOTLIB FUNCTIONS, THEN MATPLOTLIB
|
7
|
+
# MUST ALSO BE LISTED BELOW EVEN IF YOU DO NOT CALL ANY OF ITS FUNCTIONS EXPLICITLY.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'zillabyte'
|
2
|
+
|
3
|
+
comp = Zillabyte.component("<%= name %>")
|
4
|
+
|
5
|
+
# Declare the schema for inputs to the component
|
6
|
+
url_stream = comp.inputs do
|
7
|
+
name "urls"
|
8
|
+
field "url", :string
|
9
|
+
end
|
10
|
+
|
11
|
+
# This component strips HTTP and HTTPS prefixes
|
12
|
+
suffix_streams = url_stream.each do |tuple|
|
13
|
+
emit :urls => tuple["url"].gsub(/^http(s)?:\/\//,"")
|
14
|
+
end
|
15
|
+
|
16
|
+
# Declare the output schema for the component
|
17
|
+
suffix_streams.outputs do
|
18
|
+
name "suffix_urls"
|
19
|
+
field "urls", :string
|
20
|
+
end
|
data/lib/zillabyte/helpers.rb
CHANGED
@@ -66,7 +66,7 @@ module Zillabyte
|
|
66
66
|
return if git('remote').split("\n").include?(remote)
|
67
67
|
return unless File.exists?(".git")
|
68
68
|
git "remote add #{remote} #{url}"
|
69
|
-
display "
|
69
|
+
display "git remote #{remote} added"
|
70
70
|
end
|
71
71
|
|
72
72
|
|
@@ -113,6 +113,46 @@ module Zillabyte
|
|
113
113
|
remote == "" ? nil : remote
|
114
114
|
end
|
115
115
|
|
116
|
+
|
117
|
+
def add_git_remote(name, remote = "zillabyte")
|
118
|
+
|
119
|
+
remotes = {}
|
120
|
+
remotes[remote] = Zillabyte::Auth.git_host
|
121
|
+
|
122
|
+
if ENV["ZILLABYTE_EXTRA_GIT_REMOTES"]
|
123
|
+
# This is for dev purposes -- auto init various git env endpoints
|
124
|
+
JSON.parse(ENV["ZILLABYTE_EXTRA_GIT_REMOTES"]).each_pair do |remote, host|
|
125
|
+
remotes[remote] = host
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Maybe initialize a git directory at the app root...
|
130
|
+
if File.exists?(File.join(Dir.pwd, ".git")) == false && File.exists?(File.join(Dir.pwd, "zillabyte.conf.yaml"))
|
131
|
+
git("init .")
|
132
|
+
end
|
133
|
+
|
134
|
+
# Install each git remote
|
135
|
+
remotes.each_pair do |remote, host|
|
136
|
+
|
137
|
+
if git('remote').split("\n").include?(remote)
|
138
|
+
# already exists.. remove it.
|
139
|
+
git("remote remove #{remote}")
|
140
|
+
end
|
141
|
+
|
142
|
+
git_url = "git@#{host}:#{Zillabyte::Auth.user}/#{name}"
|
143
|
+
create_git_remote(remote, git_url)
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def get_flow_name(dir = Dir.pwd)
|
151
|
+
meta = Zillabyte::API::Flows.get_rich_meta_info_from_script(dir)
|
152
|
+
return meta["name"] if meta
|
153
|
+
return nil
|
154
|
+
end
|
155
|
+
|
116
156
|
|
117
157
|
end
|
118
158
|
end
|
@@ -8,35 +8,20 @@ require 'thread'
|
|
8
8
|
class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
9
9
|
include Zillabyte::Helpers
|
10
10
|
|
11
|
-
def run (dir = Dir.pwd, session = nil, options = {})
|
11
|
+
def run (meta, dir = Dir.pwd, session = nil, options = {})
|
12
12
|
|
13
|
-
if session.nil?
|
13
|
+
if meta.nil? or session.nil?
|
14
14
|
return
|
15
15
|
end
|
16
16
|
|
17
17
|
@session = session
|
18
|
+
|
18
19
|
@colors = {}
|
19
20
|
output = options[:output]
|
20
21
|
otype = options[:output_type]
|
21
22
|
interactive = options[:interactive]
|
22
23
|
cycles = (options[:cycles] || "1").to_i
|
23
24
|
|
24
|
-
# Get app metadata
|
25
|
-
meta = Zillabyte::API::Flows.get_rich_meta_info_from_script(dir, @session, {:test => true})
|
26
|
-
if meta.nil? || meta["nodes"].nil?
|
27
|
-
error "this is not a valid zillabyte app directory"
|
28
|
-
exit
|
29
|
-
end
|
30
|
-
|
31
|
-
# Check that multilang version is atleast 0.1.0
|
32
|
-
version = meta["multilang_version"] || "0.0.0"
|
33
|
-
version_arr = version.split('.').map {|v| v.to_i}
|
34
|
-
if version_arr.empty? || (version_arr[0] == 0 && version_arr[1] < 1)
|
35
|
-
display "The version of zillabyte used in your application is outdated."
|
36
|
-
display "Please use upgrade your zillabyte gem via 'bundle update zillabyte; gem cleanup zillabyte'"
|
37
|
-
return
|
38
|
-
end
|
39
|
-
|
40
25
|
# Show the user what we know about their app...
|
41
26
|
display "inferring your app details..."
|
42
27
|
describe_app(meta)
|
@@ -151,7 +136,11 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
151
136
|
end
|
152
137
|
|
153
138
|
if interactive
|
139
|
+
display "To view results: Enter 'end' "
|
140
|
+
display "To exit the test: Enter 'Ctrl-C' "
|
154
141
|
display ""
|
142
|
+
|
143
|
+
|
155
144
|
while true
|
156
145
|
display "Enter an input tuple in JSON format i.e.{ \"url\" : \"foo.com\", \"html\" : \"bar.html\" }"
|
157
146
|
msg = ask
|
@@ -223,4 +212,4 @@ class Zillabyte::Runner::AppRunner < Zillabyte::Command::Base
|
|
223
212
|
end
|
224
213
|
|
225
214
|
|
226
|
-
end
|
215
|
+
end
|