1
0
mirror of https://github.com/rancher/os.git synced 2025-06-20 12:11:56 +00:00
os/cmd/control/os.go

177 lines
3.1 KiB
Go
Raw Normal View History

package control
import (
"fmt"
"io/ioutil"
"net/http"
2015-03-18 12:34:23 +00:00
"net/url"
"strings"
log "github.com/Sirupsen/logrus"
2015-03-18 12:34:23 +00:00
"gopkg.in/yaml.v2"
dockerClient "github.com/fsouza/go-dockerclient"
"github.com/codegangsta/cli"
"github.com/rancherio/os/cmd/power"
"github.com/rancherio/os/config"
"github.com/rancherio/os/docker"
)
2015-03-18 12:34:23 +00:00
type Images struct {
Current string `yaml:"current,omitempty"`
Available []string `yaml:"available,omitempty"`
}
func osSubcommands() []cli.Command {
return []cli.Command{
{
Name: "upgrade",
Usage: "upgrade to latest version",
Action: osUpgrade,
Flags: []cli.Flag{
cli.BoolFlag{
2015-02-23 19:00:33 +00:00
Name: "stage, s",
Usage: "Only stage the new upgrade, don't apply it",
},
cli.StringFlag{
2015-02-23 19:00:33 +00:00
Name: "image, i",
Usage: "upgrade to a certain image",
},
},
},
{
2015-02-23 19:00:33 +00:00
Name: "list",
Usage: "list the current available versions",
Action: osMetaDataGet,
},
}
}
2015-03-18 12:34:23 +00:00
func getImages() (*Images, error) {
upgradeUrl, err := getUpgradeUrl()
if err != nil {
2015-03-18 12:34:23 +00:00
return nil, err
}
2015-03-18 12:34:23 +00:00
var body []byte
if strings.HasPrefix(upgradeUrl, "/") {
body, err = ioutil.ReadFile(upgradeUrl)
if err != nil {
return nil, err
}
} else {
u, err := url.Parse(upgradeUrl)
if err != nil {
return nil, err
}
q := u.Query()
q.Set("current", config.VERSION)
u.RawQuery = q.Encode()
upgradeUrl = u.String()
resp, err := http.Get(upgradeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
}
2015-03-18 12:34:23 +00:00
return parseBody(body)
}
2015-02-23 19:00:33 +00:00
func osMetaDataGet(c *cli.Context) {
2015-03-18 12:34:23 +00:00
images, err := getImages()
if err != nil {
log.Fatal(err)
}
2015-03-18 12:34:23 +00:00
client, err := docker.NewSystemClient()
if err != nil {
log.Fatal(err)
}
2015-03-18 12:34:23 +00:00
for _, image := range images.Available {
_, err := client.InspectImage(image)
if err == dockerClient.ErrNoSuchImage {
fmt.Println(image, " remote")
} else {
fmt.Println(image, " local")
}
}
}
2015-03-18 12:34:23 +00:00
func getLatestImage() (string, error) {
images, err := getImages()
if err != nil {
return "", err
}
2015-03-18 12:34:23 +00:00
return images.Current, nil
}
func osUpgrade(c *cli.Context) {
image := c.String("image")
if image == "" {
var err error
2015-03-18 12:34:23 +00:00
image, err = getLatestImage()
if err != nil {
log.Fatal(err)
}
2015-03-18 12:34:23 +00:00
if image == "" {
log.Fatal("Failed to find latest image")
}
}
startUpgradeContainer(image, c.Bool("stage"))
}
func startUpgradeContainer(image string, stage bool) {
container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &config.ContainerConfig{
2015-03-18 12:34:23 +00:00
Cmd: "--name=os-upgrade " +
"--rm " +
"--privileged " +
"--net=host " +
2015-03-18 12:34:23 +00:00
image + " " +
"-t rancher-upgrade " +
"-r " + config.VERSION,
}).Stage()
if container.Err != nil {
log.Fatal(container.Err)
}
if !stage {
container.StartAndWait()
if container.Err != nil {
log.Fatal(container.Err)
}
power.Reboot()
}
}
2015-03-18 12:34:23 +00:00
func parseBody(body []byte) (*Images, error) {
update := &Images{}
err := yaml.Unmarshal(body, update)
if err != nil {
2015-03-18 12:34:23 +00:00
return nil, err
}
2015-03-18 12:34:23 +00:00
return update, nil
}
2015-03-18 12:34:23 +00:00
func getUpgradeUrl() (string, error) {
cfg, err := config.LoadConfig()
if err != nil {
return "", err
}
2015-03-18 12:34:23 +00:00
return cfg.Upgrade.Url, nil
}