packet.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package cloudinitsave
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "path"
  8. "strings"
  9. "github.com/rancher/os/log"
  10. yaml "github.com/cloudfoundry-incubator/candiedyaml"
  11. "github.com/packethost/packngo/metadata"
  12. "github.com/rancher/os/config"
  13. "github.com/rancher/os/netconf"
  14. )
  15. func enablePacketNetwork(cfg *config.RancherConfig) {
  16. bootStrapped := false
  17. for _, v := range cfg.Network.Interfaces {
  18. if v.Address != "" {
  19. if err := netconf.ApplyNetworkConfigs(&cfg.Network); err != nil {
  20. log.Errorf("Failed to bootstrap network: %v", err)
  21. return
  22. }
  23. bootStrapped = true
  24. break
  25. }
  26. }
  27. if !bootStrapped {
  28. return
  29. }
  30. c := metadata.NewClient(http.DefaultClient)
  31. m, err := c.Metadata.Get()
  32. if err != nil {
  33. log.Errorf("Failed to get Packet metadata: %v", err)
  34. return
  35. }
  36. bondCfg := config.InterfaceConfig{
  37. Addresses: []string{},
  38. BondOpts: map[string]string{
  39. "lacp_rate": "1",
  40. "xmit_hash_policy": "layer3+4",
  41. "downdelay": "200",
  42. "updelay": "200",
  43. "miimon": "100",
  44. "mode": "4",
  45. },
  46. }
  47. netCfg := config.NetworkConfig{
  48. Interfaces: map[string]config.InterfaceConfig{},
  49. }
  50. for _, iface := range m.Network.Interfaces {
  51. netCfg.Interfaces["mac="+iface.Mac] = config.InterfaceConfig{
  52. Bond: "bond0",
  53. }
  54. }
  55. for _, addr := range m.Network.Addresses {
  56. bondCfg.Addresses = append(bondCfg.Addresses, fmt.Sprintf("%s/%d", addr.Address, addr.Cidr))
  57. if addr.Gateway != "" {
  58. if addr.AddressFamily == 4 {
  59. if addr.Public {
  60. bondCfg.Gateway = addr.Gateway
  61. }
  62. } else {
  63. bondCfg.GatewayIpv6 = addr.Gateway
  64. }
  65. }
  66. if addr.AddressFamily == 4 && strings.HasPrefix(addr.Gateway, "10.") {
  67. bondCfg.PostUp = append(bondCfg.PostUp, "ip route add 10.0.0.0/8 via "+addr.Gateway)
  68. }
  69. }
  70. netCfg.Interfaces["bond0"] = bondCfg
  71. b, _ := yaml.Marshal(netCfg)
  72. log.Debugf("Generated network config: %s", string(b))
  73. cc := config.CloudConfig{
  74. Rancher: config.RancherConfig{
  75. Network: netCfg,
  76. },
  77. }
  78. // Post to phone home URL on first boot
  79. if _, err = os.Stat(config.CloudConfigNetworkFile); err != nil {
  80. if _, err = http.Post(m.PhoneHomeURL, "application/json", bytes.NewReader([]byte{})); err != nil {
  81. log.Errorf("Failed to post to Packet phone home URL: %v", err)
  82. }
  83. }
  84. if err := os.MkdirAll(path.Dir(config.CloudConfigNetworkFile), 0700); err != nil {
  85. log.Errorf("Failed to create directory for file %s: %v", config.CloudConfigNetworkFile, err)
  86. }
  87. if err := config.WriteToFile(cc, config.CloudConfigNetworkFile); err != nil {
  88. log.Errorf("Failed to save config file %s: %v", config.CloudConfigNetworkFile, err)
  89. }
  90. }