4
0
raspi-alpine-builder/network.go
2019-11-29 19:53:17 +01:00

172 lines
4.0 KiB
Go

package alpine_builder
import (
"bufio"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
)
// network configuration
var networkConfig = "/data/etc/network/interfaces"
var networkInterface = "eth0"
// regular expressions
var reSectionStart = regexp.MustCompile("^(iface|mapping|auto|allow-|source)")
var reIface = regexp.MustCompile("^iface (\\w+) inet (\\w+)")
var reStaticAddress = regexp.MustCompile("^(\\s*)address ([0-9.]+)")
var reStaticNetmask = regexp.MustCompile("^(\\s*)netmask ([0-9.]+)")
var reStaticGateway = regexp.MustCompile("^(\\s*)gateway ([0-9.]+)")
// NetworkInfo represents the actual network configuration
type NetworkInfo struct {
IsStatic bool
Address string
Netmask string
Gateway string
}
// GetNetworkInfo from config file
func GetNetworkInfo() (*NetworkInfo, error) {
// load config file
file, err := os.Open(networkConfig)
if err != nil {
return nil, fmt.Errorf("failed to open network config: %w", err)
}
defer file.Close()
var info *NetworkInfo
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// check for section start
if reSectionStart.MatchString(line) {
infLine := reIface.FindStringSubmatch(line)
if infLine != nil {
// interface found
if infLine[1] == networkInterface {
info = &NetworkInfo{
IsStatic: infLine[2] == "static",
}
}
} else {
// info set -> stop here
if info != nil {
break
}
}
} else if info != nil {
// interface config
address := reStaticAddress.FindStringSubmatch(line)
if address != nil {
info.Address = address[2]
}
netmask := reStaticNetmask.FindStringSubmatch(line)
if netmask != nil {
info.Netmask = netmask[2]
}
gateway := reStaticGateway.FindStringSubmatch(line)
if gateway != nil {
info.Gateway = gateway[2]
}
}
}
if info != nil {
return info, nil
}
return nil, errors.New("invalid network config")
}
// NetworkEnableDHCP configures the network to use DHCP client
func NetworkEnableDHCP() error {
// load config file
file, err := os.Open(networkConfig)
if err != nil {
return fmt.Errorf("failed to open network config: %w", err)
}
defer file.Close()
var buffer bytes.Buffer
var infFound bool
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// check for section start
if reSectionStart.MatchString(line) {
infLine := reIface.FindStringSubmatch(line)
if infLine != nil {
// interface found
if infLine[1] == networkInterface {
infFound = true
buffer.WriteString(fmt.Sprintf("iface %s inet dhcp\n", networkInterface))
continue
}
} else {
if infFound {
infFound = false
}
}
buffer.WriteString(line + "\n")
} else if !infFound {
buffer.WriteString(line + "\n")
}
}
// write config file
return ioutil.WriteFile(networkConfig, buffer.Bytes(), os.ModePerm)
}
// NetworkSetStatic IP configuration
func NetworkSetStatic(address, netmask, gateway string) error {
// load config file
file, err := os.Open(networkConfig)
if err != nil {
return fmt.Errorf("failed to open network config: %w", err)
}
defer file.Close()
var buffer bytes.Buffer
var infFound bool
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// check for section start
if reSectionStart.MatchString(line) {
infLine := reIface.FindStringSubmatch(line)
if infLine != nil {
// interface found
if infLine[1] == networkInterface {
infFound = true
buffer.WriteString(fmt.Sprintf("iface %s inet static\n", networkInterface))
buffer.WriteString(fmt.Sprintf(" address %s\n", address))
buffer.WriteString(fmt.Sprintf(" netmask %s\n", netmask))
buffer.WriteString(fmt.Sprintf(" gateway %s\n", gateway))
continue
}
} else {
if infFound {
infFound = false
}
}
buffer.WriteString(line + "\n")
} else if !infFound {
buffer.WriteString(line + "\n")
}
}
// write config file
return ioutil.WriteFile(networkConfig, buffer.Bytes(), os.ModePerm)
}