vagrant-bosh 0.0.3 → 0.0.4

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.
Files changed (59) hide show
  1. data/README.md +24 -1
  2. data/dev/Vagrantfile +7 -4
  3. data/dev/example-winston-manifest.yml +2 -2
  4. data/docs/build-aws-stemcell.md +66 -0
  5. data/docs/release-url.md +39 -0
  6. data/go/src/boshprovisioner/downloader/local_fs_downloader.go +1 -1
  7. data/go/src/boshprovisioner/main/config.go +28 -13
  8. data/go/src/boshprovisioner/main/config_test.go +67 -0
  9. data/go/src/boshprovisioner/main/main.go +7 -7
  10. data/go/src/boshprovisioner/main/main_suite_test.go +13 -0
  11. data/go/src/boshprovisioner/main/repos_factory.go +0 -10
  12. data/go/src/boshprovisioner/packagescompiler/concrete_packages_compiler.go +3 -3
  13. data/go/src/boshprovisioner/provisioner/deployment_provisioner_interface.go +10 -0
  14. data/go/src/boshprovisioner/provisioner/release_compiler.go +11 -51
  15. data/go/src/boshprovisioner/provisioner/{deployment_provisioner.go → single_configured_vm_provisioner.go} +8 -12
  16. data/go/src/boshprovisioner/provisioner/single_non_configured_vm_provisioner.go +40 -0
  17. data/go/src/boshprovisioner/provisioner/single_vm_provisioner_factory.go +68 -0
  18. data/go/src/boshprovisioner/release/dir_reader.go +127 -0
  19. data/go/src/boshprovisioner/release/manifest/manifest.go +38 -14
  20. data/go/src/boshprovisioner/release/manifest/manifest_suite_test.go +13 -0
  21. data/go/src/boshprovisioner/release/manifest/manifest_test.go +72 -0
  22. data/go/src/boshprovisioner/release/manifest/syntax_validator.go +134 -0
  23. data/go/src/boshprovisioner/release/reader_factory.go +13 -2
  24. data/go/src/boshprovisioner/release/reader_interface.go +6 -0
  25. data/go/src/boshprovisioner/release/tar_reader.go +26 -24
  26. data/go/src/boshprovisioner/vm/vagrant/agent_provisioner.go +70 -40
  27. data/go/src/boshprovisioner/vm/vagrant/asset_manager.go +1 -1
  28. data/go/src/boshprovisioner/vm/vagrant/configured_vm.go +29 -0
  29. data/go/src/boshprovisioner/vm/vagrant/deps_provisioner.go +38 -24
  30. data/go/src/boshprovisioner/vm/vagrant/monit_provisioner.go +1 -1
  31. data/go/src/boshprovisioner/vm/vagrant/non_configured_vm.go +26 -0
  32. data/go/src/boshprovisioner/vm/vagrant/runit_provisioner.go +1 -1
  33. data/go/src/boshprovisioner/vm/vagrant/simple_cmds.go +1 -1
  34. data/go/src/boshprovisioner/vm/vagrant/vcap_user_provisioner.go +87 -40
  35. data/go/src/boshprovisioner/vm/vagrant/vm_provisioner.go +58 -20
  36. data/go/src/boshprovisioner/vm/vagrant/vm_provisioner_factory.go +4 -7
  37. data/go/src/boshprovisioner/vm/vm_interface.go +25 -6
  38. data/lib/vagrant-bosh/asset_uploader.rb +4 -3
  39. data/lib/vagrant-bosh/assets/agent/agent-run +4 -1
  40. data/lib/vagrant-bosh/assets/agent/bosh-agent +0 -0
  41. data/lib/vagrant-bosh/assets/provisioner +0 -0
  42. data/lib/vagrant-bosh/bootstrapper.rb +34 -21
  43. data/lib/vagrant-bosh/communicator.rb +1 -0
  44. data/lib/vagrant-bosh/config.rb +25 -1
  45. data/lib/vagrant-bosh/deployment/manifest.rb +79 -0
  46. data/lib/vagrant-bosh/deployment/manifest_factory.rb +29 -0
  47. data/lib/vagrant-bosh/deployment/release_uploader.rb +40 -0
  48. data/lib/vagrant-bosh/deployment/uploadable_release.rb +82 -0
  49. data/lib/vagrant-bosh/deployment/uploadable_release_factory.rb +28 -0
  50. data/lib/vagrant-bosh/errors.rb +1 -3
  51. data/lib/vagrant-bosh/provisioner.rb +24 -5
  52. data/lib/vagrant-bosh/ui.rb +9 -7
  53. data/lib/vagrant-bosh/version.rb +1 -1
  54. data/templates/locales/en.yml +27 -0
  55. metadata +22 -7
  56. data/go/src/boshprovisioner/release/manifest_reader.go +0 -29
  57. data/go/src/boshprovisioner/releasesrepo/blobstore_releases_repository.go +0 -114
  58. data/go/src/boshprovisioner/releasesrepo/releases_repository_interface.go +0 -15
  59. data/go/src/boshprovisioner/vm/vagrant/vm.go +0 -27
