mirror of
https://github.com/rancher/os.git
synced 2025-08-06 01:04:26 +00:00
latest rancher-compose, default.go -> os-config.yml
also, gofmt
This commit is contained in:
parent
e8aa88530f
commit
dff70f8362
@ -20,7 +20,7 @@ func envAction(c *cli.Context) {
|
|||||||
args := c.Args()
|
args := c.Args()
|
||||||
osEnv := os.Environ()
|
osEnv := os.Environ()
|
||||||
|
|
||||||
envMap := make(map[string]string, len(cfg.Environment) + len(osEnv))
|
envMap := make(map[string]string, len(cfg.Environment)+len(osEnv))
|
||||||
for k, v := range cfg.Environment {
|
for k, v := range cfg.Environment {
|
||||||
envMap[k] = v
|
envMap[k] = v
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ func shutDownContainers() error {
|
|||||||
opts := dockerClient.ListContainersOptions{
|
opts := dockerClient.ListContainersOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: map[string][]string{
|
Filters: map[string][]string{
|
||||||
"status": []string{"running"},
|
"status": {"running"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func setupSigterm() {
|
|||||||
sigtermChan := make(chan os.Signal)
|
sigtermChan := make(chan os.Signal)
|
||||||
signal.Notify(sigtermChan, syscall.SIGTERM)
|
signal.Notify(sigtermChan, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
for _ = range sigtermChan {
|
for range sigtermChan {
|
||||||
termPids()
|
termPids()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -2,6 +2,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
import "reflect"
|
import "reflect"
|
||||||
|
|
||||||
func TestParseCmdline(t *testing.T) {
|
func testParseCmdline(t *testing.T) {
|
||||||
expected := map[string]interface{}{
|
expected := map[string]interface{}{
|
||||||
"rescue": true,
|
"rescue": true,
|
||||||
"key1": "value1",
|
"key1": "value1",
|
||||||
|
@ -1,394 +1,15 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return ReadConfig(OsConfigFile)
|
||||||
Debug: DEBUG,
|
}
|
||||||
State: StateConfig{
|
|
||||||
Required: false,
|
func ReadConfig(file string) *Config {
|
||||||
Dev: "LABEL=RANCHER_STATE",
|
if data, err := readConfig(nil, file); err == nil {
|
||||||
FsType: "auto",
|
c := &Config{}
|
||||||
},
|
c.merge(data)
|
||||||
BootstrapDocker: DockerConfig{
|
return c
|
||||||
Args: []string{
|
} else {
|
||||||
"docker",
|
return nil
|
||||||
"-d",
|
|
||||||
"-s", "overlay",
|
|
||||||
"-b", "none",
|
|
||||||
"--restart=false",
|
|
||||||
"-g", "/var/lib/system-docker",
|
|
||||||
"-G", "root",
|
|
||||||
"-H", DOCKER_SYSTEM_HOST,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SystemDocker: DockerConfig{
|
|
||||||
Args: []string{
|
|
||||||
"docker",
|
|
||||||
"-d",
|
|
||||||
"--log-driver", "syslog",
|
|
||||||
"-s", "overlay",
|
|
||||||
"-b", "docker-sys",
|
|
||||||
"--fixed-cidr", "172.18.42.1/16",
|
|
||||||
"--restart=false",
|
|
||||||
"-g", "/var/lib/system-docker",
|
|
||||||
"-G", "root",
|
|
||||||
"-H", DOCKER_SYSTEM_HOST,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Modules: []string{},
|
|
||||||
UserDocker: DockerConfig{
|
|
||||||
TLSArgs: []string{
|
|
||||||
"--tlsverify",
|
|
||||||
"--tlscacert=ca.pem",
|
|
||||||
"--tlscert=server-cert.pem",
|
|
||||||
"--tlskey=server-key.pem",
|
|
||||||
"-H=0.0.0.0:2376",
|
|
||||||
},
|
|
||||||
Args: []string{
|
|
||||||
"docker",
|
|
||||||
"-d",
|
|
||||||
"-s", "overlay",
|
|
||||||
"-G", "docker",
|
|
||||||
"-H", DOCKER_HOST,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Network: NetworkConfig{
|
|
||||||
Dns: DnsConfig{
|
|
||||||
Nameservers: []string{"8.8.8.8", "8.8.4.4"},
|
|
||||||
},
|
|
||||||
Interfaces: map[string]InterfaceConfig{
|
|
||||||
"eth*": {
|
|
||||||
DHCP: true,
|
|
||||||
},
|
|
||||||
"lo": {
|
|
||||||
Address: "127.0.0.1/8",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CloudInit: CloudInit{
|
|
||||||
Datasources: []string{"configdrive:/media/config-2"},
|
|
||||||
},
|
|
||||||
Upgrade: UpgradeConfig{
|
|
||||||
Url: "https://releases.rancher.com/os/versions.yml",
|
|
||||||
Image: "rancher/os",
|
|
||||||
},
|
|
||||||
BootstrapContainers: map[string]*project.ServiceConfig{
|
|
||||||
"udev": {
|
|
||||||
Net: "host",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Volumes: []string{
|
|
||||||
"/dev:/host/dev",
|
|
||||||
"/lib/modules:/lib/modules",
|
|
||||||
"/lib/firmware:/lib/firmware",
|
|
||||||
},
|
|
||||||
Image: "udev",
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SystemContainers: map[string]*project.ServiceConfig{
|
|
||||||
"udev": {
|
|
||||||
Image: "udev",
|
|
||||||
Restart: "always",
|
|
||||||
Net: "host",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Environment: project.NewMaporslice([]string{
|
|
||||||
"DAEMON=true",
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"system-volumes": {
|
|
||||||
Image: "state",
|
|
||||||
Net: "none",
|
|
||||||
ReadOnly: true,
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
CREATE_ONLY: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Volumes: []string{
|
|
||||||
"/dev:/host/dev",
|
|
||||||
"/var/lib/rancher:/var/lib/rancher",
|
|
||||||
"/var/lib/rancher/conf:/var/lib/rancher/conf",
|
|
||||||
"/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt.rancher",
|
|
||||||
"/lib/modules:/lib/modules",
|
|
||||||
"/lib/firmware:/lib/firmware",
|
|
||||||
"/var/run:/var/run",
|
|
||||||
"/var/log:/var/log",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"command-volumes": {
|
|
||||||
Image: "state",
|
|
||||||
Net: "none",
|
|
||||||
ReadOnly: true,
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
CREATE_ONLY: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Volumes: []string{
|
|
||||||
"/init:/sbin/halt:ro",
|
|
||||||
"/init:/sbin/poweroff:ro",
|
|
||||||
"/init:/sbin/reboot:ro",
|
|
||||||
"/init:/sbin/shutdown:ro",
|
|
||||||
"/init:/sbin/netconf:ro",
|
|
||||||
"/init:/usr/bin/cloud-init:ro",
|
|
||||||
"/init:/usr/bin/rancherctl:ro", // deprecated, use `ros` instead
|
|
||||||
"/init:/usr/bin/ros:ro",
|
|
||||||
"/init:/usr/bin/respawn:ro",
|
|
||||||
"/init:/usr/bin/system-docker:ro",
|
|
||||||
"/init:/usr/sbin/wait-for-docker:ro",
|
|
||||||
"/lib/modules:/lib/modules",
|
|
||||||
"/usr/bin/docker:/usr/bin/docker:ro",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"user-volumes": {
|
|
||||||
Image: "state",
|
|
||||||
Net: "none",
|
|
||||||
ReadOnly: true,
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
CREATE_ONLY: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Volumes: []string{
|
|
||||||
"/home:/home",
|
|
||||||
"/opt:/opt",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"docker-volumes": {
|
|
||||||
Image: "state",
|
|
||||||
Net: "none",
|
|
||||||
ReadOnly: true,
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
CREATE_ONLY: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Volumes: []string{
|
|
||||||
"/var/lib/rancher/conf:/var/lib/rancher/conf",
|
|
||||||
"/var/lib/docker:/var/lib/docker",
|
|
||||||
"/var/lib/system-docker:/var/lib/system-docker",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"all-volumes": {
|
|
||||||
Image: "state",
|
|
||||||
Net: "none",
|
|
||||||
ReadOnly: true,
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
CREATE_ONLY: "true",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"docker-volumes",
|
|
||||||
"command-volumes",
|
|
||||||
"user-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"preload-system-images": {
|
|
||||||
Image: "preload",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
Volumes: []string{
|
|
||||||
"/var/run/system-docker.sock:/var/run/docker.sock",
|
|
||||||
"/var/lib/system-docker/preload:/mnt/preload",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"cloud-init-pre": {
|
|
||||||
Image: "cloudinit",
|
|
||||||
Privileged: true,
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
RELOAD_CONFIG: "true",
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Environment: project.NewMaporslice([]string{
|
|
||||||
"CLOUD_INIT_NETWORK=false",
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"preload-system-images",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
Image: "network",
|
|
||||||
Privileged: true,
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"cloud-init-pre",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"cloud-init": {
|
|
||||||
Image: "cloudinit",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
RELOAD_CONFIG: "true",
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Net: "host",
|
|
||||||
Links: []string{
|
|
||||||
"preload-user-images",
|
|
||||||
"cloud-init-pre",
|
|
||||||
"network",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"ntp": {
|
|
||||||
Image: "ntp",
|
|
||||||
Restart: "always",
|
|
||||||
Privileged: true,
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"cloud-init",
|
|
||||||
"network",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"syslog": {
|
|
||||||
Image: "syslog",
|
|
||||||
Restart: "always",
|
|
||||||
Privileged: true,
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
LogDriver: "json-file",
|
|
||||||
},
|
|
||||||
"docker": {
|
|
||||||
Image: "docker",
|
|
||||||
Restart: "always",
|
|
||||||
Privileged: true,
|
|
||||||
Pid: "host",
|
|
||||||
Ipc: "host",
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"network",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"all-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"dockerwait": {
|
|
||||||
Image: "dockerwait",
|
|
||||||
Net: "host",
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"docker",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"all-volumes",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"preload-user-images": {
|
|
||||||
Image: "preload",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
DETACH: "false",
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
Links: []string{
|
|
||||||
"dockerwait",
|
|
||||||
},
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
Volumes: []string{
|
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"/var/lib/docker/preload:/mnt/preload",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"console": {
|
|
||||||
Image: "console",
|
|
||||||
Privileged: true,
|
|
||||||
Links: []string{
|
|
||||||
"cloud-init",
|
|
||||||
},
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"all-volumes",
|
|
||||||
},
|
|
||||||
Restart: "always",
|
|
||||||
Pid: "host",
|
|
||||||
Ipc: "host",
|
|
||||||
Net: "host",
|
|
||||||
},
|
|
||||||
"acpid": {
|
|
||||||
Image: "acpid",
|
|
||||||
Privileged: true,
|
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
|
||||||
SCOPE: SYSTEM,
|
|
||||||
}),
|
|
||||||
VolumesFrom: []string{
|
|
||||||
"command-volumes",
|
|
||||||
"system-volumes",
|
|
||||||
},
|
|
||||||
Net: "host",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ServicesInclude: map[string]bool{
|
|
||||||
"ubuntu-console": false,
|
|
||||||
},
|
|
||||||
Repositories: map[string]Repository{
|
|
||||||
"core": Repository{
|
|
||||||
Url: "https://raw.githubusercontent.com/rancherio/os-services/" + DEFAULT_IMAGE_VERSION,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Services: map[string]*project.ServiceConfig{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ const (
|
|||||||
var (
|
var (
|
||||||
VERSION string
|
VERSION string
|
||||||
IMAGE_VERSION string
|
IMAGE_VERSION string
|
||||||
|
OsConfigFile = "/os-config.yml"
|
||||||
CloudConfigFile = "/var/lib/rancher/conf/cloud-config-rancher.yml"
|
CloudConfigFile = "/var/lib/rancher/conf/cloud-config-rancher.yml"
|
||||||
ConfigFile = "/var/lib/rancher/conf/rancher.yml"
|
ConfigFile = "/var/lib/rancher/conf/rancher.yml"
|
||||||
PrivateConfigFile = "/var/lib/rancher/conf/rancher-private.yml"
|
PrivateConfigFile = "/var/lib/rancher/conf/rancher-private.yml"
|
||||||
|
@ -92,9 +92,30 @@ func getHash(containerCfg *config.ContainerConfig) string {
|
|||||||
for _, sliceKey := range sliceKeys {
|
for _, sliceKey := range sliceKeys {
|
||||||
io.WriteString(hash, fmt.Sprintf("%s=%v, ", sliceKey, s.MapParts()[sliceKey]))
|
io.WriteString(hash, fmt.Sprintf("%s=%v, ", sliceKey, s.MapParts()[sliceKey]))
|
||||||
}
|
}
|
||||||
case project.Maporslice:
|
case project.MaporEqualSlice:
|
||||||
sliceKeys := s.Slice()
|
sliceKeys := s.Slice()
|
||||||
// do not sort environment keys as the order matters
|
// do not sort keys as the order matters
|
||||||
|
|
||||||
|
for _, sliceKey := range sliceKeys {
|
||||||
|
io.WriteString(hash, fmt.Sprintf("%s, ", sliceKey))
|
||||||
|
}
|
||||||
|
case project.MaporColonSlice:
|
||||||
|
sliceKeys := s.Slice()
|
||||||
|
// do not sort keys as the order matters
|
||||||
|
|
||||||
|
for _, sliceKey := range sliceKeys {
|
||||||
|
io.WriteString(hash, fmt.Sprintf("%s, ", sliceKey))
|
||||||
|
}
|
||||||
|
case project.MaporSpaceSlice:
|
||||||
|
sliceKeys := s.Slice()
|
||||||
|
// do not sort keys as the order matters
|
||||||
|
|
||||||
|
for _, sliceKey := range sliceKeys {
|
||||||
|
io.WriteString(hash, fmt.Sprintf("%s, ", sliceKey))
|
||||||
|
}
|
||||||
|
case project.Command:
|
||||||
|
sliceKeys := s.Slice()
|
||||||
|
// do not sort keys as the order matters
|
||||||
|
|
||||||
for _, sliceKey := range sliceKeys {
|
for _, sliceKey := range sliceKeys {
|
||||||
io.WriteString(hash, fmt.Sprintf("%s, ", sliceKey))
|
io.WriteString(hash, fmt.Sprintf("%s, ", sliceKey))
|
||||||
@ -157,7 +178,7 @@ func getByLabel(client *dockerClient.Client, key, value string) (*dockerClient.A
|
|||||||
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: map[string][]string{
|
Filters: map[string][]string{
|
||||||
config.LABEL: []string{fmt.Sprintf("%s=%s", key, value)},
|
config.LABEL: {fmt.Sprintf("%s=%s", key, value)},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -190,7 +211,7 @@ func (c *Container) Lookup() *Container {
|
|||||||
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: map[string][]string{
|
Filters: map[string][]string{
|
||||||
config.LABEL: []string{fmt.Sprintf("%s=%s", config.HASH, hash)},
|
config.LABEL: {fmt.Sprintf("%s=%s", config.HASH, hash)},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -246,7 +267,7 @@ func (c *Container) requiresUserDocker() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) hasLink(link string) bool {
|
func (c *Container) hasLink(link string) bool {
|
||||||
return util.Contains(c.ContainerCfg.Service.Links, link)
|
return util.Contains(c.ContainerCfg.Service.Links.Slice(), link)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) addLink(link string) {
|
func (c *Container) addLink(link string) {
|
||||||
@ -255,7 +276,7 @@ func (c *Container) addLink(link string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Adding %s link to %s", link, c.Name)
|
log.Debugf("Adding %s link to %s", link, c.Name)
|
||||||
c.ContainerCfg.Service.Links = append(c.ContainerCfg.Service.Links, link)
|
c.ContainerCfg.Service.Links = project.NewMaporColonSlice(append(c.ContainerCfg.Service.Links.Slice(), link))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) parseService() {
|
func (c *Container) parseService() {
|
||||||
|
@ -45,7 +45,45 @@ func TestHash2(t *testing.T) {
|
|||||||
MigrateVolumes: false,
|
MigrateVolumes: false,
|
||||||
ReloadConfig: false,
|
ReloadConfig: false,
|
||||||
CreateOnly: true,
|
CreateOnly: true,
|
||||||
Service: &project.ServiceConfig{CapAdd:nil, CapDrop:nil, CpuShares:0, Command:"", Detach:"", Dns:project.NewStringorslice(), DnsSearch:project.NewStringorslice(), DomainName:"", Entrypoint:"", EnvFile:"", Environment:project.NewMaporslice([]string{}), Hostname:"", Image:"state", Labels:project.NewSliceorMap(map[string]string{"io.rancher.os.createonly":"true", "io.rancher.os.scope":"system"}), Links:nil, LogDriver:"json-file", MemLimit:0, Name:"", Net:"none", Pid:"", Ipc:"", Ports:nil, Privileged:true, Restart:"", ReadOnly:true, StdinOpen:false, Tty:false, User:"", Volumes:[]string{"/var/lib/docker:/var/lib/docker", "/var/lib/rancher/conf:/var/lib/rancher/conf", "/var/lib/system-docker:/var/lib/system-docker"}, VolumesFrom:nil, WorkingDir:"", Expose:nil, ExternalLinks:nil},
|
Service: &project.ServiceConfig{
|
||||||
|
CapAdd: nil,
|
||||||
|
CapDrop: nil,
|
||||||
|
CpuShares: 0,
|
||||||
|
Command: project.NewCommand(),
|
||||||
|
Detach: "",
|
||||||
|
Dns: project.NewStringorslice(),
|
||||||
|
DnsSearch: project.NewStringorslice(),
|
||||||
|
DomainName: "",
|
||||||
|
Entrypoint: project.NewCommand(),
|
||||||
|
EnvFile: project.NewStringorslice(),
|
||||||
|
Environment: project.NewMaporEqualSlice([]string{}),
|
||||||
|
Hostname: "",
|
||||||
|
Image: "state",
|
||||||
|
Labels: project.NewSliceorMap(map[string]string{
|
||||||
|
"io.rancher.os.createonly": "true",
|
||||||
|
"io.rancher.os.scope": "system"}),
|
||||||
|
Links: project.NewMaporColonSlice(nil),
|
||||||
|
LogDriver: "json-file",
|
||||||
|
MemLimit: 0,
|
||||||
|
Name: "",
|
||||||
|
Net: "none",
|
||||||
|
Pid: "",
|
||||||
|
Ipc: "",
|
||||||
|
Ports: nil,
|
||||||
|
Privileged: true,
|
||||||
|
Restart: "",
|
||||||
|
ReadOnly: true,
|
||||||
|
StdinOpen: false,
|
||||||
|
Tty: false,
|
||||||
|
User: "",
|
||||||
|
Volumes: []string{
|
||||||
|
"/var/lib/docker:/var/lib/docker",
|
||||||
|
"/var/lib/rancher/conf:/var/lib/rancher/conf",
|
||||||
|
"/var/lib/system-docker:/var/lib/system-docker"},
|
||||||
|
VolumesFrom: nil,
|
||||||
|
WorkingDir: "",
|
||||||
|
Expose: nil,
|
||||||
|
ExternalLinks: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
@ -58,7 +96,6 @@ func TestBool2String(t *testing.T) {
|
|||||||
assert.Equal("true", fmt.Sprint(true), "")
|
assert.Equal("true", fmt.Sprint(true), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ type ContainerFactory struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type containerBasedService struct {
|
type containerBasedService struct {
|
||||||
|
project.EmptyService
|
||||||
name string
|
name string
|
||||||
project *project.Project
|
project *project.Project
|
||||||
container *Container
|
container *Container
|
||||||
|
@ -70,7 +70,7 @@ outer:
|
|||||||
|
|
||||||
// copy
|
// copy
|
||||||
udev := *cfg.BootstrapContainers["udev"]
|
udev := *cfg.BootstrapContainers["udev"]
|
||||||
udev.Links = append(udev.Links, "autoformat")
|
udev.Links = project.NewMaporColonSlice(append(udev.Links.Slice(), "autoformat"))
|
||||||
udev.LogDriver = "json-file"
|
udev.LogDriver = "json-file"
|
||||||
|
|
||||||
err := docker.RunServices("autoformat", cfg, map[string]*project.ServiceConfig{
|
err := docker.RunServices("autoformat", cfg, map[string]*project.ServiceConfig{
|
||||||
@ -78,13 +78,13 @@ outer:
|
|||||||
Net: "none",
|
Net: "none",
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
Image: "autoformat",
|
Image: "autoformat",
|
||||||
Command: format,
|
Command: project.NewCommand(format),
|
||||||
Labels: project.NewSliceorMap(map[string]string{
|
Labels: project.NewSliceorMap(map[string]string{
|
||||||
config.DETACH: "false",
|
config.DETACH: "false",
|
||||||
config.SCOPE: config.SYSTEM,
|
config.SCOPE: config.SYSTEM,
|
||||||
}),
|
}),
|
||||||
LogDriver: "json-file",
|
LogDriver: "json-file",
|
||||||
Environment: project.NewMaporslice([]string{
|
Environment: project.NewMaporEqualSlice([]string{
|
||||||
"MAGIC=" + boot2dockerMagic,
|
"MAGIC=" + boot2dockerMagic,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
18
init/init.go
18
init/init.go
@ -34,16 +34,16 @@ var (
|
|||||||
"/var/lib/rancher/state/opt",
|
"/var/lib/rancher/state/opt",
|
||||||
}
|
}
|
||||||
mounts [][]string = [][]string{
|
mounts [][]string = [][]string{
|
||||||
[]string{"devtmpfs", "/dev", "devtmpfs", ""},
|
{"devtmpfs", "/dev", "devtmpfs", ""},
|
||||||
[]string{"none", "/dev/pts", "devpts", ""},
|
{"none", "/dev/pts", "devpts", ""},
|
||||||
[]string{"none", "/etc/docker", "tmpfs", ""},
|
{"none", "/etc/docker", "tmpfs", ""},
|
||||||
[]string{"none", "/proc", "proc", ""},
|
{"none", "/proc", "proc", ""},
|
||||||
[]string{"none", "/run", "tmpfs", ""},
|
{"none", "/run", "tmpfs", ""},
|
||||||
[]string{"none", "/sys", "sysfs", ""},
|
{"none", "/sys", "sysfs", ""},
|
||||||
[]string{"none", "/sys/fs/cgroup", "tmpfs", ""},
|
{"none", "/sys/fs/cgroup", "tmpfs", ""},
|
||||||
}
|
}
|
||||||
postMounts [][]string = [][]string{
|
postMounts [][]string = [][]string{
|
||||||
[]string{"none", "/var/run", "tmpfs", ""},
|
{"none", "/var/run", "tmpfs", ""},
|
||||||
}
|
}
|
||||||
cgroups []string = []string{
|
cgroups []string = []string{
|
||||||
"blkio",
|
"blkio",
|
||||||
@ -123,7 +123,7 @@ func mountCgroups(cfg *config.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = createMounts([][]string{
|
err = createMounts([][]string{
|
||||||
[]string{"none", "sys/fs/cgroup/" + cgroup, "cgroup", cgroup},
|
{"none", "sys/fs/cgroup/" + cgroup, "cgroup", cgroup},
|
||||||
}...)
|
}...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
370
os-config.yml
Normal file
370
os-config.yml
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
bootstrap_containers:
|
||||||
|
udev:
|
||||||
|
image: udev
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- /dev:/host/dev
|
||||||
|
- /lib/modules:/lib/modules
|
||||||
|
- /lib/firmware:/lib/firmware
|
||||||
|
bootstrap_docker:
|
||||||
|
args: [docker, -d, -s, overlay, -b, none, --restart=false, -g, /var/lib/system-docker,
|
||||||
|
-G, root, -H, 'unix:///var/run/system-docker.sock']
|
||||||
|
cloud_init:
|
||||||
|
datasources:
|
||||||
|
- configdrive:/media/config-2
|
||||||
|
services_include:
|
||||||
|
ubuntu-console: false
|
||||||
|
network:
|
||||||
|
dns:
|
||||||
|
nameservers: [8.8.8.8, 8.8.4.4]
|
||||||
|
interfaces:
|
||||||
|
eth*:
|
||||||
|
dhcp: true
|
||||||
|
lo:
|
||||||
|
address: 127.0.0.1/8
|
||||||
|
repositories:
|
||||||
|
core:
|
||||||
|
url: https://raw.githubusercontent.com/rancherio/os-services/v0.3.1
|
||||||
|
state:
|
||||||
|
fstype: auto
|
||||||
|
dev: LABEL=RANCHER_STATE
|
||||||
|
system_containers:
|
||||||
|
acpid:
|
||||||
|
image: acpid
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
all-volumes:
|
||||||
|
image: state
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.createonly: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: none
|
||||||
|
privileged: true
|
||||||
|
read_only: true
|
||||||
|
volumes_from:
|
||||||
|
- docker-volumes
|
||||||
|
- command-volumes
|
||||||
|
- user-volumes
|
||||||
|
- system-volumes
|
||||||
|
cloud-init:
|
||||||
|
image: cloudinit
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.reloadconfig: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- preload-user-images
|
||||||
|
- cloud-init-pre
|
||||||
|
- network
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
cloud-init-pre:
|
||||||
|
image: cloudinit
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment:
|
||||||
|
- CLOUD_INIT_NETWORK=false
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.reloadconfig: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- preload-system-images
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
command-volumes:
|
||||||
|
image: state
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.createonly: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: none
|
||||||
|
privileged: true
|
||||||
|
read_only: true
|
||||||
|
volumes:
|
||||||
|
- /init:/sbin/halt:ro
|
||||||
|
- /init:/sbin/poweroff:ro
|
||||||
|
- /init:/sbin/reboot:ro
|
||||||
|
- /init:/sbin/shutdown:ro
|
||||||
|
- /init:/sbin/netconf:ro
|
||||||
|
- /init:/usr/bin/cloud-init:ro
|
||||||
|
- /init:/usr/bin/rancherctl:ro
|
||||||
|
- /init:/usr/bin/ros:ro
|
||||||
|
- /init:/usr/bin/respawn:ro
|
||||||
|
- /init:/usr/bin/system-docker:ro
|
||||||
|
- /init:/usr/sbin/wait-for-docker:ro
|
||||||
|
- /lib/modules:/lib/modules
|
||||||
|
- /usr/bin/docker:/usr/bin/docker:ro
|
||||||
|
console:
|
||||||
|
image: console
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.remove: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- cloud-init
|
||||||
|
net: host
|
||||||
|
pid: host
|
||||||
|
ipc: host
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
volumes_from:
|
||||||
|
- all-volumes
|
||||||
|
docker:
|
||||||
|
image: docker
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- network
|
||||||
|
net: host
|
||||||
|
pid: host
|
||||||
|
ipc: host
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
volumes_from:
|
||||||
|
- all-volumes
|
||||||
|
docker-volumes:
|
||||||
|
image: state
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.createonly: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: none
|
||||||
|
privileged: true
|
||||||
|
read_only: true
|
||||||
|
volumes:
|
||||||
|
- /var/lib/rancher/conf:/var/lib/rancher/conf
|
||||||
|
- /var/lib/docker:/var/lib/docker
|
||||||
|
- /var/lib/system-docker:/var/lib/system-docker
|
||||||
|
dockerwait:
|
||||||
|
image: dockerwait
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- docker
|
||||||
|
net: host
|
||||||
|
volumes_from:
|
||||||
|
- all-volumes
|
||||||
|
network:
|
||||||
|
image: network
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- cloud-init-pre
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
ntp:
|
||||||
|
image: ntp
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- cloud-init
|
||||||
|
- network
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
preload-system-images:
|
||||||
|
image: preload
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- /var/run/system-docker.sock:/var/run/docker.sock
|
||||||
|
- /var/lib/system-docker/preload:/mnt/preload
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
preload-user-images:
|
||||||
|
image: preload
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: false
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links:
|
||||||
|
- dockerwait
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /var/lib/docker/preload:/mnt/preload
|
||||||
|
volumes_from:
|
||||||
|
- command-volumes
|
||||||
|
- system-volumes
|
||||||
|
syslog:
|
||||||
|
image: syslog
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
volumes_from:
|
||||||
|
- system-volumes
|
||||||
|
system-volumes:
|
||||||
|
image: state
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.createonly: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: none
|
||||||
|
privileged: true
|
||||||
|
read_only: true
|
||||||
|
volumes:
|
||||||
|
- /dev:/host/dev
|
||||||
|
- /os-config.yml:/os-config.yml
|
||||||
|
- /var/lib/rancher/conf:/var/lib/rancher/conf
|
||||||
|
- /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt.rancher
|
||||||
|
- /lib/modules:/lib/modules
|
||||||
|
- /lib/firmware:/lib/firmware
|
||||||
|
- /var/run:/var/run
|
||||||
|
- /var/log:/var/log
|
||||||
|
udev:
|
||||||
|
image: udev
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment:
|
||||||
|
- DAEMON=true
|
||||||
|
labels:
|
||||||
|
io.rancher.os.detach: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
net: host
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
volumes_from:
|
||||||
|
- system-volumes
|
||||||
|
user-volumes:
|
||||||
|
image: state
|
||||||
|
command: []
|
||||||
|
dns: []
|
||||||
|
dns_search: []
|
||||||
|
env_file: []
|
||||||
|
environment: []
|
||||||
|
labels:
|
||||||
|
io.rancher.os.createonly: true
|
||||||
|
io.rancher.os.scope: system
|
||||||
|
links: []
|
||||||
|
log_driver: json-file
|
||||||
|
net: none
|
||||||
|
privileged: true
|
||||||
|
read_only: true
|
||||||
|
volumes:
|
||||||
|
- /home:/home
|
||||||
|
- /opt:/opt
|
||||||
|
system_docker:
|
||||||
|
args: [docker, -d, --log-driver, syslog, -s, overlay, -b, docker-sys, --fixed-cidr,
|
||||||
|
172.18.42.1/16, --restart=false, -g, /var/lib/system-docker, -G, root, -H, 'unix:///var/run/system-docker.sock']
|
||||||
|
upgrade:
|
||||||
|
url: https://releases.rancher.com/os/versions.yml
|
||||||
|
image: rancher/os
|
||||||
|
user_docker:
|
||||||
|
tls_args: [--tlsverify, --tlscacert=ca.pem, --tlscert=server-cert.pem, --tlskey=server-key.pem,
|
||||||
|
'-H=0.0.0.0:2376']
|
||||||
|
args: [docker, -d, -s, overlay, -G, docker, -H, 'unix:///var/run/docker.sock']
|
@ -7,6 +7,7 @@ source scripts/build-common
|
|||||||
|
|
||||||
|
|
||||||
cp bin/rancheros ${BUILD}/initrd/init
|
cp bin/rancheros ${BUILD}/initrd/init
|
||||||
|
cp ./os-config.yml ${BUILD}/initrd/
|
||||||
|
|
||||||
cd ${BUILD}/initrd
|
cd ${BUILD}/initrd
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ if [ ! -e bin/rancheros ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cp bin/rancheros ${INITRD_TMP}/init
|
cp bin/rancheros ${INITRD_TMP}/init
|
||||||
|
cp -f os-config.yml ${INITRD_TMP}/
|
||||||
cd ${INITRD_TMP}
|
cd ${INITRD_TMP}
|
||||||
|
|
||||||
find | cpio -H newc -o > ${INITRD_TEST}
|
find | cpio -H newc -o > ${INITRD_TEST}
|
||||||
|
@ -306,7 +306,7 @@ func GetValue(kvPairs []string, key string) string {
|
|||||||
func Map2KVPairs(m map[string]string) []string {
|
func Map2KVPairs(m map[string]string) []string {
|
||||||
r := make([]string, 0, len(m))
|
r := make([]string, 0, len(m))
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
r = append(r, k + "=" + v)
|
r = append(r, k+"="+v)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user