switch Packet references to Equinix Metal

Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
Avi Deitcher 2024-07-05 17:17:17 +03:00
parent 3f80ca694f
commit 8f6ea3c85e
24 changed files with 148 additions and 228 deletions

View File

@ -87,7 +87,7 @@ Currently supported platforms are:
- [OpenStack](docs/platform-openstack.md) `[x86_64]`
- [Scaleway](docs/platform-scaleway.md) `[x86_64]`
- Baremetal:
- [packet.net](docs/platform-packet.md) `[x86_64, arm64]`
- [deploy.equinix.com](docs/platform-equinixmetal.md) `[x86_64, arm64]`
- [Raspberry Pi Model 3b](docs/platform-rpi3.md) `[arm64]`

View File

@ -1,26 +1,17 @@
# LinuxKit with bare metal on Packet
# LinuxKit with bare metal on Equinix Metal
[Packet](http://packet.net) is a bare metal hosting provider.
[Equinix Metal](http://deploy.equinix.com) is a bare metal hosting provider.
You will need to [create a Packet account] and a project to
You will need to [create an Equinix Metal account] and a project to
put this new machine into. You will also need to [create an API key]
with appropriate read/write permissions to allow the image to boot.
[create a Packet account]:https://app.packet.net/#/registration/
[create an API key]:https://help.packet.net/quick-start/api-integrations
[create an Equinix Metal account]:https://console.equinix.com/sign-up
[create an API key]:https://deploy.equinix.com/developers/docs/metal/identity-access-management/api-keys/
Linuxkit is known to boot on the [Type 0]
and [Type 1] servers at Packet.
Support for other server types, including the [Type 2A] ARM server,
is a work in progress.
[Type 0]:https://www.packet.net/bare-metal/servers/type-0/
[Type 1]:https://www.packet.net/bare-metal/servers/type-1/
[Type 2A]:https://www.packet.net/bare-metal/servers/type-2a/
The `linuxkit run packet` command can mostly either be configured via
The `linuxkit run equinixmetal` command can mostly either be configured via
command line options or with environment variables. see `linuxkit run
packet --help` for the options and environment variables.
equinixmetal --help` for the options and environment variables.
By default, `linuxkit run` will provision a new machine and remove it
once you are done. With the `-keep` option the provisioned machine
@ -29,8 +20,8 @@ device ID on subsequent `linuxkit run` invocations to re-use an
existing machine. These subsequent runs will update the iPXE data so
you can boot alternative kernels on an existing machine.
There is an example YAML file for [x86_64](../examples/packet.yml) and
an additional YAML for [arm64](../examples/packet.arm64.yml) servers
There is an example YAML file for [x86_64](../examples/equinixmetal.yml) and
an additional YAML for [arm64](../examples/equinixmetal.arm64.yml) servers
which provide both access to the serial console and via ssh and
configures bonding for network devices via metadata (if supported).
@ -47,52 +38,52 @@ retry the boot typically fixes this.
## Boot
LinuxKit on Packet boots the `kernel+initrd` output from moby via
[iPXE](https://help.packet.net/technical/infrastructure/custom-ipxe)
LinuxKit on Equinix Metal boots the `kernel+initrd` output from moby via
[iPXE](https://deploy.equinix.com/developers/docs/metal/operating-systems/custom-ipxe/)
which also requires a iPXE script. iPXE booting requires a HTTP server
on which you can store your images. The `-base-url` option specifies
the URL to a HTTP server from which `<name>-kernel`,
`<name>-initrd.img`, and `<name>-packet.ipxe` can be downloaded during
`<name>-initrd.img`, and `<name>-equinixmetal.ipxe` can be downloaded during
boot.
If you have your own HTTP server, you can use `linuxkit push packet`
If you have your own HTTP server, you can use `linuxkit push equinixmetal`
to create the files (including the iPXE script) you need to make
available.
If you don't have a public HTTP server at hand, you can use the
`-serve` option. This will create a local HTTP server which can either
be run on another Packet machine or be made accessible with tools
be run on another Equinix Metal machine or be made accessible with tools
like [ngrok](https://ngrok.com/).
For example, to boot the [example](../examples/packet.net)
For example, to boot the [example](../examples/platform-equinixmetal.yml)
with a local HTTP server:
```sh
linuxkit build packet.yml
linuxkit build platform-equinixmetal.yml
# run the web server
# run 'ngrok http 8080' in another window
PACKET_API_KEY=<API key> PACKET_PROJECT_ID=<Project ID> \
linuxkit run packet -serve :8080 -base-url <ngrok url> packet
METAL_AUTH_TOKEN=<API key> METAL_PROJECT_ID=<Project ID> \
linuxkit run equinixmetal -serve :8080 -base-url <ngrok url> equinixmetal
```
To boot a `arm64` image for Type 2a machine (`-machine baremetal_2a`)
you currently need to build using `linuxkit build packet.yml
packet.arm64.yml` and then un-compress both the kernel and the initrd
you currently need to build using `linuxkit build equinixmetal.yml
equinixmetal.arm64.yml` and then un-compress both the kernel and the initrd
before booting, e.g:
```sh
mv packet-initrd.img packet-initrd.img.gz && gzip -d packet-initrd.img.gz
mv packet-kernel packet-kernel.gz && gzip -d packet-kernel.gz
mv equinixmetal-initrd.img equinixmetal-initrd.img.gz && gzip -d equinixmetal-initrd.img.gz
mv equinixmetal-kernel equinixmetal-kernel.gz && gzip -d equinixmetal-kernel.gz
```
The LinuxKit image can then be booted with:
```sh
PACKET_API_KEY=<API key> PACKET_PROJECT_ID=<Project ID> \
linuxkit run packet -machine baremetal_2a -serve :8080 -base-url -base-url <ngrok url> packet
METAL_API_TOKEN=<API key> METAL_PROJECT_ID=<Project ID> \
linuxkit run equinixmetal -machine baremetal_2a -serve :8080 -base-url -base-url <ngrok url> equinixmetal
```
Alternatively, `linuxkit push packet` will uncompress the kernel and
Alternatively, `linuxkit push equinixmetal` will uncompress the kernel and
initrd images on arm machines (or explicitly via the `-decompress`
flag. There is also a `linuxkit serve` command which will start a
local HTTP server serving the specified directory.
@ -104,18 +95,18 @@ messages.
## Console
By default, `linuxkit run packet ...` will connect to the
Packet
[SOS ("Serial over SSH") console](https://help.packet.net/technical/networking/sos-rescue-mode). This
By default, `linuxkit run equinixmetal ...` will connect to the
Equinix Metal
[SOS ("Serial over SSH") console](https://deploy.equinix.com/developers/docs/metal/resilience-recovery/serial-over-ssh/). This
requires `ssh` access, i.e., you must have uploaded your SSH keys to
Packet beforehand.
Equinix Metal beforehand.
You can exit the console vi `~.` on a new line once you are
disconnected from the serial, e.g. after poweroff.
**Note**: We also require that the Packet SOS host is in your
**Note**: We also require that the Equinix Metal SOS host is in your
`known_hosts` file, otherwise the connection to the console will
fail. There is a Packet SOS host per zone.
fail. There is a Equinix Metal SOS host per zone.
You can disable the serial console access with the `-console=false`
command line option.
@ -124,7 +115,7 @@ command line option.
## Disks
At this moment the Linuxkit server boots from RAM, with no persistent
storage. We are working on adding persistent storage support on Packet.
storage. We are working on adding persistent storage support on Equinix Metal.
## Networking
@ -139,13 +130,13 @@ On the baremetal type 2a system (arm64 Cavium Thunder X) the network device driv
to your YAML files before any containers requiring the network to be up, e.g., the `dhcpcd` container.
Some Packet server types have bonded networks; the `metadata` package has support for setting
Some Equinix Metal server types have bonded networks; the `metadata` package has support for setting
these up, and also for adding additional IP addresses.
## Integration services and Metadata
Packet supports [user state](https://help.packet.net/technical/infrastructure/user-state)
Equinix Metal supports [user state](https://deploy.equinix.com/developers/docs/metal/server-metadata/user-data/)
during system bringup, which enables the boot process to be more informative about the
current state of the boot process once the kernel has loaded but before the
system is ready for login.

View File

@ -1,5 +1,5 @@
# This YAML snippet is to be used in conjunction with packet.yml to
# build a arm64 image for packet.net. It adds a modprobe of the NIC
# This YAML snippet is to be used in conjunction with equinixmetal.yml to
# build a arm64 image for Equinix Metal. It adds a modprobe of the NIC
# driver and overrides the kernel section to disable prepending the
# Intel CPU microcode to the initrd. If writing a YAML specifically
# for arm64 then the 'ucode' line in the kernel section can be left

View File

@ -19,7 +19,7 @@ onboot:
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
- name: metadata
image: linuxkit/metadata:b082f1bf97a9034d1e4c0e36a5d2923f4e58f540
command: ["/usr/bin/metadata", "packet"]
command: ["/usr/bin/metadata", "equinixmetal"]
services:
- name: rngd
image: linuxkit/rngd:cdb919e4aee49fed0bf6075f0a104037cba83c39

View File

@ -1,12 +1,22 @@
module github.com/linuxkit/linuxkit/pkg/metadata
go 1.16
go 1.21
require (
github.com/diskfs/go-diskfs v1.3.1-0.20230612151643-22d22fd7e558
github.com/packethost/packngo v0.1.0
github.com/sirupsen/logrus v1.9.0
github.com/vishvananda/netlink v0.0.0-20170808154308-f5a6f697a596
github.com/vishvananda/netns v0.0.0-20170707011535-86bef332bfc3 // indirect
github.com/vmware/vmw-guestinfo v0.0.0-20220317130741-510905f0efa3
)
require (
github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pkg/xattr v0.4.9 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/vishvananda/netns v0.0.0-20170707011535-86bef332bfc3 // indirect
golang.org/x/sys v0.5.0 // indirect
gopkg.in/djherbis/times.v1 v1.3.0 // indirect
)

View File

@ -77,7 +77,7 @@ func main() {
log.SetLevel(log.DebugLevel)
}
providers := []string{"aws", "gcp", "hetzner", "openstack", "scaleway", "vultr", "digitalocean", "packet", "metaldata", "vmware", "cdrom"}
providers := []string{"aws", "gcp", "hetzner", "openstack", "scaleway", "vultr", "digitalocean", "equinixmetal", "metaldata", "vmware", "cdrom"}
args := flag.Args()
if len(args) > 0 {
providers = args
@ -92,8 +92,8 @@ func main() {
netProviders = append(netProviders, NewHetzner())
case p == "openstack":
netProviders = append(netProviders, NewOpenstack())
case p == "packet":
netProviders = append(netProviders, NewPacket())
case p == "equinixmetal":
netProviders = append(netProviders, NewEquinixMetal())
case p == "scaleway":
netProviders = append(netProviders, NewScaleway())
case p == "vultr":

View File

@ -12,30 +12,30 @@ import (
"github.com/vishvananda/netlink"
)
// ProviderPacket is the type implementing the Provider interface for Packet.net
type ProviderPacket struct {
// ProviderEquinixMetal is the type implementing the Provider interface for Equinix Metal
type ProviderEquinixMetal struct {
metadata *metadata.CurrentDevice
err error
}
// NewPacket returns a new ProviderPacket
func NewPacket() *ProviderPacket {
return &ProviderPacket{}
// NewEquinixMetal returns a new ProviderEquinixMetal
func NewEquinixMetal() *ProviderEquinixMetal {
return &ProviderEquinixMetal{}
}
func (p *ProviderPacket) String() string {
return "Packet"
func (p *ProviderEquinixMetal) String() string {
return "EquinixMetal"
}
// Probe checks if we are running on Packet
func (p *ProviderPacket) Probe() bool {
// Probe checks if we are running on EquinixMetal
func (p *ProviderEquinixMetal) Probe() bool {
// Unfortunately the host is resolveable globally, so no easy test
p.metadata, p.err = metadata.GetMetadata()
return p.err == nil
}
// Extract gets both the Packet specific and generic userdata
func (p *ProviderPacket) Extract() ([]byte, error) {
// Extract gets both the EquinixMetal specific and generic userdata
func (p *ProviderEquinixMetal) Extract() ([]byte, error) {
// do not retrieve if we Probed
if p.metadata == nil && p.err == nil {
p.metadata, p.err = metadata.GetMetadata()
@ -47,7 +47,7 @@ func (p *ProviderPacket) Extract() ([]byte, error) {
}
if err := os.WriteFile(path.Join(ConfigPath, Hostname), []byte(p.metadata.Hostname), 0644); err != nil {
return nil, fmt.Errorf("Packet: Failed to write hostname: %s", err)
return nil, fmt.Errorf("EquinixMetal: Failed to write hostname: %s", err)
}
if err := os.MkdirAll(path.Join(ConfigPath, SSH), 0755); err != nil {
@ -66,7 +66,7 @@ func (p *ProviderPacket) Extract() ([]byte, error) {
userData, err := metadata.GetUserData()
if err != nil {
return nil, fmt.Errorf("Packet: failed to get userdata: %s", err)
return nil, fmt.Errorf("EquinixMetal: failed to get userdata: %s", err)
}
if len(userData) == 0 {
@ -81,7 +81,7 @@ func (p *ProviderPacket) Extract() ([]byte, error) {
return userData, nil
}
// networkConfig handles Packet network configuration, primarily bonding
// networkConfig handles EquinixMetal network configuration, primarily bonding
func networkConfig(ni metadata.NetworkInfo) error {
// rename interfaces to match what the metadata calls them
links, err := netlink.LinkList()
@ -119,7 +119,7 @@ func networkConfig(ni metadata.NetworkInfo) error {
// set up bonding
la := netlink.LinkAttrs{Name: "bond0"}
bond := &netlink.GenericLink{la, "bond"}
bond := &netlink.GenericLink{LinkAttrs: la, LinkType: "bond"}
if err := netlink.LinkAdd(bond); err != nil {
// weirdly creating a bind always seems to return EEXIST
fmt.Fprintf(os.Stderr, "Error adding bond0: %v (ignoring)", err)

View File

@ -1,15 +0,0 @@
module github.com/diskfs/go-diskfs
go 1.19
require (
github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab
github.com/go-test/deep v1.0.8
github.com/google/uuid v1.3.0
github.com/pierrec/lz4/v4 v4.1.17
github.com/pkg/xattr v0.4.9
github.com/sirupsen/logrus v1.9.0
github.com/ulikunitz/xz v0.5.11
golang.org/x/sys v0.5.0
gopkg.in/djherbis/times.v1 v1.3.0
)

View File

@ -1,31 +0,0 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab h1:h1UgjJdAAhj+uPL68n7XASS6bU+07ZX1WJvVS2eyoeY=
github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab/go.mod h1:GLo/8fDswSAniFG+BFIaiSPcK610jyzgEhWYPQwuQdw=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE=
github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/djherbis/times.v1 v1.3.0 h1:uxMS4iMtH6Pwsxog094W0FYldiNnfY/xba00vq6C2+o=
gopkg.in/djherbis/times.v1 v1.3.0/go.mod h1:AQlg6unIsrsCEdQYhTzERy542dz6SFdQFZFv6mUY0P8=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,3 +0,0 @@
module github.com/elliotwutingfeng/asciiset
go 1.11

View File

@ -1 +0,0 @@
module github.com/google/uuid

View File

@ -1,3 +0,0 @@
module github.com/pierrec/lz4/v4
go 1.14

View File

@ -1,5 +0,0 @@
module github.com/pkg/xattr
go 1.14
require golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f

View File

@ -1,4 +0,0 @@
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -1,9 +0,0 @@
module github.com/sirupsen/logrus
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8
)
go 1.13

View File

@ -1,14 +0,0 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,3 +0,0 @@
module github.com/ulikunitz/xz
go 1.12

View File

@ -1,5 +1,5 @@
# github.com/diskfs/go-diskfs v1.3.1-0.20230612151643-22d22fd7e558
## explicit
## explicit; go 1.19
github.com/diskfs/go-diskfs
github.com/diskfs/go-diskfs/disk
github.com/diskfs/go-diskfs/filesystem
@ -12,24 +12,29 @@ github.com/diskfs/go-diskfs/partition/mbr
github.com/diskfs/go-diskfs/partition/part
github.com/diskfs/go-diskfs/util
# github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab
## explicit; go 1.11
github.com/elliotwutingfeng/asciiset
# github.com/google/uuid v1.3.0
## explicit
github.com/google/uuid
# github.com/packethost/packngo v0.1.0
## explicit
github.com/packethost/packngo/metadata
# github.com/pierrec/lz4/v4 v4.1.17
## explicit; go 1.14
github.com/pierrec/lz4/v4
github.com/pierrec/lz4/v4/internal/lz4block
github.com/pierrec/lz4/v4/internal/lz4errors
github.com/pierrec/lz4/v4/internal/lz4stream
github.com/pierrec/lz4/v4/internal/xxh32
# github.com/pkg/xattr v0.4.9
## explicit; go 1.14
github.com/pkg/xattr
# github.com/sirupsen/logrus v1.9.0
## explicit
## explicit; go 1.13
github.com/sirupsen/logrus
# github.com/ulikunitz/xz v0.5.11
## explicit; go 1.12
github.com/ulikunitz/xz
github.com/ulikunitz/xz/internal/hash
github.com/ulikunitz/xz/internal/xlog
@ -42,15 +47,17 @@ github.com/vishvananda/netlink/nl
## explicit
github.com/vishvananda/netns
# github.com/vmware/vmw-guestinfo v0.0.0-20220317130741-510905f0efa3
## explicit
## explicit; go 1.12
github.com/vmware/vmw-guestinfo/bdoor
github.com/vmware/vmw-guestinfo/message
github.com/vmware/vmw-guestinfo/rpcout
github.com/vmware/vmw-guestinfo/rpcvmx
github.com/vmware/vmw-guestinfo/vmcheck
# golang.org/x/sys v0.5.0
## explicit; go 1.17
golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/unix
golang.org/x/sys/windows
# gopkg.in/djherbis/times.v1 v1.3.0
## explicit
gopkg.in/djherbis/times.v1

View File

@ -17,7 +17,7 @@ func pushCmd() *cobra.Command {
cmd.AddCommand(pushAzureCmd())
cmd.AddCommand(pushGCPCmd())
cmd.AddCommand(pushOpenstackCmd())
cmd.AddCommand(pushPacketCmd())
cmd.AddCommand(pushEquinixMetalCmd())
cmd.AddCommand(pushScalewayCmd())
cmd.AddCommand(pushVCenterCmd())

View File

@ -15,20 +15,20 @@ import (
)
var (
packetDefaultArch = "x86_64"
packetDefaultDecompress = false
equinixmetalDefaultArch = "x86_64"
equinixmetalDefaultDecompress = false
)
func init() {
if runtime.GOARCH == "arm64" {
packetDefaultArch = "aarch64"
equinixmetalDefaultArch = "aarch64"
// decompress on arm64. iPXE/kernel does not
// seem to grok compressed kernels/initrds.
packetDefaultDecompress = true
equinixmetalDefaultDecompress = true
}
}
func pushPacketCmd() *cobra.Command {
func pushEquinixMetalCmd() *cobra.Command {
var (
baseURLFlag string
nameFlag string
@ -37,19 +37,19 @@ func pushPacketCmd() *cobra.Command {
decompress bool
)
cmd := &cobra.Command{
Use: "packet",
Short: "push image to Equinix Metal / Packet",
Long: `Push image to Equinix Metal / Packet.
Single argument is the prefix to use for the image, defualts to "packet".
Use: "equinixmetal",
Short: "push image to Equinix Metal",
Long: `Push image to Equinix Metal.
Single argument is the prefix to use for the image, defaults to "equinixmetal".
`,
Example: "linuxkit push packet [options] [name]",
Example: "linuxkit push equinixmetal [options] [name]",
RunE: func(cmd *cobra.Command, args []string) error {
prefix := "packet"
prefix := "equinixmetal"
if len(args) > 0 {
prefix = args[0]
}
baseURL := getStringValue(packetBaseURL, baseURLFlag, "")
baseURL := getStringValue(equinixmetalBaseURL, baseURLFlag, "")
if baseURL == "" {
return fmt.Errorf("Need to specify a value for --base-url from where the kernel, initrd and iPXE script will be loaded from.")
}
@ -58,7 +58,7 @@ func pushPacketCmd() *cobra.Command {
return fmt.Errorf("Need to specify the destination where to push to.")
}
name := getStringValue(packetNameVar, nameFlag, prefix)
name := getStringValue(equinixmetalNameVar, nameFlag, prefix)
if _, err := os.Stat(fmt.Sprintf("%s-kernel", name)); os.IsNotExist(err) {
return fmt.Errorf("kernel file does not exist: %v", err)
@ -75,7 +75,7 @@ func pushPacketCmd() *cobra.Command {
cmdline = string(c)
}
ipxeScript := packetIPXEScript(name, baseURL, cmdline, arch)
ipxeScript := equinixmetalIPXEScript(name, baseURL, cmdline, arch)
// Parse the destination
dst, err := url.Parse(dst)
@ -84,7 +84,7 @@ func pushPacketCmd() *cobra.Command {
}
switch dst.Scheme {
case "", "file":
packetPushFile(dst, decompress, name, cmdline, ipxeScript)
equinixmetalPushFile(dst, decompress, name, cmdline, ipxeScript)
default:
return fmt.Errorf("Unknown destination format: %s", dst.Scheme)
}
@ -92,16 +92,16 @@ func pushPacketCmd() *cobra.Command {
},
}
cmd.Flags().StringVar(&baseURLFlag, "base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+packetBaseURL+")")
cmd.Flags().StringVar(&nameFlag, "img-name", "", "Overrides the prefix used to identify the files. Defaults to [name] (or "+packetNameVar+")")
cmd.Flags().StringVar(&arch, "arch", packetDefaultArch, "Image architecture (x86_64 or aarch64)")
cmd.Flags().BoolVar(&decompress, "decompress", packetDefaultDecompress, "Decompress kernel/initrd before pushing")
cmd.Flags().StringVar(&baseURLFlag, "base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+equinixmetalBaseURL+")")
cmd.Flags().StringVar(&nameFlag, "img-name", "", "Overrides the prefix used to identify the files. Defaults to [name] (or "+equinixmetalNameVar+")")
cmd.Flags().StringVar(&arch, "arch", equinixmetalDefaultArch, "Image architecture (x86_64 or aarch64)")
cmd.Flags().BoolVar(&decompress, "decompress", equinixmetalDefaultDecompress, "Decompress kernel/initrd before pushing")
cmd.Flags().StringVar(&dst, "destination", "", "URL where to push the image to. Currently only 'file' is supported as a scheme (which is also the default if omitted)")
return cmd
}
func packetPushFile(dst *url.URL, decompress bool, name, cmdline, ipxeScript string) {
func equinixmetalPushFile(dst *url.URL, decompress bool, name, cmdline, ipxeScript string) {
// Make sure the destination exists
dstPath := filepath.Clean(dst.Path)
if err := os.MkdirAll(dstPath, 0755); err != nil {
@ -109,22 +109,22 @@ func packetPushFile(dst *url.URL, decompress bool, name, cmdline, ipxeScript str
}
kernelName := fmt.Sprintf("%s-kernel", name)
if err := packetCopy(filepath.Join(dstPath, kernelName), kernelName, decompress); err != nil {
if err := equinixmetalCopy(filepath.Join(dstPath, kernelName), kernelName, decompress); err != nil {
log.Fatalf("Error copying kernel: %v", err)
}
initrdName := fmt.Sprintf("%s-initrd.img", name)
if err := packetCopy(filepath.Join(dstPath, initrdName), initrdName, decompress); err != nil {
if err := equinixmetalCopy(filepath.Join(dstPath, initrdName), initrdName, decompress); err != nil {
log.Fatalf("Error copying initrd: %v", err)
}
ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name)
ipxeScriptName := fmt.Sprintf("%s-equinixmetal.ipxe", name)
if err := os.WriteFile(filepath.Join(dstPath, ipxeScriptName), []byte(ipxeScript), 0644); err != nil {
log.Fatalf("Error writing iPXE script: %v", err)
}
}
func packetCopy(dst, src string, decompress bool) error {
func equinixmetalCopy(dst, src string, decompress bool) error {
in, err := os.Open(src)
if err != nil {
return err

View File

@ -58,7 +58,7 @@ func runCmd() *cobra.Command {
cmd.AddCommand(runVirtualizationFrameworkCmd())
cmd.AddCommand(runHyperVCmd())
cmd.AddCommand(runOpenStackCmd())
cmd.AddCommand(runPacketCmd())
cmd.AddCommand(runEquinixMetalCmd())
cmd.AddCommand(runQEMUCmd())
cmd.AddCommand(runScalewayCmd())
cmd.AddCommand(runVMWareCmd())

View File

@ -25,29 +25,29 @@ import (
)
const (
packetDefaultZone = "ams1"
packetDefaultMachine = "baremetal_0"
packetBaseURL = "PACKET_BASE_URL"
packetZoneVar = "PACKET_ZONE"
packetMachineVar = "PACKET_MACHINE"
packetAPIKeyVar = "PACKET_API_KEY"
packetProjectIDVar = "PACKET_PROJECT_ID"
packetHostnameVar = "PACKET_HOSTNAME"
packetNameVar = "PACKET_NAME"
equinixmetalDefaultZone = "ams1"
equinixmetalDefaultMachine = "baremetal_0"
equinixmetalBaseURL = "METAL_BASE_URL"
equinixmetalZoneVar = "METAL_FACILITY"
equinixmetalMachineVar = "METAL_MACHINE"
equinixmetalAPIKeyVar = "METAL_API_TOKEN"
equinixmetalProjectIDVar = "METAL_PROJECT_ID"
equinixmetalHostnameVar = "METAL_HOSTNAME"
equinixmetalNameVar = "METAL_NAME"
)
var (
packetDefaultHostname = "linuxkit"
equinixmetalDefaultHostname = "linuxkit"
)
func init() {
// Prefix host name with username
if u, err := user.Current(); err == nil {
packetDefaultHostname = u.Username + "-" + packetDefaultHostname
equinixmetalDefaultHostname = u.Username + "-" + equinixmetalDefaultHostname
}
}
func runPacketCmd() *cobra.Command {
func runEquinixMetalCmd() *cobra.Command {
var (
baseURLFlag string
zoneFlag string
@ -64,33 +64,33 @@ func runPacketCmd() *cobra.Command {
)
cmd := &cobra.Command{
Use: "packet",
Short: "launch an Equinix Metal (Packet) device",
Long: `Launch an Equinix Metal (Packet) device.
Use: "equinixmetal",
Short: "launch an Equinix Metal device",
Long: `Launch an Equinix Metal device.
`,
Args: cobra.ExactArgs(1),
Example: "linuxkit run packet [options] name",
Example: "linuxkit run equinixmetal [options] name",
RunE: func(cmd *cobra.Command, args []string) error {
prefix := "packet"
prefix := "equinixmetal"
if len(args) > 0 {
prefix = args[0]
}
url := getStringValue(packetBaseURL, baseURLFlag, "")
url := getStringValue(equinixmetalBaseURL, baseURLFlag, "")
if url == "" {
return fmt.Errorf("Need to specify a value for --base-url where the images are hosted. This URL should contain <url>/%s-kernel, <url>/%s-initrd.img and <url>/%s-packet.ipxe", prefix, prefix, prefix)
return fmt.Errorf("Need to specify a value for --base-url where the images are hosted. This URL should contain <url>/%s-kernel, <url>/%s-initrd.img and <url>/%s-equinixmetal.ipxe", prefix, prefix, prefix)
}
facility := getStringValue(packetZoneVar, zoneFlag, "")
plan := getStringValue(packetMachineVar, machineFlag, defaultMachine)
apiKey := getStringValue(packetAPIKeyVar, apiKeyFlag, "")
facility := getStringValue(equinixmetalZoneVar, zoneFlag, "")
plan := getStringValue(equinixmetalMachineVar, machineFlag, defaultMachine)
apiKey := getStringValue(equinixmetalAPIKeyVar, apiKeyFlag, "")
if apiKey == "" {
return errors.New("Must specify a Packet.net API key with --api-key")
return errors.New("Must specify an api.equinix.com API key with --api-key")
}
projectID := getStringValue(packetProjectIDVar, projectFlag, "")
projectID := getStringValue(equinixmetalProjectIDVar, projectFlag, "")
if projectID == "" {
return errors.New("Must specify a Packet.net Project ID with --project-id")
return errors.New("Must specify an api.equinix.com Project ID with --project-id")
}
hostname := getStringValue(packetHostnameVar, hostNameFlag, "")
name := getStringValue(packetNameVar, nameFlag, prefix)
hostname := getStringValue(equinixmetalHostnameVar, hostNameFlag, "")
name := getStringValue(equinixmetalNameVar, nameFlag, prefix)
osType := "custom_ipxe"
billing := "hourly"
@ -98,7 +98,7 @@ func runPacketCmd() *cobra.Command {
return fmt.Errorf("Combination of keep=%t and console=%t makes little sense", keepFlag, consoleFlag)
}
ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name)
ipxeScriptName := fmt.Sprintf("%s-equinixmetal.ipxe", name)
// Serve files with a local http server
var httpServer *http.Server
@ -111,7 +111,7 @@ func runPacketCmd() *cobra.Command {
cmdline = string(c)
}
ipxeScript := packetIPXEScript(name, url, cmdline, packetMachineToArch(machineFlag))
ipxeScript := equinixmetalIPXEScript(name, url, cmdline, equinixmetalMachineToArch(machineFlag))
log.Debugf("Using iPXE script:\n%s\n", ipxeScript)
// Two handlers, one for the iPXE script and one for the kernel/initrd files
@ -204,10 +204,10 @@ func runPacketCmd() *cobra.Command {
log.Printf("Booting %s...", dev.ID)
sshHost := "sos." + dev.Facility.Code + ".packet.net"
sshHost := "sos." + dev.Facility.Code + ".platformequinix.com"
if consoleFlag {
// Connect to the serial console
if err := packetSOS(dev.ID, sshHost); err != nil {
if err := equinixmetalSOS(dev.ID, sshHost); err != nil {
return err
}
} else {
@ -244,14 +244,14 @@ func runPacketCmd() *cobra.Command {
},
}
cmd.Flags().StringVar(&baseURLFlag, "base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+packetBaseURL+")")
cmd.Flags().StringVar(&zoneFlag, "zone", packetDefaultZone, "Packet Zone (or "+packetZoneVar+")")
cmd.Flags().StringVar(&machineFlag, "machine", packetDefaultMachine, "Packet Machine Type (or "+packetMachineVar+")")
cmd.Flags().StringVar(&apiKeyFlag, "api-key", "", "Packet API key (or "+packetAPIKeyVar+")")
cmd.Flags().StringVar(&projectFlag, "project-id", "", "Packet Project ID (or "+packetProjectIDVar+")")
cmd.Flags().StringVar(&baseURLFlag, "base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+equinixmetalBaseURL+")")
cmd.Flags().StringVar(&zoneFlag, "zone", equinixmetalDefaultZone, "Equinix Metal Facility (or "+equinixmetalZoneVar+")")
cmd.Flags().StringVar(&machineFlag, "machine", equinixmetalDefaultMachine, "Equinix Metal Machine Type (or "+equinixmetalMachineVar+")")
cmd.Flags().StringVar(&apiKeyFlag, "api-key", "", "Equinix Metal API key (or "+equinixmetalAPIKeyVar+")")
cmd.Flags().StringVar(&projectFlag, "project-id", "", "EquinixMetal Project ID (or "+equinixmetalProjectIDVar+")")
cmd.Flags().StringVar(&deviceFlag, "device", "", "The ID of an existing device")
cmd.Flags().StringVar(&hostNameFlag, "hostname", packetDefaultHostname, "Hostname of new instance (or "+packetHostnameVar+")")
cmd.Flags().StringVar(&nameFlag, "img-name", "", "Overrides the prefix used to identify the files. Defaults to [name] (or "+packetNameVar+")")
cmd.Flags().StringVar(&hostNameFlag, "hostname", equinixmetalDefaultHostname, "Hostname of new instance (or "+equinixmetalHostnameVar+")")
cmd.Flags().StringVar(&nameFlag, "img-name", "", "Overrides the prefix used to identify the files. Defaults to [name] (or "+equinixmetalNameVar+")")
cmd.Flags().BoolVar(&alwaysPXE, "always-pxe", true, "Reboot from PXE every time.")
cmd.Flags().StringVar(&serveFlag, "serve", "", "Serve local files via the http port specified, e.g. ':8080'.")
cmd.Flags().BoolVar(&consoleFlag, "console", true, "Provide interactive access on the console.")
@ -261,7 +261,7 @@ func runPacketCmd() *cobra.Command {
}
// Convert machine type to architecture
func packetMachineToArch(machine string) string {
func equinixmetalMachineToArch(machine string) string {
switch machine {
case "baremetal_2a", "baremetal_2a2":
return "aarch64"
@ -270,8 +270,8 @@ func packetMachineToArch(machine string) string {
}
}
// Build the iPXE script for packet machines
func packetIPXEScript(name, baseURL, cmdline, arch string) string {
// Build the iPXE script for equinix metal machines
func equinixmetalIPXEScript(name, baseURL, cmdline, arch string) string {
// Note, we *append* the <prefix>-cmdline. iXPE booting will
// need the first set of "kernel-params" and we don't want to
// require these to be added to every YAML file.
@ -280,7 +280,7 @@ func packetIPXEScript(name, baseURL, cmdline, arch string) string {
script += fmt.Sprintf("set base-url %s\n", baseURL)
if arch != "aarch64" {
var tty string
// x86_64 Packet machines have console on non standard ttyS1 which is not in most examples
// x86_64 Equinix Metal machines have console on non standard ttyS1 which is not in most examples
if !strings.Contains(cmdline, "console=ttyS1") {
tty = "console=ttyS1,115200"
}
@ -311,7 +311,7 @@ func validateHTTPURL(url string) error {
return nil
}
func packetSOS(user, host string) error {
func equinixmetalSOS(user, host string) error {
log.Debugf("console: ssh %s@%s", user, host)
hostKey, err := sshHostKey(host)

View File

@ -1,5 +1,5 @@
#!/bin/sh
# SUMMARY: LinuxKit packet.net tests
# SUMMARY: LinuxKit Equinix Metal tests
# LABELS:
# For the top level group.sh also specify a 'NAME:' comment