Skip to content
This repository was archived by the owner on May 7, 2021. It is now read-only.

Commit 55db340

Browse files
authored
Merge pull request #919 from arithx/openstack
platform: add OpenStack
2 parents b09fef5 + aa59d59 commit 55db340

106 files changed

Lines changed: 11691 additions & 147 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Ideally, all software needed for a test should be included by building
5656
it into the image from the SDK.
5757

5858
Kola supports running tests on multiple platforms, currently QEMU, GCE,
59-
AWS, VMware VSphere, and Packet. In the future systemd-nspawn and other
59+
AWS, VMware VSphere, Packet, and OpenStack. In the future systemd-nspawn and other
6060
platforms may be added.
6161
Local platforms do not rely on access to the Internet as a design
6262
principle of kola, minimizing external dependencies. Any network
@@ -261,6 +261,25 @@ you can paste in. This will populate the `.boto` file.
261261
See [Google Cloud Platform's Documentation](https://cloud.google.com/storage/docs/boto-gsutil)
262262
for more information about the `.boto` file.
263263

264+
### openstack
265+
`openstack` uses `~/.config/openstack.json`. This can be configured manually:
266+
```
267+
{
268+
"default": {
269+
"auth_url": "auth url here",
270+
"tenant_id": "tenant id here",
271+
"tenant_name": "tenant name here",
272+
"username": "username here",
273+
"password": "password here",
274+
"user_domain": "domain id here",
275+
"floating_ip_pool": "floating ip pool here",
276+
"region_name": "region here"
277+
}
278+
}
279+
```
280+
281+
`user_domain` is required on some newer versions of OpenStack using Keystone V3 but is optional on older versions. `floating_ip_pool` and `region_name` can be optionally specified here to be used as a default if not specified on the command line.
282+
264283
### packet
265284
`packet` uses `~/.config/packet.json`. This can be configured manually:
266285
```

auth/openstack.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2018 Red Hat
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package auth
16+
17+
import (
18+
"encoding/json"
19+
"fmt"
20+
"os"
21+
"os/user"
22+
"path/filepath"
23+
)
24+
25+
const OpenStackConfigPath = ".config/openstack.json"
26+
27+
type OpenStackProfile struct {
28+
AuthURL string `json:"auth_url"`
29+
TenantID string `json:"tenant_id"`
30+
TenantName string `json:"tenant_name"`
31+
Username string `json:"username"`
32+
Password string `json:"password"`
33+
34+
//Optional
35+
Domain string `json:"user_domain"`
36+
FloatingIPPool string `json:"floating_ip_pool"`
37+
Region string `json:"region_name"`
38+
}
39+
40+
// ReadOpenStackConfig decodes an OpenStack config file,
41+
// which is a custom format used by Mantle to hold OpenStack
42+
// server information.
43+
//
44+
// If path is empty, $HOME/.config/openstack.json is read.
45+
func ReadOpenStackConfig(path string) (map[string]OpenStackProfile, error) {
46+
if path == "" {
47+
user, err := user.Current()
48+
if err != nil {
49+
return nil, err
50+
}
51+
path = filepath.Join(user.HomeDir, OpenStackConfigPath)
52+
}
53+
54+
f, err := os.Open(path)
55+
if err != nil {
56+
return nil, err
57+
}
58+
defer f.Close()
59+
60+
var profiles map[string]OpenStackProfile
61+
if err := json.NewDecoder(f).Decode(&profiles); err != nil {
62+
return nil, err
63+
}
64+
if len(profiles) == 0 {
65+
return nil, fmt.Errorf("OpenStack config %q contains no profiles", path)
66+
}
67+
68+
return profiles, nil
69+
}

cmd/kola/kola.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ func writeProps() error {
148148
Image string `json:"image"`
149149
MachineType string `json:"type"`
150150
}
151+
type OpenStack struct {
152+
Region string `json:"region"`
153+
Image string `json:"image"`
154+
Flavor string `json:"flavor"`
155+
}
151156
type Packet struct {
152157
Facility string `json:"facility"`
153158
Plan string `json:"plan"`
@@ -159,16 +164,17 @@ func writeProps() error {
159164
Mangled bool `json:"mangled"`
160165
}
161166
return enc.Encode(&struct {
162-
Cmdline []string `json:"cmdline"`
163-
Platform string `json:"platform"`
164-
Distro string `json:"distro"`
165-
Board string `json:"board"`
166-
AWS AWS `json:"aws"`
167-
DO DO `json:"do"`
168-
ESX ESX `json:"esx"`
169-
GCE GCE `json:"gce"`
170-
Packet Packet `json:"packet"`
171-
QEMU QEMU `json:"qemu"`
167+
Cmdline []string `json:"cmdline"`
168+
Platform string `json:"platform"`
169+
Distro string `json:"distro"`
170+
Board string `json:"board"`
171+
AWS AWS `json:"aws"`
172+
DO DO `json:"do"`
173+
ESX ESX `json:"esx"`
174+
GCE GCE `json:"gce"`
175+
OpenStack OpenStack `json:"openstack"`
176+
Packet Packet `json:"packet"`
177+
QEMU QEMU `json:"qemu"`
172178
}{
173179
Cmdline: os.Args,
174180
Platform: kolaPlatform,
@@ -192,6 +198,11 @@ func writeProps() error {
192198
Image: kola.GCEOptions.Image,
193199
MachineType: kola.GCEOptions.MachineType,
194200
},
201+
OpenStack: OpenStack{
202+
Region: kola.OpenStackOptions.Region,
203+
Image: kola.OpenStackOptions.Image,
204+
Flavor: kola.OpenStackOptions.Flavor,
205+
},
195206
Packet: Packet{
196207
Facility: kola.PacketOptions.Facility,
197208
Plan: kola.PacketOptions.Plan,

cmd/kola/options.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var (
2929
outputDir string
3030
kolaPlatform string
3131
defaultTargetBoard = sdk.DefaultBoard()
32-
kolaPlatforms = []string{"aws", "do", "esx", "gce", "packet", "qemu"}
32+
kolaPlatforms = []string{"aws", "do", "esx", "gce", "openstack", "packet", "qemu"}
3333
kolaDistros = []string{"cl", "fcos", "rhcos"}
3434
kolaDefaultImages = map[string]string{
3535
"amd64-usr": sdk.BuildRoot() + "/images/amd64-usr/latest/coreos_production_image.bin",
@@ -95,6 +95,16 @@ func init() {
9595
bv(&kola.GCEOptions.ServiceAuth, "gce-service-auth", false, "for non-interactive auth when running within GCE")
9696
sv(&kola.GCEOptions.JSONKeyFile, "gce-json-key", "", "use a service account's JSON key for authentication")
9797

98+
// openstack-specific options
99+
sv(&kola.OpenStackOptions.ConfigPath, "openstack-config-file", "", "OpenStack config file (default \"~/"+auth.OpenStackConfigPath+"\")")
100+
sv(&kola.OpenStackOptions.Profile, "openstack-profile", "", "OpenStack profile (default \"default\")")
101+
sv(&kola.OpenStackOptions.Region, "openstack-region", "", "OpenStack region")
102+
sv(&kola.OpenStackOptions.Image, "openstack-image", "", "OpenStack image ref")
103+
sv(&kola.OpenStackOptions.Flavor, "openstack-flavor", "1", "OpenStack flavor ref")
104+
sv(&kola.OpenStackOptions.Network, "openstack-network", "", "OpenStack network")
105+
sv(&kola.OpenStackOptions.Domain, "openstack-domain", "", "OpenStack domain ID")
106+
sv(&kola.OpenStackOptions.FloatingIPPool, "openstack-floating-ip-pool", "", "OpenStack floating IP pool for Compute v2 networking")
107+
98108
// packet-specific options
99109
sv(&kola.PacketOptions.ConfigPath, "packet-config-file", "", "Packet config file (default \"~/"+auth.PacketConfigPath+"\")")
100110
sv(&kola.PacketOptions.Profile, "packet-profile", "", "Packet profile (default \"default\")")

cmd/ore/openstack.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2018 Red Hat
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"github.com/coreos/mantle/cmd/ore/openstack"
19+
)
20+
21+
func init() {
22+
root.AddCommand(openstack.OpenStack)
23+
}

cmd/ore/openstack/create.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2018 Red Hat
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package openstack
16+
17+
import (
18+
"fmt"
19+
"os"
20+
21+
"github.com/coreos/mantle/sdk"
22+
"github.com/spf13/cobra"
23+
)
24+
25+
var (
26+
cmdCreate = &cobra.Command{
27+
Use: "create-image",
28+
Short: "Create image on OpenStack",
29+
Long: `Upload an image to OpenStack.
30+
31+
After a successful run, the final line of output will be the ID of the image.
32+
`,
33+
RunE: runCreate,
34+
}
35+
36+
path string
37+
name string
38+
)
39+
40+
func init() {
41+
OpenStack.AddCommand(cmdCreate)
42+
cmdCreate.Flags().StringVar(&path, "file",
43+
sdk.BuildRoot()+"/images/amd64-usr/latest/coreos_production_openstack_image.img",
44+
"path to CoreOS image (build with: ./image_to_vm.sh --format=openstack ...)")
45+
cmdCreate.Flags().StringVar(&name, "name", "", "image name")
46+
}
47+
48+
func runCreate(cmd *cobra.Command, args []string) error {
49+
id, err := API.UploadImage(name, path)
50+
if err != nil {
51+
fmt.Fprintf(os.Stderr, "Couldn't create image: %v\n", err)
52+
os.Exit(1)
53+
}
54+
fmt.Println(id)
55+
return nil
56+
}

cmd/ore/openstack/delete.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2018 Red Hat
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package openstack
16+
17+
import (
18+
"fmt"
19+
"os"
20+
21+
"github.com/spf13/cobra"
22+
)
23+
24+
var (
25+
cmdDelete = &cobra.Command{
26+
Use: "delete-image",
27+
Short: "Delete image on OpenStack",
28+
Long: `Delete an image from OpenStack.`,
29+
RunE: runDelete,
30+
}
31+
32+
id string
33+
)
34+
35+
func init() {
36+
OpenStack.AddCommand(cmdDelete)
37+
cmdDelete.Flags().StringVar(&id, "id", "", "image ID")
38+
}
39+
40+
func runDelete(cmd *cobra.Command, args []string) error {
41+
img, err := API.ResolveImage(id)
42+
if err != nil {
43+
fmt.Fprintf(os.Stderr, "Couldn't find image: %v\n", err)
44+
os.Exit(1)
45+
}
46+
err = API.DeleteImage(img)
47+
if err != nil {
48+
fmt.Fprintf(os.Stderr, "Couldn't delete image: %v\n", err)
49+
os.Exit(1)
50+
}
51+
return nil
52+
}

cmd/ore/openstack/gc.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2018 Red Hat
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package openstack
16+
17+
import (
18+
"fmt"
19+
"os"
20+
"time"
21+
22+
"github.com/spf13/cobra"
23+
)
24+
25+
var (
26+
cmdGC = &cobra.Command{
27+
Use: "gc",
28+
Short: "GC resources in OpenStack",
29+
Long: `Delete instances created over the given duration ago`,
30+
RunE: runGC,
31+
}
32+
33+
gcDuration time.Duration
34+
)
35+
36+
func init() {
37+
OpenStack.AddCommand(cmdGC)
38+
cmdGC.Flags().DurationVar(&gcDuration, "duration", 5*time.Hour, "how old resources must be before they're considered garbage")
39+
}
40+
41+
func runGC(cmd *cobra.Command, args []string) error {
42+
err := API.GC(gcDuration)
43+
if err != nil {
44+
fmt.Fprintf(os.Stderr, "Couldn't gc: %v\n", err)
45+
os.Exit(1)
46+
}
47+
return nil
48+
}

0 commit comments

Comments
 (0)