devbox_launcher 0.4.0 → 0.6.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.
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