update_helpers.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package debtik
  2. import (
  3. _ "embed"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. )
  8. // Embed the helpers so an upgrade launched by a legacy updater also updates
  9. // its own tooling when the newly installed server starts.
  10. //
  11. //go:embed scripts/debtik-update
  12. var updateHelper []byte
  13. //go:embed scripts/release-version.py
  14. var versionHelper []byte
  15. // RefreshUpdateHelpers refreshes an existing installation, without creating one
  16. // when the server is run from a development checkout.
  17. func RefreshUpdateHelpers(dir string) error {
  18. if _, err := os.Stat(filepath.Join(dir, "debtik-update")); os.IsNotExist(err) {
  19. return nil
  20. } else if err != nil {
  21. return err
  22. }
  23. for _, helper := range []struct {
  24. name string
  25. data []byte
  26. }{{"debtik-update", updateHelper}, {"debtik-release-version", versionHelper}} {
  27. if err := writeHelper(dir, helper.name, helper.data); err != nil {
  28. return err
  29. }
  30. }
  31. return nil
  32. }
  33. func writeHelper(dir, name string, data []byte) error {
  34. f, err := os.CreateTemp(dir, ".debtik-helper-*")
  35. if err != nil {
  36. return err
  37. }
  38. defer os.Remove(f.Name())
  39. if err = f.Chmod(0750); err == nil {
  40. _, err = f.Write(data)
  41. }
  42. if err == nil {
  43. err = f.Sync()
  44. }
  45. closeErr := f.Close()
  46. if err == nil {
  47. err = closeErr
  48. }
  49. if err == nil {
  50. err = os.Rename(f.Name(), filepath.Join(dir, name))
  51. }
  52. if err != nil {
  53. return fmt.Errorf("install %s: %w", name, err)
  54. }
  55. return nil
  56. }