heighliner 0.9.0 → 0.10.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 +4 -4
- data/README.md +12 -0
- data/lib/heighliner/cli.rb +89 -58
- data/lib/heighliner/config.rb +27 -4
- data/lib/heighliner/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 07c572f9013340944a13b0fb7a784e97e4d9e589bddd9937d60df842346f9d80
|
|
4
|
+
data.tar.gz: 8d9c848d91867755298a95474fc53225f04d5bed4a7811f681b86b6930260300
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26b7a442e80ee8249f08a854faa624f03b6af32845f151958f12fd35c162755f10642d9a098d0bbe76922f975feca0525fe9ba6a814abc9f74d1e6055eb0c028
|
|
7
|
+
data.tar.gz: 971f71b9a51aa4e27404289f2b8d61614168e0a59a83da1189d4ee2c6569500cfef412b968657e0338d3d185f7da74311ded0c074591078a0cbf59bb1bd1c9fc
|
data/README.md
CHANGED
|
@@ -112,6 +112,12 @@ open http://myapp.lvh.me
|
|
|
112
112
|
|
|
113
113
|
And enjoy previewing your app!
|
|
114
114
|
|
|
115
|
+
## Examples
|
|
116
|
+
|
|
117
|
+
See the [examples](examples/) directory for starter projects:
|
|
118
|
+
|
|
119
|
+
- [simple](examples/simple/) — a minimal Sinatra + Puma app
|
|
120
|
+
|
|
115
121
|
## More documentation
|
|
116
122
|
|
|
117
123
|
You can find even more documentation in https://davidsiaw.github.io/heighliner.
|
|
@@ -145,6 +151,9 @@ alias heighliner='docker run --rm -ti \
|
|
|
145
151
|
-e _HEIGHLINER_USER_HOME=$HOME \
|
|
146
152
|
-e _HEIGHLINER_POS=docker \
|
|
147
153
|
-e CONTEXT_DIR="`pwd`" \
|
|
154
|
+
-e GIT_CONFIG_COUNT=1 \
|
|
155
|
+
-e GIT_CONFIG_KEY_0=safe.directory \
|
|
156
|
+
-e GIT_CONFIG_VALUE_0="$PWD" \
|
|
148
157
|
davidsiaw/heighliner'
|
|
149
158
|
```
|
|
150
159
|
|
|
@@ -163,6 +172,9 @@ alias heighliner='docker run --rm -ti \
|
|
|
163
172
|
-e _HEIGHLINER_USER_HOME=$HOME \
|
|
164
173
|
-e _HEIGHLINER_POS=docker \
|
|
165
174
|
-e CONTEXT_DIR="`pwd`" \
|
|
175
|
+
-e GIT_CONFIG_COUNT=1 \
|
|
176
|
+
-e GIT_CONFIG_KEY_0=safe.directory \
|
|
177
|
+
-e GIT_CONFIG_VALUE_0="$PWD" \
|
|
166
178
|
-e OP_SERVICE_ACCOUNT_TOKEN=`op read op://Private/local-dev/credential` \
|
|
167
179
|
davidsiaw/heighliner'
|
|
168
180
|
```
|
data/lib/heighliner/cli.rb
CHANGED
|
@@ -503,60 +503,76 @@ module Heighliner
|
|
|
503
503
|
|
|
504
504
|
def copy_keyfile(file)
|
|
505
505
|
Config.info_out.puts "Loading certificate file: #{file}"
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
field = origfield
|
|
526
|
-
if Config.config[:cert_source]["1password-fields"]
|
|
527
|
-
field = Config.config[:cert_source]["1password-fields"][origfield]
|
|
528
|
-
end
|
|
506
|
+
cert_source = Config.config[:cert_source]
|
|
507
|
+
|
|
508
|
+
if cert_source[:folder]
|
|
509
|
+
copy_keyfile_from_folder(file)
|
|
510
|
+
elsif cert_source[:url]
|
|
511
|
+
copy_keyfile_from_url(file)
|
|
512
|
+
elsif cert_source[:"1password"]
|
|
513
|
+
copy_keyfile_from_1password(file)
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def copy_keyfile_from_folder(file)
|
|
518
|
+
folder = Config.config[:cert_source][:folder]
|
|
519
|
+
Config.info_out.puts " Source: folder (#{folder})"
|
|
520
|
+
CommandRunner.run! Config.out, "docker run --rm
|
|
521
|
+
-v #{Config.config[:shared_names][:certs]}:/certs
|
|
522
|
+
-v #{folder}:/cert_source
|
|
523
|
+
alpine cp /cert_source/#{file} /certs/#{file}"
|
|
524
|
+
end
|
|
529
525
|
|
|
530
|
-
|
|
526
|
+
def copy_keyfile_from_url(file)
|
|
527
|
+
url = Config.config[:cert_source][:url]
|
|
528
|
+
Config.info_out.puts " Source: URL (#{url}/#{file})"
|
|
529
|
+
CommandRunner.run! Config.out, "docker run --rm
|
|
530
|
+
-v #{Config.config[:shared_names][:certs]}:/certs
|
|
531
|
+
alpine wget #{url}/#{file}
|
|
532
|
+
-O /certs/#{file}"
|
|
533
|
+
end
|
|
531
534
|
|
|
532
|
-
|
|
535
|
+
def onepassword_field_for(file)
|
|
536
|
+
origfield = file.sub(/^#{http_suffix}\./, '')
|
|
537
|
+
fields = Config.config[:cert_source]['1password-fields']
|
|
538
|
+
field = fields ? fields[origfield] : origfield
|
|
539
|
+
[origfield, field]
|
|
540
|
+
end
|
|
533
541
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
CommandRunner.run!(Config.out, "mkdir -p #{certstoredir}")
|
|
538
|
-
CommandRunner.run!(Config.out, "op read \"op://#{item}/#{field}\" > #{tmpfile}")
|
|
539
|
-
Config.info_out.puts("wrote into file #{tmpfile}")
|
|
540
|
-
CommandRunner.run!(Config.out, "ls #{tmpfile}")
|
|
542
|
+
def copy_keyfile_from_1password(file)
|
|
543
|
+
item = Config.config[:cert_source][:"1password"]
|
|
544
|
+
origfield, field = onepassword_field_for(file)
|
|
541
545
|
|
|
542
|
-
|
|
543
|
-
CommandRunner.run! Config.out, "docker run --rm
|
|
544
|
-
-v #{Config.config[:shared_names][:certs]}:/certs
|
|
545
|
-
-v #{certstoredir}:/tmpcert
|
|
546
|
-
alpine
|
|
547
|
-
cp /tmpcert/#{file} /certs/#{file}"
|
|
546
|
+
raise Heighliner::Error, 'OP_SERVICE_ACCOUNT_TOKEN is not set' unless ENV['OP_SERVICE_ACCOUNT_TOKEN']
|
|
548
547
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
548
|
+
Config.info_out.puts " Source: 1Password (item: #{item}, field: #{field} (#{origfield}) )"
|
|
549
|
+
|
|
550
|
+
certstoredir = "#{ENV['CONTEXT_DIR']}/.tmp.certstore"
|
|
551
|
+
tmpfile = "#{certstoredir}/#{file}"
|
|
553
552
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
553
|
+
# take it out
|
|
554
|
+
CommandRunner.run!(Config.out, "mkdir -p #{certstoredir}")
|
|
555
|
+
CommandRunner.run!(Config.out, "op read \"op://#{item}/#{field}\" > #{tmpfile}")
|
|
556
|
+
Config.info_out.puts("wrote into file #{tmpfile}")
|
|
557
|
+
CommandRunner.run!(Config.out, "ls #{tmpfile}")
|
|
558
|
+
|
|
559
|
+
# put it in
|
|
560
|
+
CommandRunner.run! Config.out, "docker run --rm
|
|
561
|
+
-v #{Config.config[:shared_names][:certs]}:/certs
|
|
562
|
+
-v #{certstoredir}:/tmpcert
|
|
563
|
+
alpine
|
|
564
|
+
cp /tmpcert/#{file} /certs/#{file}"
|
|
565
|
+
|
|
566
|
+
unless File.exist?(tmpfile) && File.size(tmpfile).positive?
|
|
567
|
+
raise Heighliner::Error,
|
|
568
|
+
"1Password field '#{field}' not found in item '#{item}'"
|
|
559
569
|
end
|
|
570
|
+
|
|
571
|
+
CommandRunner.run! Config.out, "docker run --rm
|
|
572
|
+
-v #{Config.config[:shared_names][:certs]}:/certs
|
|
573
|
+
-v #{tmpfile}:/cert_source
|
|
574
|
+
alpine cp /cert_source /certs/#{file}"
|
|
575
|
+
CommandRunner.run!(Config.out, "rm #{tmpfile}")
|
|
560
576
|
end
|
|
561
577
|
|
|
562
578
|
def prepare_cert_volume!
|
|
@@ -596,8 +612,6 @@ module Heighliner
|
|
|
596
612
|
def ensure_setup
|
|
597
613
|
ensure_env
|
|
598
614
|
|
|
599
|
-
setup if network.nil?
|
|
600
|
-
|
|
601
615
|
create_if_network_not_exist Config.config[:networkname]
|
|
602
616
|
if_container_dead Config.config[:shared_names][:nginx] do
|
|
603
617
|
prepare_cert_volume!
|
|
@@ -615,8 +629,11 @@ module Heighliner
|
|
|
615
629
|
jwilder/nginx-proxy"
|
|
616
630
|
)
|
|
617
631
|
|
|
618
|
-
|
|
619
|
-
|
|
632
|
+
# The config dir is ~/.kaiser on hosts upgraded from Kaiser, so derive the
|
|
633
|
+
# directory name instead of hardcoding .heighliner.
|
|
634
|
+
config_dir_name = File.basename(Config.config_dir)
|
|
635
|
+
innerdnsconffile = "#{Config.config_dir}/dnsconf"
|
|
636
|
+
outerdnsconffile = "#{home_dir_loc}/#{config_dir_name}/dnsconf"
|
|
620
637
|
File.write(innerdnsconffile, <<~HOSTS)
|
|
621
638
|
log-queries
|
|
622
639
|
no-resolv
|
|
@@ -656,8 +673,20 @@ module Heighliner
|
|
|
656
673
|
`docker inspect -f '{{#{networkname}}}' #{containername}`.chomp
|
|
657
674
|
end
|
|
658
675
|
|
|
659
|
-
def
|
|
660
|
-
`docker network inspect #{
|
|
676
|
+
def network_inspect_output(net)
|
|
677
|
+
`docker network inspect #{net} 2>/dev/null`
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
def network_exists?(net)
|
|
681
|
+
out = network_inspect_output(net)
|
|
682
|
+
return false if out.strip.empty?
|
|
683
|
+
|
|
684
|
+
!JSON.parse(out).empty?
|
|
685
|
+
rescue JSON::ParserError
|
|
686
|
+
# Unparseable output is not evidence the network is absent, and guessing
|
|
687
|
+
# "absent" is the expensive guess: creating an existing network exits 1 and
|
|
688
|
+
# kills the command. Assume present and let docker report a real problem.
|
|
689
|
+
true
|
|
661
690
|
end
|
|
662
691
|
|
|
663
692
|
def container_dead?(container)
|
|
@@ -679,12 +708,14 @@ module Heighliner
|
|
|
679
708
|
end
|
|
680
709
|
|
|
681
710
|
def create_if_network_not_exist(net)
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
711
|
+
return if network_exists?(net)
|
|
712
|
+
|
|
713
|
+
# Another heighliner process may create the network between the check and
|
|
714
|
+
# here, so a failure is not fatal by itself: re-check instead of raising.
|
|
715
|
+
CommandRunner.run Config.out, "docker network create #{net}"
|
|
716
|
+
return if network_exists?(net)
|
|
686
717
|
|
|
687
|
-
|
|
718
|
+
raise Heighliner::Error, "could not create docker network #{net}"
|
|
688
719
|
end
|
|
689
720
|
|
|
690
721
|
def run_if_dead(container, command)
|
data/lib/heighliner/config.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Heighliner
|
|
|
14
14
|
|
|
15
15
|
def load(work_dir, use_steerfile: true)
|
|
16
16
|
@work_dir = work_dir
|
|
17
|
-
@config_dir =
|
|
17
|
+
@config_dir = detect_config_dir
|
|
18
18
|
|
|
19
19
|
migrate_dotted_config_files
|
|
20
20
|
|
|
@@ -38,9 +38,7 @@ module Heighliner
|
|
|
38
38
|
load_config
|
|
39
39
|
|
|
40
40
|
if use_steerfile
|
|
41
|
-
|
|
42
|
-
@fname = x if File.exist?(x)
|
|
43
|
-
end
|
|
41
|
+
@fname = detect_steerfile_name
|
|
44
42
|
|
|
45
43
|
Optimist.die <<~ERROR if @fname.nil?
|
|
46
44
|
No Steerfile in current directory.
|
|
@@ -53,16 +51,41 @@ module Heighliner
|
|
|
53
51
|
@config
|
|
54
52
|
end
|
|
55
53
|
|
|
54
|
+
# Later entries win over earlier ones, so the legacy Kaiser name comes
|
|
55
|
+
# first: a repo with both files uses the Steerfile.
|
|
56
56
|
POSSIBLE_STEERFILES = %w[
|
|
57
|
+
Kaiserfile
|
|
57
58
|
Steerfile
|
|
58
59
|
Heighliner.config
|
|
59
60
|
heighliner.config
|
|
60
61
|
].freeze
|
|
61
62
|
|
|
63
|
+
# Kaiserfile is the name Heighliner used when it was called Kaiser. It has
|
|
64
|
+
# the same contents as a Steerfile, so it is loaded the same way.
|
|
65
|
+
def detect_steerfile_name
|
|
66
|
+
POSSIBLE_STEERFILES.select { |x| File.exist?(x) }.last
|
|
67
|
+
end
|
|
68
|
+
|
|
62
69
|
def always_verbose?
|
|
63
70
|
@config[:always_verbose]
|
|
64
71
|
end
|
|
65
72
|
|
|
73
|
+
# Heighliner used to be called Kaiser. If a user has an old ~/.kaiser
|
|
74
|
+
# directory and no ~/.heighliner directory yet, keep using the old one
|
|
75
|
+
# instead of starting from scratch.
|
|
76
|
+
def detect_config_dir
|
|
77
|
+
heighliner_dir = "#{home_dir}/.heighliner"
|
|
78
|
+
kaiser_dir = "#{home_dir}/.kaiser"
|
|
79
|
+
|
|
80
|
+
return kaiser_dir if !Dir.exist?(heighliner_dir) && Dir.exist?(kaiser_dir)
|
|
81
|
+
|
|
82
|
+
heighliner_dir
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def home_dir
|
|
86
|
+
ENV['HOME']
|
|
87
|
+
end
|
|
88
|
+
|
|
66
89
|
# Up until version 0.5.1, heighliner used dotfiles for all of it configuration.
|
|
67
90
|
# It makes sense of hide the configuration directory itself but hiding the files
|
|
68
91
|
# inside of it just causes confusion.
|
data/lib/heighliner/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: heighliner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Siaw
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|