Skip to content

Commit

Permalink
Merge branch 'rename-power-commands' into 'develop'
Browse files Browse the repository at this point in the history
Rename power commands

Closes #253

See merge request open-source/bytemark-client!249
  • Loading branch information
James Carter committed Apr 6, 2018
2 parents e2bf49c + a160d99 commit 26b24da
Show file tree
Hide file tree
Showing 15 changed files with 417 additions and 295 deletions.
3 changes: 2 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ doc-check:
- |
if ! ./gen/test-HACKING.sh; then
echo "HACKING has not been updated to match the new folder structure!"
echo "Run tree -d 'vendor' | sha256sum and paste the shasum over the one in HACKING"
echo "Run the following and paste the shasum over the one in HACKING"
echo " find . -type d \! -path './.*' \! -path './vendor/*' | sort | sha256sum"
exit 1
fi
Expand Down
10 changes: 7 additions & 3 deletions HACKING
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ what they're for
│   │   ├── args - functions for chaining together using app.Action to parse
│   │ │ arguments into flags
│   │   ├── flags - common flags
│   │ ├── wait - functions which wait for a condition to be true before
│   │ │ returning
│   │   └── with - functions for chaining together using app.Action to attach
│   │ things to the Context by parsing flag values.
│   ├── cliutil - workarounds for deficiencies in urfave/cli
   ├── commands - top-level command skeletons and those which contain no
   ├── commands - top-level command skeletons and those which contain no
│ │ │ subcommands or only one subcommand
│   │   ├── admin - contains all the admin commands in admin.Commands
│   │ ├── admin - contains all the admin commands in admin.Commands
│ │ │ └── add - contains all the admin add commands for adding resources
│   │ │ that only an admin would have permission to do
│   │   ├── add - contains commands for adding or creating extra resources to
Expand Down Expand Up @@ -191,6 +193,8 @@ billing-definition' command in update.go and the UpdateDefinition and
GetDefinition functions in lib/requests/billing, and the tests for those, for
examples on how to structure code in this new way.

3.0 was primarily about fixing our slightly wacky command naming.

The focus of 4.0 is going to be carving up cmd/bytemark and lib into multiple
smaller packages, and splitting the files within up into smaller ones - one per
request type.
Expand All @@ -216,4 +220,4 @@ To generate the hash, use the following command.

find . -type d \! -path './.*' \! -path './vendor/*' | sort | shasum -a 256

# sha256sum: 784106ea0a960d51952630a349c6426952a9e32de7f2b48ef9aca92979c200dd
# sha256sum: ef446f7be454a2a4a19d0d758388ea79df936beeeedb3c96580cbf8c90cbced0
30 changes: 30 additions & 0 deletions cmd/bytemark/app/wait/vm_power_off.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package wait

import (
"fmt"
"time"

"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app"
"github.com/BytemarkHosting/bytemark-client/lib"
"github.com/BytemarkHosting/bytemark-client/lib/brain"
)

// VMPowerOff waits for the named virtual machine to power off before returning
// a nil error. This is done by frequently polling the brain for info about the
// VM. If any calls fail, the error is returned.
func VMPowerOff(c *app.Context, name lib.VirtualMachineName) (err error) {
vm := brain.VirtualMachine{PowerOn: true}

for vm.PowerOn {
if !c.IsTest() {
time.Sleep(5 * time.Second)
}
fmt.Fprint(c.App().Writer, ".")

vm, err = c.Client().GetVirtualMachine(name)
if err != nil {
return
}
}
return
}
47 changes: 47 additions & 0 deletions cmd/bytemark/commands/reset_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package commands

import (
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/args"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/with"
"github.com/urfave/cli"
)

func init() {
serverFlag := cli.GenericFlag{
Name: "server",
Usage: "the server to reset",
Value: new(app.VirtualMachineNameFlag),
}

Commands = append(Commands, cli.Command{
Name: "reset",
Usage: "restart a server as though the reset button had been pushed FISMO",
UsageText: "reset server <server>",
Description: "For cloud servers, this does not cause the qemu process to be restarted. This means that the server will remain on the same head and will not notice hardware changes.",
Action: cli.ShowSubcommandHelp,
Flags: []cli.Flag{
serverFlag,
},
Subcommands: []cli.Command{{
Name: "server",
Usage: "restart a server as though the reset button had been pushed",
UsageText: "reset server <server>",
Description: "For cloud servers, this does not cause the qemu process to be restarted. This means that the server will remain on the same head and will not notice hardware changes.",
Flags: []cli.Flag{
serverFlag,
},
Action: app.Action(args.Optional("server"), with.RequiredFlags("server"), with.Auth, func(c *app.Context) (err error) {
vmName := c.VirtualMachineName("server")
c.LogErr("Attempting to reset %v...\r\n", vmName)
err = c.Client().ResetVirtualMachine(vmName)
if err != nil {
return err
}

c.LogErr("%v reset successfully.\r\n", vmName)
return
}),
}},
})
}
27 changes: 27 additions & 0 deletions cmd/bytemark/commands/reset_server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package commands_test

