mirror of
https://github.com/rancher/os.git
synced 2025-06-27 23:36:49 +00:00
Refactor the cloud-init metadata to return a netconf.NetworkConfig
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
This commit is contained in:
parent
5dbb0f2a28
commit
0779e13d46
@ -16,8 +16,10 @@
|
|||||||
package cloudinitsave
|
package cloudinitsave
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -110,8 +112,8 @@ func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadat
|
|||||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Don't put secrets into the log
|
// TODO: Don't put secrets into the log
|
||||||
//log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
metaDataBytes, err := yaml.Marshal(metadata)
|
metaDataBytes, err := yaml.Marshal(metadata)
|
||||||
@ -122,8 +124,34 @@ func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadat
|
|||||||
if err = util.WriteFileAtomic(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
if err = util.WriteFileAtomic(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Don't put secrets into the log
|
// TODO: Don't put secrets into the log
|
||||||
//log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
|
log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
|
||||||
|
|
||||||
|
// if we write the empty meta yml, the merge fails.
|
||||||
|
// TODO: the problem is that a partially filled one will still have merge issues, so that needs fixing - presumably by making merge more clever, and making more fields optional
|
||||||
|
emptyMeta, err := yaml.Marshal(datasource.Metadata{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if bytes.Compare(metaDataBytes, emptyMeta) == 0 {
|
||||||
|
log.Infof("not writing %s: its all defaults.", rancherConfig.CloudConfigNetworkFile)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// write the network.yml file from metadata
|
||||||
|
cc := rancherConfig.CloudConfig{
|
||||||
|
Rancher: rancherConfig.RancherConfig{
|
||||||
|
Network: metadata.NetworkConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(path.Dir(rancherConfig.CloudConfigNetworkFile), 0700); err != nil {
|
||||||
|
log.Errorf("Failed to create directory for file %s: %v", rancherConfig.CloudConfigNetworkFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rancherConfig.WriteToFile(cc, rancherConfig.CloudConfigNetworkFile); err != nil {
|
||||||
|
log.Errorf("Failed to save config file %s: %v", rancherConfig.CloudConfigNetworkFile, err)
|
||||||
|
}
|
||||||
|
log.Infof("Written to %s:", rancherConfig.CloudConfigNetworkFile)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -161,7 +189,7 @@ func fetchAndSave(ds datasource.Datasource) error {
|
|||||||
userDataBytes = []byte{}
|
userDataBytes = []byte{}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("Unrecognized user-data\n%s", userData)
|
log.Errorf("Unrecognized user-data\n(%s)", userData)
|
||||||
userDataBytes = []byte{}
|
userDataBytes = []byte{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +261,8 @@ func getDatasources(cfg *rancherConfig.CloudConfig, network bool) []datasource.D
|
|||||||
}
|
}
|
||||||
|
|
||||||
func enableDoLinkLocal() {
|
func enableDoLinkLocal() {
|
||||||
err := netconf.ApplyNetworkConfigs(&rancherConfig.NetworkConfig{
|
err := netconf.ApplyNetworkConfigs(&netconf.NetworkConfig{
|
||||||
Interfaces: map[string]rancherConfig.InterfaceConfig{
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
"eth0": {
|
"eth0": {
|
||||||
IPV4LL: true,
|
IPV4LL: true,
|
||||||
},
|
},
|
||||||
|
88
cmd/cloudinitsave/packet.go
Normal file → Executable file
88
cmd/cloudinitsave/packet.go
Normal file → Executable file
@ -1,18 +1,8 @@
|
|||||||
package cloudinitsave
|
package cloudinitsave
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
|
||||||
|
|
||||||
"github.com/packethost/packngo/metadata"
|
|
||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
"github.com/rancher/os/netconf"
|
"github.com/rancher/os/netconf"
|
||||||
)
|
)
|
||||||
@ -34,71 +24,29 @@ func enablePacketNetwork(cfg *config.RancherConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c := metadata.NewClient(http.DefaultClient)
|
// Post to phone home URL on first boot
|
||||||
m, err := c.Metadata.Get()
|
/*
|
||||||
if err != nil {
|
// TODO: bring this back
|
||||||
log.Errorf("Failed to get Packet metadata: %v", err)
|
if _, err = os.Stat(config.CloudConfigNetworkFile); err != nil {
|
||||||
return
|
if _, err = http.Post(m.PhoneHomeURL, "application/json", bytes.NewReader([]byte{})); err != nil {
|
||||||
}
|
log.Errorf("Failed to post to Packet phone home URL: %v", err)
|
||||||
|
|
||||||
bondCfg := config.InterfaceConfig{
|
|
||||||
Addresses: []string{},
|
|
||||||
BondOpts: map[string]string{
|
|
||||||
"lacp_rate": "1",
|
|
||||||
"xmit_hash_policy": "layer3+4",
|
|
||||||
"downdelay": "200",
|
|
||||||
"updelay": "200",
|
|
||||||
"miimon": "100",
|
|
||||||
"mode": "4",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
netCfg := config.NetworkConfig{
|
|
||||||
Interfaces: map[string]config.InterfaceConfig{},
|
|
||||||
}
|
|
||||||
for _, iface := range m.Network.Interfaces {
|
|
||||||
netCfg.Interfaces["mac="+iface.Mac] = config.InterfaceConfig{
|
|
||||||
Bond: "bond0",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, addr := range m.Network.Addresses {
|
|
||||||
bondCfg.Addresses = append(bondCfg.Addresses, fmt.Sprintf("%s/%d", addr.Address, addr.Cidr))
|
|
||||||
if addr.Gateway != "" {
|
|
||||||
if addr.AddressFamily == 4 {
|
|
||||||
if addr.Public {
|
|
||||||
bondCfg.Gateway = addr.Gateway
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bondCfg.GatewayIpv6 = addr.Gateway
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if addr.AddressFamily == 4 && strings.HasPrefix(addr.Gateway, "10.") {
|
/*
|
||||||
bondCfg.PostUp = append(bondCfg.PostUp, "ip route add 10.0.0.0/8 via "+addr.Gateway)
|
cc := config.CloudConfig{
|
||||||
|
Rancher: config.RancherConfig{
|
||||||
|
Network: netCfg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
netCfg.Interfaces["bond0"] = bondCfg
|
if err := os.MkdirAll(path.Dir(config.CloudConfigNetworkFile), 0700); err != nil {
|
||||||
b, _ := yaml.Marshal(netCfg)
|
log.Errorf("Failed to create directory for file %s: %v", config.CloudConfigNetworkFile, err)
|
||||||
log.Debugf("Generated network config: %s", string(b))
|
|
||||||
|
|
||||||
cc := config.CloudConfig{
|
|
||||||
Rancher: config.RancherConfig{
|
|
||||||
Network: netCfg,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post to phone home URL on first boot
|
|
||||||
if _, err = os.Stat(config.CloudConfigNetworkFile); err != nil {
|
|
||||||
if _, err = http.Post(m.PhoneHomeURL, "application/json", bytes.NewReader([]byte{})); err != nil {
|
|
||||||
log.Errorf("Failed to post to Packet phone home URL: %v", err)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(path.Dir(config.CloudConfigNetworkFile), 0700); err != nil {
|
if err := config.WriteToFile(cc, config.CloudConfigNetworkFile); err != nil {
|
||||||
log.Errorf("Failed to create directory for file %s: %v", config.CloudConfigNetworkFile, err)
|
log.Errorf("Failed to save config file %s: %v", config.CloudConfigNetworkFile, err)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if err := config.WriteToFile(cc, config.CloudConfigNetworkFile); err != nil {
|
|
||||||
log.Errorf("Failed to save config file %s: %v", config.CloudConfigNetworkFile, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ func ApplyNetworkConfig(cfg *config.CloudConfig) {
|
|||||||
search = cfg.Rancher.Defaults.Network.DNS.Search
|
search = cfg.Rancher.Defaults.Network.DNS.Search
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: don't write to the file if nameservers is still empty
|
||||||
if _, err := resolvconf.Build("/etc/resolv.conf", nameservers, search, nil); err != nil {
|
if _, err := resolvconf.Build("/etc/resolv.conf", nameservers, search, nil); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -102,10 +102,11 @@ func (cd *ConfigDrive) FetchMetadata() (metadata datasource.Metadata, err error)
|
|||||||
|
|
||||||
metadata.SSHPublicKeys = m.SSHAuthorizedKeyMap
|
metadata.SSHPublicKeys = m.SSHAuthorizedKeyMap
|
||||||
metadata.Hostname = m.Hostname
|
metadata.Hostname = m.Hostname
|
||||||
if m.NetworkConfig.ContentPath != "" {
|
// TODO: I don't think we've used this for anything
|
||||||
metadata.NetworkConfig, err = cd.tryReadFile(path.Join(cd.openstackRoot(), m.NetworkConfig.ContentPath))
|
/* if m.NetworkConfig.ContentPath != "" {
|
||||||
}
|
metadata.NetworkConfig, err = cd.tryReadFile(path.Join(cd.openstackRoot(), m.NetworkConfig.ContentPath))
|
||||||
|
}
|
||||||
|
*/
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,7 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
test.File{Path: "/media/configdrive/openstack/config_file.json", Contents: "make it work"},
|
test.File{Path: "/media/configdrive/openstack/config_file.json", Contents: "make it work"},
|
||||||
),
|
),
|
||||||
metadata: datasource.Metadata{
|
metadata: datasource.Metadata{
|
||||||
Hostname: "host",
|
Hostname: "host",
|
||||||
NetworkConfig: []byte("make it work"),
|
|
||||||
SSHPublicKeys: map[string]string{
|
SSHPublicKeys: map[string]string{
|
||||||
"1": "key1",
|
"1": "key1",
|
||||||
"2": "key2",
|
"2": "key2",
|
||||||
|
@ -16,6 +16,8 @@ package datasource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datasource interface {
|
type Datasource interface {
|
||||||
@ -31,11 +33,17 @@ type Datasource interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
PublicIPv4 net.IP
|
// TODO: move to netconf/types.go ?
|
||||||
PublicIPv6 net.IP
|
// see https://ahmetalpbalkan.com/blog/comparison-of-instance-metadata-services/
|
||||||
PrivateIPv4 net.IP
|
|
||||||
PrivateIPv6 net.IP
|
|
||||||
Hostname string
|
Hostname string
|
||||||
SSHPublicKeys map[string]string
|
SSHPublicKeys map[string]string
|
||||||
NetworkConfig interface{}
|
NetworkConfig netconf.NetworkConfig
|
||||||
|
|
||||||
|
// probably unused, but its in the initialize.env code
|
||||||
|
// TODO: work out if there's any reason to keep it.
|
||||||
|
// Lets see if anyone notices when its not set.
|
||||||
|
PublicIPv4 net.IP
|
||||||
|
PublicIPv6 net.IP
|
||||||
|
PrivateIPv4 net.IP
|
||||||
|
PrivateIPv6 net.IP
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,13 @@ package digitalocean
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
)
|
)
|
||||||
@ -99,12 +103,70 @@ func (ms *MetadataService) FetchMetadata() (metadata datasource.Metadata, err er
|
|||||||
metadata.PrivateIPv6 = net.ParseIP(m.Interfaces.Private[0].IPv6.IPAddress)
|
metadata.PrivateIPv6 = net.ParseIP(m.Interfaces.Private[0].IPv6.IPAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadata.NetworkConfig.Interfaces = make(map[string]netconf.InterfaceConfig)
|
||||||
|
|
||||||
|
ethNumber := 0
|
||||||
|
|
||||||
|
for _, eth := range m.Interfaces.Public {
|
||||||
|
network := netconf.InterfaceConfig{}
|
||||||
|
|
||||||
|
if eth.IPv4 != nil {
|
||||||
|
network.Gateway = eth.IPv4.Gateway
|
||||||
|
|
||||||
|
network.Addresses = append(network.Addresses, fmt.Sprintf("%s/%s", eth.IPv4.IPAddress, eth.IPv4.Netmask))
|
||||||
|
if metadata.PublicIPv4 == nil {
|
||||||
|
metadata.PublicIPv4 = net.ParseIP(eth.IPv4.IPAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if eth.AnchorIPv4 != nil {
|
||||||
|
network.Addresses = append(network.Addresses, fmt.Sprintf("%s/%s", eth.AnchorIPv4.IPAddress, eth.AnchorIPv4.Netmask))
|
||||||
|
|
||||||
|
}
|
||||||
|
if eth.IPv6 != nil {
|
||||||
|
network.Addresses = append(network.Addresses, eth.IPv6.IPAddress)
|
||||||
|
network.GatewayIpv6 = eth.IPv6.Gateway
|
||||||
|
if metadata.PublicIPv6 == nil {
|
||||||
|
metadata.PublicIPv6 = net.ParseIP(eth.IPv6.IPAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata.NetworkConfig.Interfaces[fmt.Sprintf("eth%d", ethNumber)] = network
|
||||||
|
ethNumber = ethNumber + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, eth := range m.Interfaces.Private {
|
||||||
|
network := netconf.InterfaceConfig{}
|
||||||
|
if eth.IPv4 != nil {
|
||||||
|
network.Gateway = eth.IPv4.Gateway
|
||||||
|
|
||||||
|
network.Addresses = append(network.Addresses, fmt.Sprintf("%s/%s", eth.IPv4.IPAddress, eth.IPv4.Netmask))
|
||||||
|
if metadata.PrivateIPv4 == nil {
|
||||||
|
metadata.PrivateIPv4 = net.ParseIP(eth.IPv6.IPAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if eth.AnchorIPv4 != nil {
|
||||||
|
network.Addresses = append(network.Addresses, fmt.Sprintf("%s/%s", eth.AnchorIPv4.IPAddress, eth.AnchorIPv4.Netmask))
|
||||||
|
|
||||||
|
}
|
||||||
|
if eth.IPv6 != nil {
|
||||||
|
network.Address = eth.IPv6.IPAddress
|
||||||
|
network.GatewayIpv6 = eth.IPv6.Gateway
|
||||||
|
if metadata.PrivateIPv6 == nil {
|
||||||
|
metadata.PrivateIPv6 = net.ParseIP(eth.IPv6.IPAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata.NetworkConfig.Interfaces[fmt.Sprintf("eth%d", ethNumber)] = network
|
||||||
|
ethNumber = ethNumber + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata.NetworkConfig.DNS.Nameservers = m.DNS.Nameservers
|
||||||
|
|
||||||
metadata.Hostname = m.Hostname
|
metadata.Hostname = m.Hostname
|
||||||
metadata.SSHPublicKeys = map[string]string{}
|
metadata.SSHPublicKeys = map[string]string{}
|
||||||
for i, key := range m.PublicKeys {
|
for i, key := range m.PublicKeys {
|
||||||
metadata.SSHPublicKeys[strconv.Itoa(i)] = key
|
metadata.SSHPublicKeys[strconv.Itoa(i)] = key
|
||||||
}
|
}
|
||||||
metadata.NetworkConfig = m
|
// metadata.NetworkConfig = m
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
37
config/cloudinit/datasource/metadata/digitalocean/metadata_test.go
Normal file → Executable file
37
config/cloudinit/datasource/metadata/digitalocean/metadata_test.go
Normal file → Executable file
@ -20,6 +20,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||||
@ -90,26 +92,23 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
"0": "publickey1",
|
"0": "publickey1",
|
||||||
"1": "publickey2",
|
"1": "publickey2",
|
||||||
},
|
},
|
||||||
NetworkConfig: Metadata{
|
NetworkConfig: netconf.NetworkConfig{
|
||||||
Interfaces: Interfaces{
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
Public: []Interface{
|
"eth0": netconf.InterfaceConfig{
|
||||||
{
|
Addresses: []string{
|
||||||
IPv4: &Address{
|
"192.168.1.2/255.255.255.0",
|
||||||
IPAddress: "192.168.1.2",
|
"fe00::",
|
||||||
Netmask: "255.255.255.0",
|
|
||||||
Gateway: "192.168.1.1",
|
|
||||||
},
|
|
||||||
IPv6: &Address{
|
|
||||||
IPAddress: "fe00::",
|
|
||||||
Cidr: 126,
|
|
||||||
Gateway: "fe00::",
|
|
||||||
},
|
|
||||||
MAC: "ab:cd:ef:gh:ij",
|
|
||||||
Type: "public",
|
|
||||||
},
|
},
|
||||||
|
//Netmask: "255.255.255.0",
|
||||||
|
Gateway: "192.168.1.1",
|
||||||
|
|
||||||
|
//Cidr: 126,
|
||||||
|
GatewayIpv6: "fe00::",
|
||||||
|
//MAC: "ab:cd:ef:gh:ij",
|
||||||
|
//Type: "public",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PublicKeys: []string{"publickey1", "publickey2"},
|
//PublicKeys: []string{"publickey1", "publickey2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -127,10 +126,10 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
metadata, err := service.FetchMetadata()
|
metadata, err := service.FetchMetadata()
|
||||||
if Error(err) != Error(tt.expectErr) {
|
if Error(err) != Error(tt.expectErr) {
|
||||||
t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err)
|
t.Fatalf("bad error (%q): \nwant %#v,\n got %#v", tt.resources, tt.expectErr, err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(tt.expect, metadata) {
|
if !reflect.DeepEqual(tt.expect, metadata) {
|
||||||
t.Fatalf("bad fetch (%q): want %#q, got %#q", tt.resources, tt.expect, metadata)
|
t.Fatalf("bad fetch (%q): \nwant %#v,\n got %#v", tt.resources, tt.expect, metadata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
@ -47,6 +49,7 @@ func NewDatasource(root string) *MetadataService {
|
|||||||
|
|
||||||
func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||||
metadata := datasource.Metadata{}
|
metadata := datasource.Metadata{}
|
||||||
|
metadata.NetworkConfig = netconf.NetworkConfig{}
|
||||||
|
|
||||||
if keynames, err := ms.fetchAttributes(fmt.Sprintf("%s/public-keys", ms.MetadataURL())); err == nil {
|
if keynames, err := ms.fetchAttributes(fmt.Sprintf("%s/public-keys", ms.MetadataURL())); err == nil {
|
||||||
keyIDs := make(map[string]string)
|
keyIDs := make(map[string]string)
|
||||||
@ -77,18 +80,25 @@ func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
|||||||
return metadata, err
|
return metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network := netconf.InterfaceConfig{}
|
||||||
if localAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/local-ipv4", ms.MetadataURL())); err == nil {
|
if localAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/local-ipv4", ms.MetadataURL())); err == nil {
|
||||||
metadata.PrivateIPv4 = net.ParseIP(localAddr)
|
metadata.PrivateIPv4 = net.ParseIP(localAddr)
|
||||||
|
network.Addresses = append(network.Addresses, localAddr)
|
||||||
|
|
||||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||||
return metadata, err
|
return metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/public-ipv4", ms.MetadataURL())); err == nil {
|
if publicAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/public-ipv4", ms.MetadataURL())); err == nil {
|
||||||
metadata.PublicIPv4 = net.ParseIP(publicAddr)
|
metadata.PublicIPv4 = net.ParseIP(publicAddr)
|
||||||
|
network.Addresses = append(network.Addresses, publicAddr)
|
||||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||||
return metadata, err
|
return metadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadata.NetworkConfig.Interfaces = make(map[string]netconf.InterfaceConfig)
|
||||||
|
metadata.NetworkConfig.Interfaces["eth0"] = network
|
||||||
|
|
||||||
return metadata, nil
|
return metadata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
config/cloudinit/datasource/metadata/ec2/metadata_test.go
Normal file → Executable file
21
config/cloudinit/datasource/metadata/ec2/metadata_test.go
Normal file → Executable file
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestType(t *testing.T) {
|
func TestType(t *testing.T) {
|
||||||
@ -174,6 +175,16 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
||||||
PublicIPv4: net.ParseIP("5.6.7.8"),
|
PublicIPv4: net.ParseIP("5.6.7.8"),
|
||||||
SSHPublicKeys: map[string]string{"test1": "key"},
|
SSHPublicKeys: map[string]string{"test1": "key"},
|
||||||
|
NetworkConfig: netconf.NetworkConfig{
|
||||||
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
|
"eth0": netconf.InterfaceConfig{
|
||||||
|
Addresses: []string{
|
||||||
|
"1.2.3.4",
|
||||||
|
"5.6.7.8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -192,6 +203,16 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
||||||
PublicIPv4: net.ParseIP("5.6.7.8"),
|
PublicIPv4: net.ParseIP("5.6.7.8"),
|
||||||
SSHPublicKeys: map[string]string{"test1": "key"},
|
SSHPublicKeys: map[string]string{"test1": "key"},
|
||||||
|
NetworkConfig: netconf.NetworkConfig{
|
||||||
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
|
"eth0": netconf.InterfaceConfig{
|
||||||
|
Addresses: []string{
|
||||||
|
"1.2.3.4",
|
||||||
|
"5.6.7.8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
)
|
)
|
||||||
@ -72,6 +74,22 @@ func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
|||||||
SSHPublicKeys: nil,
|
SSHPublicKeys: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addresses := []string{}
|
||||||
|
if public != nil {
|
||||||
|
addresses = append(addresses, public.String())
|
||||||
|
}
|
||||||
|
if local != nil {
|
||||||
|
addresses = append(addresses, local.String())
|
||||||
|
}
|
||||||
|
if len(addresses) > 0 {
|
||||||
|
network := netconf.InterfaceConfig{
|
||||||
|
Addresses: addresses,
|
||||||
|
}
|
||||||
|
|
||||||
|
md.NetworkConfig.Interfaces = make(map[string]netconf.InterfaceConfig)
|
||||||
|
md.NetworkConfig.Interfaces["eth0"] = network
|
||||||
|
}
|
||||||
|
|
||||||
keyStrings := strings.Split(projectSSHKeys+"\n"+instanceSSHKeys, "\n")
|
keyStrings := strings.Split(projectSSHKeys+"\n"+instanceSSHKeys, "\n")
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -20,6 +20,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||||
@ -73,6 +75,16 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
Hostname: "host",
|
Hostname: "host",
|
||||||
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
||||||
PublicIPv4: net.ParseIP("5.6.7.8"),
|
PublicIPv4: net.ParseIP("5.6.7.8"),
|
||||||
|
NetworkConfig: netconf.NetworkConfig{
|
||||||
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
|
"eth0": netconf.InterfaceConfig{
|
||||||
|
Addresses: []string{
|
||||||
|
"5.6.7.8",
|
||||||
|
"1.2.3.4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
|
"github.com/rancher/os/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
@ -40,6 +41,9 @@ func NewDatasource(root, apiVersion, userdataPath, metadataPath string, header h
|
|||||||
|
|
||||||
func (ms Service) IsAvailable() bool {
|
func (ms Service) IsAvailable() bool {
|
||||||
_, ms.lastError = ms.Client.Get(ms.Root + ms.APIVersion)
|
_, ms.lastError = ms.Client.Get(ms.Root + ms.APIVersion)
|
||||||
|
if ms.lastError != nil {
|
||||||
|
log.Errorf("%s: %s (lastError: %s)", "IsAvailable", ms.Root+":"+ms.UserdataPath, ms.lastError)
|
||||||
|
}
|
||||||
return (ms.lastError == nil)
|
return (ms.lastError == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +52,7 @@ func (ms *Service) Finish() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ms *Service) String() string {
|
func (ms *Service) String() string {
|
||||||
return fmt.Sprintf("%s: %s (lastError: %s)", "metadata", ms.Root+":"+ms.UserdataPath, ms.lastError)
|
return fmt.Sprintf("%s: %s (lastError: %s)", "metadata", ms.Root+ms.UserdataPath, ms.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms Service) AvailabilityChanges() bool {
|
func (ms Service) AvailabilityChanges() bool {
|
||||||
|
@ -15,12 +15,18 @@
|
|||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"fmt"
|
||||||
"net"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||||
|
"github.com/rancher/os/log"
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
|
|
||||||
|
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||||
|
packetMetadata "github.com/packethost/packngo/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -30,33 +36,6 @@ const (
|
|||||||
metadataPath = "metadata"
|
metadataPath = "metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Netblock struct {
|
|
||||||
Address net.IP `json:"address"`
|
|
||||||
Cidr int `json:"cidr"`
|
|
||||||
Netmask net.IP `json:"netmask"`
|
|
||||||
Gateway net.IP `json:"gateway"`
|
|
||||||
AddressFamily int `json:"address_family"`
|
|
||||||
Public bool `json:"public"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Nic struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Mac string `json:"mac"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type NetworkData struct {
|
|
||||||
Interfaces []Nic `json:"interfaces"`
|
|
||||||
Netblocks []Netblock `json:"addresses"`
|
|
||||||
DNS []net.IP `json:"dns"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Metadata that will be pulled from the https://metadata.packet.net/metadata only. We have the opportunity to add more later.
|
|
||||||
type Metadata struct {
|
|
||||||
Hostname string `json:"hostname"`
|
|
||||||
SSHKeys []string `json:"ssh_keys"`
|
|
||||||
NetworkData NetworkData `json:"network"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MetadataService struct {
|
type MetadataService struct {
|
||||||
metadata.Service
|
metadata.Service
|
||||||
}
|
}
|
||||||
@ -70,37 +49,85 @@ func NewDatasource(root string) *MetadataService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ms *MetadataService) FetchMetadata() (metadata datasource.Metadata, err error) {
|
func (ms *MetadataService) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||||
var data []byte
|
c := packetMetadata.NewClient(http.DefaultClient)
|
||||||
var m Metadata
|
m, err := c.Metadata.Get()
|
||||||
|
if err != nil {
|
||||||
if data, err = ms.FetchData(ms.MetadataURL()); err != nil || len(data) == 0 {
|
log.Errorf("Failed to get Packet metadata: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(data, &m); err != nil {
|
bondCfg := netconf.InterfaceConfig{
|
||||||
return
|
Addresses: []string{},
|
||||||
|
BondOpts: map[string]string{
|
||||||
|
"lacp_rate": "1",
|
||||||
|
"xmit_hash_policy": "layer3+4",
|
||||||
|
"downdelay": "200",
|
||||||
|
"updelay": "200",
|
||||||
|
"miimon": "100",
|
||||||
|
"mode": "4",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
netCfg := netconf.NetworkConfig{
|
||||||
if len(m.NetworkData.Netblocks) > 0 {
|
Interfaces: map[string]netconf.InterfaceConfig{},
|
||||||
for _, Netblock := range m.NetworkData.Netblocks {
|
}
|
||||||
if Netblock.AddressFamily == 4 {
|
for _, iface := range m.Network.Interfaces {
|
||||||
if Netblock.Public == true {
|
netCfg.Interfaces["mac="+iface.Mac] = netconf.InterfaceConfig{
|
||||||
metadata.PublicIPv4 = Netblock.Address
|
Bond: "bond0",
|
||||||
} else {
|
|
||||||
metadata.PrivateIPv4 = Netblock.Address
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
metadata.PublicIPv6 = Netblock.Address
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, addr := range m.Network.Addresses {
|
||||||
|
bondCfg.Addresses = append(bondCfg.Addresses, fmt.Sprintf("%s/%d", addr.Address, addr.Cidr))
|
||||||
|
if addr.Gateway != "" {
|
||||||
|
if addr.AddressFamily == 4 {
|
||||||
|
if addr.Public {
|
||||||
|
bondCfg.Gateway = addr.Gateway
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bondCfg.GatewayIpv6 = addr.Gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if addr.AddressFamily == 4 && strings.HasPrefix(addr.Gateway, "10.") {
|
||||||
|
bondCfg.PostUp = append(bondCfg.PostUp, "ip route add 10.0.0.0/8 via "+addr.Gateway)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
netCfg.Interfaces["bond0"] = bondCfg
|
||||||
|
b, _ := yaml.Marshal(netCfg)
|
||||||
|
log.Debugf("Generated network config: %s", string(b))
|
||||||
|
|
||||||
|
// the old code var data []byte
|
||||||
|
/* var m Metadata
|
||||||
|
|
||||||
|
if data, err = ms.FetchData(ms.MetadataURL()); err != nil || len(data) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = json.Unmarshal(data, &m); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.NetworkData.Netblocks) > 0 {
|
||||||
|
for _, Netblock := range m.NetworkData.Netblocks {
|
||||||
|
if Netblock.AddressFamily == 4 {
|
||||||
|
if Netblock.Public == true {
|
||||||
|
metadata.PublicIPv4 = Netblock.Address
|
||||||
|
} else {
|
||||||
|
metadata.PrivateIPv4 = Netblock.Address
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
metadata.PublicIPv6 = Netblock.Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
metadata.Hostname = m.Hostname
|
metadata.Hostname = m.Hostname
|
||||||
metadata.SSHPublicKeys = map[string]string{}
|
metadata.SSHPublicKeys = map[string]string{}
|
||||||
for i, key := range m.SSHKeys {
|
for i, key := range m.SshKeys {
|
||||||
metadata.SSHPublicKeys[strconv.Itoa(i)] = key
|
metadata.SSHPublicKeys[strconv.Itoa(i)] = key
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.NetworkConfig = m.NetworkData
|
metadata.NetworkConfig = netCfg
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ func (v VMWare) FetchMetadata() (metadata datasource.Metadata, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metadata.NetworkConfig = netconf
|
// metadata.NetworkConfig = netconf
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,10 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
"interface.0.dhcp": "yes",
|
"interface.0.dhcp": "yes",
|
||||||
},
|
},
|
||||||
metadata: datasource.Metadata{
|
metadata: datasource.Metadata{
|
||||||
NetworkConfig: map[string]string{
|
// NetworkConfig: map[string]string{
|
||||||
"interface.0.mac": "test mac",
|
// "interface.0.mac": "test mac",
|
||||||
"interface.0.dhcp": "yes",
|
// "interface.0.dhcp": "yes",
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -68,10 +68,10 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
"interface.0.dhcp": "yes",
|
"interface.0.dhcp": "yes",
|
||||||
},
|
},
|
||||||
metadata: datasource.Metadata{
|
metadata: datasource.Metadata{
|
||||||
NetworkConfig: map[string]string{
|
// NetworkConfig: map[string]string{
|
||||||
"interface.0.name": "test name",
|
// "interface.0.name": "test name",
|
||||||
"interface.0.dhcp": "yes",
|
// "interface.0.dhcp": "yes",
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -86,12 +86,12 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
metadata: datasource.Metadata{
|
metadata: datasource.Metadata{
|
||||||
Hostname: "test host",
|
Hostname: "test host",
|
||||||
PrivateIPv6: net.ParseIP("fe00::100"),
|
PrivateIPv6: net.ParseIP("fe00::100"),
|
||||||
NetworkConfig: map[string]string{
|
// NetworkConfig: map[string]string{
|
||||||
"interface.0.mac": "test mac",
|
// "interface.0.mac": "test mac",
|
||||||
"interface.0.ip.0.address": "fe00::100/64",
|
// "interface.0.ip.0.address": "fe00::100/64",
|
||||||
"interface.0.route.0.gateway": "fe00::1",
|
// "interface.0.route.0.gateway": "fe00::1",
|
||||||
"interface.0.route.0.destination": "::",
|
// "interface.0.route.0.destination": "::",
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,17 +113,17 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
Hostname: "test host",
|
Hostname: "test host",
|
||||||
PublicIPv4: net.ParseIP("10.0.0.101"),
|
PublicIPv4: net.ParseIP("10.0.0.101"),
|
||||||
PrivateIPv4: net.ParseIP("10.0.0.102"),
|
PrivateIPv4: net.ParseIP("10.0.0.102"),
|
||||||
NetworkConfig: map[string]string{
|
// NetworkConfig: map[string]string{
|
||||||
"interface.0.name": "test name",
|
// "interface.0.name": "test name",
|
||||||
"interface.0.ip.0.address": "10.0.0.100/24",
|
// "interface.0.ip.0.address": "10.0.0.100/24",
|
||||||
"interface.0.ip.1.address": "10.0.0.101/24",
|
// "interface.0.ip.1.address": "10.0.0.101/24",
|
||||||
"interface.0.route.0.gateway": "10.0.0.1",
|
// "interface.0.route.0.gateway": "10.0.0.1",
|
||||||
"interface.0.route.0.destination": "0.0.0.0",
|
// "interface.0.route.0.destination": "0.0.0.0",
|
||||||
"interface.1.mac": "test mac",
|
// "interface.1.mac": "test mac",
|
||||||
"interface.1.route.0.gateway": "10.0.0.2",
|
// "interface.1.route.0.gateway": "10.0.0.2",
|
||||||
"interface.1.route.0.destination": "0.0.0.0",
|
// "interface.1.route.0.destination": "0.0.0.0",
|
||||||
"interface.1.ip.0.address": "10.0.0.102/24",
|
// "interface.1.ip.0.address": "10.0.0.102/24",
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -257,17 +257,17 @@ func TestOvfTransport(t *testing.T) {
|
|||||||
Hostname: "test host",
|
Hostname: "test host",
|
||||||
PublicIPv4: net.ParseIP("10.0.0.101"),
|
PublicIPv4: net.ParseIP("10.0.0.101"),
|
||||||
PrivateIPv4: net.ParseIP("10.0.0.102"),
|
PrivateIPv4: net.ParseIP("10.0.0.102"),
|
||||||
NetworkConfig: map[string]string{
|
//NetworkConfig: map[string]string{
|
||||||
"interface.0.name": "test name",
|
// "interface.0.name": "test name",
|
||||||
"interface.0.ip.0.address": "10.0.0.100/24",
|
// "interface.0.ip.0.address": "10.0.0.100/24",
|
||||||
"interface.0.ip.1.address": "10.0.0.101/24",
|
// "interface.0.ip.1.address": "10.0.0.101/24",
|
||||||
"interface.0.route.0.gateway": "10.0.0.1",
|
// "interface.0.route.0.gateway": "10.0.0.1",
|
||||||
"interface.0.route.0.destination": "0.0.0.0",
|
// "interface.0.route.0.destination": "0.0.0.0",
|
||||||
"interface.1.mac": "test mac",
|
// "interface.1.mac": "test mac",
|
||||||
"interface.1.route.0.gateway": "10.0.0.2",
|
// "interface.1.route.0.gateway": "10.0.0.2",
|
||||||
"interface.1.route.0.destination": "0.0.0.0",
|
// "interface.1.route.0.destination": "0.0.0.0",
|
||||||
"interface.1.ip.0.address": "10.0.0.102/24",
|
// "interface.1.ip.0.address": "10.0.0.102/24",
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
userdata: []byte("test config"),
|
userdata: []byte("test config"),
|
||||||
},
|
},
|
||||||
|
72
config/cloudinit/network/packet.go
Normal file → Executable file
72
config/cloudinit/network/packet.go
Normal file → Executable file
@ -17,14 +17,15 @@ package network
|
|||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/packet"
|
"github.com/rancher/os/netconf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProcessPacketNetconf(netdata packet.NetworkData) ([]InterfaceGenerator, error) {
|
func ProcessPacketNetconf(netdata netconf.NetworkConfig) ([]InterfaceGenerator, error) {
|
||||||
var nameservers []net.IP
|
var nameservers []net.IP
|
||||||
if netdata.DNS != nil {
|
for _, v := range netdata.DNS.Nameservers {
|
||||||
nameservers = netdata.DNS
|
nameservers = append(nameservers, net.ParseIP(v))
|
||||||
} else {
|
}
|
||||||
|
if len(nameservers) == 0 {
|
||||||
nameservers = append(nameservers, net.ParseIP("8.8.8.8"), net.ParseIP("8.8.4.4"))
|
nameservers = append(nameservers, net.ParseIP("8.8.8.8"), net.ParseIP("8.8.4.4"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,43 +37,44 @@ func ProcessPacketNetconf(netdata packet.NetworkData) ([]InterfaceGenerator, err
|
|||||||
return generators, nil
|
return generators, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNetwork(netdata packet.NetworkData, nameservers []net.IP) ([]InterfaceGenerator, error) {
|
func parseNetwork(netdata netconf.NetworkConfig, nameservers []net.IP) ([]InterfaceGenerator, error) {
|
||||||
var interfaces []InterfaceGenerator
|
var interfaces []InterfaceGenerator
|
||||||
var addresses []net.IPNet
|
var addresses []net.IPNet
|
||||||
var routes []route
|
var routes []route
|
||||||
for _, netblock := range netdata.Netblocks {
|
/* for _, netblock := range netdata.Netblocks {
|
||||||
addresses = append(addresses, net.IPNet{
|
addresses = append(addresses, net.IPNet{
|
||||||
IP: netblock.Address,
|
IP: netblock.Address,
|
||||||
Mask: net.IPMask(netblock.Netmask),
|
Mask: net.IPMask(netblock.Netmask),
|
||||||
})
|
|
||||||
if netblock.Public == false {
|
|
||||||
routes = append(routes, route{
|
|
||||||
destination: net.IPNet{
|
|
||||||
IP: net.IPv4(10, 0, 0, 0),
|
|
||||||
Mask: net.IPv4Mask(255, 0, 0, 0),
|
|
||||||
},
|
|
||||||
gateway: netblock.Gateway,
|
|
||||||
})
|
})
|
||||||
} else {
|
if netblock.Public == false {
|
||||||
if netblock.AddressFamily == 4 {
|
|
||||||
routes = append(routes, route{
|
routes = append(routes, route{
|
||||||
destination: net.IPNet{
|
destination: net.IPNet{
|
||||||
IP: net.IPv4zero,
|
IP: net.IPv4(10, 0, 0, 0),
|
||||||
Mask: net.IPMask(net.IPv4zero),
|
Mask: net.IPv4Mask(255, 0, 0, 0),
|
||||||
},
|
},
|
||||||
gateway: netblock.Gateway,
|
gateway: netblock.Gateway,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
routes = append(routes, route{
|
if netblock.AddressFamily == 4 {
|
||||||
destination: net.IPNet{
|
routes = append(routes, route{
|
||||||
IP: net.IPv6zero,
|
destination: net.IPNet{
|
||||||
Mask: net.IPMask(net.IPv6zero),
|
IP: net.IPv4zero,
|
||||||
},
|
Mask: net.IPMask(net.IPv4zero),
|
||||||
gateway: netblock.Gateway,
|
},
|
||||||
})
|
gateway: netblock.Gateway,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
routes = append(routes, route{
|
||||||
|
destination: net.IPNet{
|
||||||
|
IP: net.IPv6zero,
|
||||||
|
Mask: net.IPMask(net.IPv6zero),
|
||||||
|
},
|
||||||
|
gateway: netblock.Gateway,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
|
|
||||||
bond := bondInterface{
|
bond := bondInterface{
|
||||||
logicalInterface: logicalInterface{
|
logicalInterface: logicalInterface{
|
||||||
@ -92,14 +94,15 @@ func parseNetwork(netdata packet.NetworkData, nameservers []net.IP) ([]Interface
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
bond.hwaddr, _ = net.ParseMAC(netdata.Interfaces[0].Mac)
|
//bond.hwaddr, _ = net.ParseMAC(netdata.Interfaces[0].Mac)
|
||||||
|
|
||||||
for index, iface := range netdata.Interfaces {
|
index := 0
|
||||||
bond.slaves = append(bond.slaves, iface.Name)
|
for name := range netdata.Interfaces {
|
||||||
|
bond.slaves = append(bond.slaves, name)
|
||||||
|
|
||||||
interfaces = append(interfaces, &physicalInterface{
|
interfaces = append(interfaces, &physicalInterface{
|
||||||
logicalInterface: logicalInterface{
|
logicalInterface: logicalInterface{
|
||||||
name: iface.Name,
|
name: name,
|
||||||
config: configMethodStatic{
|
config: configMethodStatic{
|
||||||
nameservers: nameservers,
|
nameservers: nameservers,
|
||||||
},
|
},
|
||||||
@ -107,6 +110,7 @@ func parseNetwork(netdata packet.NetworkData, nameservers []net.IP) ([]Interface
|
|||||||
configDepth: index,
|
configDepth: index,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
index = index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces = append(interfaces, &bond)
|
interfaces = append(interfaces, &bond)
|
||||||
|
@ -317,6 +317,7 @@ func readConfigFile(file string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func substituteVars(userDataBytes []byte, metadata datasource.Metadata) []byte {
|
func substituteVars(userDataBytes []byte, metadata datasource.Metadata) []byte {
|
||||||
|
// TODO: I think this currently does nothing - its hardcoded for COREOS env..
|
||||||
env := initialize.NewEnvironment("", "", "", "", metadata)
|
env := initialize.NewEnvironment("", "", "", "", metadata)
|
||||||
userData := env.Apply(string(userDataBytes))
|
userData := env.Apply(string(userDataBytes))
|
||||||
|
|
||||||
|
44
config/types.go
Normal file → Executable file
44
config/types.go
Normal file → Executable file
@ -8,6 +8,7 @@ import (
|
|||||||
composeConfig "github.com/docker/libcompose/config"
|
composeConfig "github.com/docker/libcompose/config"
|
||||||
"github.com/rancher/os/config/cloudinit/config"
|
"github.com/rancher/os/config/cloudinit/config"
|
||||||
"github.com/rancher/os/config/yaml"
|
"github.com/rancher/os/config/yaml"
|
||||||
|
"github.com/rancher/os/netconf"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -113,8 +114,8 @@ type RancherConfig struct {
|
|||||||
Disable []string `yaml:"disable,omitempty"`
|
Disable []string `yaml:"disable,omitempty"`
|
||||||
ServicesInclude map[string]bool `yaml:"services_include,omitempty"`
|
ServicesInclude map[string]bool `yaml:"services_include,omitempty"`
|
||||||
Modules []string `yaml:"modules,omitempty"`
|
Modules []string `yaml:"modules,omitempty"`
|
||||||
Network NetworkConfig `yaml:"network,omitempty"`
|
Network netconf.NetworkConfig `yaml:"network,omitempty"`
|
||||||
DefaultNetwork NetworkConfig `yaml:"default_network,omitempty"`
|
DefaultNetwork netconf.NetworkConfig `yaml:"default_network,omitempty"`
|
||||||
Repositories Repositories `yaml:"repositories,omitempty"`
|
Repositories Repositories `yaml:"repositories,omitempty"`
|
||||||
SSH SSHConfig `yaml:"ssh,omitempty"`
|
SSH SSHConfig `yaml:"ssh,omitempty"`
|
||||||
State StateConfig `yaml:"state,omitempty"`
|
State StateConfig `yaml:"state,omitempty"`
|
||||||
@ -170,39 +171,6 @@ type DockerConfig struct {
|
|||||||
Exec bool `yaml:"exec,omitempty"`
|
Exec bool `yaml:"exec,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkConfig struct {
|
|
||||||
PreCmds []string `yaml:"pre_cmds,omitempty"`
|
|
||||||
DNS DNSConfig `yaml:"dns,omitempty"`
|
|
||||||
Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
|
|
||||||
PostCmds []string `yaml:"post_cmds,omitempty"`
|
|
||||||
HTTPProxy string `yaml:"http_proxy,omitempty"`
|
|
||||||
HTTPSProxy string `yaml:"https_proxy,omitempty"`
|
|
||||||
NoProxy string `yaml:"no_proxy,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type InterfaceConfig struct {
|
|
||||||
Match string `yaml:"match,omitempty"`
|
|
||||||
DHCP bool `yaml:"dhcp,omitempty"`
|
|
||||||
DHCPArgs string `yaml:"dhcp_args,omitempty"`
|
|
||||||
Address string `yaml:"address,omitempty"`
|
|
||||||
Addresses []string `yaml:"addresses,omitempty"`
|
|
||||||
IPV4LL bool `yaml:"ipv4ll,omitempty"`
|
|
||||||
Gateway string `yaml:"gateway,omitempty"`
|
|
||||||
GatewayIpv6 string `yaml:"gateway_ipv6,omitempty"`
|
|
||||||
MTU int `yaml:"mtu,omitempty"`
|
|
||||||
Bridge string `yaml:"bridge,omitempty"`
|
|
||||||
Bond string `yaml:"bond,omitempty"`
|
|
||||||
BondOpts map[string]string `yaml:"bond_opts,omitempty"`
|
|
||||||
PostUp []string `yaml:"post_up,omitempty"`
|
|
||||||
PreUp []string `yaml:"pre_up,omitempty"`
|
|
||||||
Vlans string `yaml:"vlans,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSConfig struct {
|
|
||||||
Nameservers []string `yaml:"nameservers,flow,omitempty"`
|
|
||||||
Search []string `yaml:"search,flow,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SSHConfig struct {
|
type SSHConfig struct {
|
||||||
Keys map[string]string `yaml:"keys,omitempty"`
|
Keys map[string]string `yaml:"keys,omitempty"`
|
||||||
}
|
}
|
||||||
@ -225,9 +193,9 @@ type CloudInit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Defaults struct {
|
type Defaults struct {
|
||||||
Hostname string `yaml:"hostname,omitempty"`
|
Hostname string `yaml:"hostname,omitempty"`
|
||||||
Docker DockerConfig `yaml:"docker,omitempty"`
|
Docker DockerConfig `yaml:"docker,omitempty"`
|
||||||
Network NetworkConfig `yaml:"network,omitempty"`
|
Network netconf.NetworkConfig `yaml:"network,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Repositories) ToArray() []string {
|
func (r Repositories) ToArray() []string {
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/libnetwork/resolvconf"
|
"github.com/docker/libnetwork/resolvconf"
|
||||||
"github.com/rancher/os/config"
|
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
"github.com/rancher/os/netconf"
|
"github.com/rancher/os/netconf"
|
||||||
"github.com/rancher/os/selinux"
|
"github.com/rancher/os/selinux"
|
||||||
@ -46,7 +45,7 @@ type Config struct {
|
|||||||
Fork bool
|
Fork bool
|
||||||
PidOne bool
|
PidOne bool
|
||||||
CommandName string
|
CommandName string
|
||||||
DNSConfig config.DNSConfig
|
DNSConfig netconf.DNSConfig
|
||||||
BridgeName string
|
BridgeName string
|
||||||
BridgeAddress string
|
BridgeAddress string
|
||||||
BridgeMtu int
|
BridgeMtu int
|
||||||
@ -359,8 +358,8 @@ ff02::2 ip6-allrouters
|
|||||||
|
|
||||||
if cfg.BridgeName != "" && cfg.BridgeName != "none" {
|
if cfg.BridgeName != "" && cfg.BridgeName != "none" {
|
||||||
log.Debugf("Creating bridge %s (%s)", cfg.BridgeName, cfg.BridgeAddress)
|
log.Debugf("Creating bridge %s (%s)", cfg.BridgeName, cfg.BridgeAddress)
|
||||||
if err := netconf.ApplyNetworkConfigs(&config.NetworkConfig{
|
if err := netconf.ApplyNetworkConfigs(&netconf.NetworkConfig{
|
||||||
Interfaces: map[string]config.InterfaceConfig{
|
Interfaces: map[string]netconf.InterfaceConfig{
|
||||||
cfg.BridgeName: {
|
cfg.BridgeName: {
|
||||||
Address: cfg.BridgeAddress,
|
Address: cfg.BridgeAddress,
|
||||||
MTU: cfg.BridgeMtu,
|
MTU: cfg.BridgeMtu,
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/flynn/go-shlex"
|
"github.com/flynn/go-shlex"
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
"github.com/rancher/os/config"
|
|
||||||
"github.com/ryanuber/go-glob"
|
"github.com/ryanuber/go-glob"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
@ -27,7 +26,7 @@ var (
|
|||||||
defaultDhcpArgs = []string{"dhcpcd", "-MA4"}
|
defaultDhcpArgs = []string{"dhcpcd", "-MA4"}
|
||||||
)
|
)
|
||||||
|
|
||||||
func createInterfaces(netCfg *config.NetworkConfig) {
|
func createInterfaces(netCfg *NetworkConfig) {
|
||||||
configured := map[string]bool{}
|
configured := map[string]bool{}
|
||||||
|
|
||||||
for name, iface := range netCfg.Interfaces {
|
for name, iface := range netCfg.Interfaces {
|
||||||
@ -65,7 +64,7 @@ func createInterfaces(netCfg *config.NetworkConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSlaveInterfaces(netCfg *config.NetworkConfig) {
|
func createSlaveInterfaces(netCfg *NetworkConfig) {
|
||||||
links, err := netlink.LinkList()
|
links, err := netlink.LinkList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to list links: %v", err)
|
log.Errorf("Failed to list links: %v", err)
|
||||||
@ -92,9 +91,9 @@ func createSlaveInterfaces(netCfg *config.NetworkConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func findMatch(link netlink.Link, netCfg *config.NetworkConfig) (config.InterfaceConfig, bool) {
|
func findMatch(link netlink.Link, netCfg *NetworkConfig) (InterfaceConfig, bool) {
|
||||||
linkName := link.Attrs().Name
|
linkName := link.Attrs().Name
|
||||||
var match config.InterfaceConfig
|
var match InterfaceConfig
|
||||||
exactMatch := false
|
exactMatch := false
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
@ -136,25 +135,25 @@ func findMatch(link netlink.Link, netCfg *config.NetworkConfig) (config.Interfac
|
|||||||
return match, exactMatch || found
|
return match, exactMatch || found
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateDefault(netCfg *config.NetworkConfig) {
|
func populateDefault(netCfg *NetworkConfig) {
|
||||||
if netCfg.Interfaces == nil {
|
if netCfg.Interfaces == nil {
|
||||||
netCfg.Interfaces = map[string]config.InterfaceConfig{}
|
netCfg.Interfaces = map[string]InterfaceConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(netCfg.Interfaces) == 0 {
|
if len(netCfg.Interfaces) == 0 {
|
||||||
netCfg.Interfaces["eth*"] = config.InterfaceConfig{
|
netCfg.Interfaces["eth*"] = InterfaceConfig{
|
||||||
DHCP: true,
|
DHCP: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := netCfg.Interfaces["lo"]; !ok {
|
if _, ok := netCfg.Interfaces["lo"]; !ok {
|
||||||
netCfg.Interfaces["lo"] = config.InterfaceConfig{
|
netCfg.Interfaces["lo"] = InterfaceConfig{
|
||||||
Address: "127.0.0.1/8",
|
Address: "127.0.0.1/8",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error {
|
func ApplyNetworkConfigs(netCfg *NetworkConfig) error {
|
||||||
populateDefault(netCfg)
|
populateDefault(netCfg)
|
||||||
|
|
||||||
log.Debugf("Config: %#v", netCfg)
|
log.Debugf("Config: %#v", netCfg)
|
||||||
@ -183,7 +182,7 @@ func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunDhcp(netCfg *config.NetworkConfig, setHostname, setDNS bool) error {
|
func RunDhcp(netCfg *NetworkConfig, setHostname, setDNS bool) error {
|
||||||
populateDefault(netCfg)
|
populateDefault(netCfg)
|
||||||
|
|
||||||
links, err := netlink.LinkList()
|
links, err := netlink.LinkList()
|
||||||
@ -212,7 +211,7 @@ func RunDhcp(netCfg *config.NetworkConfig, setHostname, setDNS bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDhcp(netCfg *config.NetworkConfig, iface string, argstr string, setHostname, setDNS bool) {
|
func runDhcp(netCfg *NetworkConfig, iface string, argstr string, setHostname, setDNS bool) {
|
||||||
log.Infof("Running DHCP on %s", iface)
|
log.Infof("Running DHCP on %s", iface)
|
||||||
args := []string{}
|
args := []string{}
|
||||||
if argstr != "" {
|
if argstr != "" {
|
||||||
@ -243,7 +242,7 @@ func runDhcp(netCfg *config.NetworkConfig, iface string, argstr string, setHostn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkUp(link netlink.Link, netConf config.InterfaceConfig) error {
|
func linkUp(link netlink.Link, netConf InterfaceConfig) error {
|
||||||
if err := netlink.LinkSetUp(link); err != nil {
|
if err := netlink.LinkSetUp(link); err != nil {
|
||||||
log.Errorf("failed to setup link: %v", err)
|
log.Errorf("failed to setup link: %v", err)
|
||||||
return err
|
return err
|
||||||
@ -252,7 +251,7 @@ func linkUp(link netlink.Link, netConf config.InterfaceConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyAddress(address string, link netlink.Link, netConf config.InterfaceConfig) error {
|
func applyAddress(address string, link netlink.Link, netConf InterfaceConfig) error {
|
||||||
addr, err := netlink.ParseAddr(address)
|
addr, err := netlink.ParseAddr(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -294,7 +293,7 @@ func setGateway(gateway string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyInterfaceConfig(link netlink.Link, netConf config.InterfaceConfig) error {
|
func applyInterfaceConfig(link netlink.Link, netConf InterfaceConfig) error {
|
||||||
if netConf.Bond != "" {
|
if netConf.Bond != "" {
|
||||||
if err := netlink.LinkSetDown(link); err != nil {
|
if err := netlink.LinkSetDown(link); err != nil {
|
||||||
return err
|
return err
|
||||||
|
34
netconf/types.go
Executable file
34
netconf/types.go
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
package netconf
|
||||||
|
|
||||||
|
type NetworkConfig struct {
|
||||||
|
PreCmds []string `yaml:"pre_cmds,omitempty"`
|
||||||
|
DNS DNSConfig `yaml:"dns,omitempty"`
|
||||||
|
Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
|
||||||
|
PostCmds []string `yaml:"post_cmds,omitempty"`
|
||||||
|
HTTPProxy string `yaml:"http_proxy,omitempty"`
|
||||||
|
HTTPSProxy string `yaml:"https_proxy,omitempty"`
|
||||||
|
NoProxy string `yaml:"no_proxy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterfaceConfig struct {
|
||||||
|
Match string `yaml:"match,omitempty"`
|
||||||
|
DHCP bool `yaml:"dhcp,omitempty"`
|
||||||
|
DHCPArgs string `yaml:"dhcp_args,omitempty"`
|
||||||
|
Address string `yaml:"address,omitempty"`
|
||||||
|
Addresses []string `yaml:"addresses,omitempty"`
|
||||||
|
IPV4LL bool `yaml:"ipv4ll,omitempty"`
|
||||||
|
Gateway string `yaml:"gateway,omitempty"`
|
||||||
|
GatewayIpv6 string `yaml:"gateway_ipv6,omitempty"`
|
||||||
|
MTU int `yaml:"mtu,omitempty"`
|
||||||
|
Bridge string `yaml:"bridge,omitempty"`
|
||||||
|
Bond string `yaml:"bond,omitempty"`
|
||||||
|
BondOpts map[string]string `yaml:"bond_opts,omitempty"`
|
||||||
|
PostUp []string `yaml:"post_up,omitempty"`
|
||||||
|
PreUp []string `yaml:"pre_up,omitempty"`
|
||||||
|
Vlans string `yaml:"vlans,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DNSConfig struct {
|
||||||
|
Nameservers []string `yaml:"nameservers,flow,omitempty"`
|
||||||
|
Search []string `yaml:"search,flow,omitempty"`
|
||||||
|
}
|
29
scripts/ros
Executable file
29
scripts/ros
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
|
if [ ! -e "./build/initrd/usr/share/ros/os-config.yml" ]; then
|
||||||
|
./.dapper release
|
||||||
|
else
|
||||||
|
echo "using existing build of ros"
|
||||||
|
# ./.dapper build-target
|
||||||
|
fi
|
||||||
|
|
||||||
|
source ./scripts/version
|
||||||
|
|
||||||
|
echo "---------------------------------"
|
||||||
|
echo "ln -s /usr/bin/ros /usr/bin/cloud-init-save"
|
||||||
|
echo "ros config set rancher.cloud_init.datasources [packet:https://metadata.packet.net/]"
|
||||||
|
#echo "ros config set rancher.cloud_init.datasources [packet:https://192.80.8.124/]"
|
||||||
|
echo "cloud-init-save"
|
||||||
|
echo "---------------------------------"
|
||||||
|
|
||||||
|
docker run --rm -it \
|
||||||
|
-v $(pwd)/build/initrd/usr/share:/usr/share \
|
||||||
|
-v $(pwd)/bin/ros:/usr/bin/ros \
|
||||||
|
-v /etc/ssl/certs:/etc/ssl/certs \
|
||||||
|
-v /usr/share/ca-certificates:/usr/share/ca-certificates \
|
||||||
|
-w /var/lib/rancher \
|
||||||
|
--entrypoint sh \
|
||||||
|
rancher/os-base:v0.8.1
|
Loading…
Reference in New Issue
Block a user