zillabyte-cli 0.1.0 → 0.1.1
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 +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
|