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.
@@ -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 "flow ##{res['id']} pulled to #{dir}"
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
- flow_id = options[:id] || shift_argument
339
+ id = options[:id] || shift_argument
337
340
 
338
- if flow_id.nil?
339
- flow_id = read_name_from_conf(options)
341
+ if id.nil?
342
+ id = read_name_from_conf(options)
340
343
  options[:is_name] = true
341
- elsif !(flow_id =~ /^\d*$/)
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
- response = api.flows.delete(flow_id, options)
366
- if type == "json"
367
- display "{}"
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
- display response["body"]
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 # app directory
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
- # Get the class
445
- flow_class = read_class_from_conf(options)
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 flow_class
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 ]
@@ -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
- app_name = options[:name] || File.basename(Dir.pwd)
28
-
29
- if git('remote').split("\n").include?(remote)
30
- # already exists.. remove it.
31
- git("remote remove #{remote}")
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
@@ -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,2 @@
1
+ language: js
2
+ script: simple_function.js
@@ -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,4 @@
1
+ language: python
2
+ script: component.py
3
+ ignore_files:
4
+ - ./vEnv
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "zillabyte"
@@ -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
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ script: component.rb
3
+ flow_type: component
4
+
5
+
@@ -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 "Git remote #{remote} added"
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