devbox_launcher 0.4.0 → 0.6.0

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: eb4a378b2f76aac6847c19aa98173e0ec1eaa4dd94ee5983dce3b2b2025ff989
4
- data.tar.gz: e0185ccc0c83c43091399da51229fe7f677b6bf295362449b81deca893a359a5
3
+ metadata.gz: c48092de409744a2c52020e6caf65cf2d06377ab686aca517ede0b9790b0d414
4
+ data.tar.gz: 7cdae080f466ead661718d23bc320f424049cc118887aab9402d5043f0d05184
5
5
  SHA512:
6
- metadata.gz: 00dcd892ade882a93cc908451b6ed9dedb229160f55f28a9aa2735e573aafae7732e6df4221fbf06d0669060f5ec4082d331de908917ae172a0157c84cef001b
7
- data.tar.gz: dee55da84e14e426fdc605201725f3ddb0d9525e9838edbae1a8af62438420040d51a48cda06cac2e898383b3b85bfa8d62355148f63ab2870373cb942198901
6
+ metadata.gz: 32574d16bae08ed7470449b7c36cdd6acc9f76b176e9e5342b9a70a49da9001debee5ee4793bb0295221606e07158e6aa20984f7d762d462bd8fbfb69ec36923
7
+ data.tar.gz: 94fee4aa07ef525c2b5c4de214bc2452aa7c8c8f9a2e7a43103d0a0c6e9c3a6c72f76bbe66a93601006d8532efe46b42a211a9d2fbdc96c194907f800d8ff257
data/.gitignore CHANGED
File without changes
data/.rspec CHANGED
File without changes
data/.travis.yml CHANGED
File without changes
data/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.6.0] - 2021-09-21
8
+ ### Changed
9
+ - Ability to configure multiple boxes under one account
10
+
11
+ ## [0.5.2] - 2021-05-31
12
+ ### Added
13
+ - Ignore VCS as recommended by mutagen
14
+
15
+ ### Fixed
16
+ - Retry on `Errno::ECONNREFUSED`
17
+
18
+ ## [0.5.1] - 2021-04-08
19
+ ### Fixed
20
+ - Use configured `zone` for describe as well
21
+
22
+ ## [0.5.0] - 2021-04-06
23
+ ### Added
24
+ - Ability to specify `zone` in config
25
+
7
26
  ## [0.4.0]
8
27
  ### Added
9
28
  - Sync mutagen with two-way-resolved
data/CODE_OF_CONDUCT.md CHANGED
File without changes
data/Gemfile CHANGED
File without changes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devbox_launcher (0.3.5)
4
+ devbox_launcher (0.6.0)
5
5
  activesupport (~> 6.0)
6
6
  bcrypt_pbkdf (~> 1.0)
7
7
  ed25519 (~> 1.2)
@@ -14,22 +14,22 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- activesupport (6.0.3.4)
17
+ activesupport (6.1.4.1)
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
- i18n (>= 0.7, < 2)
20
- minitest (~> 5.1)
21
- tzinfo (~> 1.1)
22
- zeitwerk (~> 2.2, >= 2.2.2)
23
- bcrypt_pbkdf (1.0.1)
19
+ i18n (>= 1.6, < 2)
20
+ minitest (>= 5.1)
21
+ tzinfo (~> 2.0)
22
+ zeitwerk (~> 2.3)
23
+ bcrypt_pbkdf (1.1.0)
24
24
  byebug (11.0.1)
25
25
  coderay (1.1.2)
26
- concurrent-ruby (1.1.7)
26
+ concurrent-ruby (1.1.9)
27
27
  diff-lcs (1.3)
28
28
  ed25519 (1.2.4)
29
- i18n (1.8.5)
29
+ i18n (1.8.10)
30
30
  concurrent-ruby (~> 1.0)
31
31
  method_source (0.9.2)
32
- minitest (5.14.2)
32
+ minitest (5.14.4)
33
33
  net-ssh (5.2.0)
34
34
  os (1.1.1)
35
35
  pry (0.12.2)
@@ -38,7 +38,7 @@ GEM
38
38
  pry-byebug (3.7.0)
39
39
  byebug (~> 11.0)
