Merge pull request #3365 from josephholsten/f-add-parallelism-to-ui
add parallelism to ui
This commit is contained in:
commit
18125d84d2
|
@ -39,6 +39,7 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
cmdFlags.BoolVar(&destroyForce, "force", false, "force")
|
cmdFlags.BoolVar(&destroyForce, "force", false, "force")
|
||||||
}
|
}
|
||||||
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
||||||
|
cmdFlags.IntVar(&c.Meta.parallelism, "parallelism", 0, "parallelism")
|
||||||
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
||||||
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
||||||
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
||||||
|
@ -94,9 +95,10 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Build the context based on the arguments given
|
// Build the context based on the arguments given
|
||||||
ctx, planned, err := c.Context(contextOpts{
|
ctx, planned, err := c.Context(contextOpts{
|
||||||
Destroy: c.Destroy,
|
Destroy: c.Destroy,
|
||||||
Path: configPath,
|
Path: configPath,
|
||||||
StatePath: c.Meta.statePath,
|
StatePath: c.Meta.statePath,
|
||||||
|
Parallelism: c.Meta.parallelism,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
|
@ -278,6 +280,8 @@ Options:
|
||||||
|
|
||||||
-no-color If specified, output won't contain any color.
|
-no-color If specified, output won't contain any color.
|
||||||
|
|
||||||
|
-parallelism=# Limit the number of concurrent operations.
|
||||||
|
|
||||||
-refresh=true Update state prior to checking for differences. This
|
-refresh=true Update state prior to checking for differences. This
|
||||||
has no effect if a plan file is given to apply.
|
has no effect if a plan file is given to apply.
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,82 @@ func TestApply(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApply_parallelism1(t *testing.T) {
|
||||||
|
statePath := testTempFile(t)
|
||||||
|
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
p := testProvider()
|
||||||
|
pr := new(terraform.MockResourceProvisioner)
|
||||||
|
|
||||||
|
pr.ApplyFn = func(*terraform.InstanceState, *terraform.ResourceConfig) error {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{
|
||||||
|
"-state", statePath,
|
||||||
|
"-parallelism=1",
|
||||||
|
testFixturePath("parallelism"),
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &ApplyCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
ContextOpts: testCtxConfigWithShell(p, pr),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
if code := c.Run(args); code != 0 {
|
||||||
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
elapsed := time.Since(start).Seconds()
|
||||||
|
|
||||||
|
// This test should take exactly two seconds, plus some minor amount of execution time.
|
||||||
|
if elapsed < 2 || elapsed > 2.2 {
|
||||||
|
t.Fatalf("bad: %f\n\n%s", elapsed, ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApply_parallelism2(t *testing.T) {
|
||||||
|
statePath := testTempFile(t)
|
||||||
|
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
p := testProvider()
|
||||||
|
pr := new(terraform.MockResourceProvisioner)
|
||||||
|
|
||||||
|
pr.ApplyFn = func(*terraform.InstanceState, *terraform.ResourceConfig) error {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{
|
||||||
|
"-state", statePath,
|
||||||
|
"-parallelism=2",
|
||||||
|
testFixturePath("parallelism"),
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &ApplyCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
ContextOpts: testCtxConfigWithShell(p, pr),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
if code := c.Run(args); code != 0 {
|
||||||
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
elapsed := time.Since(start).Seconds()
|
||||||
|
|
||||||
|
// This test should take exactly one second, plus some minor amount of execution time.
|
||||||
|
if elapsed < 1 || elapsed > 1.2 {
|
||||||
|
t.Fatalf("bad: %f\n\n%s", elapsed, ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestApply_configInvalid(t *testing.T) {
|
func TestApply_configInvalid(t *testing.T) {
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
|
|
@ -52,6 +52,21 @@ func testCtxConfig(p terraform.ResourceProvider) *terraform.ContextOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testCtxConfigWithShell(p terraform.ResourceProvider, pr terraform.ResourceProvisioner) *terraform.ContextOpts {
|
||||||
|
return &terraform.ContextOpts{
|
||||||
|
Providers: map[string]terraform.ResourceProviderFactory{
|
||||||
|
"test": func() (terraform.ResourceProvider, error) {
|
||||||
|
return p, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Provisioners: map[string]terraform.ResourceProvisionerFactory{
|
||||||
|
"shell": func() (terraform.ResourceProvisioner, error) {
|
||||||
|
return pr, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testModule(t *testing.T, name string) *module.Tree {
|
func testModule(t *testing.T, name string) *module.Tree {
|
||||||
mod, err := module.NewTreeModule("", filepath.Join(fixtureDir, name))
|
mod, err := module.NewTreeModule("", filepath.Join(fixtureDir, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -59,9 +59,13 @@ type Meta struct {
|
||||||
//
|
//
|
||||||
// backupPath is used to backup the state file before writing a modified
|
// backupPath is used to backup the state file before writing a modified
|
||||||
// version. It defaults to stateOutPath + DefaultBackupExtension
|
// version. It defaults to stateOutPath + DefaultBackupExtension
|
||||||
|
//
|
||||||
|
// parallelism is used to control the number of concurrent operations
|
||||||
|
// allowed when walking the graph
|
||||||
statePath string
|
statePath string
|
||||||
stateOutPath string
|
stateOutPath string
|
||||||
backupPath string
|
backupPath string
|
||||||
|
parallelism int
|
||||||
}
|
}
|
||||||
|
|
||||||
// initStatePaths is used to initialize the default values for
|
// initStatePaths is used to initialize the default values for
|
||||||
|
@ -151,6 +155,7 @@ func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Module = mod
|
opts.Module = mod
|
||||||
|
opts.Parallelism = copts.Parallelism
|
||||||
opts.State = state.State()
|
opts.State = state.State()
|
||||||
ctx := terraform.NewContext(opts)
|
ctx := terraform.NewContext(opts)
|
||||||
return ctx, false, nil
|
return ctx, false, nil
|
||||||
|
@ -430,4 +435,7 @@ type contextOpts struct {
|
||||||
|
|
||||||
// Set to true when running a destroy plan/apply.
|
// Set to true when running a destroy plan/apply.
|
||||||
Destroy bool
|
Destroy bool
|
||||||
|
|
||||||
|
// Number of concurrent operations allowed
|
||||||
|
Parallelism int
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
||||||
c.addModuleDepthFlag(cmdFlags, &moduleDepth)
|
c.addModuleDepthFlag(cmdFlags, &moduleDepth)
|
||||||
cmdFlags.StringVar(&outPath, "out", "", "path")
|
cmdFlags.StringVar(&outPath, "out", "", "path")
|
||||||
|
cmdFlags.IntVar(&c.Meta.parallelism, "parallelism", 0, "parallelism")
|
||||||
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
||||||
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
||||||
cmdFlags.BoolVar(&detailed, "detailed-exitcode", false, "detailed-exitcode")
|
cmdFlags.BoolVar(&detailed, "detailed-exitcode", false, "detailed-exitcode")
|
||||||
|
@ -57,9 +58,10 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
c.Meta.extraHooks = []terraform.Hook{countHook}
|
c.Meta.extraHooks = []terraform.Hook{countHook}
|
||||||
|
|
||||||
ctx, _, err := c.Context(contextOpts{
|
ctx, _, err := c.Context(contextOpts{
|
||||||
Destroy: destroy,
|
Destroy: destroy,
|
||||||
Path: path,
|
Path: path,
|
||||||
StatePath: c.Meta.statePath,
|
StatePath: c.Meta.statePath,
|
||||||
|
Parallelism: c.Meta.parallelism,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
|
|
|
@ -18,6 +18,7 @@ func (c *RefreshCommand) Run(args []string) int {
|
||||||
|
|
||||||
cmdFlags := c.Meta.flagSet("refresh")
|
cmdFlags := c.Meta.flagSet("refresh")
|
||||||
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
|
||||||
|
cmdFlags.IntVar(&c.Meta.parallelism, "parallelism", 0, "parallelism")
|
||||||
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
||||||
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
||||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||||
|
@ -78,8 +79,9 @@ func (c *RefreshCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Build the context based on the arguments given
|
// Build the context based on the arguments given
|
||||||
ctx, _, err := c.Context(contextOpts{
|
ctx, _, err := c.Context(contextOpts{
|
||||||
Path: configPath,
|
Path: configPath,
|
||||||
StatePath: c.Meta.statePath,
|
StatePath: c.Meta.statePath,
|
||||||
|
Parallelism: c.Meta.parallelism,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
resource "test_instance" "foo1" {
|
||||||
|
ami = "bar"
|
||||||
|
|
||||||
|
// shell has been configured to sleep for one second
|
||||||
|
provisioner "shell" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "foo2" {
|
||||||
|
ami = "bar"
|
||||||
|
|
||||||
|
// shell has been configured to sleep for one second
|
||||||
|
provisioner "shell" {}
|
||||||
|
}
|
Loading…
Reference in New Issue