PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/config/legacy_deployment_state_migrator.go

https://gitlab.com/JamesClonk/bosh-init
Go | 168 lines | 138 code | 29 blank | 1 comment | 30 complexity | 763576824fcfa637da43e2dc9bf378cd MD5 | raw file
  1. package config
  2. import (
  3. "github.com/cloudfoundry/bosh-init/internal/gopkg.in/yaml.v2"
  4. "path"
  5. "regexp"
  6. bosherr "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/errors"
  7. boshlog "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/logger"
  8. biproperty "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/property"
  9. boshsys "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/system"
  10. boshuuid "github.com/cloudfoundry/bosh-init/internal/github.com/cloudfoundry/bosh-utils/uuid"
  11. )
  12. type LegacyDeploymentStateMigrator interface {
  13. MigrateIfExists(configPath string) (migrated bool, err error)
  14. }
  15. type legacyDeploymentStateMigrator struct {
  16. deploymentStateService DeploymentStateService
  17. fs boshsys.FileSystem
  18. uuidGenerator boshuuid.Generator
  19. logger boshlog.Logger
  20. logTag string
  21. }
  22. func NewLegacyDeploymentStateMigrator(
  23. deploymentStateService DeploymentStateService,
  24. fs boshsys.FileSystem,
  25. uuidGenerator boshuuid.Generator,
  26. logger boshlog.Logger,
  27. ) LegacyDeploymentStateMigrator {
  28. return &legacyDeploymentStateMigrator{
  29. deploymentStateService: deploymentStateService,
  30. fs: fs,
  31. uuidGenerator: uuidGenerator,
  32. logger: logger,
  33. logTag: "legacyDeploymentStateMigrator",
  34. }
  35. }
  36. func (m *legacyDeploymentStateMigrator) MigrateIfExists(configPath string) (migrated bool, err error) {
  37. if !m.fs.FileExists(configPath) {
  38. return false, nil
  39. }
  40. deploymentState, err := m.migrate(configPath)
  41. if err != nil {
  42. return false, err
  43. }
  44. err = m.deploymentStateService.Save(deploymentState)
  45. if err != nil {
  46. return false, bosherr.WrapError(err, "Saving migrated deployment state")
  47. }
  48. err = m.fs.RemoveAll(configPath)
  49. if err != nil {
  50. return false, bosherr.WrapError(err, "Deleting legacy deployment state")
  51. }
  52. return true, nil
  53. }
  54. func (m *legacyDeploymentStateMigrator) migrate(configPath string) (deploymentState DeploymentState, err error) {
  55. m.logger.Info(m.logTag, "Migrating legacy bosh-deployments.yml")
  56. bytes, err := m.fs.ReadFile(configPath)
  57. if err != nil {
  58. return deploymentState, bosherr.WrapErrorf(err, "Reading legacy deployment state file '%s'", configPath)
  59. }
  60. // go-yaml does not currently support ':' as the first character in a key.
  61. regex := regexp.MustCompile("\n([- ]) :")
  62. parsableString := regex.ReplaceAllString(string(bytes), "\n$1 ")
  63. m.logger.Debug(m.logTag, "Processed legacy bosh-deployments.yml:\n%s", parsableString)
  64. var legacyDeploymentState legacyDeploymentState
  65. err = yaml.Unmarshal([]byte(parsableString), &legacyDeploymentState)
  66. if err != nil {
  67. return deploymentState, bosherr.WrapError(err, "Parsing job manifest")
  68. }
  69. m.logger.Debug(m.logTag, "Parsed legacy bosh-deployments.yml: %#v", legacyDeploymentState)
  70. if (len(legacyDeploymentState.Instances) > 0) && (legacyDeploymentState.Instances[0].UUID != "") {
  71. deploymentState.DirectorID = legacyDeploymentState.Instances[0].UUID
  72. } else {
  73. uuid, err := m.uuidGenerator.Generate()
  74. if err != nil {
  75. return deploymentState, bosherr.WrapError(err, "Generating UUID")
  76. }
  77. deploymentState.DirectorID = uuid
  78. }
  79. deploymentState.Disks = []DiskRecord{}
  80. deploymentState.Stemcells = []StemcellRecord{}
  81. deploymentState.Releases = []ReleaseRecord{}
  82. if len(legacyDeploymentState.Instances) > 0 {
  83. instance := legacyDeploymentState.Instances[0]
  84. diskCID := instance.DiskCID
  85. if diskCID != "" {
  86. uuid, err := m.uuidGenerator.Generate()
  87. if err != nil {
  88. return deploymentState, bosherr.WrapError(err, "Generating UUID")
  89. }
  90. deploymentState.CurrentDiskID = uuid
  91. deploymentState.Disks = []DiskRecord{
  92. {
  93. ID: uuid,
  94. CID: diskCID,
  95. Size: 0,
  96. CloudProperties: biproperty.Map{},
  97. },
  98. }
  99. }
  100. vmCID := instance.VMCID
  101. if vmCID != "" {
  102. deploymentState.CurrentVMCID = vmCID
  103. }
  104. stemcellCID := instance.StemcellCID
  105. if stemcellCID != "" {
  106. uuid, err := m.uuidGenerator.Generate()
  107. if err != nil {
  108. return deploymentState, bosherr.WrapError(err, "Generating UUID")
  109. }
  110. stemcellName := instance.StemcellName
  111. if stemcellName == "" {
  112. stemcellName = "unknown-stemcell"
  113. }
  114. deploymentState.Stemcells = []StemcellRecord{
  115. {
  116. ID: uuid,
  117. Name: stemcellName,
  118. Version: "", // unknown, will never match new stemcell
  119. CID: stemcellCID,
  120. },
  121. }
  122. }
  123. }
  124. m.logger.Debug(m.logTag, "New deployment.json (migrated from legacy bosh-deployments.yml): %#v", deploymentState)
  125. return deploymentState, nil
  126. }
  127. type legacyDeploymentState struct {
  128. Instances []instance `yaml:"instances"`
  129. }
  130. type instance struct {
  131. UUID string `yaml:"uuid"`
  132. VMCID string `yaml:"vm_cid"`
  133. DiskCID string `yaml:"disk_cid"`
  134. StemcellCID string `yaml:"stemcell_cid"`
  135. StemcellName string `yaml:"stemcell_name"`
  136. }
  137. func LegacyDeploymentStatePath(deploymentManifestPath string) string {
  138. return path.Join(path.Dir(deploymentManifestPath), "bosh-deployments.yml")
  139. }