Skip to content

Commit

Permalink
Merge branch 'create-migration-job' into 239-command-to-create-a-migr…
Browse files Browse the repository at this point in the history
…ation-job
  • Loading branch information
James F. Carter committed Mar 27, 2018
2 parents 11c35be + 8ebe8ff commit f9437ef
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 25 deletions.
8 changes: 8 additions & 0 deletions cmd/bytemark/app/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ func (c *Context) String(flagname string) string {
return c.Context.GlobalString(flagname)
}

// StringSlice returns the values of the named flag as a []string
func (c *Context) StringSlice(flagname string) []string {
if c.Context.IsSet(flagname) || c.Context.String(flagname) != "" {
return c.Context.StringSlice(flagname)
}
return c.Context.GlobalStringSlice(flagname)
}

// Size returns the value of the named SizeSpecFlag as an int in megabytes
func (c *Context) Size(flagname string) int {
size, ok := c.Context.Generic(flagname).(*util.SizeSpecFlag)
Expand Down
123 changes: 98 additions & 25 deletions cmd/bytemark/commands/admin/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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/BytemarkHosting/bytemark-client/lib/brain"
"github.com/BytemarkHosting/bytemark-client/util/log"
"github.com/urfave/cli"
)
Expand All @@ -14,9 +15,103 @@ func init() {
Action: cli.ShowSubcommandHelp,
Subcommands: []cli.Command{
{
Name: "user",
Usage: "creates a new cluster admin or cluster superuser",
UsageText: "bytemark --admin create user <username> <privilege>",
Name: "ip range",
Usage: "create a new IP range in a VLAN",
UsageText: "bytemark --admin create ip range <ip-range> <vlan-num>",
Flags: []cli.Flag{
cli.StringFlag{
Name: "ip-range",
Usage: "the IP range to add",
},
cli.IntFlag{
Name: "vlan-num",
Usage: "The VLAN number to add the IP range to",
},
},
Action: app.Action(args.Optional("ip-range", "vlan-num"), with.RequiredFlags("ip-range", "vlan-num"), with.Auth, func(c *app.Context) error {
if err := c.Client().CreateIPRange(c.String("ip-range"), c.Int("vlan-num")); err != nil {
return err
}
log.Logf("IP range created\r\n")
return nil
}),
}, {
Name: "migration",
Usage: "creates a new migration job",
UsageText: "bytemark --admin create migration [--priority <number>] [--disc <disc>]... [--pool <pool>]... [--tail <tail>]... [--to-pool <pool>]...",
Description: `Requests that the brain starts a migration from the various discs, pools and tails specified to the various pools specified.
If no --to-pools are specified, the brain will decide destinations on its own. To migrate multiple discs, pools, or tails, or to distribute migrating discs across multiple storage pools, simply specify those flags multiple times.
Source discs, tails and pools and destination pools can all be specified as their numeric IDs, their label, or their IP address.
When there are multiple migration jobs at once and migration concurrency limits are being reached, jobs with highest priority will have their migrations scheduled ahead of other jobs.
EXAMPLES:
# migrate one disc whose IP is fe80::1 to tail2-sata1
bytemark --admin create migration --disc fe80::1 --to-pool tail2-sata1
# empty a tail to wherever is appropriate with a high priority
bytemark --admin create migration --priority 10 --tail tail1
# migrate two discs, one called very-unique-label and one whose ID is 45859 to tail2-sata1
bytemark --admin create migration --disc very-unique-label --disc 45859 --to-pool tail2-sata1
# migrate one pool to another
bytemark --admin create migration --pool tail1-sata1 --to-pool tail2-sata1
# migrate two pools to one pool
bytemark --admin create migration --pool tail1-sata1 --pool tail1-sata2 --to-pool tail2-sata1
# migrate a pool and a specific disc away from their current tail
bytemark --admin create migration --pool tail1-sata1 --disc 45859`,

Flags: []cli.Flag{
cli.StringSliceFlag{
Name: "disc",
Usage: "a disc to migrate to some other destination. Can be specified multiple times to migrate multiple discs",
},
cli.StringSliceFlag{
Name: "pool",
Usage: "a storage pool to migrate to some other destination. Can be specified multiple times to migrate multiple storage pools",
},
cli.StringSliceFlag{
Name: "tail",
Usage: "a tail to migrate to some other destination. Can be specified multiple times to migrate multiple tails",
},
cli.StringSliceFlag{
Name: "to-pool",
Usage: "a disc to migrate to some other destination. Can be specified multiple times to migrate multiple discs",
},
cli.IntFlag{
Name: "priority",
Usage: "an optional priority to set - bigger is higher priority",
},
},
Action: app.Action(with.Auth, func(ctx *app.Context) err {
jobRequest := brain.MigrationJob{
Sources: brain.MigrationJobLocations{
Discs: ctx.StringSlice("disc"),
Pools: ctx.StringSlice("pool"),
Tails: ctx.StringSlice("tail"),
},
Destinations: brain.MigrationJobDestinations{
Pools: ctx.StringSlice("to-pool"),
},
Priority: ctx.Int("priority"),
}
job, err := adminRequests.CreateMigrationJob(jobRequest)
if err != nil {
ctx.Output("Migration job created")
return ctx.OutputInDesiredForm(job)
}
ctx.Output("Couldn't create migration job")
return err
}),
}, {
Name: "user",
Usage: "creates a new cluster admin or cluster superuser",
UsageText: "bytemark --admin create user <username> <privilege>",
Description: `creates a new cluster admin or superuser. The privilege field must be either cluster_admin or cluster_su.`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "username",
Expand Down Expand Up @@ -63,28 +158,6 @@ Used when setting up a private VLAN for a customer.`,
return nil
}),
},
{
Name: "ip range",
Usage: "create a new IP range in a VLAN",
UsageText: "bytemark --admin create ip range <ip-range> <vlan-num>",
Flags: []cli.Flag{
cli.StringFlag{
Name: "ip-range",
Usage: "the IP range to add",
},
cli.IntFlag{
Name: "vlan-num",
Usage: "The VLAN number to add the IP range to",
},
},
Action: app.Action(args.Optional("ip-range", "vlan-num"), with.RequiredFlags("ip-range", "vlan-num"), with.Auth, func(c *app.Context) error {
if err := c.Client().CreateIPRange(c.String("ip-range"), c.Int("vlan-num")); err != nil {
return err
}
log.Logf("IP range created\r\n")
return nil
}),
},
},
})
}
12 changes: 12 additions & 0 deletions cmd/bytemark/commands/admin/util_funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package admin

import "encoding/json"

func stringsToJsonNumbers(in []string) (out []json.Number) {
out = make([]json.Number, len(in))
for i, str := range in {
out[i] = json.Number(str)
}

return out
}
16 changes: 16 additions & 0 deletions cmd/bytemark/commands/admin/util_funcs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package admin

import "testing"

func TestStringsToJsonNumbers(t *testing.T) {
in := []string{"hello", "world", "8092"}
out := stringsToJsonNumbers(in)
if len(out) != 3 {
t.Fatalf("len(out) = %d, expected 3", len(out))
}
for i := range in {
if string(out[i]) != in[i] {
t.Fatalf("out[%d] = %q, expected %q", i, out[i], in[i])
}
}
}

0 comments on commit f9437ef

Please sign in to comment.