mirror of
https://github.com/rancher/os.git
synced 2025-06-30 16:51:47 +00:00
Merge pull request #980 from joshwget/first-class-consoles
First class consoles
This commit is contained in:
commit
cd76d85aea
@ -31,6 +31,12 @@ func Main() {
|
|||||||
HideHelp: true,
|
HideHelp: true,
|
||||||
Subcommands: configSubcommands(),
|
Subcommands: configSubcommands(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "console",
|
||||||
|
Usage: "console container commands",
|
||||||
|
HideHelp: true,
|
||||||
|
Subcommands: consoleSubcommands(),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "dev",
|
Name: "dev",
|
||||||
ShortName: "d",
|
ShortName: "d",
|
||||||
|
104
cmd/control/console.go
Normal file
104
cmd/control/console.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
composeConfig "github.com/docker/libcompose/config"
|
||||||
|
"github.com/docker/libcompose/project/options"
|
||||||
|
"github.com/rancher/os/compose"
|
||||||
|
"github.com/rancher/os/config"
|
||||||
|
"github.com/rancher/os/docker"
|
||||||
|
"github.com/rancher/os/util"
|
||||||
|
"github.com/rancher/os/util/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
func consoleSubcommands() []cli.Command {
|
||||||
|
return []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "switch",
|
||||||
|
Usage: "switch currently running console",
|
||||||
|
Action: consoleSwitch,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "list available consoles",
|
||||||
|
Action: consoleList,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleSwitch(c *cli.Context) error {
|
||||||
|
if len(c.Args()) != 1 {
|
||||||
|
log.Fatal("Must specify exactly one existing container")
|
||||||
|
}
|
||||||
|
newConsole := c.Args()[0]
|
||||||
|
|
||||||
|
in := bufio.NewReader(os.Stdin)
|
||||||
|
question := fmt.Sprintf("Switching consoles will destroy the current console container and restart Docker. Continue")
|
||||||
|
if !yes(in, question) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
|
if err := compose.StageServices(cfg, newConsole); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := docker.NewSystemClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
currentContainerId, err := util.GetCurrentContainerId()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
currentContainer, err := client.ContainerInspect(context.Background(), currentContainerId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
service, err := compose.CreateService(nil, "switch-console", &composeConfig.ServiceConfigV1{
|
||||||
|
LogDriver: "json-file",
|
||||||
|
Privileged: true,
|
||||||
|
Net: "host",
|
||||||
|
Pid: "host",
|
||||||
|
Image: currentContainer.Config.Image,
|
||||||
|
Labels: map[string]string{
|
||||||
|
config.SCOPE: config.SYSTEM,
|
||||||
|
},
|
||||||
|
Command: []string{"/usr/bin/switch-console", newConsole},
|
||||||
|
VolumesFrom: []string{"all-volumes"},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = service.Delete(context.Background(), options.Delete{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return service.Up(context.Background(), options.Up{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleList(c *cli.Context) error {
|
||||||
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
|
consoles, err := network.GetConsoles(cfg.Rancher.Repositories.ToArray())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, console := range consoles {
|
||||||
|
fmt.Println(console)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -177,16 +177,6 @@ func osVersion(c *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func yes(in *bufio.Reader, question string) bool {
|
|
||||||
fmt.Printf("%s [y/N]: ", question)
|
|
||||||
line, err := in.ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.ToLower(line[0:1]) == "y"
|
|
||||||
}
|
|
||||||
|
|
||||||
func startUpgradeContainer(image string, stage, force, reboot, kexec bool, upgradeConsole bool, kernelArgs string) error {
|
func startUpgradeContainer(image string, stage, force, reboot, kexec bool, upgradeConsole bool, kernelArgs string) error {
|
||||||
in := bufio.NewReader(os.Stdin)
|
in := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
19
cmd/control/util.go
Normal file
19
cmd/control/util.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func yes(in *bufio.Reader, question string) bool {
|
||||||
|
fmt.Printf("%s [y/N]: ", question)
|
||||||
|
line, err := in.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.ToLower(line[0:1]) == "y"
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package power
|
package power
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -17,10 +16,7 @@ import (
|
|||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
|
|
||||||
"github.com/rancher/os/docker"
|
"github.com/rancher/os/docker"
|
||||||
)
|
"github.com/rancher/os/util"
|
||||||
|
|
||||||
const (
|
|
||||||
DOCKER_CGROUPS_FILE = "/proc/self/cgroup"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func runDocker(name string) error {
|
func runDocker(name string) error {
|
||||||
@ -51,7 +47,7 @@ func runDocker(name string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentContainerId, err := getCurrentContainerId()
|
currentContainerId, err := util.GetCurrentContainerId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -185,7 +181,7 @@ func shutDownContainers() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentContainerId, err := getCurrentContainerId()
|
currentContainerId, err := util.GetCurrentContainerId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -222,35 +218,3 @@ func shutDownContainers() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCurrentContainerId() (string, error) {
|
|
||||||
file, err := os.Open(DOCKER_CGROUPS_FILE)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
fileReader := bufio.NewScanner(file)
|
|
||||||
if !fileReader.Scan() {
|
|
||||||
return "", errors.New("Empty file /proc/self/cgroup")
|
|
||||||
}
|
|
||||||
line := fileReader.Text()
|
|
||||||
parts := strings.Split(line, "/")
|
|
||||||
|
|
||||||
for len(parts) != 3 {
|
|
||||||
if !fileReader.Scan() {
|
|
||||||
return "", errors.New("Found no docker cgroups")
|
|
||||||
}
|
|
||||||
line = fileReader.Text()
|
|
||||||
parts = strings.Split(line, "/")
|
|
||||||
if len(parts) == 3 {
|
|
||||||
if strings.HasSuffix(parts[1], "docker") {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
parts = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts[len(parts)-1:][0], nil
|
|
||||||
}
|
|
||||||
|
41
cmd/switchconsole/switch_console.go
Normal file
41
cmd/switchconsole/switch_console.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package switchconsole
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/libcompose/project/options"
|
||||||
|
"github.com/rancher/os/compose"
|
||||||
|
"github.com/rancher/os/config"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Main() {
|
||||||
|
if len(os.Args) != 2 {
|
||||||
|
log.Fatal("Must specify exactly one existing container")
|
||||||
|
}
|
||||||
|
newConsole := os.Args[1]
|
||||||
|
|
||||||
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
|
project, err := compose.GetProject(cfg, true)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = compose.LoadService(project, cfg, true, newConsole); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = project.Up(context.Background(), options.Up{}, "console"); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = project.Restart(context.Background(), 10, "docker"); err != nil {
|
||||||
|
log.Errorf("Failed to restart Docker: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = config.Set("rancher.console", newConsole); err != nil {
|
||||||
|
log.Errorf("Failed to update 'rancher.console': %v", err)
|
||||||
|
}
|
||||||
|
}
|
@ -183,9 +183,6 @@ func adjustContainerNames(m map[interface{}]interface{}) map[interface{}]interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newCoreServiceProject(cfg *config.CloudConfig, useNetwork bool) (*project.Project, error) {
|
func newCoreServiceProject(cfg *config.CloudConfig, useNetwork bool) (*project.Project, error) {
|
||||||
projectEvents := make(chan events.Event)
|
|
||||||
enabled := map[interface{}]interface{}{}
|
|
||||||
|
|
||||||
environmentLookup := rosDocker.NewConfigEnvironment(cfg)
|
environmentLookup := rosDocker.NewConfigEnvironment(cfg)
|
||||||
authLookup := rosDocker.NewConfigAuthLookup(cfg)
|
authLookup := rosDocker.NewConfigAuthLookup(cfg)
|
||||||
|
|
||||||
@ -194,53 +191,11 @@ func newCoreServiceProject(cfg *config.CloudConfig, useNetwork bool) (*project.P
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
projectEvents := make(chan events.Event)
|
||||||
p.AddListener(project.NewDefaultListener(p))
|
p.AddListener(project.NewDefaultListener(p))
|
||||||
p.AddListener(projectEvents)
|
p.AddListener(projectEvents)
|
||||||
|
|
||||||
p.ReloadCallback = func() error {
|
p.ReloadCallback = projectReload(p, &useNetwork, environmentLookup, authLookup)
|
||||||
cfg = config.LoadConfig()
|
|
||||||
|
|
||||||
environmentLookup.SetConfig(cfg)
|
|
||||||
authLookup.SetConfig(cfg)
|
|
||||||
|
|
||||||
enabled = addServices(p, enabled, cfg.Rancher.Services)
|
|
||||||
|
|
||||||
for service, serviceEnabled := range cfg.Rancher.ServicesInclude {
|
|
||||||
if _, ok := enabled[service]; ok || !serviceEnabled {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := network.LoadServiceResource(service, useNetwork, cfg)
|
|
||||||
if err != nil {
|
|
||||||
if err == network.ErrNoNetwork {
|
|
||||||
log.Debugf("Can not load %s, networking not enabled", service)
|
|
||||||
} else {
|
|
||||||
log.Errorf("Failed to load %s : %v", service, err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
m := map[interface{}]interface{}{}
|
|
||||||
if err := yaml.Unmarshal(bytes, &m); err != nil {
|
|
||||||
log.Errorf("Failed to parse YAML configuration: %s : %v", service, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
bytes, err = yaml.Marshal(adjustContainerNames(m))
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to marshal YAML configuration: %s : %v", service, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = p.Load(bytes)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s : %v", service, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled[service] = service
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for event := range projectEvents {
|
for event := range projectEvents {
|
||||||
|
73
compose/reload.go
Normal file
73
compose/reload.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||||
|
"github.com/docker/libcompose/project"
|
||||||
|
"github.com/rancher/os/config"
|
||||||
|
"github.com/rancher/os/docker"
|
||||||
|
"github.com/rancher/os/util/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadService(p *project.Project, cfg *config.CloudConfig, useNetwork bool, service string) error {
|
||||||
|
bytes, err := network.LoadServiceResource(service, useNetwork, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := map[interface{}]interface{}{}
|
||||||
|
if err = yaml.Unmarshal(bytes, &m); err != nil {
|
||||||
|
return fmt.Errorf("Failed to parse YAML configuration for %s: %v", service, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m = adjustContainerNames(m)
|
||||||
|
|
||||||
|
bytes, err = yaml.Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to marshal YAML configuration for %s: %v", service, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = p.Load(bytes); err != nil {
|
||||||
|
return fmt.Errorf("Failed to load %s: %v", service, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func projectReload(p *project.Project, useNetwork *bool, environmentLookup *docker.ConfigEnvironment, authLookup *docker.ConfigAuthLookup) func() error {
|
||||||
|
enabled := map[interface{}]interface{}{}
|
||||||
|
return func() error {
|
||||||
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
|
environmentLookup.SetConfig(cfg)
|
||||||
|
authLookup.SetConfig(cfg)
|
||||||
|
|
||||||
|
enabled = addServices(p, enabled, cfg.Rancher.Services)
|
||||||
|
|
||||||
|
for service, serviceEnabled := range cfg.Rancher.ServicesInclude {
|
||||||
|
if _, ok := enabled[service]; ok || !serviceEnabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := LoadService(p, cfg, *useNetwork, service); err != nil {
|
||||||
|
if err != network.ErrNoNetwork {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled[service] = service
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Rancher.Console != "" {
|
||||||
|
err := LoadService(p, cfg, *useNetwork, cfg.Rancher.Console)
|
||||||
|
if err != nil && err != network.ErrNoNetwork {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
@ -85,6 +85,7 @@ type CloudConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RancherConfig struct {
|
type RancherConfig struct {
|
||||||
|
Console string `yaml:"console,omitempty"`
|
||||||
Environment map[string]string `yaml:"environment,omitempty"`
|
Environment map[string]string `yaml:"environment,omitempty"`
|
||||||
Services map[string]*composeConfig.ServiceConfigV1 `yaml:"services,omitempty"`
|
Services map[string]*composeConfig.ServiceConfigV1 `yaml:"services,omitempty"`
|
||||||
BootstrapContainers map[string]*composeConfig.ServiceConfigV1 `yaml:"bootstrap,omitempty"`
|
BootstrapContainers map[string]*composeConfig.ServiceConfigV1 `yaml:"bootstrap,omitempty"`
|
||||||
|
2
main.go
2
main.go
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/rancher/os/cmd/network"
|
"github.com/rancher/os/cmd/network"
|
||||||
"github.com/rancher/os/cmd/power"
|
"github.com/rancher/os/cmd/power"
|
||||||
"github.com/rancher/os/cmd/respawn"
|
"github.com/rancher/os/cmd/respawn"
|
||||||
|
"github.com/rancher/os/cmd/switchconsole"
|
||||||
"github.com/rancher/os/cmd/sysinit"
|
"github.com/rancher/os/cmd/sysinit"
|
||||||
"github.com/rancher/os/cmd/systemdocker"
|
"github.com/rancher/os/cmd/systemdocker"
|
||||||
"github.com/rancher/os/cmd/userdocker"
|
"github.com/rancher/os/cmd/userdocker"
|
||||||
@ -28,6 +29,7 @@ var entrypoints = map[string]func(){
|
|||||||
"respawn": respawn.Main,
|
"respawn": respawn.Main,
|
||||||
"ros-sysinit": sysinit.Main,
|
"ros-sysinit": sysinit.Main,
|
||||||
"shutdown": power.Main,
|
"shutdown": power.Main,
|
||||||
|
"switch-console": switchconsole.Main,
|
||||||
"system-docker": systemdocker.Main,
|
"system-docker": systemdocker.Main,
|
||||||
"user-docker": userdocker.Main,
|
"user-docker": userdocker.Main,
|
||||||
"wait-for-docker": wait.Main,
|
"wait-for-docker": wait.Main,
|
||||||
|
@ -154,6 +154,7 @@ rancher:
|
|||||||
- /usr/bin/ros:/usr/bin/cloud-init:ro
|
- /usr/bin/ros:/usr/bin/cloud-init:ro
|
||||||
- /usr/bin/ros:/usr/sbin/netconf:ro
|
- /usr/bin/ros:/usr/sbin/netconf:ro
|
||||||
- /usr/bin/ros:/usr/sbin/wait-for-docker:ro
|
- /usr/bin/ros:/usr/sbin/wait-for-docker:ro
|
||||||
|
- /usr/bin/ros:/usr/bin/switch-console:ro
|
||||||
console:
|
console:
|
||||||
image: {{.OS_REPO}}/os-console:{{.VERSION}}{{.SUFFIX}}
|
image: {{.OS_REPO}}/os-console:{{.VERSION}}{{.SUFFIX}}
|
||||||
labels:
|
labels:
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#cloud-config
|
#cloud-config
|
||||||
rancher:
|
rancher:
|
||||||
services_include:
|
console: debian
|
||||||
debian-console: true
|
|
||||||
ssh_authorized_keys:
|
ssh_authorized_keys:
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#cloud-config
|
#cloud-config
|
||||||
rancher:
|
rancher:
|
||||||
services_include:
|
console: debian
|
||||||
debian-console: true
|
|
||||||
ssh_authorized_keys:
|
ssh_authorized_keys:
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#cloud-config
|
#cloud-config
|
||||||
rancher:
|
rancher:
|
||||||
|
console: debian
|
||||||
services:
|
services:
|
||||||
missing_image:
|
missing_image:
|
||||||
image: tianon/true
|
image: tianon/true
|
||||||
labels:
|
labels:
|
||||||
io.rancher.os.scope: system
|
io.rancher.os.scope: system
|
||||||
services_include:
|
|
||||||
debian-console: true
|
|
||||||
ssh_authorized_keys:
|
ssh_authorized_keys:
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85w9stZyiLQp/DkVO6fqwiShYcj1ClKdtCqgHtf+PLpJkFReSFu8y21y+ev09gsSMRRrjF7yt0pUHV6zncQhVeqsZtgc5WbELY2DOYUGmRn/CCvPbXovoBrQjSorqlBmpuPwsStYLr92Xn+VVsMNSUIegHY22DphGbDKG85vrKB8HxUxGIDxFBds/uE8FhSy+xsoyT/jUZDK6pgq2HnGl6D81ViIlKecpOpWlW3B+fea99ADNyZNVvDzbHE5pcI3VRw8u59WmpWOUgT6qacNVACl8GqpBvQk8sw7O/X9DSZHCKafeD9G5k+GYbAUz92fKWrx/lOXfUXPS3+c8dRIF
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85w9stZyiLQp/DkVO6fqwiShYcj1ClKdtCqgHtf+PLpJkFReSFu8y21y+ev09gsSMRRrjF7yt0pUHV6zncQhVeqsZtgc5WbELY2DOYUGmRn/CCvPbXovoBrQjSorqlBmpuPwsStYLr92Xn+VVsMNSUIegHY22DphGbDKG85vrKB8HxUxGIDxFBds/uE8FhSy+xsoyT/jUZDK6pgq2HnGl6D81ViIlKecpOpWlW3B+fea99ADNyZNVvDzbHE5pcI3VRw8u59WmpWOUgT6qacNVACl8GqpBvQk8sw7O/X9DSZHCKafeD9G5k+GYbAUz92fKWrx/lOXfUXPS3+c8dRIF
|
||||||
|
@ -21,6 +21,14 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func GetServices(urls []string) ([]string, error) {
|
func GetServices(urls []string) ([]string, error) {
|
||||||
|
return getServices(urls, "services")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConsoles(urls []string) ([]string, error) {
|
||||||
|
return getServices(urls, "consoles")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServices(urls []string, key string) ([]string, error) {
|
||||||
result := []string{}
|
result := []string{}
|
||||||
|
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
@ -38,7 +46,7 @@ func GetServices(urls []string) ([]string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if list, ok := services["services"]; ok {
|
if list, ok := services[key]; ok {
|
||||||
result = append(result, list...)
|
result = append(result, list...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
util/util.go
38
util/util.go
@ -1,7 +1,9 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -13,6 +15,10 @@ import (
|
|||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DOCKER_CGROUPS_FILE = "/proc/self/cgroup"
|
||||||
|
)
|
||||||
|
|
||||||
type AnyMap map[interface{}]interface{}
|
type AnyMap map[interface{}]interface{}
|
||||||
|
|
||||||
func Contains(values []string, value string) bool {
|
func Contains(values []string, value string) bool {
|
||||||
@ -187,3 +193,35 @@ func TrimSplitN(str, sep string, count int) []string {
|
|||||||
func TrimSplit(str, sep string) []string {
|
func TrimSplit(str, sep string) []string {
|
||||||
return TrimSplitN(str, sep, -1)
|
return TrimSplitN(str, sep, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetCurrentContainerId() (string, error) {
|
||||||
|
file, err := os.Open(DOCKER_CGROUPS_FILE)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileReader := bufio.NewScanner(file)
|
||||||
|
if !fileReader.Scan() {
|
||||||
|
return "", errors.New("Empty file /proc/self/cgroup")
|
||||||
|
}
|
||||||
|
line := fileReader.Text()
|
||||||
|
parts := strings.Split(line, "/")
|
||||||
|
|
||||||
|
for len(parts) != 3 {
|
||||||
|
if !fileReader.Scan() {
|
||||||
|
return "", errors.New("Found no docker cgroups")
|
||||||
|
}
|
||||||
|
line = fileReader.Text()
|
||||||
|
parts = strings.Split(line, "/")
|
||||||
|
if len(parts) == 3 {
|
||||||
|
if strings.HasSuffix(parts[1], "docker") {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
parts = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts[len(parts)-1:][0], nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user