40
40
  pry (~> 0.10)
41
- rake (10.5.0)
41
+ rake (13.0.1)
42
42
  rspec (3.9.0)
43
43
  rspec-core (~> 3.9.0)
44
44
  rspec-expectations (~> 3.9.0)
@@ -54,11 +54,10 @@ GEM
54
54
  rspec-support (3.9.0)
55
55
  ruby-watchman (0.0.2)
56
56
  ssh-config (0.1.3)
57
- thor (1.0.1)
58
- thread_safe (0.3.6)
59
- tzinfo (1.2.8)
60
- thread_safe (~> 0.1)
61
- zeitwerk (2.4.1)
57
+ thor (1.1.0)
58
+ tzinfo (2.0.4)
59
+ concurrent-ruby (~> 1.0)
60
+ zeitwerk (2.4.2)
62
61
 
63
62
  PLATFORMS
64
63
  ruby
@@ -67,7 +66,7 @@ DEPENDENCIES
67
66
  bundler (~> 2.0)
68
67
  devbox_launcher!
69
68
  pry-byebug
70
- rake (~> 10.0)
69
+ rake (~> 13.0)
71
70
  rspec (~> 3.0)
72
71
 
73
72
  BUNDLED WITH
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -4,13 +4,9 @@ Start devboxes quickly
4
4
 
5
5
  ## Installation
6
6
 
