mirror of
https://github.com/rancher/os.git
synced 2025-09-02 07:15:41 +00:00
Revert "WIP New ros cli"
This commit is contained in:
@@ -185,7 +185,7 @@ func fetchAndSave(ds datasource.Datasource) error {
|
|||||||
scriptBytes = userDataBytes
|
scriptBytes = userDataBytes
|
||||||
userDataBytes = []byte{}
|
userDataBytes = []byte{}
|
||||||
} else if isCompose(userData) {
|
} else if isCompose(userData) {
|
||||||
if userDataBytes, err = ComposeToCloudConfig(userDataBytes); err != nil {
|
if userDataBytes, err = composeToCloudConfig(userDataBytes); err != nil {
|
||||||
log.Errorf("Failed to convert compose to cloud-config syntax: %v", err)
|
log.Errorf("Failed to convert compose to cloud-config syntax: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -328,9 +328,7 @@ func isCompose(content string) bool {
|
|||||||
return strings.HasPrefix(content, "#compose\n")
|
return strings.HasPrefix(content, "#compose\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComposeToCloudConfig converts a loaded compose file into a ros config struct
|
func composeToCloudConfig(bytes []byte) ([]byte, error) {
|
||||||
func ComposeToCloudConfig(bytes []byte) ([]byte, error) {
|
|
||||||
//TODO: move to config?
|
|
||||||
compose := make(map[interface{}]interface{})
|
compose := make(map[interface{}]interface{})
|
||||||
err := yaml.Unmarshal(bytes, &compose)
|
err := yaml.Unmarshal(bytes, &compose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
456
cmd/control/cli.go
Executable file → Normal file
456
cmd/control/cli.go
Executable file → Normal file
@@ -1,22 +1,12 @@
|
|||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
|
|
||||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
composeApp "github.com/docker/libcompose/cli/app"
|
|
||||||
libcomposeConfig "github.com/docker/libcompose/config"
|
|
||||||
serviceApp "github.com/rancher/os/cmd/control/service/app"
|
|
||||||
|
|
||||||
"github.com/rancher/os/cmd/control/service"
|
"github.com/rancher/os/cmd/control/service"
|
||||||
|
|
||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
"github.com/rancher/os/util/network"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
@@ -35,366 +25,112 @@ func Main() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//factory := &service.ProjectFactory{}
|
|
||||||
|
|
||||||
app.Commands = []cli.Command{}
|
|
||||||
app.Commands = append(app.Commands, originalCli...)
|
|
||||||
app.Commands = append(app.Commands, hiddenInternalCommands...)
|
|
||||||
|
|
||||||
app.Run(os.Args)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMain() {
|
|
||||||
log.InitLogger()
|
|
||||||
app := cli.NewApp()
|
|
||||||
|
|
||||||
app.Name = os.Args[0]
|
|
||||||
app.Usage = "Control and configure RancherOS"
|
|
||||||
app.Version = config.Version
|
|
||||||
app.Author = "Rancher Labs, Inc."
|
|
||||||
app.EnableBashCompletion = true
|
|
||||||
app.Before = func(c *cli.Context) error {
|
|
||||||
if os.Geteuid() != 0 {
|
|
||||||
log.Fatalf("%s: Need to be root", os.Args[0])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
factory := &service.ProjectFactory{}
|
|
||||||
|
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "fetch",
|
Name: "bootstrap",
|
||||||
ShortName: "f",
|
Hidden: true,
|
||||||
Usage: "fetch configs from repos",
|
HideHelp: true,
|
||||||
HideHelp: true,
|
SkipFlagParsing: true,
|
||||||
Action: fetchServices,
|
Action: bootstrapAction,
|
||||||
},
|
},
|
||||||
// service
|
|
||||||
{
|
{
|
||||||
Name: "list",
|
Name: "config",
|
||||||
ShortName: "",
|
ShortName: "c",
|
||||||
Usage: "list services and states",
|
Usage: "configure settings",
|
||||||
HideHelp: true,
|
HideHelp: true,
|
||||||
Action: listServices,
|
Subcommands: configSubcommands(),
|
||||||
}, {
|
|
||||||
Name: "install",
|
|
||||||
// TODO: add an --apply or --up ...
|
|
||||||
// TODO: also support the repo-name prefix
|
|
||||||
ShortName: "",
|
|
||||||
Usage: "install/upgrade service / RancherOS",
|
|
||||||
HideHelp: true,
|
|
||||||
Action: service.Enable,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "apply",
|
|
||||||
Usage: "Switch console/engine, or start service.",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "force",
|
|
||||||
Usage: "Don't ask questions.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "remove",
|
|
||||||
ShortName: "",
|
|
||||||
Usage: "remove service",
|
|
||||||
HideHelp: true,
|
|
||||||
Action: service.Del,
|
|
||||||
}, {
|
|
||||||
Name: "logs",
|
|
||||||
Usage: "View output from containers",
|
|
||||||
//Before: verifyOneOrMoreServices,
|
|
||||||
Action: composeApp.WithProject(factory, serviceApp.ProjectLog),
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.IntFlag{
|
|
||||||
Name: "lines",
|
|
||||||
Usage: "number of lines to tail",
|
|
||||||
Value: 100,
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "follow",
|
|
||||||
Usage: "Follow log output.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// settings / partial configs
|
|
||||||
{
|
{
|
||||||
Name: "get",
|
Name: "console",
|
||||||
// TODO: also add the merge command functionality
|
Usage: "manage which console container is used",
|
||||||
ShortName: "",
|
HideHelp: true,
|
||||||
Usage: "get config value(s)",
|
Subcommands: consoleSubcommands(),
|
||||||
HideHelp: true,
|
|
||||||
Action: configGet,
|
|
||||||
}, {
|
|
||||||
Name: "set",
|
|
||||||
ShortName: "",
|
|
||||||
Usage: "set config value(s)",
|
|
||||||
HideHelp: true,
|
|
||||||
Action: configSet,
|
|
||||||
},
|
},
|
||||||
// complete config
|
|
||||||
{
|
{
|
||||||
Name: "export",
|
Name: "console-init",
|
||||||
Usage: "export configuration",
|
Hidden: true,
|
||||||
Flags: []cli.Flag{
|
HideHelp: true,
|
||||||
cli.StringFlag{
|
SkipFlagParsing: true,
|
||||||
Name: "output, o",
|
Action: consoleInitAction,
|
||||||
Usage: "File to which to save",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "private, p",
|
|
||||||
Usage: "Include the generated private keys",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "full, f",
|
|
||||||
Usage: "Export full configuration, including internal and default settings",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: export,
|
|
||||||
}, {
|
|
||||||
Name: "validate",
|
|
||||||
Usage: "validate configuration from stdin",
|
|
||||||
Action: validate,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "input, i",
|
|
||||||
Usage: "File from which to read",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "apply",
|
|
||||||
ShortName: "",
|
|
||||||
Usage: "apply service&config changes",
|
|
||||||
HideHelp: true,
|
|
||||||
Action: dummy,
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "dev",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: devAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "docker-init",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: dockerInitAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "engine",
|
||||||
|
Usage: "manage which Docker engine is used",
|
||||||
|
HideHelp: true,
|
||||||
|
Subcommands: engineSubcommands(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "entrypoint",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: entrypointAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "env",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: envAction,
|
||||||
|
},
|
||||||
|
service.Commands(),
|
||||||
|
{
|
||||||
|
Name: "os",
|
||||||
|
Usage: "operating system upgrade/downgrade",
|
||||||
|
HideHelp: true,
|
||||||
|
Subcommands: osSubcommands(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "preload-images",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: preloadImagesAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "switch-console",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: switchConsoleAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "tls",
|
||||||
|
Usage: "setup tls configuration",
|
||||||
|
HideHelp: true,
|
||||||
|
Subcommands: tlsConfCommands(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "udev-settle",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: udevSettleAction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "user-docker",
|
||||||
|
Hidden: true,
|
||||||
|
HideHelp: true,
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: userDockerAction,
|
||||||
|
},
|
||||||
|
installCommand,
|
||||||
|
selinuxCommand(),
|
||||||
}
|
}
|
||||||
app.Commands = append(app.Commands, hiddenInternalCommands...)
|
|
||||||
|
|
||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dummy(c *cli.Context) error {
|
|
||||||
fmt.Printf("Not implemented yet - use the `ros old` commands for now\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchServices(c *cli.Context) error {
|
|
||||||
// fetch all the index.yml files, and the service.yml files that they refer to
|
|
||||||
// and put into a cache dir.
|
|
||||||
// Q - should there be one dir per index.yml so that you can have more than one service with the same name..
|
|
||||||
|
|
||||||
//TODO: need a --purge
|
|
||||||
//TODO: also need to fetch the rancher/os choices
|
|
||||||
|
|
||||||
return network.FetchAllServices()
|
|
||||||
}
|
|
||||||
|
|
||||||
func listServices(c *cli.Context) error {
|
|
||||||
//get the current cfg, and the make a cfg with all cached services
|
|
||||||
//then iterate through, listing all possible services, and what version is running, vs what version they could run
|
|
||||||
//Can't just merge current cfg and cached services, as we lose service.yml version info
|
|
||||||
|
|
||||||
currentConfig := config.LoadConfig()
|
|
||||||
cachedConfigs := GetAllServices()
|
|
||||||
// TODO: sort them!
|
|
||||||
fmt.Printf("Enabled\n")
|
|
||||||
enabledServices := make([]string, len(currentConfig.Rancher.Services)+len(currentConfig.Rancher.ServicesInclude))
|
|
||||||
i := 0
|
|
||||||
for k := range currentConfig.Rancher.Services {
|
|
||||||
enabledServices[i] = k
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
for k := range currentConfig.Rancher.ServicesInclude {
|
|
||||||
enabledServices[i] = k
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
sort.Strings(enabledServices)
|
|
||||||
for _, serviceName := range enabledServices {
|
|
||||||
// TODO: add running / stopped, error etc state
|
|
||||||
// TODO: separate the volumes out too (they don't need the image listed - list the volumes instead)
|
|
||||||
serviceConfig, _ := currentConfig.Rancher.Services[serviceName]
|
|
||||||
if serviceConfig != nil {
|
|
||||||
fmt.Printf("\t%s: %s\n", serviceName, serviceConfig.Image)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fmt.Printf("\t%s\n", serviceName)
|
|
||||||
|
|
||||||
}
|
|
||||||
if len(cachedConfigs[serviceName]) > 0 {
|
|
||||||
fmt.Printf("\t\tAlternatives: ")
|
|
||||||
for serviceLongName := range cachedConfigs[serviceName] {
|
|
||||||
fmt.Printf("%s, ", serviceLongName)
|
|
||||||
}
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Available\n")
|
|
||||||
for serviceName, service := range cachedConfigs {
|
|
||||||
if _, ok := currentConfig.Rancher.Services[serviceName]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for serviceLongName := range service {
|
|
||||||
fmt.Printf("\t%s: %s\n", serviceName, serviceLongName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAllServices() map[string]map[string]*libcomposeConfig.ServiceConfigV1 {
|
|
||||||
//result := make(map[string]*libcomposeConfig.ServiceConfig)
|
|
||||||
result := make(map[string]map[string]*libcomposeConfig.ServiceConfigV1)
|
|
||||||
|
|
||||||
cfg := config.LoadConfig()
|
|
||||||
for repoName := range cfg.Rancher.Repositories {
|
|
||||||
indexPath := fmt.Sprintf("%s/index.yml", repoName)
|
|
||||||
//content, err := network.LoadResource(indexPath, false)
|
|
||||||
content, err := network.CacheLookup(indexPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s: %v", indexPath, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
services := make(map[string][]string)
|
|
||||||
err = yaml.Unmarshal(content, &services)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to unmarshal %s: %v", indexPath, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for serviceType, serviceList := range services {
|
|
||||||
for _, serviceLongName := range serviceList {
|
|
||||||
p, err := service.LoadService(repoName, serviceLongName)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s/%s : %v", repoName, serviceLongName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// yes, the serviceLongName is really only the yml file name
|
|
||||||
// and each yml file can contain more than one actual service
|
|
||||||
for serviceName, service := range p.Rancher.Services {
|
|
||||||
//service, _ := p.ServiceConfigs.Get(serviceName)
|
|
||||||
n := fmt.Sprintf("%s/%s", repoName, serviceLongName)
|
|
||||||
if result[serviceName] == nil {
|
|
||||||
result[serviceName] = map[string]*libcomposeConfig.ServiceConfigV1{}
|
|
||||||
}
|
|
||||||
result[serviceName][n] = service
|
|
||||||
log.Debugf("loaded %s(%s): %s", n, serviceType, serviceName)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
var originalCli = []cli.Command{
|
|
||||||
{
|
|
||||||
Name: "config",
|
|
||||||
ShortName: "c",
|
|
||||||
Usage: "configure settings",
|
|
||||||
HideHelp: true,
|
|
||||||
Subcommands: configSubcommands(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "console",
|
|
||||||
Usage: "manage which console container is used",
|
|
||||||
HideHelp: true,
|
|
||||||
Subcommands: consoleSubcommands(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "engine",
|
|
||||||
Usage: "manage which Docker engine is used",
|
|
||||||
HideHelp: true,
|
|
||||||
Subcommands: engineSubcommands(),
|
|
||||||
},
|
|
||||||
service.Commands(),
|
|
||||||
{
|
|
||||||
Name: "os",
|
|
||||||
Usage: "operating system upgrade/downgrade",
|
|
||||||
HideHelp: true,
|
|
||||||
Subcommands: osSubcommands(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "tls",
|
|
||||||
Usage: "setup tls configuration",
|
|
||||||
HideHelp: true,
|
|
||||||
Subcommands: tlsConfCommands(),
|
|
||||||
},
|
|
||||||
installCommand,
|
|
||||||
selinuxCommand(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var hiddenInternalCommands = []cli.Command{
|
|
||||||
{
|
|
||||||
Name: "bootstrap",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: bootstrapAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "udev-settle",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: udevSettleAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "user-docker",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: userDockerAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "preload-images",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: preloadImagesAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "switch-console",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: switchConsoleAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "entrypoint",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: entrypointAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "env",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: envAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "console-init",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: consoleInitAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "dev",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: devAction,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "docker-init",
|
|
||||||
Hidden: true,
|
|
||||||
HideHelp: true,
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
Action: dockerInitAction,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
3
cmd/control/console.go
Executable file → Normal file
3
cmd/control/console.go
Executable file → Normal file
@@ -66,7 +66,7 @@ func consoleSwitch(c *cli.Context) error {
|
|||||||
1. destroy the current console container
|
1. destroy the current console container
|
||||||
2. log you out
|
2. log you out
|
||||||
3. restart Docker`)
|
3. restart Docker`)
|
||||||
if !util.Yes("Continue") {
|
if !yes("Continue") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,6 @@ func consoleEnable(c *cli.Context) error {
|
|||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
validateConsole(newConsole, cfg)
|
validateConsole(newConsole, cfg)
|
||||||
|
|
||||||
//TODO: why does default not need to be staged?
|
|
||||||
if newConsole != "default" {
|
if newConsole != "default" {
|
||||||
if err := compose.StageServices(cfg, newConsole); err != nil {
|
if err := compose.StageServices(cfg, newConsole); err != nil {
|
||||||
return err
|
return err
|
||||||
|
1
cmd/control/entrypoint.go
Executable file → Normal file
1
cmd/control/entrypoint.go
Executable file → Normal file
@@ -103,7 +103,6 @@ func setupCommandSymlinks() {
|
|||||||
{config.RosBin, "/sbin/reboot"},
|
{config.RosBin, "/sbin/reboot"},
|
||||||
{config.RosBin, "/sbin/halt"},
|
{config.RosBin, "/sbin/halt"},
|
||||||
{config.RosBin, "/sbin/shutdown"},
|
{config.RosBin, "/sbin/shutdown"},
|
||||||
{config.RosBin, "/sbin/os"},
|
|
||||||
} {
|
} {
|
||||||
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
@@ -153,7 +153,7 @@ func installAction(c *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !kexec && reboot && (force || util.Yes("Continue with reboot")) {
|
if !kexec && reboot && (force || yes("Continue with reboot")) {
|
||||||
log.Info("Rebooting")
|
log.Info("Rebooting")
|
||||||
power.Reboot()
|
power.Reboot()
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
|||||||
fmt.Printf("Installing from %s\n", image)
|
fmt.Printf("Installing from %s\n", image)
|
||||||
|
|
||||||
if !force {
|
if !force {
|
||||||
if util.IsRunningInTty() && !util.Yes("Continue") {
|
if util.IsRunningInTty() && !yes("Continue") {
|
||||||
log.Infof("Not continuing with installation due to user not saying 'yes'")
|
log.Infof("Not continuing with installation due to user not saying 'yes'")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,6 @@ import (
|
|||||||
"github.com/rancher/os/compose"
|
"github.com/rancher/os/compose"
|
||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
"github.com/rancher/os/docker"
|
"github.com/rancher/os/docker"
|
||||||
"github.com/rancher/os/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Images struct {
|
type Images struct {
|
||||||
@@ -227,7 +226,7 @@ func startUpgradeContainer(image string, stage, force, reboot, kexec bool, upgra
|
|||||||
if len(imageSplit) > 1 && imageSplit[1] == config.Version+config.Suffix {
|
if len(imageSplit) > 1 && imageSplit[1] == config.Version+config.Suffix {
|
||||||
confirmation = fmt.Sprintf("Already at version %s. Continue anyway", imageSplit[1])
|
confirmation = fmt.Sprintf("Already at version %s. Continue anyway", imageSplit[1])
|
||||||
}
|
}
|
||||||
if !force && !util.Yes(confirmation) {
|
if !force && !yes(confirmation) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +276,7 @@ func startUpgradeContainer(image string, stage, force, reboot, kexec bool, upgra
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if reboot && (force || util.Yes("Continue with reboot")) {
|
if reboot && (force || yes("Continue with reboot")) {
|
||||||
log.Info("Rebooting")
|
log.Info("Rebooting")
|
||||||
power.Reboot()
|
power.Reboot()
|
||||||
}
|
}
|
||||||
|
187
cmd/control/service/service.go
Executable file → Normal file
187
cmd/control/service/service.go
Executable file → Normal file
@@ -1,17 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
dockerApp "github.com/docker/libcompose/cli/docker/app"
|
dockerApp "github.com/docker/libcompose/cli/docker/app"
|
||||||
composeConfig "github.com/docker/libcompose/config"
|
|
||||||
|
|
||||||
"github.com/docker/libcompose/project/options"
|
|
||||||
|
|
||||||
"github.com/docker/libcompose/project"
|
"github.com/docker/libcompose/project"
|
||||||
"github.com/rancher/os/cmd/control/service/command"
|
"github.com/rancher/os/cmd/control/service/command"
|
||||||
"github.com/rancher/os/compose"
|
"github.com/rancher/os/compose"
|
||||||
@@ -21,10 +15,10 @@ import (
|
|||||||
"github.com/rancher/os/util/network"
|
"github.com/rancher/os/util/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProjectFactory struct {
|
type projectFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProjectFactory) Create(c *cli.Context) (project.APIProject, error) {
|
func (p *projectFactory) Create(c *cli.Context) (project.APIProject, error) {
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
return compose.GetProject(cfg, true, false)
|
return compose.GetProject(cfg, true, false)
|
||||||
}
|
}
|
||||||
@@ -37,7 +31,7 @@ func beforeApp(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Commands() cli.Command {
|
func Commands() cli.Command {
|
||||||
factory := &ProjectFactory{}
|
factory := &projectFactory{}
|
||||||
|
|
||||||
app := cli.Command{}
|
app := cli.Command{}
|
||||||
app.Name = "service"
|
app.Name = "service"
|
||||||
@@ -69,7 +63,7 @@ func serviceSubCommands() []cli.Command {
|
|||||||
{
|
{
|
||||||
Name: "enable",
|
Name: "enable",
|
||||||
Usage: "turn on an service",
|
Usage: "turn on an service",
|
||||||
Action: Enable,
|
Action: enable,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "disable",
|
Name: "disable",
|
||||||
@@ -84,7 +78,7 @@ func serviceSubCommands() []cli.Command {
|
|||||||
{
|
{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "delete a service",
|
Usage: "delete a service",
|
||||||
Action: Del,
|
Action: del,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,7 +111,7 @@ func disable(c *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Del(c *cli.Context) error {
|
func del(c *cli.Context) error {
|
||||||
changed := false
|
changed := false
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
@@ -141,125 +135,20 @@ func Del(c *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ComposeToCloudConfig(bytes []byte) ([]byte, error) {
|
func enable(c *cli.Context) error {
|
||||||
//TODO: copied from cloudinitsave, move to config.
|
|
||||||
compose := make(map[interface{}]interface{})
|
|
||||||
err := yaml.Unmarshal(bytes, &compose)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return yaml.Marshal(map[interface{}]interface{}{
|
|
||||||
"rancher": map[interface{}]interface{}{
|
|
||||||
"services": compose,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadService(repoName, serviceLongName string) (*config.CloudConfig, error) {
|
|
||||||
// TODO: this should move to something like config/service.go?
|
|
||||||
// WARNING: this can contain more than one service - Josh and I aren't sure this is worth it
|
|
||||||
servicePath := fmt.Sprintf("%s/%s.yml", repoName, serviceLongName)
|
|
||||||
//log.Infof("loading %s", serviceLongName)
|
|
||||||
content, err := network.CacheLookup(servicePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to load %s: %v", servicePath, err)
|
|
||||||
}
|
|
||||||
if content, err = ComposeToCloudConfig(content); err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to convert compose to cloud-config syntax: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := config.ReadConfig(content, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to load %s : %v", servicePath, err)
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsConsole(serviceCfg *config.CloudConfig) bool {
|
|
||||||
// TODO: this should move to something like config/service.go?
|
|
||||||
//the service is called console, and has an io.rancher.os.console label.
|
|
||||||
for serviceName, service := range serviceCfg.Rancher.Services {
|
|
||||||
if serviceName == "console" {
|
|
||||||
for k := range service.Labels {
|
|
||||||
if k == "io.rancher.os.console" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsEngine(serviceCfg *config.CloudConfig) bool {
|
|
||||||
// TODO: this should move to something like config/service.go?
|
|
||||||
//the service is called docker, and the command is "ros user-docker"
|
|
||||||
for serviceName, service := range serviceCfg.Rancher.Services {
|
|
||||||
log.Infof("serviceName == %s", serviceName)
|
|
||||||
if serviceName == "docker" {
|
|
||||||
cmd := strings.Join(service.Command, " ")
|
|
||||||
log.Infof("service command == %s", cmd)
|
|
||||||
if cmd == "ros user-docker" {
|
|
||||||
log.Infof("yes, its a docker engine")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func Enable(c *cli.Context) error {
|
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
var enabledServices []string
|
var enabledServices []string
|
||||||
var consoleService, engineService string
|
|
||||||
var errorServices []string
|
|
||||||
serviceMap := make(map[string]*config.CloudConfig)
|
|
||||||
|
|
||||||
for _, service := range c.Args() {
|
for _, service := range c.Args() {
|
||||||
//validateService(service, cfg)
|
validateService(service, cfg)
|
||||||
//log.Infof("start4")
|
|
||||||
// TODO: need to search for the service in all the repos.
|
|
||||||
// TODO: also need to deal with local file paths and URLs
|
|
||||||
serviceConfig, err := LoadService("core", service)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s: %s", service, err)
|
|
||||||
errorServices = append(errorServices, service)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
serviceMap[service] = serviceConfig
|
|
||||||
}
|
|
||||||
if len(serviceMap) == 0 {
|
|
||||||
log.Fatalf("No valid Services found")
|
|
||||||
}
|
|
||||||
if len(errorServices) > 0 {
|
|
||||||
if c.Bool("force") || !util.Yes("Some services failed to load, Continue?") {
|
|
||||||
log.Fatalf("Services failed to load: %v", errorServices)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for service, serviceConfig := range serviceMap {
|
|
||||||
if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val {
|
if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val {
|
||||||
if isLocal(service) && !strings.HasPrefix(service, "/var/lib/rancher/conf") {
|
if isLocal(service) && !strings.HasPrefix(service, "/var/lib/rancher/conf") {
|
||||||
log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf")
|
log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf")
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsConsole(serviceConfig) {
|
cfg.Rancher.ServicesInclude[service] = true
|
||||||
log.Debugf("Enabling the %s console", service)
|
|
||||||
if err := config.Set("rancher.console", service); err != nil {
|
|
||||||
log.Errorf("Failed to update 'rancher.console': %v", err)
|
|
||||||
}
|
|
||||||
consoleService = service
|
|
||||||
|
|
||||||
} else if IsEngine(serviceConfig) {
|
|
||||||
log.Debugf("Enabling the %s user engine", service)
|
|
||||||
if err := config.Set("rancher.docker.engine", service); err != nil {
|
|
||||||
log.Errorf("Failed to update 'rancher.docker.engine': %v", err)
|
|
||||||
}
|
|
||||||
engineService = service
|
|
||||||
} else {
|
|
||||||
cfg.Rancher.ServicesInclude[service] = true
|
|
||||||
}
|
|
||||||
enabledServices = append(enabledServices, service)
|
enabledServices = append(enabledServices, service)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,64 +163,6 @@ func Enable(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: fix the case where the user is applying both a new console and a new docker engine
|
|
||||||
if consoleService != "" && c.Bool("apply") {
|
|
||||||
//ros console switch.
|
|
||||||
if !c.Bool("force") {
|
|
||||||
fmt.Println(`Switching consoles will
|
|
||||||
1. destroy the current console container
|
|
||||||
2. log you out
|
|
||||||
3. restart Docker`)
|
|
||||||
if !util.Yes("Continue") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
switchService, err := compose.CreateService(nil, "switch-console", &composeConfig.ServiceConfigV1{
|
|
||||||
LogDriver: "json-file",
|
|
||||||
Privileged: true,
|
|
||||||
Net: "host",
|
|
||||||
Pid: "host",
|
|
||||||
Image: config.OsBase,
|
|
||||||
Labels: map[string]string{
|
|
||||||
config.ScopeLabel: config.System,
|
|
||||||
},
|
|
||||||
Command: []string{"/usr/bin/ros", "switch-console", consoleService},
|
|
||||||
VolumesFrom: []string{"all-volumes"},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = switchService.Delete(context.Background(), options.Delete{}); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = switchService.Up(context.Background(), options.Up{}); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = switchService.Log(context.Background(), true); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if engineService != "" && c.Bool("apply") {
|
|
||||||
log.Info("Starting the %s engine", engineService)
|
|
||||||
project, err := compose.GetProject(cfg, true, false)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = project.Stop(context.Background(), 10, "docker"); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = compose.LoadSpecialService(project, cfg, "docker", engineService); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = project.Up(context.Background(), options.Up{}, "docker"); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package util
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Yes(question string) bool {
|
func yes(question string) bool {
|
||||||
fmt.Printf("%s [y/N]: ", question)
|
fmt.Printf("%s [y/N]: ", question)
|
||||||
in := bufio.NewReader(os.Stdin)
|
in := bufio.NewReader(os.Stdin)
|
||||||
line, err := in.ReadString('\n')
|
line, err := in.ReadString('\n')
|
@@ -45,7 +45,6 @@ const (
|
|||||||
CloudConfigScriptFile = "/var/lib/rancher/conf/cloud-config-script"
|
CloudConfigScriptFile = "/var/lib/rancher/conf/cloud-config-script"
|
||||||
MetaDataFile = "/var/lib/rancher/conf/metadata"
|
MetaDataFile = "/var/lib/rancher/conf/metadata"
|
||||||
CloudConfigFile = "/var/lib/rancher/conf/cloud-config.yml"
|
CloudConfigFile = "/var/lib/rancher/conf/cloud-config.yml"
|
||||||
CacheDirectory = "/var/lib/rancher/cache/"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
6
main.go
Executable file → Normal file
6
main.go
Executable file → Normal file
@@ -1,11 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
hostlocal "github.com/containernetworking/cni/plugins/ipam/host-local"
|
"github.com/containernetworking/cni/plugins/ipam/host-local"
|
||||||
"github.com/containernetworking/cni/plugins/main/bridge"
|
"github.com/containernetworking/cni/plugins/main/bridge"
|
||||||
"github.com/docker/docker/docker"
|
"github.com/docker/docker/docker"
|
||||||
"github.com/docker/docker/pkg/reexec"
|
"github.com/docker/docker/pkg/reexec"
|
||||||
glue "github.com/rancher/cniglue"
|
"github.com/rancher/cniglue"
|
||||||
"github.com/rancher/os/cmd/cloudinitexecute"
|
"github.com/rancher/os/cmd/cloudinitexecute"
|
||||||
"github.com/rancher/os/cmd/cloudinitsave"
|
"github.com/rancher/os/cmd/cloudinitsave"
|
||||||
"github.com/rancher/os/cmd/control"
|
"github.com/rancher/os/cmd/control"
|
||||||
@@ -39,8 +39,6 @@ var entrypoints = map[string]func(){
|
|||||||
"cni-glue": glue.Main,
|
"cni-glue": glue.Main,
|
||||||
"bridge": bridge.Main,
|
"bridge": bridge.Main,
|
||||||
"host-local": hostlocal.Main,
|
"host-local": hostlocal.Main,
|
||||||
// new CLI
|
|
||||||
"os": control.NewMain,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@@ -24,7 +24,6 @@ docker run --rm -it \
|
|||||||
-v $(pwd)/bin/ros:/usr/bin/ros \
|
-v $(pwd)/bin/ros:/usr/bin/ros \
|
||||||
-v /etc/ssl/certs:/etc/ssl/certs \
|
-v /etc/ssl/certs:/etc/ssl/certs \
|
||||||
-v /usr/share/ca-certificates:/usr/share/ca-certificates \
|
-v /usr/share/ca-certificates:/usr/share/ca-certificates \
|
||||||
-v $(pwd)/bin/ros:/usr/bin/os \
|
|
||||||
-w /var/lib/rancher \
|
-w /var/lib/rancher \
|
||||||
--entrypoint sh \
|
--entrypoint sh \
|
||||||
rancher/os-base:v0.8.1
|
rancher/os-base:v0.8.1
|
||||||
|
30
util/network/cache.go
Executable file → Normal file
30
util/network/cache.go
Executable file → Normal file
@@ -5,45 +5,41 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/rancher/os/config"
|
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cacheDirectory = "/var/lib/rancher/cache/"
|
||||||
|
)
|
||||||
|
|
||||||
func locationHash(location string) string {
|
func locationHash(location string) string {
|
||||||
sum := md5.Sum([]byte(location))
|
sum := md5.Sum([]byte(location))
|
||||||
return hex.EncodeToString(sum[:])
|
return hex.EncodeToString(sum[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func CacheLookup(location string) ([]byte, error) {
|
func cacheLookup(location string) []byte {
|
||||||
cacheFile := filepath.Join(config.CacheDirectory, location)
|
cacheFile := cacheDirectory + locationHash(location)
|
||||||
bytes, err := ioutil.ReadFile(cacheFile)
|
bytes, err := ioutil.ReadFile(cacheFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Debugf("Using cached file: %s", cacheFile)
|
log.Debugf("Using cached file: %s", cacheFile)
|
||||||
return bytes, nil
|
return bytes
|
||||||
}
|
}
|
||||||
log.Debugf("Cached file not found: %s", cacheFile)
|
return nil
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cacheAdd(location string, data []byte) error {
|
func cacheAdd(location string, data []byte) {
|
||||||
os.MkdirAll(config.CacheDirectory, 0755)
|
tempFile, err := ioutil.TempFile(cacheDirectory, "")
|
||||||
tempFile, err := ioutil.TempFile(config.CacheDirectory, "")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
defer os.Remove(tempFile.Name())
|
defer os.Remove(tempFile.Name())
|
||||||
|
|
||||||
_, err = tempFile.Write(data)
|
_, err = tempFile.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheFile := filepath.Join(config.CacheDirectory, location)
|
cacheFile := cacheDirectory + locationHash(location)
|
||||||
cacheDir := filepath.Dir(cacheFile)
|
|
||||||
log.Debugf("writing %s to %s", cacheFile, cacheDir)
|
|
||||||
os.MkdirAll(cacheDir, 0755)
|
|
||||||
os.Rename(tempFile.Name(), cacheFile)
|
os.Rename(tempFile.Name(), cacheFile)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
52
util/network/network.go
Executable file → Normal file
52
util/network/network.go
Executable file → Normal file
@@ -32,48 +32,6 @@ func GetEngines(urls []string) ([]string, error) {
|
|||||||
return getServices(urls, "engines")
|
return getServices(urls, "engines")
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchAllServices() error {
|
|
||||||
cfg := config.LoadConfig()
|
|
||||||
for name, url := range cfg.Rancher.Repositories {
|
|
||||||
log.Infof("repo index %s: %v", name, url.URL)
|
|
||||||
indexURL := fmt.Sprintf("%s/index.yml", url.URL)
|
|
||||||
content, err := loadFromNetwork(indexURL)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s: %v", indexURL, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// save the index file to the cache dir
|
|
||||||
cacheAdd(fmt.Sprintf("%s/index.yml", name), content)
|
|
||||||
// load it, and then download each service file and cache too
|
|
||||||
services := make(map[string][]string)
|
|
||||||
err = yaml.Unmarshal(content, &services)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to unmarshal %s: %v", indexURL, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for serviceType, serviceList := range services {
|
|
||||||
for _, serviceName := range serviceList {
|
|
||||||
fmt.Printf("\t%s is type %s from %s\n", serviceName, serviceType, name)
|
|
||||||
serviceURL := serviceURL(url.URL, serviceName)
|
|
||||||
content, err := loadFromNetwork(serviceURL)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to load %s: %v", serviceURL, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// save the service file to the cache dir
|
|
||||||
if err = cacheAdd(fmt.Sprintf("%s/%s.yml", name, serviceName), content); err != nil {
|
|
||||||
log.Errorf("cacheAdd: %s", err)
|
|
||||||
}
|
|
||||||
//display which services are new, and which are updated from previous cache
|
|
||||||
//and `listServices` will need to compare the cached servcies with the version that was enabled/up
|
|
||||||
//also list the services that are no longer updated (ie, purge candidates)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getServices(urls []string, key string) ([]string, error) {
|
func getServices(urls []string, key string) ([]string, error) {
|
||||||
result := []string{}
|
result := []string{}
|
||||||
|
|
||||||
@@ -122,11 +80,11 @@ func SetProxyEnvironmentVariables(cfg *config.CloudConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadFromNetwork(location string) ([]byte, error) {
|
func loadFromNetwork(location string) ([]byte, error) {
|
||||||
/* bytes := cacheLookup(location)
|
bytes := cacheLookup(location)
|
||||||
if bytes != nil {
|
if bytes != nil {
|
||||||
return bytes, nil
|
return bytes, nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
SetProxyEnvironmentVariables(cfg)
|
SetProxyEnvironmentVariables(cfg)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user