~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/provider/common/destroy.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package common
 
5
 
 
6
import (
 
7
        "strings"
 
8
 
 
9
        "github.com/juju/errors"
 
10
 
 
11
        "github.com/juju/juju/environs"
 
12
        "github.com/juju/juju/instance"
 
13
        "github.com/juju/juju/storage"
 
14
)
 
15
 
 
16
// Destroy is a common implementation of the Destroy method defined on
 
17
// environs.Environ; we strongly recommend that this implementation be
 
18
// used when writing a new provider.
 
19
func Destroy(env environs.Environ) error {
 
20
        logger.Infof("destroying model %q", env.Config().Name())
 
21
        if err := destroyInstances(env); err != nil {
 
22
                return errors.Annotate(err, "destroying instances")
 
23
        }
 
24
        if err := destroyStorage(env); err != nil {
 
25
                return errors.Annotate(err, "destroying storage")
 
26
        }
 
27
        return nil
 
28
}
 
29
 
 
30
func destroyInstances(env environs.Environ) error {
 
31
        logger.Infof("destroying instances")
 
32
        instances, err := env.AllInstances()
 
33
        switch err {
 
34
        case nil:
 
35
                ids := make([]instance.Id, len(instances))
 
36
                for i, inst := range instances {
 
37
                        ids[i] = inst.Id()
 
38
                }
 
39
                if err := env.StopInstances(ids...); err != nil {
 
40
                        return err
 
41
                }
 
42
                fallthrough
 
43
        case environs.ErrNoInstances:
 
44
                return nil
 
45
        default:
 
46
                return err
 
47
        }
 
48
}
 
49
 
 
50
func destroyStorage(env environs.Environ) error {
 
51
        logger.Infof("destroying storage")
 
52
        for _, storageProviderType := range env.StorageProviderTypes() {
 
53
                storageProvider, err := env.StorageProvider(storageProviderType)
 
54
                if err != nil {
 
55
                        return errors.Trace(err)
 
56
                }
 
57
                if !storageProvider.Dynamic() {
 
58
                        continue
 
59
                }
 
60
                if storageProvider.Scope() != storage.ScopeEnviron {
 
61
                        continue
 
62
                }
 
63
                if err := destroyVolumes(storageProviderType, storageProvider); err != nil {
 
64
                        return errors.Trace(err)
 
65
                }
 
66
                // TODO(axw) destroy env-level filesystems when we have them.
 
67
        }
 
68
        return nil
 
69
}
 
70
 
 
71
func destroyVolumes(
 
72
        storageProviderType storage.ProviderType,
 
73
        storageProvider storage.Provider,
 
74
) error {
 
75
        if !storageProvider.Supports(storage.StorageKindBlock) {
 
76
                return nil
 
77
        }
 
78
 
 
79
        storageConfig, err := storage.NewConfig(
 
80
                string(storageProviderType),
 
81
                storageProviderType,
 
82
                map[string]interface{}{},
 
83
        )
 
84
        if err != nil {
 
85
                return errors.Trace(err)
 
86
        }
 
87
 
 
88
        volumeSource, err := storageProvider.VolumeSource(storageConfig)
 
89
        if err != nil {
 
90
                return errors.Annotate(err, "getting volume source")
 
91
        }
 
92
 
 
93
        volumeIds, err := volumeSource.ListVolumes()
 
94
        if err != nil {
 
95
                return errors.Annotate(err, "listing volumes")
 
96
        }
 
97
 
 
98
        var errStrings []string
 
99
        errs, err := volumeSource.DestroyVolumes(volumeIds)
 
100
        if err != nil {
 
101
                return errors.Annotate(err, "destroying volumes")
 
102
        }
 
103
        for _, err := range errs {
 
104
                if err != nil {
 
105
                        errStrings = append(errStrings, err.Error())
 
106
                }
 
107
        }
 
108
        if len(errStrings) > 0 {
 
109
                return errors.Errorf("destroying volumes: %s", strings.Join(errStrings, ", "))
 
110
        }
 
111
        return nil
 
112
}