import (
"strings"
"testing"

"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/commands"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/testutil"
"github.com/BytemarkHosting/bytemark-client/lib"
"github.com/cheekybits/is"
)

func TestResetCommand(t *testing.T) {
is := is.New(t)
config, c, app := testutil.BaseTestAuthSetup(t, false, commands.Commands)
vmn := lib.VirtualMachineName{VirtualMachine: "test-server", Group: "test-group", Account: "test-account"}

config.When("GetVirtualMachine").Return(lib.VirtualMachineName{VirtualMachine: "smog-daniels", Group: "creation", Account: "science"})

c.When("ResetVirtualMachine", vmn).Times(1)

err := app.Run(strings.Split("bytemark reset server test-server.test-group.test-account", " "))
is.Nil(err)
if ok, err := c.Verify(); !ok {
t.Fatal(err)
}
}
74 changes: 74 additions & 0 deletions cmd/bytemark/commands/restart_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package commands

import (
"fmt"

"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/args"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/wait"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/with"
brainRequests "github.com/BytemarkHosting/bytemark-client/lib/requests/brain"
"github.com/urfave/cli"
)

func init() {
Commands = append(Commands, cli.Command{
Name: "restart",
Usage: "power off a server and start it again",
UsageText: "restart server [--rescue | --appliance <appliance>] <server>",
Description: "This command will power down a server and then start it back up again.",
Action: cli.ShowSubcommandHelp,
Subcommands: []cli.Command{{
Name: "server",
Usage: "power off a server and start it again",
UsageText: "restart server [--rescue | --appliance <appliance>] <server>",
Flags: []cli.Flag{
cli.GenericFlag{
Name: "server",
Usage: "the server to restart",
Value: new(app.VirtualMachineNameFlag),
},
cli.BoolFlag{
Name: "rescue",
Usage: "boots the server using the rescue appliance",
},
cli.StringFlag{
Name: "appliance",
Usage: "the appliance to boot into when the server starts",
},
},
Action: app.Action(args.Optional("server"), with.RequiredFlags("server"), with.Auth, func(c *app.Context) (err error) {
vmName := c.VirtualMachineName("server")
appliance := c.String("appliance")

if appliance != "" && c.Bool("rescue") {
return fmt.Errorf("--appliance and --rescue have both been set when only one is allowed")
}

if c.Bool("rescue") {
appliance = "rescue"
}

fmt.Fprintf(c.App().Writer, "Shutting down %v...", vmName)
err = c.Client().ShutdownVirtualMachine(vmName, true)
if err != nil {
return
}
err = wait.VMPowerOff(c, vmName)
if err != nil {
return
}

c.Log("Done!\n\nStarting %s back up.", vmName)
if appliance != "" {
err = brainRequests.StartVirtualMachineWithAppliance(c.Client(), vmName, appliance)
c.Log("Server has now started. Use `bytemark console %v` or visit %v to connect.", c.String("server"), c.Config().PanelURL())
} else {
err = c.Client().StartVirtualMachine(vmName)
}

return
}),
}},
})
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,18 @@
package main
package commands_test

import (
"fmt"
"strings"
"testing"

"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/commands"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/testutil"
"github.com/BytemarkHosting/bytemark-client/lib"
"github.com/BytemarkHosting/bytemark-client/lib/brain"
"github.com/BytemarkHosting/bytemark-client/mocks"
"github.com/cheekybits/is"
)

func TestResetCommand(t *testing.T) {
is := is.New(t)
config, c, app := testutil.BaseTestAuthSetup(t, false, commands)
vmn := lib.VirtualMachineName{VirtualMachine: "test-server", Group: "test-group", Account: "test-account"}

config.When("GetVirtualMachine").Return(defVM)

c.When("ResetVirtualMachine", vmn).Times(1)

err := app.Run(strings.Split("bytemark reset test-server.test-group.test-account", " "))
is.Nil(err)
if ok, err := c.Verify(); !ok {
t.Fatal(err)
}
}
func TestRestartCommand(t *testing.T) {
func TestRestartServerCommand(t *testing.T) {
tests := []struct {
name string
input string
Expand Down Expand Up @@ -61,7 +46,7 @@ func TestRestartCommand(t *testing.T) {
},
}, {
name: "RestartWithApplianceFlagWithoutAppliance",
input: "test-server --appliance",
input: "--appliance test-server",
vmname: lib.VirtualMachineName{
VirtualMachine: "test-server",
Group: "default",
Expand All @@ -70,7 +55,7 @@ func TestRestartCommand(t *testing.T) {
shouldErr: true,
}, {
name: "RestartWithApplianceFlag",
input: "test-server --appliance rescue",
input: "--appliance rescue test-server",
vmname: lib.VirtualMachineName{
VirtualMachine: "test-server",
Group: "default",
Expand All @@ -79,7 +64,7 @@ func TestRestartCommand(t *testing.T) {
applianceBoot: true,
}, {
name: "RestartWithRescueFlag",
input: "test-server --rescue",
input: "--rescue test-server",
vmname: lib.VirtualMachineName{
VirtualMachine: "test-server",
Group: "default",
Expand All @@ -88,7 +73,7 @@ func TestRestartCommand(t *testing.T) {
applianceBoot: true,
}, {
name: "RestartWithApplianceAndRescueFlag",
input: "test-server --appliance a --rescue",
input: "--appliance a --rescue test-server",
vmname: lib.VirtualMachineName{
VirtualMachine: "test-server",
Group: "default",
Expand All @@ -99,8 +84,8 @@ func TestRestartCommand(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
config, client, app := testutil.BaseTestAuthSetup(t, false, commands)
config.When("GetVirtualMachine").Return(defVM)
config, client, app := testutil.BaseTestAuthSetup(t, false, commands.Commands)
config.When("GetVirtualMachine").Return(lib.VirtualMachineName{Group: "default", Account: "default-account"})
config.When("PanelURL").Return("something.com")

client.When("ShutdownVirtualMachine", test.vmname, true).Times(1)
Expand All @@ -120,7 +105,7 @@ func TestRestartCommand(t *testing.T) {
client.When("StartVirtualMachine", test.vmname).Times(1)
}

args := fmt.Sprintf("bytemark restart %s", test.input)
args := fmt.Sprintf("bytemark restart server %s", test.input)
err := app.Run(strings.Split(args, " "))
if !test.shouldErr && err != nil {
t.Errorf("shouldn't err, but did: %T{%s}", err, err.Error())
Expand All @@ -135,51 +120,3 @@ func TestRestartCommand(t *testing.T) {
})
}
}
func TestShutdownCommand(t *testing.T) {
is := is.New(t)
config, c, app := testutil.BaseTestAuthSetup(t, false, commands)
vmn := lib.VirtualMachineName{VirtualMachine: "test-server", Group: "test-group", Account: "test-account"}

config.When("GetVirtualMachine").Return(defVM)

c.When("ShutdownVirtualMachine", vmn, true).Times(1)
c.When("GetVirtualMachine", vmn).Return(brain.VirtualMachine{PowerOn: false})

err := app.Run(strings.Split("bytemark shutdown test-server.test-group.test-account", " "))
is.Nil(err)
if ok, err := c.Verify(); !ok {
t.Fatal(err)
}
}
func TestStartCommand(t *testing.T) {
is := is.New(t)
config, c, app := testutil.BaseTestAuthSetup(t, false, commands)
vmn := lib.VirtualMachineName{VirtualMachine: "test-server", Group: "test-group", Account: "test-account"}

config.When("GetVirtualMachine").Return(defVM)

c.When("StartVirtualMachine", vmn).Times(1)

err := app.Run(strings.Split("bytemark start test-server.test-group.test-account", " "))
is.Nil(err)
if ok, err := c.Verify(); !ok {
t.Fatal(err)
}
}
func TestStopCommand(t *testing.T) {
is := is.New(t)
config, c, app := testutil.BaseTestAuthSetup(t, false, commands)

vmn := lib.VirtualMachineName{VirtualMachine: "test-server", Group: "test-group", Account: "test-account"}

config.When("GetVirtualMachine").Return(defVM)

c.When("StopVirtualMachine", vmn).Times(1)

err := app.Run(strings.Split("bytemark stop test-server.test-group.test-account", " "))
is.Nil(err)

if ok, err := c.Verify(); !ok {
t.Fatal(err)
}
}
Loading

0 comments on commit 26b24da

Please sign in to comment.