-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
platform: implement the kola elements for Scaleway
Signed-off-by: Mathieu Tortuyaux <[email protected]>
- Loading branch information
Showing
5 changed files
with
277 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright The Mantle Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package scaleway | ||
|
||
import ( | ||
"context" | ||
"crypto/rand" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/flatcar/mantle/platform" | ||
"github.com/flatcar/mantle/platform/conf" | ||
) | ||
|
||
type cluster struct { | ||
*platform.BaseCluster | ||
flight *flight | ||
} | ||
|
||
func (bc *cluster) NewMachine(userdata *conf.UserData) (platform.Machine, error) { | ||
conf, err := bc.RenderUserData(userdata, map[string]string{ | ||
"$public_ipv4": "${COREOS_CUSTOM_PUBLIC_IPV4}", | ||
"$private_ipv4": "${COREOS_CUSTOM_PRIVATE_IPV4}", | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Hack to workaround CT inheritance. | ||
// Can be dropped once we remove CT dependency. | ||
// https://github.com/flatcar/Flatcar/issues/1386 | ||
conf.AddSystemdUnitDropin("coreos-metadata.service", "00-custom-metadata.conf", `[Service] | ||
ExecStartPost=/usr/bin/sed -i "s/SCALEWAY/CUSTOM/" /run/metadata/flatcar | ||
ExecStartPost=/usr/bin/sed -i "s/IPV4_PRIVATE/PRIVATE_IPV4/" /run/metadata/flatcar | ||
ExecStartPost=/usr/bin/sed -i "s/IPV4_PUBLIC/PUBLIC_IPV4/" /run/metadata/flatcar | ||
`) | ||
|
||
instance, err := bc.flight.api.CreateServer(context.TODO(), bc.vmname(), conf.String()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
mach := &machine{ | ||
cluster: bc, | ||
mach: instance, | ||
} | ||
|
||
mach.dir = filepath.Join(bc.RuntimeConf().OutputDir, mach.ID()) | ||
if err := os.Mkdir(mach.dir, 0777); err != nil { | ||
mach.Destroy() | ||
return nil, err | ||
} | ||
|
||
confPath := filepath.Join(mach.dir, "ignition.json") | ||
if err := conf.WriteFile(confPath); err != nil { | ||
mach.Destroy() | ||
return nil, err | ||
} | ||
|
||
if mach.journal, err = platform.NewJournal(mach.dir); err != nil { | ||
mach.Destroy() | ||
return nil, err | ||
} | ||
|
||
if err := platform.StartMachine(mach, mach.journal); err != nil { | ||
mach.Destroy() | ||
return nil, err | ||
} | ||
|
||
bc.AddMach(mach) | ||
|
||
return mach, nil | ||
} | ||
|
||
func (bc *cluster) vmname() string { | ||
b := make([]byte, 5) | ||
rand.Read(b) | ||
return fmt.Sprintf("%s-%x", bc.Name()[0:13], b) | ||
} | ||
|
||
func (bc *cluster) Destroy() { | ||
bc.BaseCluster.Destroy() | ||
bc.flight.DelCluster(bc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright The Mantle Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package scaleway | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/coreos/pkg/capnslog" | ||
ctplatform "github.com/flatcar/container-linux-config-transpiler/config/platform" | ||
|
||
"github.com/flatcar/mantle/platform" | ||
"github.com/flatcar/mantle/platform/api/scaleway" | ||
) | ||
|
||
const ( | ||
Platform platform.Name = "scaleway" | ||
) | ||
|
||
var ( | ||
plog = capnslog.NewPackageLogger("github.com/flatcar/mantle", "platform/machine/scaleway") | ||
) | ||
|
||
type flight struct { | ||
*platform.BaseFlight | ||
api *scaleway.API | ||
} | ||
|
||
func NewFlight(opts *scaleway.Options) (platform.Flight, error) { | ||
api, err := scaleway.New(opts) | ||
if err != nil { | ||
return nil, fmt.Errorf("creating scaleway API client: %w", err) | ||
} | ||
|
||
// TODO: Rework the Base Flight to remove the CT dependency. | ||
base, err := platform.NewBaseFlight(opts.Options, Platform, ctplatform.Custom) | ||
if err != nil { | ||
return nil, fmt.Errorf("creating base flight: %w", err) | ||
} | ||
|
||
bf := &flight{ | ||
BaseFlight: base, | ||
api: api, | ||
} | ||
|
||
return bf, nil | ||
} | ||
|
||
// NewCluster creates an instance of a Cluster suitable for spawning | ||
// instances on the Scaleway platform. | ||
func (bf *flight) NewCluster(rconf *platform.RuntimeConfig) (platform.Cluster, error) { | ||
bc, err := platform.NewBaseCluster(bf.BaseFlight, rconf) | ||
if err != nil { | ||
return nil, fmt.Errorf("creating scaleway base cluster: %w", err) | ||
} | ||
|
||
c := &cluster{ | ||
BaseCluster: bc, | ||
flight: bf, | ||
} | ||
|
||
bf.AddCluster(c) | ||
|
||
return c, nil | ||
} | ||
|
||
func (bf *flight) Destroy() { | ||
bf.BaseFlight.Destroy() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Copyright The Mantle Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package scaleway | ||
|
||
import ( | ||
"context" | ||
|
||
"golang.org/x/crypto/ssh" | ||
|
||
"github.com/flatcar/mantle/platform" | ||
"github.com/flatcar/mantle/platform/api/scaleway" | ||
) | ||
|
||
type machine struct { | ||
cluster *cluster | ||
mach *scaleway.Server | ||
dir string | ||
journal *platform.Journal | ||
console string | ||
} | ||
|
||
// ID returns the ID of the machine. | ||
func (bm *machine) ID() string { | ||
return bm.mach.Server.ID | ||
} | ||
|
||
// IP returns the IP of the machine. | ||
func (bm *machine) IP() string { | ||
if bm.mach.Server.PublicIP != nil { | ||
return bm.mach.Server.PublicIP.Address.String() | ||
} | ||
|
||
return "" | ||
} | ||
|
||
// IP returns the private IP of the machine. | ||
func (bm *machine) PrivateIP() string { | ||
if bm.mach.Server.PrivateIP != nil { | ||
return *bm.mach.Server.PrivateIP | ||
} | ||
|
||
return "" | ||
} | ||
|
||
// RuntimeConf returns the runtime configuration of the cluster. | ||
func (bm *machine) RuntimeConf() *platform.RuntimeConfig { | ||
return bm.cluster.RuntimeConf() | ||
} | ||
|
||
func (bm *machine) SSHClient() (*ssh.Client, error) { | ||
return bm.cluster.SSHClient(bm.IP()) | ||
} | ||
|
||
func (bm *machine) PasswordSSHClient(user string, password string) (*ssh.Client, error) { | ||
return bm.cluster.PasswordSSHClient(bm.IP(), user, password) | ||
} | ||
|
||
func (bm *machine) SSH(cmd string) ([]byte, []byte, error) { | ||
return bm.cluster.SSH(bm, cmd) | ||
} | ||
|
||
func (bm *machine) Reboot() error { | ||
return platform.RebootMachine(bm, bm.journal) | ||
} | ||
|
||
func (bm *machine) Destroy() { | ||
if err := bm.saveConsole(); err != nil { | ||
plog.Errorf("Error saving console for instance %v: %v", bm.ID(), err) | ||
} | ||
|
||
if err := bm.cluster.flight.api.DeleteServer(context.TODO(), bm.ID()); err != nil { | ||
plog.Errorf("deleting server %v: %v", bm.ID(), err) | ||
} | ||
|
||
if bm.journal != nil { | ||
bm.journal.Destroy() | ||
} | ||
|
||
bm.cluster.DelMach(bm) | ||
} | ||
|
||
func (bm *machine) ConsoleOutput() string { | ||
return bm.console | ||
} | ||
|
||
func (bm *machine) saveConsole() error { | ||
return nil | ||
} | ||
|
||
func (bm *machine) JournalOutput() string { | ||
if bm.journal == nil { | ||
return "" | ||
} | ||
|
||
data, err := bm.journal.Read() | ||
if err != nil { | ||
plog.Errorf("Reading journal for instance %v: %v", bm.ID(), err) | ||
} | ||
return string(data) | ||
} | ||
|
||
func (bm *machine) Board() string { | ||
return bm.cluster.flight.Options().Board | ||
} |