@@ -1,6 +1,8 @@
1
- package vm
1
+ package vagrant
2
2
 
3
3
  import (
4
+ "strings"
5
+
4
6
  bosherr "bosh/errors"
5
7
  boshlog "bosh/logger"
6
8
  boshsys "bosh/system"
@@ -12,20 +14,20 @@ const vcapUserProvisionerLogTag = "VCAPUserProvisioner"
12
14
 
13
15
  // VCAPUserProvisioner adds and configures vcap user.
14
16
  type VCAPUserProvisioner struct {
15
- cmds SimpleCmds
17
+ fs boshsys.FileSystem
16
18
  runner boshsys.CmdRunner
17
19
  eventLog bpeventlog.Log
18
20
  logger boshlog.Logger
19
21
  }
20
22
 
21
23
  func NewVCAPUserProvisioner(
22
- cmds SimpleCmds,
24
+ fs boshsys.FileSystem,
23
25
  runner boshsys.CmdRunner,
24
26
  eventLog bpeventlog.Log,
25
27
  logger boshlog.Logger,
26
28
  ) VCAPUserProvisioner {
27
29
  return VCAPUserProvisioner{
28
- cmds: cmds,
30
+ fs: fs,
29
31
  runner: runner,
30
32
  eventLog: eventLog,
31
33
  logger: logger,
@@ -33,7 +35,7 @@ func NewVCAPUserProvisioner(
33
35
  }
34
36
 
35
37
  func (p VCAPUserProvisioner) Provision() error {
36
- stage := p.eventLog.BeginStage("Setting up vcap user", 2)
38
+ stage := p.eventLog.BeginStage("Setting up vcap user", 3)
37
39
 
38
40
  task := stage.BeginTask("Adding vcap user")
39
41
 
@@ -42,6 +44,13 @@ func (p VCAPUserProvisioner) Provision() error {
42
44
  return bosherr.WrapError(err, "Setting up vcap user")
43
45
  }
44
46
 
47
+ task = stage.BeginTask("Configuring locales")
48
+
49
+ err = task.End(p.configureLocales())
50
+ if err != nil {
51
+ return bosherr.WrapError(err, "Configuring locales")
52
+ }
53
+
45
54
  task = stage.BeginTask("Harden permissions")
46
55
 
47
56
  err = task.End(p.hardenPermissinons())
@@ -55,65 +64,103 @@ func (p VCAPUserProvisioner) Provision() error {
55
64
  func (p VCAPUserProvisioner) setUpVcapUser() error {
56
65
  p.logger.Info(vcapUserProvisionerLogTag, "Setting up vcap user")
57
66
 
58
- userBash := `
59
- groupadd --system admin
60
- useradd -m --comment 'BOSH System User' vcap
67
+ _, stderr, _, err := p.runner.RunCommand("groupadd", "--system", "admin")
68
+ if err != nil {
69
+ if !strings.Contains(stderr, "group 'admin' already exists") {
70
+ return err
71
+ }
72
+ }
73
+
74
+ _, stderr, _, err = p.runner.RunCommand("useradd", "-m", "--comment", "BOSH System User", "vcap")
75
+ if err != nil {
76
+ if !strings.Contains(stderr, "user 'vcap' already exists") {
77
+ return err
78
+ }
79
+ }
61
80
 
62
- echo "vcap:c1oudc0w" | chpasswd
63
- echo "root:c1oudc0w" | chpasswd
81
+ cmds := [][]string{
82
+ {"bash", "-c", "echo 'vcap:c1oudc0w' | chpasswd"},
83
+ {"bash", "-c", "echo 'root:c1oudc0w' | chpasswd"},
64
84
 
65
- usermod -G admin,adm,audio,cdrom,dialout,floppy,video,dip,plugdev vcap
66
- usermod -s /bin/bash vcap
67
- `
85
+ {"usermod", "-G", "admin,adm,audio,cdrom,dialout,floppy,video,dip,plugdev", "vcap"},
86
+ {"usermod", "-s", "/bin/bash", "vcap"},
87
+ }
68
88
 
69
- err := p.cmds.Bash(userBash)
70
- if err != nil {
71
- return err
89
+ for _, cmd := range cmds {
90
+ _, _, _, err := p.runner.RunCommand(cmd[0], cmd[1:]...)
91
+ if err != nil {
92
+ return err
93
+ }
72
94
  }
73
95
 
74
96
  // todo setup vcap no-password sudo access
75
- _, _, _, err = p.runner.RunCommand("usermod", "-a", "-G", "vcap", "vagrant")
97
+
98
+ _, stderr, _, err = p.runner.RunCommand("usermod", "-a", "-G", "vcap", "vagrant")
76
99
  if err != nil {
77
- return err
100
+ if !strings.Contains(stderr, "user 'vagrant' does not exist") {
101
+ return err
102
+ }
78
103
  }
79
104
 
80
- envBashs := []string{
81
- "echo 'export PATH=/var/vcap/bosh/bin:$PATH' >> /root/.bashrc",
82
- "echo 'export PATH=/var/vcap/bosh/bin:$PATH' >> /home/vcap/.bashrc",
105
+ return p.setUpBoshBinPath()
106
+ }
83
107
 
84
- // Configure vcap user locale (postgres initdb fails if mismatched)
85
- "echo 'LANG=en_US.UTF-8\nLC_ALL=en_US.UTF-8' > /etc/default/locale",
86
- }
108
+ func (p VCAPUserProvisioner) setUpBoshBinPath() error {
109
+ boshBinExport := "export PATH=/var/vcap/bosh/bin:$PATH"
87
110
 
88
- for _, bash := range envBashs {
89
- err := p.cmds.Bash(bash)
111
+ for _, bashrcPath := range []string{"/root/.bashrc", "/home/vcap/.bashrc"} {
112
+ contents, err := p.fs.ReadFileString(bashrcPath)
90
113
  if err != nil {
91
114
  return err
92
115
  }
116
+
117
+ if !strings.Contains(contents, boshBinExport) {
118
+ err := p.fs.WriteFileString(bashrcPath, contents+"\n"+boshBinExport+"\n")
119
+ if err != nil {
120
+ return err
121
+ }
122
+ }
93
123
  }
94
124
 
95
125
  return nil
96
126
  }
97
127
 
128
+ func (p VCAPUserProvisioner) configureLocales() error {
129
+ _, _, _, err := p.runner.RunCommand("locale-gen", "en_US.UTF-8")
130
+ if err != nil {
131
+ return err
132
+ }
133
+
134
+ _, _, _, err = p.runner.RunCommand("dpkg-reconfigure", "locales")
135
+ if err != nil {
136
+ return err
137
+ }
138
+
139
+ // Configure vcap user locale (postgres initdb fails if mismatched)
140
+ return p.fs.WriteFileString("/etc/default/locale", "LANG=en_US.UTF-8\nLC_ALL=en_US.UTF-8")
141
+ }
142
+
98
143
  func (p VCAPUserProvisioner) hardenPermissinons() error {
99
- permsBash := `
100
- echo 'vcap' > /etc/cron.allow
101
- echo 'vcap' > /etc/at.allow
144
+ cmds := [][]string{
145
+ {"bash", "-c", "echo 'vcap' > /etc/cron.allow"},
146
+ {"bash", "-c", "echo 'vcap' > /etc/at.allow"},
102
147
 
103
- chmod 0770 /var/lock
104
- chown -h root:vcap /var/lock
105
- chown -LR root:vcap /var/lock
148
+ {"chmod", "0770", "/var/lock"},
149
+ {"chown", "-h", "root:vcap", "/var/lock"},
150
+ {"chown", "-LR", "root:vcap", "/var/lock"},
106
151
 
107
- chmod 0640 /etc/cron.allow
108
- chown root:vcap /etc/cron.allow
152
+ {"chmod", "0640", "/etc/cron.allow"},
153
+ {"chown", "root:vcap", "/etc/cron.allow"},
109
154
 
110
- chmod 0640 /etc/at.allow
111
- chown root:vcap /etc/at.allow
112
- `
155
+ {"chmod", "0640", "/etc/at.allow"},
156
+ {"chown", "root:vcap", "/etc/at.allow"},
157
+ }
113
158
 
114
- err := p.cmds.Bash(permsBash)
115
- if err != nil {
116
- return err
159
+ for _, cmd := range cmds {
160
+ _, _, _, err := p.runner.RunCommand(cmd[0], cmd[1:]...)
161
+ if err != nil {
162
+ return err
163
+ }
117
164
  }
118
165
 
119
166
  return nil
@@ -1,4 +1,4 @@
1
- package vm
1
+ package vagrant
2
2
 
3
3
  import (
4
4
  bosherr "bosh/errors"
@@ -8,6 +8,11 @@ import (
8
8
  bpvm "boshprovisioner/vm"
9
9
  )
10
10
 
11
+ var (
12
+ ErrAlreadyProvisioned = bosherr.New("Vagrant VM is already provisioned")
13
+ ErrNotProvisioned = bosherr.New("Vagrant VM is not provisioned")
14
+ )
15
+
11
16
  // VMProvisioner installs system dependencies that are usually
12
17
  // found on a stemcell, adds vcap user and finally install Agent and Monit.
13
18
  type VMProvisioner struct {
@@ -18,12 +23,16 @@ type VMProvisioner struct {
18
23
  // Cannot provision more than 1 VM at a time until previous VM is deprovisioned.
19
24
  vmProvisioned bool
20
25
 
21
- // Remember if we have recently run provisioning for a VM to skip it next time
26
+ // Remember if we have recently run provisioning for a VM to skip it next time.
22
27
  vmPreviouslyProvisioned bool
23
28
 
24
29
  logger boshlog.Logger
25
30
  }
26
31
 
32
+ type vagrantVM interface {
33
+ vagrantVM()
34
+ }
35
+
27
36
  func NewVMProvisioner(
28
37
  vcapUserProvisioner VCAPUserProvisioner,
29
38
  depsProvisioner DepsProvisioner,
@@ -40,42 +49,71 @@ func NewVMProvisioner(
40
49
  }
41
50
 
42
51
  func (p *VMProvisioner) Provision(instance bpdep.Instance) (bpvm.VM, error) {
43
- var vm VM
44
-
45
52
  if p.vmProvisioned {
46
- return vm, bosherr.New("Vagrant VM is already provisioned")
53
+ return nil, ErrAlreadyProvisioned
47
54
  }
48
55
 
49
- if !p.vmPreviouslyProvisioned {
50
- err := p.vcapUserProvisioner.Provision()
51
- if err != nil {
52
- return vm, bosherr.WrapError(err, "Provisioning vcap user")
53
- }
56
+ err := p.provisionNonConfigured()
57
+ if err != nil {
58
+ return nil, err
59
+ }
54
60
 
55
- err = p.depsProvisioner.Provision()
56
- if err != nil {
57
- return vm, bosherr.WrapError(err, "Provisioning dependencies")
58
- }
61
+ agentClient, err := p.agentProvisioner.Configure(instance)
62
+ if err != nil {
63
+ return nil, bosherr.WrapError(err, "Configuring agent")
59
64
  }
60
65
 
61
- p.vmPreviouslyProvisioned = true
66
+ // Set this as late as possible so that caller can retry failed provisioning attempts.
67
+ p.vmProvisioned = true
68
+
69
+ return NewConfiguredVM(p, agentClient), nil
70
+ }
71
+
72
+ func (p *VMProvisioner) ProvisionNonConfigured() (bpvm.VM, error) {
73
+ if p.vmProvisioned {
74
+ return nil, ErrAlreadyProvisioned
75
+ }
62
76
 
63
- agentClient, err := p.agentProvisioner.Provision(instance)
77
+ err := p.provisionNonConfigured()
64
78
  if err != nil {
65
- return vm, bosherr.WrapError(err, "Provisioning agent")
79
+ return nil, err
66
80
  }
67
81
 
82
+ // Set this as late as possible so that caller can retry failed provisioning attempts.
68
83
  p.vmProvisioned = true
69
84
 
70
- return NewVM(p, agentClient), nil
85
+ return NewNonConfiguredVM(p), nil
71
86
  }
72
87
 
73
- func (p *VMProvisioner) Deprovision(vm VM) error {
88
+ func (p *VMProvisioner) deprovision(vm vagrantVM) error {
74
89
  if !p.vmProvisioned {
75
- return bosherr.New("Vagrant VM is not provisioned")
90
+ return ErrNotProvisioned
76
91
  }
77
92
 
78
93
  p.vmProvisioned = false
79
94
 
80
95
  return nil
81
96
  }
97
+
98
+ func (p *VMProvisioner) provisionNonConfigured() error {
99
+ if !p.vmPreviouslyProvisioned {
100
+ err := p.vcapUserProvisioner.Provision()
101
+ if err != nil {
102
+ return bosherr.WrapError(err, "Provisioning vcap user")
103
+ }
104
+
105
+ err = p.depsProvisioner.Provision()
106
+ if err != nil {
107
+ return bosherr.WrapError(err, "Provisioning dependencies")
108
+ }
109
+ }
110
+
111
+ p.vmPreviouslyProvisioned = true
112
+
113
+ err := p.agentProvisioner.Provision()
114
+ if err != nil {
115
+ return bosherr.WrapError(err, "Provisioning agent")
116
+ }
117
+
118
+ return nil
119
+ }
@@ -1,4 +1,4 @@
1
- package vm
1
+ package vagrant
2
2
 
3
3
  import (
4
4
  boshlog "bosh/logger"
@@ -26,7 +26,6 @@ func NewVMProvisionerFactory(
26
26
  fs boshsys.FileSystem,
27
27
  runner boshsys.CmdRunner,
28
28
  assetsDir string,
29
- mbus string,
30
29
  blobstoreConfig map[string]interface{},
31
30
  vmProvisionerConfig bpvm.VMProvisionerConfig,
32
31
  eventLog bpeventlog.Log,
@@ -36,9 +35,7 @@ func NewVMProvisionerFactory(
36
35
  fs: fs,
37
36
  runner: runner,
38
37
 
39
- assetsDir: assetsDir,
40
- mbus: mbus,
41
-
38
+ assetsDir: assetsDir,
42
39
  blobstoreConfig: blobstoreConfig,
43
40
  vmProvisionerConfig: vmProvisionerConfig,
44
41
 
@@ -51,7 +48,7 @@ func (f VMProvisionerFactory) NewVMProvisioner() *VMProvisioner {
51
48
  cmds := NewSimpleCmds(f.runner, f.logger)
52
49
 
53
50
  vcapUserProvisioner := NewVCAPUserProvisioner(
54
- cmds,
51
+ f.fs,
55
52
  f.runner,
56
53
  f.eventLog,
57
54
  f.logger,
@@ -88,7 +85,7 @@ func (f VMProvisionerFactory) NewVMProvisioner() *VMProvisioner {
88
85
  runitProvisioner,
89
86
  monitProvisioner,
90
87
  f.blobstoreConfig,
91
- f.mbus,
88
+ f.vmProvisionerConfig.AgentProvisioner,
92
89
  f.eventLog,
93
90
  f.logger,
94
91
  )
@@ -6,15 +6,12 @@ import (
6
6
  )
7
7
 
8
8
  type VMProvisioner interface {
9
- // Provision creates and configures VM to be usable by BOSH releases.
9
+ // Provision creates and configures VM for future agent communication.
10
10
  // todo should not rely on bpdep.Instance
11
11
  Provision(bpdep.Instance) (VM, error)
12
- }
13
12
 
14
- type VMProvisionerConfig struct {
15
- // When provisioning, install all dependencies that official stemcells carry.
16
- // By default, provisioners will only install absolutely needed dependencies.
17
- FullStemcellCompatibility bool `json:"full_stemcell_compatibility"`
13
+ // ProvisionNonConfigured creates and does NOT configure VM for communication.
14
+ ProvisionNonConfigured() (VM, error)
18
15
  }
19
16
 
20
17
  type VM interface {
@@ -24,3 +21,25 @@ type VM interface {
24
21
  // Deprovision deletes VM previously provisioned VM.
25
22
  Deprovision() error
26
23
  }
24
+
25
+ type VMProvisionerConfig struct {
26
+ // When provisioning, install all dependencies that official stemcells carry.
27
+ // By default, provisioners will only install absolutely needed dependencies.
28
+ FullStemcellCompatibility bool `json:"full_stemcell_compatibility"`
29
+
30
+ AgentProvisioner AgentProvisionerConfig `json:"agent_provisioner"`
31
+ }
32
+
33
+ type AgentProvisionerConfig struct {
34
+ // e.g. warden, aws
35
+ Infrastructure string `json:"infrastructure"`
36
+
37
+ // e.g. ubuntu, centos
38
+ Platform string `json:"platform"`
39
+
40
+ // Usually save to /var/vcap/bosh/agent.json
41
+ Configuration map[string]interface{} `json:"configuration"`
42
+
43
+ // e.g. "https://user:password@127.0.0.1:4321/agent"
44
+ Mbus string `json:"mbus"`
45
+ }
@@ -5,16 +5,17 @@ require "securerandom"
5
5
  module VagrantPlugins
6
6
  module VagrantBosh
7
7
  class AssetUploader
8
- def initialize(communicator, ui, assets_path)
8
+ def initialize(communicator, assets_dir, ui)
9
9
  @c = communicator
10
+ @assets_dir = assets_dir
11
+
10
12
  @ui = ui.for(:asset_uploader)
11
- @assets_path = assets_path
12
13
  @logger = Log4r::Logger.new("vagrant::provisioners::bosh::asset_uploader")
13
14
  end
14
15
 
15
16
  def sync(dst_path)
16
17
  @ui.timed_msg(:upload, dst_path: dst_path) do
17
- upload_path(@assets_path, dst_path)
18
+ upload_path(@assets_dir, dst_path)
18
19
  end
19
20
  end
20
21
 
@@ -9,4 +9,7 @@ exec 2>&1
9
9
  # Get into directory with agent.{cert,key}
10
10
  cd /var/vcap/bosh
11
11
 
12
- exec nice -n -10 /var/vcap/bosh/bin/bosh-agent -I warden -P ubuntu -C /var/vcap/bosh/agent.json
12
+ exec nice -n -10 /var/vcap/bosh/bin/bosh-agent \
13
+ -I $(cat /var/vcap/bosh/etc/infrastructure) \
14
+ -P $(cat /var/vcap/bosh/etc/platform) \
15
+ -C /var/vcap/bosh/agent.json
Binary file
@@ -4,57 +4,70 @@ require "json"
4
4
  module VagrantPlugins
5
5
  module VagrantBosh
6
6
  class Bootstrapper
7
- def initialize(communicator, asset_uploader, base_dir, config, provisioner_tracker)
7
+ def initialize(communicator, config, asset_uploader, provisioner_tracker, manifest_factory)
8
8
  @c = communicator
9
- @asset_uploader = asset_uploader
10
- @base_dir = base_dir
11
9
  @config = config
10
+ @asset_uploader = asset_uploader
12
11
  @provisioner_tracker = provisioner_tracker
13
- @logger = Log4r::Logger.new("vagrant::provisioners::bosh::bootstrapper")
12
+ @manifest_factory = manifest_factory
14
13
 
15
- @assets_path = File.join(@base_dir, "assets")
16
- @repos_path = File.join(@base_dir, "repos")
17
- @manifest_path = File.join(@base_dir, "manifest.yml")
18
- @config_path = File.join(@base_dir, "config.json")
14
+ @logger = Log4r::Logger.new("vagrant::provisioners::bosh::bootstrapper")
19
15
  end
20
16
 
21
17
  def bootstrap
22
- @asset_uploader.sync(@assets_path)
18
+ @asset_uploader.sync(@config.assets_dir)
23
19
 
24
- @asset_uploader.upload_text(@config.manifest, @manifest_path)
20
+ if @config.manifest
21
+ manifest = @manifest_factory.new_manifest(@config.manifest)
22
+ manifest.resolve_releases
23
+ @asset_uploader.upload_text(manifest.as_string, @config.manifest_path)
24
+ end
25
25
 
26
26
  config_json = JSON.dump(config_hash)
27
- @asset_uploader.upload_text(config_json, @config_path)
27
+ @asset_uploader.upload_text(config_json, @config.config_path)
28
+
29
+ run_provisioner
30
+ end
31
+
32
+ private
28
33
 
34
+ def run_provisioner
29
35
  # Provisioner is already uploaded when assets are synced
30
- provisioner_path = File.join(@assets_path, "provisioner")
36
+ provisioner_path = File.join(@config.assets_dir, "provisioner")
31
37
  @c.chmod_x(provisioner_path)
32
38
 
33
39
  @c.sudo(
34
- "#{provisioner_path} -configPath=#{@config_path} 2> >(tee /tmp/provisioner.log >&2)",
40
+ "#{provisioner_path} -configPath=#{@config.config_path} 2> >(tee /tmp/provisioner.log >&2)",
35
41
  &@provisioner_tracker.method(:add_data)
36
42
  )
37
43
  end
38
44
 
39
- private
40
-
41
45
  def config_hash
42
46
  {
43
- manifest_path: @manifest_path,
44
- assets_dir: @assets_path,
45
- repos_dir: @repos_path,
46
-
47
- mbus: "https://user:password@127.0.0.1:4321/agent",
47
+ assets_dir: @config.assets_dir,
48
+ repos_dir: @config.repos_dir,
48
49
 
49
50
  blobstore: {
50
51
  provider: "local",
51
52
  options: {
52
- blobstore_path: File.join(@base_dir, "blobstore"),
53
+ blobstore_path: @config.local_blobstore_dir,
53
54
  },
54
55
  },
55
56
 
56
57
  vm_provisioner: {
57
58
  full_stemcell_compatibility: @config.full_stemcell_compatibility,
59
+
60
+ agent_provisioner: {
61
+ infrastructure: @config.agent_infrastructure,
62
+ platform: @config.agent_platform,
63
+ configuration: @config.agent_configuration,
64
+
65
+ mbus: "https://user:password@127.0.0.1:4321/agent",
66
+ },
67
+ },
68
+
69
+ deployment_provisioner: {
70
+ manifest_path: (@config.manifest_path if @config.manifest),
58
71
  },
59
72
  }
60
73
  end
@@ -5,6 +5,7 @@ module VagrantPlugins
5
5
  class Communicator
6
6
  def initialize(machine, ui)
7
7
  @c = machine.communicate
8
+
8
9
  @ui = ui.for(:communicator)
9
10
  @logger = Log4r::Logger.new("vagrant::provisioners::bosh::communicator")
10
11
  end
@@ -3,6 +3,14 @@ require "vagrant"
3
3
  module VagrantPlugins
4
4
  module VagrantBosh
5
5
  class Config < Vagrant.plugin("2", :config)
6
+ attr_accessor :base_dir
7
+
8
+ attr_reader :assets_dir, :repos_dir
9
+
10
+ attr_reader :manifest_path, :config_path
11
+
12
+ attr_reader :local_blobstore_dir, :synced_releases_dir
13
+
6
14
  # Manifest holds full BOSH deployment manifest as a string.
7
15
  attr_accessor :manifest
8
16
 
@@ -10,8 +18,24 @@ module VagrantPlugins
10
18
  # (not just minimum) dependencies usually found on a stemcell.
11
19
  attr_accessor :full_stemcell_compatibility
12
20
 
21
+ attr_accessor :agent_infrastructure, :agent_platform, :agent_configuration
22
+
23
+ def initialize(*args)
24
+ super
25
+ @base_dir = "/opt/vagrant-bosh"
26
+ end
27
+
13
28
  def finalize!
14
- self.full_stemcell_compatibility = !!self.full_stemcell_compatibility
29
+ @assets_dir = File.join(@base_dir, "assets")
30
+ @repos_dir = File.join(@base_dir, "repos")
31
+
32
+ @manifest_path = File.join(@base_dir, "manifest.yml")
33
+ @config_path = File.join(@base_dir, "config.json")
34
+
35
+ @local_blobstore_dir = File.join(@base_dir, "blobstore")
36
+ @synced_releases_dir = File.join(@base_dir, "synced-releases")
37
+
38
+ @full_stemcell_compatibility = !!@full_stemcell_compatibility
15
39
  end
16
40
 
17
41
  def validate(machine)
@@ -0,0 +1,79 @@
1
+ require "log4r"
2
+ require "yaml"
3
+
4
+ module VagrantPlugins
5
+ module VagrantBosh
6
+ module Deployment
7
+ class Manifest
8
+ def initialize(manifest, uploadable_release_factory, ui)
9
+ @manifest = manifest
10
+ @uploadable_release_factory = uploadable_release_factory
11
+
12
+ @ui = ui.for(:deployment, :manifest)
13
+ @logger = Log4r::Logger.new("vagrant::provisioners::bosh::deployment::manifest")
14
+ end
15
+
16
+ # Syncs releases to guest FS and rewrites manifest to reference guest FS locations.
17
+ def resolve_releases
18
+ uploaded_releases = uploadable_releases.map(&:upload)
19
+
20
+ parsed_releases.each do |release|
21
+ uploaded_releases.each do |uploaded_release|
22
+ if release["name"] == uploaded_release.name
23
+ release.merge!(uploaded_release.as_hash)
24
+ end
25
+ end
26
+ end
27
+
28
+ nil # ah
29
+ end
30
+
31
+ def as_string
32
+ YAML.dump(parsed_manifest)
33
+ end
34
+
35
+ private
36
+
37
+ # Returns releases with url matching `dir+bosh://...`
38
+ def uploadable_releases
39
+ parsed_releases.map { |release|
40
+ next unless url = release["url"]
41
+ next unless url =~ %r{\Adir\+bosh://(.+)\z}
42
+
43
+ @uploadable_release_factory.new_uploadable_release(
44
+ release["name"],
45
+ release["version"],
46
+ $1, # host_dir
47
+ )
48
+ }.compact
49
+ end
50
+
51
+ def parsed_releases
52
+ parsed_manifest["releases"] || []
53
+ end
54
+
55
+ def parsed_manifest
56
+ return @parsed_manifest if @parsed_manifest
57
+
58
+ begin
59
+ @parsed_manifest = YAML.load(@manifest)
60
+ rescue SyntaxError => e
61
+ error_msg = @ui.msg_string(:parse_error, details: e.inspect)
62
+ raise VagrantPlugins::VagrantBosh::Errors::BoshReleaseError, error_msg
63
+ end
64
+
65
+ unless @parsed_manifest.is_a?(Hash)
66
+ error_msg = @ui.msg_string(:non_hash_class_error, {
67
+ actual_class: parsed_manifest.class.to_s,
68
+ })
69
+ raise VagrantPlugins::VagrantBosh::Errors::BoshReleaseError, error_msg
70
+ end
71
+
72
+ @parsed_manifest
73
+ end
74
+ end
75
+
76
+ #~
77
+ end
78
+ end
79
+ end