Skip to content

Commit

Permalink
Merge branch 'master' into subunit
Browse files Browse the repository at this point in the history
  • Loading branch information
come-maiz committed Nov 4, 2015
2 parents 852fdb4 + f220ee7 commit f961017
Show file tree
Hide file tree
Showing 88 changed files with 714 additions and 773 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ env:
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq squashfs-tools
install:
- echo "Skip. Install is done by the test script."
script: sh -v ./run-checks $TEST_SUITE
after_success:
- go get github.com/mattn/goveralls
Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ At this point you will have the git local repository of the `snappy` source at
`$GOPATH/github.com/ubuntu-core/snappy/snappy`. The source for any
dependent packages will also be available inside `$GOPATH`.

### Dependencies handling

To generate dependencies.tsv you need `godeps`, so

go get launchpad.net/godeps

To obtain the correct dependencies for the project, run:

godeps -t -u dependencies.tsv

If the dependencies need updating

godeps -t ./... > dependencies.tsv

### Building

To build, once the sources are available and `GOPATH` is set, you can just run
Expand Down Expand Up @@ -99,19 +113,6 @@ If a test hangs, you can enable verbose mode:
(or -check.v for less verbose output).

There is more to read about the testing framework on the [website](https://labix.org/gocheck)
### Dependencies handling

To generate dependencies.tsv you need `godeps`, so

go get launchpad.net/godeps

To obtain the correct dependencies for the project, run:

godeps -t -u dependencies.tsv

If the dependencies need updating

godeps -t ./... > dependencies.tsv


[travis-image]: https://travis-ci.org/ubuntu-core/snappy.svg?branch=master
Expand Down
15 changes: 13 additions & 2 deletions cmd/snappy/cmd_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import (
type cmdUpdate struct {
DisableGC bool `long:"no-gc"`
AutoReboot bool `long:"automatic-reboot"`
Positional struct {
PackageName string `positional-arg-name:"package name"`
} `positional-args:"yes"`
}

func init() {
Expand All @@ -46,14 +49,16 @@ func init() {
}
addOptionDescription(arg, "no-gc", i18n.G("Do not clean up old versions of the package."))
addOptionDescription(arg, "automatic-reboot", i18n.G("Reboot if necessary to be on the latest running system."))
addOptionDescription(arg, "package name", i18n.G("The Package to update"))
}

const (
shutdownCmd = "/sbin/shutdown"
shutdownTimeout = "+10"
)

var shutdownMsg = i18n.G("snappy autopilot triggered a reboot to boot into an up to date system -- temprorarily disable the reboot by running 'sudo shutdown -c'")
// TRANSLATORS: please keep this under 80 characters if possible
var shutdownMsg = i18n.G("Snappy needs to reboot to finish an update. Defer with 'shutdown -c'.")

func (x *cmdUpdate) Execute(args []string) (err error) {
return withMutexAndRetry(x.doUpdate)
Expand All @@ -66,7 +71,13 @@ func (x *cmdUpdate) doUpdate() error {
flags = 0
}

updates, err := snappy.Update(flags, progress.MakeProgressBar())
var err error
var updates []snappy.Part
if x.Positional.PackageName != "" {
updates, err = snappy.Update(x.Positional.PackageName, flags, progress.MakeProgressBar())
} else {
updates, err = snappy.UpdateAll(flags, progress.MakeProgressBar())
}
if err != nil {
return err
}
Expand Down
24 changes: 15 additions & 9 deletions cmd/snappy/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@ import (
"fmt"
"os/exec"
"strings"
sys "syscall"
"time"

"github.com/ubuntu-core/snappy/dirs"
"github.com/ubuntu-core/snappy/i18n"
"github.com/ubuntu-core/snappy/lockfile"
"github.com/ubuntu-core/snappy/logger"
"github.com/ubuntu-core/snappy/priv"
"github.com/ubuntu-core/snappy/snappy"

"github.com/jessevdk/go-flags"
)

const snappyLockFile = "/run/snappy.lock"

func isAutoPilotRunning() bool {
func isAutoUpdateRunning() bool {
unitName := "snappy-autopilot"
bs, err := exec.Command("systemctl", "show", "--property=SubState", unitName).CombinedOutput()
if err != nil {
Expand All @@ -47,18 +48,23 @@ func isAutoPilotRunning() bool {
// withMutexAndRetry runs the given function with a filelock mutex and provides
// automatic re-try and helpful messages if the lock is already taken
func withMutexAndRetry(f func() error) error {
if sys.Getuid() != 0 {
return snappy.ErrNeedRoot
}
for {
err := priv.WithMutex(snappyLockFile, f)
err := lockfile.WithLock(dirs.SnapLockFile, f)
// if already locked, auto-retry
if err == priv.ErrAlreadyLocked {
if err == lockfile.ErrAlreadyLocked {
var msg string
if isAutoPilotRunning() {
if isAutoUpdateRunning() {
// FIXME: we could even do a
// journalctl -u snappy-autopilot
// here

// TRANSLATORS: please keep each line under 80 characters.
msg = i18n.G(
`The snappy autopilot is updating your system in the background. This may
take some minutes. Will try again in %d seconds...
`Snappy is updating your system in the background. This may take some minutes.
Will try again in %d seconds...
Press ctrl-c to cancel.
`)
} else {
Expand Down
7 changes: 0 additions & 7 deletions cmd/snappy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import (
"os"

"github.com/ubuntu-core/snappy/logger"
"github.com/ubuntu-core/snappy/priv"
"github.com/ubuntu-core/snappy/snappy"

"github.com/jessevdk/go-flags"
)
Expand All @@ -47,11 +45,6 @@ func init() {

func main() {
if _, err := parser.Parse(); err != nil {
if err == priv.ErrNeedRoot {
// make the generic root error more specific for
// the CLI user.
err = snappy.ErrNeedRoot
}
fmt.Fprintln(os.Stderr, err)
if _, ok := err.(*flags.Error); !ok {
logger.Debugf("%v failed: %v", os.Args, err)
Expand Down
76 changes: 38 additions & 38 deletions coreconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ var (
)

const (
autopilotTimer string = "snappy-autopilot.timer"
autopilotTimerEnabled string = "enabled"
autopilotTimerDisabled string = "disabled"
autoUpdateTimer string = "snappy-autopilot.timer"
autoUpdateTimerEnabled string = "enabled"
autoUpdateTimerDisabled string = "disabled"
)

var (
Expand All @@ -73,13 +73,13 @@ var (
)

type systemConfig struct {
Autopilot *bool `yaml:"autopilot,omitempty"`
Timezone *string `yaml:"timezone,omitempty"`
Hostname *string `yaml:"hostname,omitempty"`
Modprobe *string `yaml:"modprobe,omitempty"`
Modules []string `yaml:"load-kernel-modules,omitempty"`
Network *networkConfig `yaml:"network,omitempty"`
Watchdog *watchdogConfig `yaml:"watchdog,omitempty"`
AutoUpdate *bool `yaml:"autoupdate,omitempty"`
Timezone *string `yaml:"timezone,omitempty"`
Hostname *string `yaml:"hostname,omitempty"`
Modprobe *string `yaml:"modprobe,omitempty"`
Modules []string `yaml:"load-kernel-modules,omitempty"`
Network *networkConfig `yaml:"network,omitempty"`
Watchdog *watchdogConfig `yaml:"watchdog,omitempty"`
}

type networkConfig struct {
Expand Down Expand Up @@ -112,7 +112,7 @@ func newSystemConfig() (*systemConfig, error) {
return nil, err
}

autopilot, err := getAutopilot()
autoUpdate, err := getAutoUpdate()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -150,13 +150,13 @@ func newSystemConfig() (*systemConfig, error) {
}

config := &systemConfig{
Autopilot: &autopilot,
Timezone: &tz,
Hostname: &hostname,
Modprobe: &modprobe,
Modules: modules,
Network: network,
Watchdog: watchdog,
AutoUpdate: &autoUpdate,
Timezone: &tz,
Hostname: &hostname,
Modprobe: &modprobe,
Modules: modules,
Network: network,
Watchdog: watchdog,
}

return config, nil
Expand Down Expand Up @@ -230,12 +230,12 @@ func Set(rawConfig string) (newRawConfig string, err error) {
if err := setTimezone(*newConfig.Timezone); err != nil {
return "", err
}
case "Autopilot":
if *oldConfig.Autopilot == *newConfig.Autopilot {
case "AutoUpdate":
if *oldConfig.AutoUpdate == *newConfig.AutoUpdate {
continue
}

if err := setAutopilot(*newConfig.Autopilot); err != nil {
if err := setAutoUpdate(*newConfig.AutoUpdate); err != nil {
return "", err
}
case "Hostname":
Expand Down Expand Up @@ -498,13 +498,13 @@ var setWatchdog = func(wf *watchdogConfig) error {

// for testing purposes
var (
cmdAutopilotEnabled = []string{"is-enabled", autopilotTimer}
cmdSystemctl = "systemctl"
cmdAutoUpdateEnabled = []string{"is-enabled", autoUpdateTimer}
cmdSystemctl = "systemctl"
)

// getAutopilot returns the autopilot state
var getAutopilot = func() (state bool, err error) {
out, err := exec.Command(cmdSystemctl, cmdAutopilotEnabled...).Output()
// getAutoUpdate returns the autoupdate state
var getAutoUpdate = func() (state bool, err error) {
out, err := exec.Command(cmdSystemctl, cmdAutoUpdateEnabled...).Output()
if exitErr, ok := err.(*exec.ExitError); ok {
waitStatus := exitErr.Sys().(syscall.WaitStatus)

Expand All @@ -516,9 +516,9 @@ var getAutopilot = func() (state bool, err error) {

status := strings.TrimSpace(string(out))

if status == autopilotTimerEnabled {
if status == autoUpdateTimerEnabled {
return true, nil
} else if status == autopilotTimerDisabled {
} else if status == autoUpdateTimerDisabled {
return false, nil
} else {
return false, ErrInvalidUnitStatus
Expand All @@ -527,26 +527,26 @@ var getAutopilot = func() (state bool, err error) {

// for testing purposes
var (
cmdEnableAutopilot = []string{"enable", autopilotTimer}
cmdStartAutopilot = []string{"start", autopilotTimer}
cmdDisableAutopilot = []string{"disable", autopilotTimer}
cmdStopAutopilot = []string{"stop", autopilotTimer}
cmdEnableAutoUpdate = []string{"enable", autoUpdateTimer}
cmdStartAutoUpdate = []string{"start", autoUpdateTimer}
cmdDisableAutoUpdate = []string{"disable", autoUpdateTimer}
cmdStopAutoUpdate = []string{"stop", autoUpdateTimer}
)

// setAutopilot enables and starts, or stops and disables autopilot
var setAutopilot = func(stateEnabled bool) error {
// setAutoUpdate enables and starts, or stops and disables autoupdate
var setAutoUpdate = func(stateEnabled bool) error {
if stateEnabled {
if err := exec.Command(cmdSystemctl, cmdEnableAutopilot...).Run(); err != nil {
if err := exec.Command(cmdSystemctl, cmdEnableAutoUpdate...).Run(); err != nil {
return err
}
if err := exec.Command(cmdSystemctl, cmdStartAutopilot...).Run(); err != nil {
if err := exec.Command(cmdSystemctl, cmdStartAutoUpdate...).Run(); err != nil {
return err
}
} else {
if err := exec.Command(cmdSystemctl, cmdStopAutopilot...).Run(); err != nil {
if err := exec.Command(cmdSystemctl, cmdStopAutoUpdate...).Run(); err != nil {
return err
}
if err := exec.Command(cmdSystemctl, cmdDisableAutopilot...).Run(); err != nil {
if err := exec.Command(cmdSystemctl, cmdDisableAutoUpdate...).Run(); err != nil {
return err
}
}
Expand Down
Loading

0 comments on commit f961017

Please sign in to comment.