7
- Install the gem:
8
-
9
- ```sh
10
- gem install devbox_launcher
11
- ```
12
-
13
- Setup gcloud init with the project that contains your VM.
7
+ - Install the gem: `gem install devbox_launcher`
8
+ - Setup `gcloud init` with the project that contains your VM
9
+ - Install [mutagen](https://mutagen.io)
14
10
 
15
11
  ## Usage
16
12
 
@@ -20,11 +16,12 @@ Create the config file at `~/.devbox_launcher.yml` so you type less. This is an
20
16
 
21
17
  ```yml
22
18
  ramon@email.com:
23
- project: general-192303
24
- box: your-instance-name
25
- mutagen:
26
- alpha: /mnt/c/Users/me/src # local machine
27
- beta: ~/src # remote machine
19
+ - box: your-instance-name
20
+ project: general-192303
21
+ zone: us-central1-a
22
+ mutagen:
23
+ alpha: /mnt/c/Users/me/src # local machine
24
+ beta: ~/src # remote machine
28
25
  ramon@company.com:
29
26
  project: development-254604
30
27
  box: ramon
@@ -36,7 +33,13 @@ To start and create the mutagen session:
36
33
  devbox start your-username
37
34
  ```
38
35
 
39
- If you want to mosh in immediately, add the `--mosh` switch.
36
+ - Want to ssh in immediately?
37
+ - Add `--ssh` switch
38
+ - Want to mosh in immediately?
39
+ - Add `--mosh` switch. Mosh needs to be [installed](https://mosh.org/) in your development machine.
40
+ - More than one box with the same Google Cloud account?
41
+ - Pass in the box in your command, via `devbox start user@domain.com/box-name`
42
+ - No need to configure `box:` in the YAML file
40
43
 
41
44
  Note: Linux users that sync mutagen sessions need to install [Watchman](https://facebook.github.io/watchman/).
42
45
 
data/Rakefile CHANGED
File without changes
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.require_paths = ["lib"]
31
31
 
32
32
  spec.add_development_dependency "bundler", "~> 2.0"
33
- spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rake", "~> 13.0"
34
34
  spec.add_development_dependency "rspec", "~> 3.0"
35
35
 
36
36
  spec.add_runtime_dependency "thor", "~> 1.0"
@@ -9,6 +9,7 @@ module DevboxLauncher
9
9
 
10
10
  desc "start configured box for account", "Start a devbox by account"
11
11
  option :mosh, type: :boolean, desc: "Mosh in"
12
+ option :ssh, type: :boolean, desc: "SSH in"
12
13
 
13
14
  def start(account)
14
15
  Box.new(account, options).start
@@ -0,0 +1,22 @@
1
+ module DevboxLauncher
2
+ class AccountConfig
3
+
4
+ attr_reader :account_name
5
+
6
+ def initialize(account_name, config)
7
+ @account_name = account_name
8
+ @config = config
9
+ end
10
+
11
+ def find_box_config(box_name)
12
+ box_config = @config.find { |c| c["box"] == box_name }
13
+
14
+ if box_config.nil?
15
+ fail "No box config found for #{box_name} under account #{account_name}"
16
+ end
17
+
18
+ BoxConfig.new(box_config)
19
+ end
20
+
21
+ end
22
+ end
@@ -6,21 +6,26 @@ module DevboxLauncher
6
6
  Net::SSH::Disconnect,
7
7
  Errno::ECONNRESET,
8
8
  Errno::ETIMEDOUT,
9
+ Errno::ECONNREFUSED,
9
10
  ]
10
11
  WAIT_BOOT_IN_SECONDS = 10.freeze
11
- MAX_BOOT_RETRIES = 10
12
+ MAX_BOOT_RETRIES = 20
12
13
  DEFAULT_IDENTIFY_FILE_PATH = "~/.ssh/google_compute_engine".freeze
13
14
  SSH_CONFIG_PATH = File.expand_path("~/.ssh/config").freeze
14
15
  CONFIG_PATH = File.expand_path("~/.devbox_launcher.yml").freeze
15
16
  CONFIG = YAML.load_file(CONFIG_PATH).freeze
16
17
 
17
- attr_reader :account, :options
18
+ attr_reader :account_and_box_name, :options
18
19
 
19
- def initialize(account, options)
20
- @account = account
20
+ def initialize(account_and_box_name, options)
21
+ @account_and_box_name = account_and_box_name
21
22
  @options = options
22
23
  end
23
24
 
25
+ def account
26
+ @account ||= @account_and_box_name.split("/")[0]
27
+ end
28
+
24
29
  def start
25
30
  start_stdout, start_stderr, start_status =
26
31
  Open3.capture3(start_cmd)
@@ -31,25 +36,11 @@ module DevboxLauncher
31
36
 
32
37
  reset_mutagen_session
33
38
 
34
- connect_mosh
39
+ connect_mosh || connect_ssh
35
40
  end
36
41
 
37
42
  def start_cmd
38
- args = {
39
- project: config[:project],
40
- account: account,
41
- }.map do |(key, val)|
42
- ["--#{key}", val].join("=")
43
- end.join(" ")
44
-
45
- [
46
- "gcloud",
47
- "compute",
48
- "instances",
49
- "start",
50
- name,
51
- args
52
- ].join(" ")
43
+ cmd_args_for('start')
53
44
  end
54
45
 
55
46
  def connect_mosh
@@ -59,6 +50,13 @@ module DevboxLauncher
59
50
  system(mosh_cmd)
60
51
  end
61
52
 
53
+ def connect_ssh
54
+ return if options[:ssh].nil?
55
+
56
+ ssh_cmd = %Q(ssh #{hostname})
57
+ system(ssh_cmd)
58
+ end
59
+
62
60
  def wait_boot(tries: 1)
63
61
  Net::SSH.start(hostname, username, timeout: WAIT_BOOT_IN_SECONDS) do |ssh|
64
62
  puts "[#{ssh.exec!('date').chomp}] Machine booted"
@@ -82,8 +80,6 @@ module DevboxLauncher
82
80
  def description(reload: false)
83
81
  return @description if !reload && @description
84
82
 
85
- puts "Fetching box's description..."
86
-
87
83
  describe_stdout, describe_stderr, describe_status =
88
84
  Open3.capture3(describe_cmd)
89
85
 
@@ -99,35 +95,21 @@ module DevboxLauncher
99
95
  end
100
96
 
101
97
  def describe_cmd
102
- args = {
103
- project: config[:project],
104
- account: account,
105
- }.map do |(key, val)|
106
- ["--#{key}", val].join("=")
107
- end.join(" ")
108
-
109
- [
110
- "gcloud",
111
- "compute",
112
- "instances",
113
- "describe",
114
- name,
115
- args
116
- ].join(" ")
98
+ cmd_args_for('describe')
117
99
  end
118
100
 
119
101
  def set_ssh_config!
120
102
  FileUtils.touch(SSH_CONFIG_PATH)
121
- config = ConfigFile.new
103
+ ssh_config = ConfigFile.new
122
104
  args = {
123
105
  "HostName" => description.ip,
124
106
  "User" => username,
125
107
  "IdentityFile" => DEFAULT_IDENTIFY_FILE_PATH,
126
108
  }
127
109
  args.each do |key, value|
128
- config.set(hostname, key, value)
110
+ ssh_config.set(hostname, key, value)
129
111
  end
130
- config.save
112
+ ssh_config.save
131
113
  end
132
114
 
133
115
  def reset_mutagen_session
@@ -192,8 +174,31 @@ module DevboxLauncher
192
174
  watchman.trigger("mutagen sync flush --label-selector=#{label}")
193
175
  end
194
176
 
177
+ def box_name_from_config
178
+ passed_in_box_name = @account_and_box_name.split("/")[1]
179
+
180
+ case account_config.count
181
+ when 0
182
+ fail "You have to specify box configuration"
183
+ when 1
184
+ account_config.first[:box]
185
+ else
186
+ account_config[name]
187
+ end
188
+ end
189
+
195
190
  def name
196
- @name ||= config[:box]
191
+ return @name if @name
192
+ passed_in_box_name = @account_and_box_name.split("/")[1]
193
+
194
+ name = passed_in_box_name.presence || box_name_from_config
195
+
196
+ if name.blank?
197
+ fail "box name must be given either in the CLI or in config. " \
198
+ "See README.md."
199
+ end
200
+
201
+ @name = name
197
202
  end
198
203
 
199
204
  def hostname
@@ -204,19 +209,44 @@ module DevboxLauncher
204
209
  @username ||= account.gsub(/\W/, "_")
205
210
  end
206
211
 
207
- def config
208
- return @config if @config
212
+ def account_config
213
+ return @account_config if @account_config
209
214
 
210
215
  if not CONFIG.has_key?(account)
211
216
  fail "No config in #{CONFIG_PATH} found for #{account}"
212
217
  end
213
218
 
214
- @config = CONFIG[account].with_indifferent_access
219
+ @account_config = AccountConfig.new(account, CONFIG[account])
220
+ end
221
+
222
+ def box_config
223
+ account_config.find_box_config(name)
215
224
  end
216
225
 
217
226
  def mutagen_config
218
- @mutagen_config ||= Mutagen.new(config[:mutagen])
227
+ @mutagen_config ||= box_config.mutagen_config
228
+ end
229
+
230
+ def cmd_args_for(method)
231
+ args = {
232
+ project: box_config.project,
233
+ account: account,
234
+ zone: box_config.zone,
235
+ }.each_with_object([]) do |(key, val), arr|
236
+ next if val.blank?
237
+ arr << ["--#{key}", val].join("=")
238
+ end.join(" ")
239
+
240
+ [
241
+ "gcloud",
242
+ "compute",
243
+ "instances",
244
+ method,
245
+ name,
246
+ args
247
+ ].join(" ")
219
248
  end
220
249
 
250
+
221
251
  end
222
252
  end
@@ -0,0 +1,23 @@
1
+ module DevboxLauncher
2
+ class BoxConfig
3
+
4
+ attr_reader :config
5
+
6
+ def initialize(config)
7
+ @config = config.with_indifferent_access
8
+ end
9
+
10
+ def mutagen_config
11
+ Mutagen.new(config[:mutagen])
12
+ end
13
+
14
+ def project
15
+ config[:project]
16
+ end
17
+
18
+ def zone
19
+ config[:zone]
20
+ end
21
+
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module DevboxLauncher
2
- VERSION = "0.4.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require "active_support/core_ext/hash/indifferent_access"
2
+ require "active_support/core_ext/object/blank"
2
3
  require "ssh-config"
3
4
  require "open3"
4
5
  require "thor"
@@ -19,3 +20,5 @@ require "devbox_launcher/watchman"
19
20
  require "devbox_launcher/models/description"
20
21
  require "devbox_launcher/models/mutagen"
21
22
  require "devbox_launcher/models/box"
23
+ require "devbox_launcher/models/account_config"
24
+ require "devbox_launcher/models/box_config"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devbox_launcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ramon Tayag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-26 00:00:00.000000000 Z
11
+ date: 2021-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -189,9 +189,10 @@ files:
189
189
  - bin/setup
190
190
  - devbox_launcher.gemspec
191
191
  - lib/devbox_launcher.rb
192
- - lib/devbox_launcher/box.rb
193
192
  - lib/devbox_launcher/cli.rb
193
+ - lib/devbox_launcher/models/account_config.rb
194
194
  - lib/devbox_launcher/models/box.rb
195
+ - lib/devbox_launcher/models/box_config.rb
195
196
  - lib/devbox_launcher/models/description.rb
196
197
  - lib/devbox_launcher/models/mutagen.rb
197
198
  - lib/devbox_launcher/version.rb
@@ -219,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
220
  - !ruby/object:Gem::Version
220
221
  version: '0'
221
222
  requirements: []
222
- rubygems_version: 3.1.4
223
+ rubygems_version: 3.1.6
223
224
  signing_key:
224
225
  specification_version: 4
225
226
  summary: Conveniently launch your devbox
@@ -1,214 +0,0 @@
1
- module DevboxLauncher
2
- class Box
3
-
4
- WAIT_BOOT_RESCUED_EXCEPTIONS = [
5
- Net::SSH::ConnectionTimeout,
6
- Net::SSH::Disconnect,
7
- Errno::ECONNRESET,
8
- Errno::ETIMEDOUT,
9
- Errno::ECONNREFUSED,
10
- ]
11
- WAIT_BOOT_IN_SECONDS = 10.freeze
12
- DEFAULT_IDENTIFY_FILE_PATH = "~/.ssh/google_compute_engine".freeze
13
- SSH_CONFIG_PATH = File.expand_path("~/.ssh/config").freeze
14
- CONFIG_PATH = File.expand_path("~/.devbox_launcher.yml").freeze
15
- CONFIG = YAML.load_file(CONFIG_PATH).freeze
16
-
17
- attr_reader :account
18
-
19
- def initialize(account)
20
- @account = account
21
- end
22
-
23
- def start
24
- start_stdout, start_stderr, start_status =
25
- run_command(start_cmd)
26
-
27
- set_ssh_config!(hostname, {
28
- username: username,
29
- ip: description.ip,
30
- })
31
-
32
- wait_boot
33
-
34
- reset_mutagen_session(
35
- mutagen_config: config[:mutagen],
36
- hostname: hostname,
37
- )
38
- end
39
-
40
- def start_cmd
41
- args = {
42
- project: config[:project],
43
- account: account,
44
- }.map do |(key, val)|
45
- ["--#{key}", val].join("=")
46
- end.join(" ")
47
-
48
- [
49
- "gcloud",
50
- "compute",
51
- "instances",
52
- "start",
53
- name,
54
- args
55
- ].join(" ")
56
- end
57
-
58
- def wait_boot(tries: 1)
59
- Net::SSH.start(hostname, username, timeout: WAIT_BOOT_IN_SECONDS) do |ssh|
60
- puts "[#{ssh.exec!('date').chomp}] Machine booted"
61
- end
62
- rescue *WAIT_BOOT_RESCUED_EXCEPTIONS
63
- puts "Not booted. Waiting #{WAIT_BOOT_IN_SECONDS} seconds before trying again..."
64
-
65
- sleep WAIT_BOOT_IN_SECONDS
66
-
67
- description = describe(name)
68
- if !description.running?
69
- puts "Detected that the machine is not running " \
70
- "(status is #{description.status}). Booting it..."
71
- start_box name, username
72
- end
73
-
74
- wait_boot name, username, tries: tries+1
75
- end
76
-
77
- def description(reload: false)
78
- return @description if !reload && @description
79
-
80
- puts "Fetching box's description..."
81
-
82
- describe_command = %Q(gcloud compute instances describe #{name})
83
- describe_stdout, describe_stderr, describe_status =
84
- run_command(describe_command)
85
-
86
- if !describe_status.success?
87
- msg = "Problem fetching the description of #{name}. "
88
- msg += "Please ensure you can call `#{describe_command}`.\n"
89
- msg += "Error:\n"
90
- msg += describe_stderr
91
- fail msg
92
- end
93
-
94
- @description = Description.new(describe_stdout)
95
- end
96
-
97
- def set_ssh_config!(hostname, username:, ip:)
98
- FileUtils.touch(SSH_CONFIG_PATH)
99
- config = ConfigFile.new
100
- args = {
101
- "HostName" => ip,
102
- "User" => username,
103
- "IdentityFile" => DEFAULT_IDENTIFY_FILE_PATH,
104
- }
105
- args.each do |key, value|
106
- config.set(hostname, key, value)
107
- end
108
- config.save
109
- end
110
-
111
- def reset_mutagen_session
112
- mutagen_config = config[:mutagen]
113
- return if mutagen_config.nil?
114
-
115
- alpha_dir = mutagen_config[:alpha]
116
- beta_dir = mutagen_config[:beta]
117
-
118
- return if alpha_dir.nil? || beta_dir.nil?
119
-
120
- terminate_mutagen_session
121
-
122
- create_mutagen_session(
123
- alpha_dir: alpha_dir,
124
- beta_dir: beta_dir,
125
- hostname: hostname,
126
- username: username,
127
- )
128
-
129
- if OS.linux?
130
- watch_alpha(alpha_dir: alpha_dir, hostname: hostname)
131
- end
132
- end
133
-
134
- def terminate_mutagen_session(username)
135
- puts "Terminating mutagen session..."
136
- terminate_mutagen_command =
137
- %Q(mutagen terminate --label-selector=#{username})
138
- terminate_mutagen_stdout,
139
- terminate_mutagen_stderr,
140
- terminate_mutagen_status =
141
- run_command(terminate_mutagen_command)
142
-
143
- if not terminate_mutagen_status.success?
144
- # mutagen prints to stdout and stderr
145
- msg = "Failed to terminate mutagen sessions: " \
146
- "#{terminate_mutagen_stdout} -" \
147
- "#{terminate_mutagen_stderr}"
148
- fail msg
149
- end
150
- end
151
-
152
- def create_mutagen_session(alpha_dir:, beta_dir:, hostname:, username:)
153
- puts "Create mutagen session syncing local #{alpha_dir} " \
154
- "with #{hostname} #{beta_dir}"
155
-
156
- create_mutagen_command = [
157
- "mutagen sync create",
158
- alpha_dir,
159
- "#{hostname}:#{beta_dir}",
160
- "--label=#{username}",
161
- "--sync-mode=two-way-resolved",
162
- ]
163
- create_mutagen_command << "--watch-mode-alpha=no-watch" if OS.linux?
164
-
165
- create_mutagen_stdout,
166
- create_mutagen_stderr,
167
- create_mutagen_status =
168
- run_command(create_mutagen_command.join(" "))
169
-
170
- if not create_mutagen_status.success?
171
- # mutagen prints to stdout and stderr
172
- msg = "Failed to create mutagen sessions: " \
173
- "#{create_mutagen_stdout} -" \
174
- "#{create_mutagen_stderr}"
175
- fail msg
176
- end
177
- end
178
-
179
- def watch_alpha(alpha_dir:, hostname:)
180
- watchman = Watchman.new(dir: alpha_dir)
181
- watchman.trigger("mutagen sync flush --label-selector=#{hostname}")
182
- end
183
-
184
- def name
185
- @name ||= config[:box]
186
- end
187
-
188
- def hostname
189
- [name, username, "devbox"].join("-")
190
- end
191
-
192
- def username
193
- @username ||= account.gsub(/\W/, "_")
194
- end
195
-
196
- def config
197
- return @config if @config
198
-
199
- if not CONFIG.has_key?(account)
200
- fail "No config in #{CONFIG_PATH} found for #{account}"
201
- end
202
-
203
- @config = CONFIG[account].with_indifferent_access
204
- end
205
-
206
- def run_command(command, tries: 0)
207
- Open3.capture3(command)
208
- rescue *WAIT_BOOT_RESCUED_EXCEPTIONS
209
- sleep WAIT_BOOT_IN_SECONDS
210
- run_command(command, tries+1)
211
- end
212
-
213
- end
214
- end