mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-22 02:21:34 +00:00
commit
cd1a472678
@ -40,11 +40,17 @@ retry the boot typically fixes this.
|
|||||||
|
|
||||||
## Boot
|
## Boot
|
||||||
|
|
||||||
LinuxKit on Packet boots the `kernel+initrd` output from moby
|
LinuxKit on Packet boots the `kernel+initrd` output from moby via
|
||||||
via
|
[iPXE](https://help.packet.net/technical/infrastructure/custom-ipxe)
|
||||||
[iPXE](https://help.packet.net/technical/infrastructure/custom-ipxe). iPXE
|
which also requires a iPXE script. iPXE booting requires a HTTP server
|
||||||
booting requires a HTTP server on which you can store your images. The
|
on which you can store your images. The `-base-url` option specifies
|
||||||
`-base-url` option specifies the URL to the HTTP server.
|
the URL to a HTTP server from which `<name>-kernel`,
|
||||||
|
`<name>-initrd.img`, and `<name>-packet.ipxe` can be downloaded during
|
||||||
|
boot.
|
||||||
|
|
||||||
|
If you have your own HTTP server, you can use `linuxkit push packet`
|
||||||
|
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
|
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
|
`-serve` option. This will create a local HTTP server which can either
|
||||||
@ -62,9 +68,10 @@ PACKET_API_KEY=<API key> PACKET_PROJECT_ID=<Project ID> \
|
|||||||
linuxkit run packet -serve :8080 -base-url <ngrok url> packet
|
linuxkit run packet -serve :8080 -base-url <ngrok url> packet
|
||||||
```
|
```
|
||||||
|
|
||||||
To boot a `arm64` image for Type 2a machine (`-machine
|
To boot a `arm64` image for Type 2a machine (`-machine baremetal_2a`)
|
||||||
baremetal_2a`) you currently need build using `linuxkit build packet.yml packet.arm64.yml` and then un-compress both the kernel and
|
you currently need to build using `linuxkit build packet.yml
|
||||||
the initrd before booting, e.g:
|
packet.arm64.yml` and then un-compress both the kernel and the initrd
|
||||||
|
before booting, e.g:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mv packet-initrd.img packet-initrd.img.gz && gzip -d packet-initrd.img.gz
|
mv packet-initrd.img packet-initrd.img.gz && gzip -d packet-initrd.img.gz
|
||||||
@ -78,12 +85,16 @@ 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
|
linuxkit run packet -machine baremetal_2a -serve :8080 -base-url -base-url <ngrok url> packet
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Alternatively, `linuxkit push packet` 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.
|
||||||
|
|
||||||
**Note**: It may take several minutes to deploy a new server. If you
|
**Note**: It may take several minutes to deploy a new server. If you
|
||||||
are attached to the console, you should see the BIOS and the boot
|
are attached to the console, you should see the BIOS and the boot
|
||||||
messages.
|
messages.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Console
|
## Console
|
||||||
|
|
||||||
By default, `linuxkit run packet ...` will connect to the
|
By default, `linuxkit run packet ...` will connect to the
|
||||||
|
@ -76,6 +76,7 @@ func main() {
|
|||||||
fmt.Printf(" pkg Package building\n")
|
fmt.Printf(" pkg Package building\n")
|
||||||
fmt.Printf(" push Push a VM image to a cloud or image store\n")
|
fmt.Printf(" push Push a VM image to a cloud or image store\n")
|
||||||
fmt.Printf(" run Run a VM image on a local hypervisor or remote cloud\n")
|
fmt.Printf(" run Run a VM image on a local hypervisor or remote cloud\n")
|
||||||
|
fmt.Printf(" serve Run a local http server (for iPXE booting)\n")
|
||||||
fmt.Printf(" version Print version information\n")
|
fmt.Printf(" version Print version information\n")
|
||||||
fmt.Printf(" help Print this message\n")
|
fmt.Printf(" help Print this message\n")
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
@ -124,6 +125,8 @@ func main() {
|
|||||||
push(args[1:])
|
push(args[1:])
|
||||||
case "run":
|
case "run":
|
||||||
run(args[1:])
|
run(args[1:])
|
||||||
|
case "serve":
|
||||||
|
serve(args[1:])
|
||||||
case "version":
|
case "version":
|
||||||
printVersion()
|
printVersion()
|
||||||
case "help":
|
case "help":
|
||||||
|
@ -18,6 +18,7 @@ func pushUsage() {
|
|||||||
fmt.Printf(" azure\n")
|
fmt.Printf(" azure\n")
|
||||||
fmt.Printf(" gcp\n")
|
fmt.Printf(" gcp\n")
|
||||||
fmt.Printf(" openstack\n")
|
fmt.Printf(" openstack\n")
|
||||||
|
fmt.Printf(" packet\n")
|
||||||
fmt.Printf(" vcenter\n")
|
fmt.Printf(" vcenter\n")
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
fmt.Printf("'options' are the backend specific options.\n")
|
fmt.Printf("'options' are the backend specific options.\n")
|
||||||
@ -41,6 +42,8 @@ func push(args []string) {
|
|||||||
pushGcp(args[1:])
|
pushGcp(args[1:])
|
||||||
case "openstack":
|
case "openstack":
|
||||||
pushOpenstack(args[1:])
|
pushOpenstack(args[1:])
|
||||||
|
case "packet":
|
||||||
|
pushPacket(args[1:])
|
||||||
case "vcenter":
|
case "vcenter":
|
||||||
pushVCenter(args[1:])
|
pushVCenter(args[1:])
|
||||||
case "help", "-h", "-help", "--help":
|
case "help", "-h", "-help", "--help":
|
||||||
|
147
src/cmd/linuxkit/push_packet.go
Normal file
147
src/cmd/linuxkit/push_packet.go
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
packetDefaultArch = "x86_64"
|
||||||
|
packetDefaultDecompress = false
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if runtime.GOARCH == "arm64" {
|
||||||
|
packetDefaultArch = "aarch64"
|
||||||
|
// decompress on arm64. iPXE/kernel does not
|
||||||
|
// seem to grok compressed kernels/initrds.
|
||||||
|
packetDefaultDecompress = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the run arguments and execute run
|
||||||
|
func pushPacket(args []string) {
|
||||||
|
flags := flag.NewFlagSet("packet", flag.ExitOnError)
|
||||||
|
invoked := filepath.Base(os.Args[0])
|
||||||
|
flags.Usage = func() {
|
||||||
|
fmt.Printf("USAGE: %s push packet [options] [name]\n\n", invoked)
|
||||||
|
fmt.Printf("Options:\n\n")
|
||||||
|
flags.PrintDefaults()
|
||||||
|
}
|
||||||
|
baseURLFlag := flags.String("base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+packetBaseURL+")")
|
||||||
|
nameFlag := flags.String("img-name", "", "Overrides the prefix used to identify the files. Defaults to [name] (or "+packetNameVar+")")
|
||||||
|
archFlag := flags.String("arch", packetDefaultArch, "Image architecture (x86_64 or aarch64)")
|
||||||
|
decompressFlag := flags.Bool("decompress", packetDefaultDecompress, "Decompress kernel/initrd before pushing")
|
||||||
|
dstFlag := flags.String("destination", "", "URL where to push the image to. Currently only 'file' is supported as a scheme (which is also the default if omitted)")
|
||||||
|
|
||||||
|
if err := flags.Parse(args); err != nil {
|
||||||
|
log.Fatal("Unable to parse args")
|
||||||
|
}
|
||||||
|
|
||||||
|
remArgs := flags.Args()
|
||||||
|
prefix := "packet"
|
||||||
|
if len(remArgs) > 0 {
|
||||||
|
prefix = remArgs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
baseURL := getStringValue(packetBaseURL, *baseURLFlag, "")
|
||||||
|
if baseURL == "" {
|
||||||
|
log.Fatal("Need to specify a value for --base-url from where the kernel, initrd and iPXE script will be loaded from.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *dstFlag == "" {
|
||||||
|
log.Fatal("Need to specify the destination where to push to.")
|
||||||
|
}
|
||||||
|
|
||||||
|
name := getStringValue(packetNameVar, *nameFlag, prefix)
|
||||||
|
|
||||||
|
if _, err := os.Stat(fmt.Sprintf("%s-kernel", name)); os.IsNotExist(err) {
|
||||||
|
log.Fatalf("kernel file does not exist: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(fmt.Sprintf("%s-initrd.img", name)); os.IsNotExist(err) {
|
||||||
|
log.Fatalf("initrd file does not exist: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read kernel command line
|
||||||
|
var cmdline string
|
||||||
|
if c, err := ioutil.ReadFile(prefix + "-cmdline"); err != nil {
|
||||||
|
log.Fatalf("Cannot open cmdline file: %v", err)
|
||||||
|
} else {
|
||||||
|
cmdline = string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipxeScript := packetIPXEScript(name, baseURL, cmdline, *archFlag)
|
||||||
|
|
||||||
|
// Parse the destination
|
||||||
|
dst, err := url.Parse(*dstFlag)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Cannot parse destination: %v", err)
|
||||||
|
}
|
||||||
|
switch dst.Scheme {
|
||||||
|
case "", "file":
|
||||||
|
packetPushFile(dst, *decompressFlag, name, cmdline, ipxeScript)
|
||||||
|
default:
|
||||||
|
log.Fatalf("Unknown destination format: %s", dst.Scheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func packetPushFile(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 {
|
||||||
|
log.Fatalf("Could not create destination directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelName := fmt.Sprintf("%s-kernel", name)
|
||||||
|
if err := packetCopy(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 {
|
||||||
|
log.Fatalf("Error copying initrd: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name)
|
||||||
|
if err := ioutil.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 {
|
||||||
|
in, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
var r io.Reader = in
|
||||||
|
if decompress {
|
||||||
|
if rd, err := gzip.NewReader(in); err != nil {
|
||||||
|
log.Warnf("%s does not seem to be gzip'ed (%v). Ignore decompress.", src, err)
|
||||||
|
} else {
|
||||||
|
r = rd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return out.Close()
|
||||||
|
}
|
@ -56,7 +56,7 @@ func runPacket(args []string) {
|
|||||||
fmt.Printf("Options:\n\n")
|
fmt.Printf("Options:\n\n")
|
||||||
flags.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
}
|
}
|
||||||
baseURLFlag := flags.String("base-url", "", "Base URL that the kernel and initrd are served from (or "+packetBaseURL+")")
|
baseURLFlag := flags.String("base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+packetBaseURL+")")
|
||||||
zoneFlag := flags.String("zone", packetDefaultZone, "Packet Zone (or "+packetZoneVar+")")
|
zoneFlag := flags.String("zone", packetDefaultZone, "Packet Zone (or "+packetZoneVar+")")
|
||||||
machineFlag := flags.String("machine", packetDefaultMachine, "Packet Machine Type (or "+packetMachineVar+")")
|
machineFlag := flags.String("machine", packetDefaultMachine, "Packet Machine Type (or "+packetMachineVar+")")
|
||||||
apiKeyFlag := flags.String("api-key", "", "Packet API key (or "+packetAPIKeyVar+")")
|
apiKeyFlag := flags.String("api-key", "", "Packet API key (or "+packetAPIKeyVar+")")
|
||||||
@ -80,7 +80,7 @@ func runPacket(args []string) {
|
|||||||
|
|
||||||
url := getStringValue(packetBaseURL, *baseURLFlag, "")
|
url := getStringValue(packetBaseURL, *baseURLFlag, "")
|
||||||
if url == "" {
|
if url == "" {
|
||||||
log.Fatal("Need to specify a value for --base-url where the images are hosted. This URL should contain <url>/%s-kernel and <url>/%s-initrd.img")
|
log.Fatal("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")
|
||||||
}
|
}
|
||||||
facility := getStringValue(packetZoneVar, *zoneFlag, "")
|
facility := getStringValue(packetZoneVar, *zoneFlag, "")
|
||||||
plan := getStringValue(packetMachineVar, *machineFlag, defaultMachine)
|
plan := getStringValue(packetMachineVar, *machineFlag, defaultMachine)
|
||||||
@ -101,19 +101,31 @@ func runPacket(args []string) {
|
|||||||
log.Fatalf("Combination of keep=%t and console=%t makes little sense", *keepFlag, *consoleFlag)
|
log.Fatalf("Combination of keep=%t and console=%t makes little sense", *keepFlag, *consoleFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read kernel command line
|
ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name)
|
||||||
var cmdline string
|
|
||||||
if c, err := ioutil.ReadFile(prefix + "-cmdline"); err != nil {
|
|
||||||
log.Fatalf("Cannot open cmdline file: %v", err)
|
|
||||||
} else {
|
|
||||||
cmdline = string(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serve files with a local http server
|
// Serve files with a local http server
|
||||||
var httpServer *http.Server
|
var httpServer *http.Server
|
||||||
if *serveFlag != "" {
|
if *serveFlag != "" {
|
||||||
|
// Read kernel command line
|
||||||
|
var cmdline string
|
||||||
|
if c, err := ioutil.ReadFile(prefix + "-cmdline"); err != nil {
|
||||||
|
log.Fatalf("Cannot open cmdline file: %v", err)
|
||||||
|
} else {
|
||||||
|
cmdline = string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipxeScript := packetIPXEScript(name, url, cmdline, packetMachineToArch(*machineFlag))
|
||||||
|
log.Debugf("Using iPXE script:\n%s\n", ipxeScript)
|
||||||
|
|
||||||
|
// Two handlers, one for the iPXE script and one for the kernel/initrd files
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc(fmt.Sprintf("/%s", ipxeScriptName),
|
||||||
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprintf(w, ipxeScript)
|
||||||
|
})
|
||||||
fs := serveFiles{[]string{fmt.Sprintf("%s-kernel", name), fmt.Sprintf("%s-initrd.img", name)}}
|
fs := serveFiles{[]string{fmt.Sprintf("%s-kernel", name), fmt.Sprintf("%s-initrd.img", name)}}
|
||||||
httpServer = &http.Server{Addr: ":8080", Handler: http.FileServer(fs)}
|
mux.Handle("/", http.FileServer(fs))
|
||||||
|
httpServer = &http.Server{Addr: *serveFlag, Handler: mux}
|
||||||
go func() {
|
go func() {
|
||||||
log.Debugf("Listening on http://%s\n", *serveFlag)
|
log.Debugf("Listening on http://%s\n", *serveFlag)
|
||||||
if err := httpServer.ListenAndServe(); err != nil {
|
if err := httpServer.ListenAndServe(); err != nil {
|
||||||
@ -122,38 +134,22 @@ func runPacket(args []string) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the iPXE script
|
// Make sure the URLs work
|
||||||
// Note, we *append* the <prefix>-cmdline. iXPE booting will
|
ipxeURL := fmt.Sprintf("%s/%s", url, ipxeScriptName)
|
||||||
// need the first set of "kernel-params" and we don't want to
|
|
||||||
// require these to be added to every YAML file.
|
|
||||||
userData := "#!ipxe\n\n"
|
|
||||||
userData += "dhcp\n"
|
|
||||||
userData += fmt.Sprintf("set base-url %s\n", url)
|
|
||||||
if *machineFlag != "baremetal_2a" {
|
|
||||||
var tty string
|
|
||||||
// x86_64 Packet machines have console on non standard ttyS1 which is not in most examples
|
|
||||||
if !strings.Contains(cmdline, "console=ttyS1") {
|
|
||||||
tty = "console=ttyS1,115200"
|
|
||||||
}
|
|
||||||
userData += fmt.Sprintf("set kernel-params ip=dhcp nomodeset ro serial %s %s\n", tty, cmdline)
|
|
||||||
userData += fmt.Sprintf("kernel ${base-url}/%s-kernel ${kernel-params}\n", name)
|
|
||||||
userData += fmt.Sprintf("initrd ${base-url}/%s-initrd.img\n", name)
|
|
||||||
} else {
|
|
||||||
// With EFI boot need to specify the initrd and root dev explicitly. See:
|
|
||||||
// http://ipxe.org/appnote/debian_preseed
|
|
||||||
// http://forum.ipxe.org/showthread.php?tid=7589
|
|
||||||
userData += fmt.Sprintf("initrd --name initrd ${base-url}/%s-initrd.img\n", name)
|
|
||||||
userData += fmt.Sprintf("set kernel-params ip=dhcp nomodeset ro %s\n", cmdline)
|
|
||||||
userData += fmt.Sprintf("kernel ${base-url}/%s-kernel initrd=initrd root=/dev/ram0 ${kernel-params}\n", name)
|
|
||||||
}
|
|
||||||
userData += "boot"
|
|
||||||
log.Debugf("Using userData of:\n%s\n", userData)
|
|
||||||
|
|
||||||
// Make sure the URL works
|
|
||||||
initrdURL := fmt.Sprintf("%s/%s-initrd.img", url, name)
|
initrdURL := fmt.Sprintf("%s/%s-initrd.img", url, name)
|
||||||
kernelURL := fmt.Sprintf("%s/%s-kernel", url, name)
|
kernelURL := fmt.Sprintf("%s/%s-kernel", url, name)
|
||||||
validateHTTPURL(kernelURL)
|
log.Infof("Validating URL: %s", ipxeURL)
|
||||||
validateHTTPURL(initrdURL)
|
if err := validateHTTPURL(ipxeURL); err != nil {
|
||||||
|
log.Fatalf("Invalid iPXE URL %s: %v", ipxeURL, err)
|
||||||
|
}
|
||||||
|
log.Infof("Validating URL: %s", kernelURL)
|
||||||
|
if err := validateHTTPURL(kernelURL); err != nil {
|
||||||
|
log.Fatalf("Invalid kernel URL %s: %v", kernelURL, err)
|
||||||
|
}
|
||||||
|
log.Infof("Validating URL: %s", initrdURL)
|
||||||
|
if err := validateHTTPURL(initrdURL); err != nil {
|
||||||
|
log.Fatalf("Invalid initrd URL %s: %v", initrdURL, err)
|
||||||
|
}
|
||||||
|
|
||||||
client := packngo.NewClient("", apiKey, nil)
|
client := packngo.NewClient("", apiKey, nil)
|
||||||
tags := []string{}
|
tags := []string{}
|
||||||
@ -172,11 +168,11 @@ func runPacket(args []string) {
|
|||||||
log.Debugf("%s\n", string(b))
|
log.Debugf("%s\n", string(b))
|
||||||
|
|
||||||
req := packngo.DeviceUpdateRequest{
|
req := packngo.DeviceUpdateRequest{
|
||||||
HostName: hostname,
|
Hostname: hostname,
|
||||||
UserData: userData,
|
Locked: dev.Locked,
|
||||||
Locked: dev.Locked,
|
Tags: dev.Tags,
|
||||||
Tags: dev.Tags,
|
IPXEScriptURL: ipxeURL,
|
||||||
AlwaysPXE: *alwaysPXE,
|
AlwaysPXE: *alwaysPXE,
|
||||||
}
|
}
|
||||||
dev, _, err = client.Devices.Update(*deviceFlag, &req)
|
dev, _, err = client.Devices.Update(*deviceFlag, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -188,15 +184,15 @@ func runPacket(args []string) {
|
|||||||
} else {
|
} else {
|
||||||
// Create a new device
|
// Create a new device
|
||||||
req := packngo.DeviceCreateRequest{
|
req := packngo.DeviceCreateRequest{
|
||||||
HostName: hostname,
|
Hostname: hostname,
|
||||||
Plan: plan,
|
Plan: plan,
|
||||||
Facility: facility,
|
Facility: facility,
|
||||||
OS: osType,
|
OS: osType,
|
||||||
BillingCycle: billing,
|
BillingCycle: billing,
|
||||||
ProjectID: projectID,
|
ProjectID: projectID,
|
||||||
UserData: userData,
|
Tags: tags,
|
||||||
Tags: tags,
|
IPXEScriptURL: ipxeURL,
|
||||||
AlwaysPXE: *alwaysPXE,
|
AlwaysPXE: *alwaysPXE,
|
||||||
}
|
}
|
||||||
dev, _, err = client.Devices.Create(&req)
|
dev, _, err = client.Devices.Create(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -214,7 +210,7 @@ func runPacket(args []string) {
|
|||||||
sshHost := "sos." + dev.Facility.Code + ".packet.net"
|
sshHost := "sos." + dev.Facility.Code + ".packet.net"
|
||||||
if *consoleFlag {
|
if *consoleFlag {
|
||||||
// Connect to the serial console
|
// Connect to the serial console
|
||||||
if err := sshSOS(dev.ID, sshHost); err != nil {
|
if err := packetSOS(dev.ID, sshHost); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -249,20 +245,58 @@ func runPacket(args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateHTTPURL does a sanity check that a URL returns a 200 or 300 response
|
// Convert machine type to architecture
|
||||||
func validateHTTPURL(url string) {
|
func packetMachineToArch(machine string) string {
|
||||||
log.Infof("Validating URL: %s", url)
|
switch machine {
|
||||||
resp, err := http.Head(url)
|
case "baremetal_2a", "baremetal_2a2":
|
||||||
if err != nil {
|
return "aarch64"
|
||||||
log.Fatal(err)
|
default:
|
||||||
|
return "x86_64"
|
||||||
}
|
}
|
||||||
if resp.StatusCode >= 400 {
|
|
||||||
log.Fatal("Got a non 200- or 300- HTTP response code: %s", resp)
|
|
||||||
}
|
|
||||||
log.Debugf("OK: %d response code", resp.StatusCode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshSOS(user, host string) error {
|
// Build the iPXE script for packet machines
|
||||||
|
func packetIPXEScript(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.
|
||||||
|
script := "#!ipxe\n\n"
|
||||||
|
script += "dhcp\n"
|
||||||
|
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
|
||||||
|
if !strings.Contains(cmdline, "console=ttyS1") {
|
||||||
|
tty = "console=ttyS1,115200"
|
||||||
|
}
|
||||||
|
script += fmt.Sprintf("set kernel-params ip=dhcp nomodeset ro serial %s %s\n", tty, cmdline)
|
||||||
|
script += fmt.Sprintf("kernel ${base-url}/%s-kernel ${kernel-params}\n", name)
|
||||||
|
script += fmt.Sprintf("initrd ${base-url}/%s-initrd.img\n", name)
|
||||||
|
} else {
|
||||||
|
// With EFI boot need to specify the initrd and root dev explicitly. See:
|
||||||
|
// http://ipxe.org/appnote/debian_preseed
|
||||||
|
// http://forum.ipxe.org/showthread.php?tid=7589
|
||||||
|
script += fmt.Sprintf("initrd --name initrd ${base-url}/%s-initrd.img\n", name)
|
||||||
|
script += fmt.Sprintf("set kernel-params ip=dhcp nomodeset ro %s\n", cmdline)
|
||||||
|
script += fmt.Sprintf("kernel ${base-url}/%s-kernel initrd=initrd root=/dev/ram0 ${kernel-params}\n", name)
|
||||||
|
}
|
||||||
|
script += "boot"
|
||||||
|
return script
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateHTTPURL does a sanity check that a URL returns a 200 or 300 response
|
||||||
|
func validateHTTPURL(url string) error {
|
||||||
|
resp, err := http.Head(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return fmt.Errorf("Got a non 200- or 300- HTTP response code: %s", resp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func packetSOS(user, host string) error {
|
||||||
log.Debugf("console: ssh %s@%s", user, host)
|
log.Debugf("console: ssh %s@%s", user, host)
|
||||||
|
|
||||||
hostKey, err := sshHostKey(host)
|
hostKey, err := sshHostKey(host)
|
||||||
|
34
src/cmd/linuxkit/serve.go
Normal file
34
src/cmd/linuxkit/serve.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func logRequest(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Infof("%s %s", r.Method, r.URL)
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// serve starts a local web server
|
||||||
|
func serve(args []string) {
|
||||||
|
flags := flag.NewFlagSet("serve", flag.ExitOnError)
|
||||||
|
invoked := filepath.Base(os.Args[0])
|
||||||
|
flags.Usage = func() {
|
||||||
|
fmt.Printf("USAGE: %s serve [options]\n\n", invoked)
|
||||||
|
fmt.Printf("Options:\n\n")
|
||||||
|
flags.PrintDefaults()
|
||||||
|
}
|
||||||
|
portFlag := flags.String("port", ":8080", "Local port to serve on")
|
||||||
|
dirFlag := flags.String("directory", ".", "Directory to serve")
|
||||||
|
|
||||||
|
http.Handle("/", http.FileServer(http.Dir(*dirFlag)))
|
||||||
|
log.Fatal(http.ListenAndServe(*portFlag, logRequest(http.DefaultServeMux)))
|
||||||
|
}
|
@ -31,7 +31,7 @@ github.com/moby/vpnkit 0e4293bb1058598c4b0a406ed171f52573ef414c
|
|||||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||||
github.com/opencontainers/image-spec v1.0.0
|
github.com/opencontainers/image-spec v1.0.0
|
||||||
github.com/opencontainers/runtime-spec v1.0.0
|
github.com/opencontainers/runtime-spec v1.0.0
|
||||||
github.com/packethost/packngo 131798f2804a1b3e895ca98047d56f0d7e094e2a
|
github.com/packethost/packngo f1be085ecd6fca1b0a0e25eda71f208dcfcee5ab
|
||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/radu-matei/azure-sdk-for-go 3b12823551999669c9a325a32472508e0af7978e
|
github.com/radu-matei/azure-sdk-for-go 3b12823551999669c9a325a32472508e0af7978e
|
||||||
|
60
src/cmd/linuxkit/vendor/github.com/docker/docker/hack/README.md
generated
vendored
60
src/cmd/linuxkit/vendor/github.com/docker/docker/hack/README.md
generated
vendored
@ -1,60 +0,0 @@
|
|||||||
## About
|
|
||||||
|
|
||||||
This directory contains a collection of scripts used to build and manage this
|
|
||||||
repository. If there are any issues regarding the intention of a particular
|
|
||||||
script (or even part of a certain script), please reach out to us.
|
|
||||||
It may help us either refine our current scripts, or add on new ones
|
|
||||||
that are appropriate for a given use case.
|
|
||||||
|
|
||||||
## DinD (dind.sh)
|
|
||||||
|
|
||||||
DinD is a wrapper script which allows Docker to be run inside a Docker
|
|
||||||
container. DinD requires the container to
|
|
||||||
be run with privileged mode enabled.
|
|
||||||
|
|
||||||
## Generate Authors (generate-authors.sh)
|
|
||||||
|
|
||||||
Generates AUTHORS; a file with all the names and corresponding emails of
|
|
||||||
individual contributors. AUTHORS can be found in the home directory of
|
|
||||||
this repository.
|
|
||||||
|
|
||||||
## Make
|
|
||||||
|
|
||||||
There are two make files, each with different extensions. Neither are supposed
|
|
||||||
to be called directly; only invoke `make`. Both scripts run inside a Docker
|
|
||||||
container.
|
|
||||||
|
|
||||||
### make.ps1
|
|
||||||
|
|
||||||
- The Windows native build script that uses PowerShell semantics; it is limited
|
|
||||||
unlike `hack\make.sh` since it does not provide support for the full set of
|
|
||||||
operations provided by the Linux counterpart, `make.sh`. However, `make.ps1`
|
|
||||||
does provide support for local Windows development and Windows to Windows CI.
|
|
||||||
More information is found within `make.ps1` by the author, @jhowardmsft
|
|
||||||
|
|
||||||
### make.sh
|
|
||||||
|
|
||||||
- Referenced via `make test` when running tests on a local machine,
|
|
||||||
or directly referenced when running tests inside a Docker development container.
|
|
||||||
- When running on a local machine, `make test` to run all tests found in
|
|
||||||
`test`, `test-unit`, `test-integration`, and `test-docker-py` on
|
|
||||||
your local machine. The default timeout is set in `make.sh` to 60 minutes
|
|
||||||
(`${TIMEOUT:=60m}`), since it currently takes up to an hour to run
|
|
||||||
all of the tests.
|
|
||||||
- When running inside a Docker development container, `hack/make.sh` does
|
|
||||||
not have a single target that runs all the tests. You need to provide a
|
|
||||||
single command line with multiple targets that performs the same thing.
|
|
||||||
An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration test-docker-py`
|
|
||||||
- For more information related to testing outside the scope of this README,
|
|
||||||
refer to
|
|
||||||
[Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/)
|
|
||||||
|
|
||||||
## Release (release.sh)
|
|
||||||
|
|
||||||
Releases any bundles built by `make` on a public AWS S3 bucket.
|
|
||||||
For information regarding configuration, please view `release.sh`.
|
|
||||||
|
|
||||||
## Vendor (vendor.sh)
|
|
||||||
|
|
||||||
A shell script that is a wrapper around Vndr. For information on how to use
|
|
||||||
this, please refer to [vndr's README](https://github.com/LK4D4/vndr/blob/master/README.md)
|
|
69
src/cmd/linuxkit/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/README.md
generated
vendored
69
src/cmd/linuxkit/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/README.md
generated
vendored
@ -1,69 +0,0 @@
|
|||||||
# Integration Testing on Swarm
|
|
||||||
|
|
||||||
IT on Swarm allows you to execute integration test in parallel across a Docker Swarm cluster
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Master service
|
|
||||||
|
|
||||||
- Works as a funker caller
|
|
||||||
- Calls a worker funker (`-worker-service`) with a chunk of `-check.f` filter strings (passed as a file via `-input` flag, typically `/mnt/input`)
|
|
||||||
|
|
||||||
### Worker service
|
|
||||||
|
|
||||||
- Works as a funker callee
|
|
||||||
- Executes an equivalent of `TESTFLAGS=-check.f TestFoo|TestBar|TestBaz ... make test-integration-cli` using the bind-mounted API socket (`docker.sock`)
|
|
||||||
|
|
||||||
### Client
|
|
||||||
|
|
||||||
- Controls master and workers via `docker stack`
|
|
||||||
- No need to have a local daemon
|
|
||||||
|
|
||||||
Typically, the master and workers are supposed to be running on a cloud environment,
|
|
||||||
while the client is supposed to be running on a laptop, e.g. Docker for Mac/Windows.
|
|
||||||
|
|
||||||
## Requirement
|
|
||||||
|
|
||||||
- Docker daemon 1.13 or later
|
|
||||||
- Private registry for distributed execution with multiple nodes
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Step 1: Prepare images
|
|
||||||
|
|
||||||
$ make build-integration-cli-on-swarm
|
|
||||||
|
|
||||||
Following environment variables are known to work in this step:
|
|
||||||
|
|
||||||
- `BUILDFLAGS`
|
|
||||||
- `DOCKER_INCREMENTAL_BINARY`
|
|
||||||
|
|
||||||
Note: during the transition into Moby Project, you might need to create a symbolic link `$GOPATH/src/github.com/docker/docker` to `$GOPATH/src/github.com/moby/moby`.
|
|
||||||
|
|
||||||
### Step 2: Execute tests
|
|
||||||
|
|
||||||
$ ./hack/integration-cli-on-swarm/integration-cli-on-swarm -replicas 40 -push-worker-image YOUR_REGISTRY.EXAMPLE.COM/integration-cli-worker:latest
|
|
||||||
|
|
||||||
Following environment variables are known to work in this step:
|
|
||||||
|
|
||||||
- `DOCKER_GRAPHDRIVER`
|
|
||||||
- `DOCKER_EXPERIMENTAL`
|
|
||||||
|
|
||||||
#### Flags
|
|
||||||
|
|
||||||
Basic flags:
|
|
||||||
|
|
||||||
- `-replicas N`: the number of worker service replicas. i.e. degree of parallelism.
|
|
||||||
- `-chunks N`: the number of chunks. By default, `chunks` == `replicas`.
|
|
||||||
- `-push-worker-image REGISTRY/IMAGE:TAG`: push the worker image to the registry. Note that if you have only single node and hence you do not need a private registry, you do not need to specify `-push-worker-image`.
|
|
||||||
|
|
||||||
Experimental flags for mitigating makespan nonuniformity:
|
|
||||||
|
|
||||||
- `-shuffle`: Shuffle the test filter strings
|
|
||||||
|
|
||||||
Flags for debugging IT on Swarm itself:
|
|
||||||
|
|
||||||
- `-rand-seed N`: the random seed. This flag is useful for deterministic replaying. By default(0), the timestamp is used.
|
|
||||||
- `-filters-file FILE`: the file contains `-check.f` strings. By default, the file is automatically generated.
|
|
||||||
- `-dry-run`: skip the actual workload
|
|
||||||
- `keep-executor`: do not auto-remove executor containers, which is used for running privileged programs on Swarm
|
|
@ -1,2 +0,0 @@
|
|||||||
# dependencies specific to worker (i.e. github.com/docker/docker/...) are not vendored here
|
|
||||||
github.com/bfirsh/funker-go eaa0a2e06f30e72c9a0b7f858951e581e26ef773
|
|
17
src/cmd/linuxkit/vendor/github.com/packethost/packngo/README.md
generated
vendored
17
src/cmd/linuxkit/vendor/github.com/packethost/packngo/README.md
generated
vendored
@ -7,3 +7,20 @@ Committing
|
|||||||
----------
|
----------
|
||||||
|
|
||||||
Before committing, it's a good idea to run `gofmt -w *.go`. ([gofmt](https://golang.org/cmd/gofmt/))
|
Before committing, it's a good idea to run `gofmt -w *.go`. ([gofmt](https://golang.org/cmd/gofmt/))
|
||||||
|
|
||||||
|
Acceptance Tests
|
||||||
|
----------------
|
||||||
|
|
||||||
|
If you want to run tests against the actual Packet API, you must set envvar `PACKET_TEST_ACTUAL_API` to non-empty string for the `go test`. The device tests wait for the device creation, so it's best to run a few in parallel.
|
||||||
|
|
||||||
|
To run all the tests, you can do
|
||||||
|
|
||||||
|
```
|
||||||
|
$ PACKNGO_TEST_ACTUAL_API=1 go test -v -parallel 8
|
||||||
|
```
|
||||||
|
|
||||||
|
It's also useful to run only single acceptance test at a time:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ PACKNGO_TEST_ACTUAL_API=1 go test -v -run=TestAccDeviceBasic
|
||||||
|
```
|
||||||
|
177
src/cmd/linuxkit/vendor/github.com/packethost/packngo/devices.go
generated
vendored
177
src/cmd/linuxkit/vendor/github.com/packethost/packngo/devices.go
generated
vendored
@ -24,24 +24,43 @@ type devicesRoot struct {
|
|||||||
|
|
||||||
// Device represents a Packet device
|
// Device represents a Packet device
|
||||||
type Device struct {
|
type Device struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Href string `json:"href,omitempty"`
|
Href string `json:"href,omitempty"`
|
||||||
Hostname string `json:"hostname,omitempty"`
|
Hostname string `json:"hostname,omitempty"`
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
Created string `json:"created_at,omitempty"`
|
Created string `json:"created_at,omitempty"`
|
||||||
Updated string `json:"updated_at,omitempty"`
|
Updated string `json:"updated_at,omitempty"`
|
||||||
Locked bool `json:"locked,omitempty"`
|
Locked bool `json:"locked,omitempty"`
|
||||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Storage map[string]interface{} `json:"storage,omitempty"`
|
||||||
Network []*IPAddress `json:"ip_addresses"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
OS *OS `json:"operating_system,omitempty"`
|
Network []*IPAddressAssignment `json:"ip_addresses"`
|
||||||
Plan *Plan `json:"plan,omitempty"`
|
Volumes []*Volume `json:"volumes"`
|
||||||
Facility *Facility `json:"facility,omitempty"`
|
OS *OS `json:"operating_system,omitempty"`
|
||||||
Project *Project `json:"project,omitempty"`
|
Plan *Plan `json:"plan,omitempty"`
|
||||||
ProvisionPer float32 `json:"provisioning_percentage,omitempty"`
|
Facility *Facility `json:"facility,omitempty"`
|
||||||
UserData string `json:"userdata",omitempty`
|
Project *Project `json:"project,omitempty"`
|
||||||
IPXEScriptUrl string `json:"ipxe_script_url,omitempty"`
|
ProvisionEvents []*ProvisionEvent `json:"provisioning_events,omitempty"`
|
||||||
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
ProvisionPer float32 `json:"provisioning_percentage,omitempty"`
|
||||||
|
UserData string `json:"userdata,omitempty"`
|
||||||
|
RootPassword string `json:"root_password,omitempty"`
|
||||||
|
IPXEScriptURL string `json:"ipxe_script_url,omitempty"`
|
||||||
|
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
||||||
|
HardwareReservation Href `json:"hardware_reservation,omitempty"`
|
||||||
|
SpotInstance bool `json:"spot_instance,omitempty"`
|
||||||
|
SpotPriceMax float64 `json:"spot_price_max,omitempty"`
|
||||||
|
TerminationTime *Timestamp `json:"termination_time,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProvisionEvent struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
Href string `json:"href"`
|
||||||
|
Interpolated string `json:"interpolated"`
|
||||||
|
Relationships []Href `json:"relationships"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Device) String() string {
|
func (d Device) String() string {
|
||||||
@ -50,28 +69,33 @@ func (d Device) String() string {
|
|||||||
|
|
||||||
// DeviceCreateRequest type used to create a Packet device
|
// DeviceCreateRequest type used to create a Packet device
|
||||||
type DeviceCreateRequest struct {
|
type DeviceCreateRequest struct {
|
||||||
HostName string `json:"hostname"`
|
Hostname string `json:"hostname"`
|
||||||
Plan string `json:"plan"`
|
Plan string `json:"plan"`
|
||||||
Facility string `json:"facility"`
|
Facility string `json:"facility"`
|
||||||
OS string `json:"operating_system"`
|
OS string `json:"operating_system"`
|
||||||
BillingCycle string `json:"billing_cycle"`
|
BillingCycle string `json:"billing_cycle"`
|
||||||
ProjectID string `json:"project_id"`
|
ProjectID string `json:"project_id"`
|
||||||
UserData string `json:"userdata"`
|
UserData string `json:"userdata"`
|
||||||
Tags []string `json:"tags"`
|
Storage string `json:"storage,omitempty"`
|
||||||
IPXEScriptUrl string `json:"ipxe_script_url,omitempty"`
|
Tags []string `json:"tags"`
|
||||||
PublicIPv4SubnetSize int `json:"public_ipv4_subnet_size,omitempty"`
|
IPXEScriptURL string `json:"ipxe_script_url,omitempty"`
|
||||||
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
PublicIPv4SubnetSize int `json:"public_ipv4_subnet_size,omitempty"`
|
||||||
|
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
||||||
|
HardwareReservationID string `json:"hardware_reservation_id,omitempty"`
|
||||||
|
SpotInstance bool `json:"spot_instance,omitempty"`
|
||||||
|
SpotPriceMax float64 `json:"spot_price_max,omitempty,string"`
|
||||||
|
TerminationTime *Timestamp `json:"termination_time,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeviceUpdateRequest type used to update a Packet device
|
// DeviceUpdateRequest type used to update a Packet device
|
||||||
type DeviceUpdateRequest struct {
|
type DeviceUpdateRequest struct {
|
||||||
HostName string `json:"hostname"`
|
Hostname string `json:"hostname"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
UserData string `json:"userdata"`
|
UserData string `json:"userdata"`
|
||||||
Locked bool `json:"locked"`
|
Locked bool `json:"locked"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
||||||
IPXEScriptUrl string `json:"ipxe_script_url,omitempty"`
|
IPXEScriptURL string `json:"ipxe_script_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d DeviceCreateRequest) String() string {
|
func (d DeviceCreateRequest) String() string {
|
||||||
@ -95,14 +119,9 @@ type DeviceServiceOp struct {
|
|||||||
// List returns devices on a project
|
// List returns devices on a project
|
||||||
func (s *DeviceServiceOp) List(projectID string) ([]Device, *Response, error) {
|
func (s *DeviceServiceOp) List(projectID string) ([]Device, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s/devices?include=facility", projectBasePath, projectID)
|
path := fmt.Sprintf("%s/%s/devices?include=facility", projectBasePath, projectID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(devicesRoot)
|
root := new(devicesRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", path, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -113,14 +132,9 @@ func (s *DeviceServiceOp) List(projectID string) ([]Device, *Response, error) {
|
|||||||
// Get returns a device by id
|
// Get returns a device by id
|
||||||
func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
|
func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s?include=facility", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s?include=facility", deviceBasePath, deviceID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
device := new(Device)
|
device := new(Device)
|
||||||
resp, err := s.client.Do(req, device)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", path, nil, device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -131,14 +145,9 @@ func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
|
|||||||
// Create creates a new device
|
// Create creates a new device
|
||||||
func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *Response, error) {
|
func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s/devices", projectBasePath, createRequest.ProjectID)
|
path := fmt.Sprintf("%s/%s/devices", projectBasePath, createRequest.ProjectID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("POST", path, createRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
device := new(Device)
|
device := new(Device)
|
||||||
resp, err := s.client.Do(req, device)
|
|
||||||
|
resp, err := s.client.DoRequest("POST", path, createRequest, device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -149,14 +158,9 @@ func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *
|
|||||||
// Update updates an existing device
|
// Update updates an existing device
|
||||||
func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateRequest) (*Device, *Response, error) {
|
func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateRequest) (*Device, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s?include=facility", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s?include=facility", deviceBasePath, deviceID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("PUT", path, updateRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
device := new(Device)
|
device := new(Device)
|
||||||
resp, err := s.client.Do(req, device)
|
|
||||||
|
resp, err := s.client.DoRequest("PUT", path, updateRequest, device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -168,59 +172,31 @@ func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateReq
|
|||||||
func (s *DeviceServiceOp) Delete(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) Delete(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reboot reboots on a device
|
// Reboot reboots on a device
|
||||||
func (s *DeviceServiceOp) Reboot(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) Reboot(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||||
|
|
||||||
action := &DeviceActionRequest{Type: "reboot"}
|
action := &DeviceActionRequest{Type: "reboot"}
|
||||||
req, err := s.client.NewRequest("POST", path, action)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
return s.client.DoRequest("POST", path, action, nil)
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PowerOff powers on a device
|
// PowerOff powers on a device
|
||||||
func (s *DeviceServiceOp) PowerOff(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) PowerOff(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||||
|
|
||||||
action := &DeviceActionRequest{Type: "power_off"}
|
action := &DeviceActionRequest{Type: "power_off"}
|
||||||
req, err := s.client.NewRequest("POST", path, action)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
return s.client.DoRequest("POST", path, action, nil)
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PowerOn powers on a device
|
// PowerOn powers on a device
|
||||||
func (s *DeviceServiceOp) PowerOn(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) PowerOn(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||||
|
|
||||||
action := &DeviceActionRequest{Type: "power_on"}
|
action := &DeviceActionRequest{Type: "power_on"}
|
||||||
req, err := s.client.NewRequest("POST", path, action)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
return s.client.DoRequest("POST", path, action, nil)
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type lockDeviceType struct {
|
type lockDeviceType struct {
|
||||||
@ -230,30 +206,15 @@ type lockDeviceType struct {
|
|||||||
// Lock sets a device to "locked"
|
// Lock sets a device to "locked"
|
||||||
func (s *DeviceServiceOp) Lock(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) Lock(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||||
|
|
||||||
action := lockDeviceType{Locked: true}
|
action := lockDeviceType{Locked: true}
|
||||||
req, err := s.client.NewRequest("PATCH", path, action)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
|
|
||||||
|
return s.client.DoRequest("PATCH", path, action, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock sets a device to "locked"
|
// Unlock sets a device to "locked"
|
||||||
func (s *DeviceServiceOp) Unlock(deviceID string) (*Response, error) {
|
func (s *DeviceServiceOp) Unlock(deviceID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||||
|
|
||||||
action := lockDeviceType{Locked: false}
|
action := lockDeviceType{Locked: false}
|
||||||
req, err := s.client.NewRequest("PATCH", path, action)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
return s.client.DoRequest("PATCH", path, action, nil)
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/email.go
generated
vendored
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/email.go
generated
vendored
@ -26,13 +26,9 @@ type EmailServiceOp struct {
|
|||||||
|
|
||||||
// Get retrieves an email by id
|
// Get retrieves an email by id
|
||||||
func (s *EmailServiceOp) Get(emailID string) (*Email, *Response, error) {
|
func (s *EmailServiceOp) Get(emailID string) (*Email, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", emailBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
email := new(Email)
|
email := new(Email)
|
||||||
resp, err := s.client.Do(req, email)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", emailBasePath, nil, email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/facilities.go
generated
vendored
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/facilities.go
generated
vendored
@ -41,13 +41,9 @@ type FacilityServiceOp struct {
|
|||||||
|
|
||||||
// List returns all available Packet facilities
|
// List returns all available Packet facilities
|
||||||
func (s *FacilityServiceOp) List() ([]Facility, *Response, error) {
|
func (s *FacilityServiceOp) List() ([]Facility, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", facilityBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(facilityRoot)
|
root := new(facilityRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", facilityBasePath, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
320
src/cmd/linuxkit/vendor/github.com/packethost/packngo/ip.go
generated
vendored
320
src/cmd/linuxkit/vendor/github.com/packethost/packngo/ip.go
generated
vendored
@ -1,110 +1,71 @@
|
|||||||
package packngo
|
package packngo
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
const ipBasePath = "/ips"
|
const ipBasePath = "/ips"
|
||||||
|
|
||||||
// IPService interface defines available IP methods
|
// DeviceIPService handles assignment of addresses from reserved blocks to instances in a project.
|
||||||
type IPService interface {
|
type DeviceIPService interface {
|
||||||
Assign(deviceID string, assignRequest *IPAddressAssignRequest) (*IPAddress, *Response, error)
|
Assign(deviceID string, assignRequest *AddressStruct) (*IPAddressAssignment, *Response, error)
|
||||||
Unassign(ipAddressID string) (*Response, error)
|
Unassign(assignmentID string) (*Response, error)
|
||||||
Get(ipAddressID string) (*IPAddress, *Response, error)
|
Get(assignmentID string) (*IPAddressAssignment, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPAddress represents a ip address
|
// ProjectIPService handles reservation of IP address blocks for a project.
|
||||||
type IPAddress struct {
|
type ProjectIPService interface {
|
||||||
ID string `json:"id"`
|
Get(reservationID string) (*IPAddressReservation, *Response, error)
|
||||||
Address string `json:"address"`
|
List(projectID string) ([]IPAddressReservation, *Response, error)
|
||||||
Gateway string `json:"gateway"`
|
Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error)
|
||||||
Network string `json:"network"`
|
|
||||||
AddressFamily int `json:"address_family"`
|
|
||||||
Netmask string `json:"netmask"`
|
|
||||||
Public bool `json:"public"`
|
|
||||||
Cidr int `json:"cidr"`
|
|
||||||
AssignedTo map[string]string `json:"assigned_to"`
|
|
||||||
Created string `json:"created_at,omitempty"`
|
|
||||||
Updated string `json:"updated_at,omitempty"`
|
|
||||||
Href string `json:"href"`
|
|
||||||
Facility Facility `json:"facility,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPAddressAssignRequest represents the body if a ip assign request
|
|
||||||
type IPAddressAssignRequest struct {
|
|
||||||
Address string `json:"address"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i IPAddress) String() string {
|
|
||||||
return Stringify(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPServiceOp implements IPService
|
|
||||||
type IPServiceOp struct {
|
|
||||||
client *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns IpAddress by ID
|
|
||||||
func (i *IPServiceOp) Get(ipAddressID string) (*IPAddress, *Response, error) {
|
|
||||||
path := fmt.Sprintf("%s/%s", ipBasePath, ipAddressID)
|
|
||||||
|
|
||||||
req, err := i.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := new(IPAddress)
|
|
||||||
resp, err := i.client.Do(req, ip)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unassign unassigns an IP address record. This will remove the relationship between an IP
|
|
||||||
// and the device and will make the IP address available to be assigned to another device.
|
|
||||||
func (i *IPServiceOp) Unassign(ipAddressID string) (*Response, error) {
|
|
||||||
path := fmt.Sprintf("%s/%s", ipBasePath, ipAddressID)
|
|
||||||
|
|
||||||
req, err := i.client.NewRequest("DELETE", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := i.client.Do(req, nil)
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign assigns an IP address to a device. The IP address must be in one of the IP ranges assigned to the device’s project.
|
|
||||||
func (i *IPServiceOp) Assign(deviceID string, assignRequest *IPAddressAssignRequest) (*IPAddress, *Response, error) {
|
|
||||||
path := fmt.Sprintf("%s/%s%s", deviceBasePath, deviceID, ipBasePath)
|
|
||||||
|
|
||||||
req, err := i.client.NewRequest("POST", path, assignRequest)
|
|
||||||
|
|
||||||
ip := new(IPAddress)
|
|
||||||
resp, err := i.client.Do(req, ip)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IP RESERVATIONS API
|
|
||||||
|
|
||||||
// IPReservationService interface defines available IPReservation methods
|
|
||||||
type IPReservationService interface {
|
|
||||||
List(projectID string) ([]IPReservation, *Response, error)
|
|
||||||
RequestMore(projectID string, ipReservationReq *IPReservationRequest) (*IPReservation, *Response, error)
|
|
||||||
Get(ipReservationID string) (*IPReservation, *Response, error)
|
|
||||||
Remove(ipReservationID string) (*Response, error)
|
Remove(ipReservationID string) (*Response, error)
|
||||||
|
AvailableAddresses(ipReservationID string, r *AvailableRequest) ([]string, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPReservationServiceOp implements the IPReservationService interface
|
type ipAddressCommon struct {
|
||||||
type IPReservationServiceOp struct {
|
ID string `json:"id"`
|
||||||
client *Client
|
Address string `json:"address"`
|
||||||
|
Gateway string `json:"gateway"`
|
||||||
|
Network string `json:"network"`
|
||||||
|
AddressFamily int `json:"address_family"`
|
||||||
|
Netmask string `json:"netmask"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
CIDR int `json:"cidr"`
|
||||||
|
Created string `json:"created_at,omitempty"`
|
||||||
|
Updated string `json:"updated_at,omitempty"`
|
||||||
|
Href string `json:"href"`
|
||||||
|
Management bool `json:"management"`
|
||||||
|
Manageable bool `json:"manageable"`
|
||||||
|
Project Href `json:"project"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPReservationRequest represents the body of a reservation request
|
// IPAddressReservation is created when user sends IP reservation request for a project (considering it's within quota).
|
||||||
|
type IPAddressReservation struct {
|
||||||
|
ipAddressCommon
|
||||||
|
Assignments []Href `json:"assignments"`
|
||||||
|
Facility Facility `json:"facility,omitempty"`
|
||||||
|
Available string `json:"available"`
|
||||||
|
Addon bool `json:"addon"`
|
||||||
|
Bill bool `json:"bill"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AvailableResponse is a type for listing of available addresses from a reserved block.
|
||||||
|
type AvailableResponse struct {
|
||||||
|
Available []string `json:"available"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AvailableRequest is a type for listing available addresses from a reserved block.
|
||||||
|
type AvailableRequest struct {
|
||||||
|
CIDR int `json:"cidr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPAddressAssignment is created when an IP address from reservation block is assigned to a device.
|
||||||
|
type IPAddressAssignment struct {
|
||||||
|
ipAddressCommon
|
||||||
|
AssignedTo Href `json:"assigned_to"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPReservationRequest represents the body of a reservation request.
|
||||||
type IPReservationRequest struct {
|
type IPReservationRequest struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
@ -112,95 +73,122 @@ type IPReservationRequest struct {
|
|||||||
Facility string `json:"facility"`
|
Facility string `json:"facility"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPReservation represent an IP reservation for a single project
|
// AddressStruct is a helper type for request/response with dict like {"address": ... }
|
||||||
type IPReservation struct {
|
type AddressStruct struct {
|
||||||
ID string `json:"id"`
|
Address string `json:"address"`
|
||||||
Network string `json:"network"`
|
|
||||||
Address string `json:"address"`
|
|
||||||
AddressFamily int `json:"address_family"`
|
|
||||||
Netmask string `json:"netmask"`
|
|
||||||
Public bool `json:"public"`
|
|
||||||
Cidr int `json:"cidr"`
|
|
||||||
Management bool `json:"management"`
|
|
||||||
Manageable bool `json:"manageable"`
|
|
||||||
Addon bool `json:"addon"`
|
|
||||||
Bill bool `json:"bill"`
|
|
||||||
Assignments []map[string]string `json:"assignments"`
|
|
||||||
Created string `json:"created_at,omitempty"`
|
|
||||||
Updated string `json:"updated_at,omitempty"`
|
|
||||||
Href string `json:"href"`
|
|
||||||
Facility Facility `json:"facility,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ipReservationRoot struct {
|
func deleteFromIP(client *Client, resourceID string) (*Response, error) {
|
||||||
IPReservations []IPReservation `json:"ip_addresses"`
|
path := fmt.Sprintf("%s/%s", ipBasePath, resourceID)
|
||||||
|
|
||||||
|
return client.DoRequest("DELETE", path, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i IPAddressReservation) String() string {
|
||||||
|
return Stringify(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i IPAddressAssignment) String() string {
|
||||||
|
return Stringify(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceIPServiceOp is interface for IP-address assignment methods.
|
||||||
|
type DeviceIPServiceOp struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unassign unassigns an IP address from the device to which it is currently assigned.
|
||||||
|
// This will remove the relationship between an IP and the device and will make the IP
|
||||||
|
// address available to be assigned to another device.
|
||||||
|
func (i *DeviceIPServiceOp) Unassign(assignmentID string) (*Response, error) {
|
||||||
|
return deleteFromIP(i.client, assignmentID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign assigns an IP address to a device.
|
||||||
|
// The IP address must be in one of the IP ranges assigned to the device’s project.
|
||||||
|
func (i *DeviceIPServiceOp) Assign(deviceID string, assignRequest *AddressStruct) (*IPAddressAssignment, *Response, error) {
|
||||||
|
path := fmt.Sprintf("%s/%s%s", deviceBasePath, deviceID, ipBasePath)
|
||||||
|
ipa := new(IPAddressAssignment)
|
||||||
|
|
||||||
|
resp, err := i.client.DoRequest("POST", path, assignRequest, ipa)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipa, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns assignment by ID.
|
||||||
|
func (i *DeviceIPServiceOp) Get(assignmentID string) (*IPAddressAssignment, *Response, error) {
|
||||||
|
path := fmt.Sprintf("%s/%s", ipBasePath, assignmentID)
|
||||||
|
ipa := new(IPAddressAssignment)
|
||||||
|
|
||||||
|
resp, err := i.client.DoRequest("GET", path, nil, ipa)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipa, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProjectIPServiceOp is interface for IP assignment methods.
|
||||||
|
type ProjectIPServiceOp struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns reservation by ID.
|
||||||
|
func (i *ProjectIPServiceOp) Get(reservationID string) (*IPAddressReservation, *Response, error) {
|
||||||
|
path := fmt.Sprintf("%s/%s", ipBasePath, reservationID)
|
||||||
|
ipr := new(IPAddressReservation)
|
||||||
|
|
||||||
|
resp, err := i.client.DoRequest("GET", path, nil, ipr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipr, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// List provides a list of IP resevations for a single project.
|
// List provides a list of IP resevations for a single project.
|
||||||
func (i *IPReservationServiceOp) List(projectID string) ([]IPReservation, *Response, error) {
|
func (i *ProjectIPServiceOp) List(projectID string) ([]IPAddressReservation, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
||||||
|
reservations := new(struct {
|
||||||
|
Reservations []IPAddressReservation `json:"ip_addresses"`
|
||||||
|
})
|
||||||
|
|
||||||
req, err := i.client.NewRequest("GET", path, nil)
|
resp, err := i.client.DoRequest("GET", path, nil, reservations)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
reservations := new(ipReservationRoot)
|
|
||||||
resp, err := i.client.Do(req, reservations)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
return reservations.IPReservations, resp, err
|
return reservations.Reservations, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestMore requests more IP space for a project in order to have additional IP addresses to assign to devices
|
// Request requests more IP space for a project in order to have additional IP addresses to assign to devices.
|
||||||
func (i *IPReservationServiceOp) RequestMore(projectID string, ipReservationReq *IPReservationRequest) (*IPReservation, *Response, error) {
|
func (i *ProjectIPServiceOp) Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
||||||
|
ipr := new(IPAddressReservation)
|
||||||
|
|
||||||
req, err := i.client.NewRequest("POST", path, &ipReservationReq)
|
resp, err := i.client.DoRequest("POST", path, ipReservationReq, ipr)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := new(IPReservation)
|
|
||||||
resp, err := i.client.Do(req, ip)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
return ip, resp, err
|
return ipr, resp, err
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a single IP reservation object
|
|
||||||
func (i *IPReservationServiceOp) Get(ipReservationID string) (*IPReservation, *Response, error) {
|
|
||||||
path := fmt.Sprintf("%s/%s", ipBasePath, ipReservationID)
|
|
||||||
|
|
||||||
req, err := i.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
reservation := new(IPReservation)
|
|
||||||
resp, err := i.client.Do(req, reservation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return reservation, resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes an IP reservation from the project.
|
// Remove removes an IP reservation from the project.
|
||||||
func (i *IPReservationServiceOp) Remove(ipReservationID string) (*Response, error) {
|
func (i *ProjectIPServiceOp) Remove(ipReservationID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", ipBasePath, ipReservationID)
|
return deleteFromIP(i.client, ipReservationID)
|
||||||
|
}
|
||||||
req, err := i.client.NewRequest("DELETE", path, nil)
|
|
||||||
if err != nil {
|
// AvailableAddresses lists addresses available from a reserved block
|
||||||
return nil, err
|
func (i *ProjectIPServiceOp) AvailableAddresses(ipReservationID string, r *AvailableRequest) ([]string, *Response, error) {
|
||||||
}
|
path := fmt.Sprintf("%s/%s/available", ipBasePath, ipReservationID)
|
||||||
|
ar := new(AvailableResponse)
|
||||||
resp, err := i.client.Do(req, nil)
|
|
||||||
if err != nil {
|
resp, err := i.client.DoRequest("GET", path, r, ar)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, resp, err
|
||||||
|
}
|
||||||
return resp, err
|
return ar.Available, resp, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/operatingsystems.go
generated
vendored
8
src/cmd/linuxkit/vendor/github.com/packethost/packngo/operatingsystems.go
generated
vendored
@ -30,13 +30,9 @@ type OSServiceOp struct {
|
|||||||
|
|
||||||
// List returns all available operating systems
|
// List returns all available operating systems
|
||||||
func (s *OSServiceOp) List() ([]OS, *Response, error) {
|
func (s *OSServiceOp) List() ([]OS, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", osBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(osRoot)
|
root := new(osRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", osBasePath, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
70
src/cmd/linuxkit/vendor/github.com/packethost/packngo/packngo.go
generated
vendored
70
src/cmd/linuxkit/vendor/github.com/packethost/packngo/packngo.go
generated
vendored
@ -6,8 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -18,6 +21,7 @@ const (
|
|||||||
baseURL = "https://api.packet.net/"
|
baseURL = "https://api.packet.net/"
|
||||||
userAgent = "packngo/" + libraryVersion
|
userAgent = "packngo/" + libraryVersion
|
||||||
mediaType = "application/json"
|
mediaType = "application/json"
|
||||||
|
debugEnvVar = "PACKNGO_DEBUG"
|
||||||
|
|
||||||
headerRateLimit = "X-RateLimit-Limit"
|
headerRateLimit = "X-RateLimit-Limit"
|
||||||
headerRateRemaining = "X-RateLimit-Remaining"
|
headerRateRemaining = "X-RateLimit-Remaining"
|
||||||
@ -42,6 +46,11 @@ type Response struct {
|
|||||||
Rate
|
Rate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Href is an API link
|
||||||
|
type Href struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Response) populateRate() {
|
func (r *Response) populateRate() {
|
||||||
// parse the rate limit headers and populate Response.Rate
|
// parse the rate limit headers and populate Response.Rate
|
||||||
if limit := r.Header.Get(headerRateLimit); limit != "" {
|
if limit := r.Header.Get(headerRateLimit); limit != "" {
|
||||||
@ -59,18 +68,20 @@ func (r *Response) populateRate() {
|
|||||||
|
|
||||||
// ErrorResponse is the http response used on errrors
|
// ErrorResponse is the http response used on errrors
|
||||||
type ErrorResponse struct {
|
type ErrorResponse struct {
|
||||||
Response *http.Response
|
Response *http.Response
|
||||||
Errors []string `json:"errors"`
|
Errors []string `json:"errors"`
|
||||||
|
SingleError string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ErrorResponse) Error() string {
|
func (r *ErrorResponse) Error() string {
|
||||||
return fmt.Sprintf("%v %v: %d %v",
|
return fmt.Sprintf("%v %v: %d %v %v",
|
||||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(r.Errors, ", "))
|
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(r.Errors, ", "), r.SingleError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is the base API Client
|
// Client is the base API Client
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
|
debug bool
|
||||||
|
|
||||||
BaseURL *url.URL
|
BaseURL *url.URL
|
||||||
|
|
||||||
@ -81,17 +92,19 @@ type Client struct {
|
|||||||
RateLimit Rate
|
RateLimit Rate
|
||||||
|
|
||||||
// Packet Api Objects
|
// Packet Api Objects
|
||||||
Plans PlanService
|
Plans PlanService
|
||||||
Users UserService
|
Users UserService
|
||||||
Emails EmailService
|
Emails EmailService
|
||||||
SSHKeys SSHKeyService
|
SSHKeys SSHKeyService
|
||||||
Devices DeviceService
|
Devices DeviceService
|
||||||
Projects ProjectService
|
Projects ProjectService
|
||||||
Facilities FacilityService
|
Facilities FacilityService
|
||||||
OperatingSystems OSService
|
OperatingSystems OSService
|
||||||
Ips IPService
|
DeviceIPs DeviceIPService
|
||||||
IpReservations IPReservationService
|
ProjectIPs ProjectIPService
|
||||||
Volumes VolumeService
|
Volumes VolumeService
|
||||||
|
VolumeAttachments VolumeAttachmentService
|
||||||
|
SpotMarket SpotMarketService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRequest inits a new http request with the proper headers
|
// NewRequest inits a new http request with the proper headers
|
||||||
@ -140,6 +153,10 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
|||||||
|
|
||||||
response := Response{Response: resp}
|
response := Response{Response: resp}
|
||||||
response.populateRate()
|
response.populateRate()
|
||||||
|
if c.debug {
|
||||||
|
o, _ := httputil.DumpResponse(response.Response, true)
|
||||||
|
log.Printf("%s\n", string(o))
|
||||||
|
}
|
||||||
c.RateLimit = response.Rate
|
c.RateLimit = response.Rate
|
||||||
|
|
||||||
err = checkResponse(resp)
|
err = checkResponse(resp)
|
||||||
@ -163,6 +180,19 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
|||||||
return &response, err
|
return &response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoRequest is a convenience method, it calls NewRequest follwed by Do
|
||||||
|
func (c *Client) DoRequest(method, path string, body, v interface{}) (*Response, error) {
|
||||||
|
req, err := c.NewRequest(method, path, body)
|
||||||
|
if c.debug {
|
||||||
|
o, _ := httputil.DumpRequestOut(req, true)
|
||||||
|
log.Printf("%s\n", string(o))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.Do(req, v)
|
||||||
|
}
|
||||||
|
|
||||||
// NewClient initializes and returns a Client, use this to get an API Client to operate on
|
// NewClient initializes and returns a Client, use this to get an API Client to operate on
|
||||||
// N.B.: Packet's API certificate requires Go 1.5+ to successfully parse. If you are using
|
// N.B.: Packet's API certificate requires Go 1.5+ to successfully parse. If you are using
|
||||||
// an older version of Go, pass in a custom http.Client with a custom TLS configuration
|
// an older version of Go, pass in a custom http.Client with a custom TLS configuration
|
||||||
@ -171,6 +201,9 @@ func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Cl
|
|||||||
client, _ := NewClientWithBaseURL(consumerToken, apiKey, httpClient, baseURL)
|
client, _ := NewClientWithBaseURL(consumerToken, apiKey, httpClient, baseURL)
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClientWithBaseURL returns a Client pointing to nonstandard API URL, e.g.
|
||||||
|
// for mocking the remote API
|
||||||
func NewClientWithBaseURL(consumerToken string, apiKey string, httpClient *http.Client, apiBaseURL string) (*Client, error) {
|
func NewClientWithBaseURL(consumerToken string, apiKey string, httpClient *http.Client, apiBaseURL string) (*Client, error) {
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
// Don't fall back on http.DefaultClient as it's not nice to adjust state
|
// Don't fall back on http.DefaultClient as it's not nice to adjust state
|
||||||
@ -185,6 +218,7 @@ func NewClientWithBaseURL(consumerToken string, apiKey string, httpClient *http.
|
|||||||
}
|
}
|
||||||
|
|
||||||
c := &Client{client: httpClient, BaseURL: u, UserAgent: userAgent, ConsumerToken: consumerToken, APIKey: apiKey}
|
c := &Client{client: httpClient, BaseURL: u, UserAgent: userAgent, ConsumerToken: consumerToken, APIKey: apiKey}
|
||||||
|
c.debug = os.Getenv(debugEnvVar) != ""
|
||||||
c.Plans = &PlanServiceOp{client: c}
|
c.Plans = &PlanServiceOp{client: c}
|
||||||
c.Users = &UserServiceOp{client: c}
|
c.Users = &UserServiceOp{client: c}
|
||||||
c.Emails = &EmailServiceOp{client: c}
|
c.Emails = &EmailServiceOp{client: c}
|
||||||
@ -193,9 +227,11 @@ func NewClientWithBaseURL(consumerToken string, apiKey string, httpClient *http.
|
|||||||
c.Projects = &ProjectServiceOp{client: c}
|
c.Projects = &ProjectServiceOp{client: c}
|
||||||
c.Facilities = &FacilityServiceOp{client: c}
|
c.Facilities = &FacilityServiceOp{client: c}
|
||||||
c.OperatingSystems = &OSServiceOp{client: c}
|
c.OperatingSystems = &OSServiceOp{client: c}
|
||||||
c.Ips = &IPServiceOp{client: c}
|
c.DeviceIPs = &DeviceIPServiceOp{client: c}
|
||||||
c.IpReservations = &IPReservationServiceOp{client: c}
|
c.ProjectIPs = &ProjectIPServiceOp{client: c}
|
||||||
c.Volumes = &VolumeServiceOp{client: c}
|
c.Volumes = &VolumeServiceOp{client: c}
|
||||||
|
c.VolumeAttachments = &VolumeAttachmentServiceOp{client: c}
|
||||||
|
c.SpotMarket = &SpotMarketServiceOp{client: c}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
9
src/cmd/linuxkit/vendor/github.com/packethost/packngo/plans.go
generated
vendored
9
src/cmd/linuxkit/vendor/github.com/packethost/packngo/plans.go
generated
vendored
@ -106,14 +106,9 @@ type PlanServiceOp struct {
|
|||||||
|
|
||||||
// List method returns all available plans
|
// List method returns all available plans
|
||||||
func (s *PlanServiceOp) List() ([]Plan, *Response, error) {
|
func (s *PlanServiceOp) List() ([]Plan, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", planBasePath, nil)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(planRoot)
|
root := new(planRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", planBasePath, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
72
src/cmd/linuxkit/vendor/github.com/packethost/packngo/projects.go
generated
vendored
72
src/cmd/linuxkit/vendor/github.com/packethost/packngo/projects.go
generated
vendored
@ -11,14 +11,9 @@ type ProjectService interface {
|
|||||||
Create(*ProjectCreateRequest) (*Project, *Response, error)
|
Create(*ProjectCreateRequest) (*Project, *Response, error)
|
||||||
Update(*ProjectUpdateRequest) (*Project, *Response, error)
|
Update(*ProjectUpdateRequest) (*Project, *Response, error)
|
||||||
Delete(string) (*Response, error)
|
Delete(string) (*Response, error)
|
||||||
ListIPAddresses(string) ([]IPAddress, *Response, error)
|
|
||||||
ListVolumes(string) ([]Volume, *Response, error)
|
ListVolumes(string) ([]Volume, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ipsRoot struct {
|
|
||||||
IPAddresses []IPAddress `json:"ip_addresses"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type volumesRoot struct {
|
type volumesRoot struct {
|
||||||
Volumes []Volume `json:"volumes"`
|
Volumes []Volume `json:"volumes"`
|
||||||
}
|
}
|
||||||
@ -69,31 +64,11 @@ type ProjectServiceOp struct {
|
|||||||
client *Client
|
client *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProjectServiceOp) ListIPAddresses(projectID string) ([]IPAddress, *Response, error) {
|
|
||||||
url := fmt.Sprintf("%s/%s/ips", projectBasePath, projectID)
|
|
||||||
req, err := s.client.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(ipsRoot)
|
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.IPAddresses, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// List returns the user's projects
|
// List returns the user's projects
|
||||||
func (s *ProjectServiceOp) List() ([]Project, *Response, error) {
|
func (s *ProjectServiceOp) List() ([]Project, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", projectBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(projectsRoot)
|
root := new(projectsRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", projectBasePath, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -104,13 +79,9 @@ func (s *ProjectServiceOp) List() ([]Project, *Response, error) {
|
|||||||
// Get returns a project by id
|
// Get returns a project by id
|
||||||
func (s *ProjectServiceOp) Get(projectID string) (*Project, *Response, error) {
|
func (s *ProjectServiceOp) Get(projectID string) (*Project, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", projectBasePath, projectID)
|
path := fmt.Sprintf("%s/%s", projectBasePath, projectID)
|
||||||
req, err := s.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
project := new(Project)
|
project := new(Project)
|
||||||
resp, err := s.client.Do(req, project)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", path, nil, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -120,13 +91,9 @@ func (s *ProjectServiceOp) Get(projectID string) (*Project, *Response, error) {
|
|||||||
|
|
||||||
// Create creates a new project
|
// Create creates a new project
|
||||||
func (s *ProjectServiceOp) Create(createRequest *ProjectCreateRequest) (*Project, *Response, error) {
|
func (s *ProjectServiceOp) Create(createRequest *ProjectCreateRequest) (*Project, *Response, error) {
|
||||||
req, err := s.client.NewRequest("POST", projectBasePath, createRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
project := new(Project)
|
project := new(Project)
|
||||||
resp, err := s.client.Do(req, project)
|
|
||||||
|
resp, err := s.client.DoRequest("POST", projectBasePath, createRequest, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -137,13 +104,9 @@ func (s *ProjectServiceOp) Create(createRequest *ProjectCreateRequest) (*Project
|
|||||||
// Update updates a project
|
// Update updates a project
|
||||||
func (s *ProjectServiceOp) Update(updateRequest *ProjectUpdateRequest) (*Project, *Response, error) {
|
func (s *ProjectServiceOp) Update(updateRequest *ProjectUpdateRequest) (*Project, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", projectBasePath, updateRequest.ID)
|
path := fmt.Sprintf("%s/%s", projectBasePath, updateRequest.ID)
|
||||||
req, err := s.client.NewRequest("PATCH", path, updateRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
project := new(Project)
|
project := new(Project)
|
||||||
resp, err := s.client.Do(req, project)
|
|
||||||
|
resp, err := s.client.DoRequest("PATCH", path, updateRequest, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -155,26 +118,15 @@ func (s *ProjectServiceOp) Update(updateRequest *ProjectUpdateRequest) (*Project
|
|||||||
func (s *ProjectServiceOp) Delete(projectID string) (*Response, error) {
|
func (s *ProjectServiceOp) Delete(projectID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", projectBasePath, projectID)
|
path := fmt.Sprintf("%s/%s", projectBasePath, projectID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns Volumes for a project
|
// ListVolumes returns Volumes for a project
|
||||||
func (s *ProjectServiceOp) ListVolumes(projectID string) ([]Volume, *Response, error) {
|
func (s *ProjectServiceOp) ListVolumes(projectID string) ([]Volume, *Response, error) {
|
||||||
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
|
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
|
||||||
req, err := s.client.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(volumesRoot)
|
root := new(volumesRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", url, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
39
src/cmd/linuxkit/vendor/github.com/packethost/packngo/spotmarket.go
generated
vendored
Normal file
39
src/cmd/linuxkit/vendor/github.com/packethost/packngo/spotmarket.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package packngo
|
||||||
|
|
||||||
|
const spotMarketBasePath = "/market/spot/prices"
|
||||||
|
|
||||||
|
// SpotMarketService expooses Spot Market methods
|
||||||
|
type SpotMarketService interface {
|
||||||
|
Prices() (PriceMap, *Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpotMarketServiceOp implements SpotMarketService
|
||||||
|
type SpotMarketServiceOp struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceMap is a map of [facility][plan]-> float Price
|
||||||
|
type PriceMap map[string]map[string]float64
|
||||||
|
|
||||||
|
// Prices gets current PriceMap from the API
|
||||||
|
func (s *SpotMarketServiceOp) Prices() (PriceMap, *Response, error) {
|
||||||
|
root := new(struct {
|
||||||
|
SMPs map[string]map[string]struct {
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
} `json:"spot_market_prices"`
|
||||||
|
})
|
||||||
|
|
||||||
|
resp, err := s.client.DoRequest("GET", spotMarketBasePath, nil, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
prices := make(PriceMap)
|
||||||
|
for facility, planMap := range root.SMPs {
|
||||||
|
prices[facility] = map[string]float64{}
|
||||||
|
for plan, v := range planMap {
|
||||||
|
prices[facility][plan] = v.Price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prices, resp, err
|
||||||
|
}
|
63
src/cmd/linuxkit/vendor/github.com/packethost/packngo/sshkeys.go
generated
vendored
63
src/cmd/linuxkit/vendor/github.com/packethost/packngo/sshkeys.go
generated
vendored
@ -2,11 +2,14 @@ package packngo
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const sshKeyBasePath = "/ssh-keys"
|
const (
|
||||||
|
sshKeyBasePath = "/ssh-keys"
|
||||||
|
)
|
||||||
|
|
||||||
// SSHKeyService interface defines available device methods
|
// SSHKeyService interface defines available device methods
|
||||||
type SSHKeyService interface {
|
type SSHKeyService interface {
|
||||||
List() ([]SSHKey, *Response, error)
|
List() ([]SSHKey, *Response, error)
|
||||||
|
ProjectList(string) ([]SSHKey, *Response, error)
|
||||||
Get(string) (*SSHKey, *Response, error)
|
Get(string) (*SSHKey, *Response, error)
|
||||||
Create(*SSHKeyCreateRequest) (*SSHKey, *Response, error)
|
Create(*SSHKeyCreateRequest) (*SSHKey, *Response, error)
|
||||||
Update(*SSHKeyUpdateRequest) (*SSHKey, *Response, error)
|
Update(*SSHKeyUpdateRequest) (*SSHKey, *Response, error)
|
||||||
@ -60,15 +63,10 @@ type SSHKeyServiceOp struct {
|
|||||||
client *Client
|
client *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a user's ssh keys
|
func (s *SSHKeyServiceOp) list(url string) ([]SSHKey, *Response, error) {
|
||||||
func (s *SSHKeyServiceOp) List() ([]SSHKey, *Response, error) {
|
|
||||||
req, err := s.client.NewRequest("GET", sshKeyBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(sshKeyRoot)
|
root := new(sshKeyRoot)
|
||||||
resp, err := s.client.Do(req, root)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", url, nil, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -76,17 +74,23 @@ func (s *SSHKeyServiceOp) List() ([]SSHKey, *Response, error) {
|
|||||||
return root.SSHKeys, resp, err
|
return root.SSHKeys, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProjectList lists ssh keys of a project
|
||||||
|
func (s *SSHKeyServiceOp) ProjectList(projectID string) ([]SSHKey, *Response, error) {
|
||||||
|
return s.list(fmt.Sprintf("%s/%s%s", projectBasePath, projectID, sshKeyBasePath))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a user's ssh keys
|
||||||
|
func (s *SSHKeyServiceOp) List() ([]SSHKey, *Response, error) {
|
||||||
|
return s.list(sshKeyBasePath)
|
||||||
|
}
|
||||||
|
|
||||||
// Get returns an ssh key by id
|
// Get returns an ssh key by id
|
||||||
func (s *SSHKeyServiceOp) Get(sshKeyID string) (*SSHKey, *Response, error) {
|
func (s *SSHKeyServiceOp) Get(sshKeyID string) (*SSHKey, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", sshKeyBasePath, sshKeyID)
|
path := fmt.Sprintf("%s/%s", sshKeyBasePath, sshKeyID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sshKey := new(SSHKey)
|
sshKey := new(SSHKey)
|
||||||
resp, err := s.client.Do(req, sshKey)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", path, nil, sshKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -98,15 +102,11 @@ func (s *SSHKeyServiceOp) Get(sshKeyID string) (*SSHKey, *Response, error) {
|
|||||||
func (s *SSHKeyServiceOp) Create(createRequest *SSHKeyCreateRequest) (*SSHKey, *Response, error) {
|
func (s *SSHKeyServiceOp) Create(createRequest *SSHKeyCreateRequest) (*SSHKey, *Response, error) {
|
||||||
path := sshKeyBasePath
|
path := sshKeyBasePath
|
||||||
if createRequest.ProjectID != "" {
|
if createRequest.ProjectID != "" {
|
||||||
path = "/projects/" + createRequest.ProjectID + sshKeyBasePath
|
path = fmt.Sprintf("%s/%s%s", projectBasePath, createRequest.ProjectID, sshKeyBasePath)
|
||||||
}
|
}
|
||||||
req, err := s.client.NewRequest("POST", path, createRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sshKey := new(SSHKey)
|
sshKey := new(SSHKey)
|
||||||
resp, err := s.client.Do(req, sshKey)
|
|
||||||
|
resp, err := s.client.DoRequest("POST", path, createRequest, sshKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -117,13 +117,9 @@ func (s *SSHKeyServiceOp) Create(createRequest *SSHKeyCreateRequest) (*SSHKey, *
|
|||||||
// Update updates an ssh key
|
// Update updates an ssh key
|
||||||
func (s *SSHKeyServiceOp) Update(updateRequest *SSHKeyUpdateRequest) (*SSHKey, *Response, error) {
|
func (s *SSHKeyServiceOp) Update(updateRequest *SSHKeyUpdateRequest) (*SSHKey, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", sshKeyBasePath, updateRequest.ID)
|
path := fmt.Sprintf("%s/%s", sshKeyBasePath, updateRequest.ID)
|
||||||
req, err := s.client.NewRequest("PATCH", path, updateRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sshKey := new(SSHKey)
|
sshKey := new(SSHKey)
|
||||||
resp, err := s.client.Do(req, sshKey)
|
|
||||||
|
resp, err := s.client.DoRequest("PATCH", path, updateRequest, sshKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -135,12 +131,5 @@ func (s *SSHKeyServiceOp) Update(updateRequest *SSHKeyUpdateRequest) (*SSHKey, *
|
|||||||
func (s *SSHKeyServiceOp) Delete(sshKeyID string) (*Response, error) {
|
func (s *SSHKeyServiceOp) Delete(sshKeyID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", sshKeyBasePath, sshKeyID)
|
path := fmt.Sprintf("%s/%s", sshKeyBasePath, sshKeyID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
10
src/cmd/linuxkit/vendor/github.com/packethost/packngo/user.go
generated
vendored
10
src/cmd/linuxkit/vendor/github.com/packethost/packngo/user.go
generated
vendored
@ -22,7 +22,7 @@ type User struct {
|
|||||||
Created string `json:"created_at,omitempty"`
|
Created string `json:"created_at,omitempty"`
|
||||||
Updated string `json:"updated_at,omitempty"`
|
Updated string `json:"updated_at,omitempty"`
|
||||||
TimeZone string `json:"timezone,omitempty"`
|
TimeZone string `json:"timezone,omitempty"`
|
||||||
Emails []Email `json:"email,omitempty"`
|
Emails []Email `json:"emails,omitempty"`
|
||||||
PhoneNumber string `json:"phone_number,omitempty"`
|
PhoneNumber string `json:"phone_number,omitempty"`
|
||||||
URL string `json:"href,omitempty"`
|
URL string `json:"href,omitempty"`
|
||||||
}
|
}
|
||||||
@ -38,13 +38,9 @@ type UserServiceOp struct {
|
|||||||
|
|
||||||
// Get method gets a user by userID
|
// Get method gets a user by userID
|
||||||
func (s *UserServiceOp) Get(userID string) (*User, *Response, error) {
|
func (s *UserServiceOp) Get(userID string) (*User, *Response, error) {
|
||||||
req, err := s.client.NewRequest("GET", userBasePath, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
user := new(User)
|
user := new(User)
|
||||||
resp, err := s.client.Do(req, user)
|
|
||||||
|
resp, err := s.client.DoRequest("GET", userBasePath, nil, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
21
src/cmd/linuxkit/vendor/github.com/packethost/packngo/utils.go
generated
vendored
21
src/cmd/linuxkit/vendor/github.com/packethost/packngo/utils.go
generated
vendored
@ -17,27 +17,6 @@ func Stringify(message interface{}) string {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// String allocates a new string value to store v and returns a pointer to it
|
|
||||||
func String(v string) *string {
|
|
||||||
p := new(string)
|
|
||||||
*p = v
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int allocates a new int32 value to store v and returns a pointer to it, but unlike Int32 its argument value is an int.
|
|
||||||
func Int(v int) *int {
|
|
||||||
p := new(int)
|
|
||||||
*p = v
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool allocates a new bool value to store v and returns a pointer to it.
|
|
||||||
func Bool(v bool) *bool {
|
|
||||||
p := new(bool)
|
|
||||||
*p = v
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// StreamToString converts a reader to a string
|
// StreamToString converts a reader to a string
|
||||||
func StreamToString(stream io.Reader) string {
|
func StreamToString(stream io.Reader) string {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
137
src/cmd/linuxkit/vendor/github.com/packethost/packngo/volumes.go
generated
vendored
137
src/cmd/linuxkit/vendor/github.com/packethost/packngo/volumes.go
generated
vendored
@ -2,33 +2,43 @@ package packngo
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const volumeBasePath = "/storage"
|
const (
|
||||||
|
volumeBasePath = "/storage"
|
||||||
|
attachmentsBasePath = "/attachments"
|
||||||
|
)
|
||||||
|
|
||||||
// VolumeService interface defines available Volume methods
|
// VolumeService interface defines available Volume methods
|
||||||
type VolumeService interface {
|
type VolumeService interface {
|
||||||
Get(string) (*Volume, *Response, error)
|
Get(string) (*Volume, *Response, error)
|
||||||
Update(*VolumeUpdateRequest) (*Volume, *Response, error)
|
Update(*VolumeUpdateRequest) (*Volume, *Response, error)
|
||||||
Delete(string) (*Response, error)
|
Delete(string) (*Response, error)
|
||||||
Create(*VolumeCreateRequest) (*Volume, *Response, error)
|
Create(*VolumeCreateRequest, string) (*Volume, *Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeAttachmentService defines attachment methdods
|
||||||
|
type VolumeAttachmentService interface {
|
||||||
|
Get(string) (*VolumeAttachment, *Response, error)
|
||||||
|
Create(string, string) (*VolumeAttachment, *Response, error)
|
||||||
|
Delete(string) (*Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume represents a volume
|
// Volume represents a volume
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Size int `json:"size,omitempty"`
|
Size int `json:"size,omitempty"`
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
Locked bool `json:"locked,omitempty"`
|
Locked bool `json:"locked,omitempty"`
|
||||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||||
Created string `json:"created_at,omitempty"`
|
Created string `json:"created_at,omitempty"`
|
||||||
Updated string `json:"updated_at,omitempty"`
|
Updated string `json:"updated_at,omitempty"`
|
||||||
Href string `json:"href,omitempty"`
|
Href string `json:"href,omitempty"`
|
||||||
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
|
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
|
||||||
Attachments []*Attachment `json:"attachments,omitempty"`
|
Attachments []*VolumeAttachment `json:"attachments,omitempty"`
|
||||||
Plan *Plan `json:"plan,omitempty"`
|
Plan *Plan `json:"plan,omitempty"`
|
||||||
Facility *Facility `json:"facility,omitempty"`
|
Facility *Facility `json:"facility,omitempty"`
|
||||||
Project *Project `json:"project,omitempty"`
|
Project *Project `json:"project,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotPolicy used to execute actions on volume
|
// SnapshotPolicy used to execute actions on volume
|
||||||
@ -39,12 +49,6 @@ type SnapshotPolicy struct {
|
|||||||
SnapshotCount int `json:"snapshot_count,omitempty"`
|
SnapshotCount int `json:"snapshot_count,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachment used to execute actions on volume
|
|
||||||
type Attachment struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Href string `json:"href"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Volume) String() string {
|
func (v Volume) String() string {
|
||||||
return Stringify(v)
|
return Stringify(v)
|
||||||
}
|
}
|
||||||
@ -71,10 +75,23 @@ type VolumeUpdateRequest struct {
|
|||||||
Plan string `json:"plan,omitempty"`
|
Plan string `json:"plan,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VolumeAttachment is a type from Packet API
|
||||||
|
type VolumeAttachment struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Volume Volume `json:"volume"`
|
||||||
|
Device Device `json:"device"`
|
||||||
|
}
|
||||||
|
|
||||||
func (v VolumeUpdateRequest) String() string {
|
func (v VolumeUpdateRequest) String() string {
|
||||||
return Stringify(v)
|
return Stringify(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VolumeAttachmentServiceOp implements VolumeService
|
||||||
|
type VolumeAttachmentServiceOp struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
// VolumeServiceOp implements VolumeService
|
// VolumeServiceOp implements VolumeService
|
||||||
type VolumeServiceOp struct {
|
type VolumeServiceOp struct {
|
||||||
client *Client
|
client *Client
|
||||||
@ -83,13 +100,9 @@ type VolumeServiceOp struct {
|
|||||||
// Get returns a volume by id
|
// Get returns a volume by id
|
||||||
func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
|
func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s?include=facility,snapshot_policies,attachments.device", volumeBasePath, volumeID)
|
path := fmt.Sprintf("%s/%s?include=facility,snapshot_policies,attachments.device", volumeBasePath, volumeID)
|
||||||
req, err := v.client.NewRequest("GET", path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
volume := new(Volume)
|
volume := new(Volume)
|
||||||
resp, err := v.client.Do(req, volume)
|
|
||||||
|
resp, err := v.client.DoRequest("GET", path, nil, volume)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -100,13 +113,9 @@ func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
|
|||||||
// Update updates a volume
|
// Update updates a volume
|
||||||
func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *Response, error) {
|
func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", volumeBasePath, updateRequest.ID)
|
path := fmt.Sprintf("%s/%s", volumeBasePath, updateRequest.ID)
|
||||||
req, err := v.client.NewRequest("PATCH", path, updateRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
volume := new(Volume)
|
volume := new(Volume)
|
||||||
resp, err := v.client.Do(req, volume)
|
|
||||||
|
resp, err := v.client.DoRequest("PATCH", path, updateRequest, volume)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@ -118,29 +127,55 @@ func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *
|
|||||||
func (v *VolumeServiceOp) Delete(volumeID string) (*Response, error) {
|
func (v *VolumeServiceOp) Delete(volumeID string) (*Response, error) {
|
||||||
path := fmt.Sprintf("%s/%s", volumeBasePath, volumeID)
|
path := fmt.Sprintf("%s/%s", volumeBasePath, volumeID)
|
||||||
|
|
||||||
req, err := v.client.NewRequest("DELETE", path, nil)
|
return v.client.DoRequest("DELETE", path, nil, nil)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := v.client.Do(req, nil)
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new volume for a project
|
// Create creates a new volume for a project
|
||||||
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest) (*Volume, *Response, error) {
|
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest, projectID string) (*Volume, *Response, error) {
|
||||||
url := fmt.Sprintf("%s/%s%s", projectBasePath, createRequest.ProjectID, volumeBasePath)
|
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
|
||||||
req, err := v.client.NewRequest("POST", url, createRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
volume := new(Volume)
|
volume := new(Volume)
|
||||||
resp, err := v.client.Do(req, volume)
|
|
||||||
|
resp, err := v.client.DoRequest("POST", url, createRequest, volume)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return volume, resp, err
|
return volume, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attachments
|
||||||
|
|
||||||
|
// Create Attachment, i.e. attach volume to a device
|
||||||
|
func (v *VolumeAttachmentServiceOp) Create(volumeID, deviceID string) (*VolumeAttachment, *Response, error) {
|
||||||
|
url := fmt.Sprintf("%s/%s%s", volumeBasePath, volumeID, attachmentsBasePath)
|
||||||
|
volAttachParam := map[string]string{
|
||||||
|
"device_id": deviceID,
|
||||||
|
}
|
||||||
|
volumeAttachment := new(VolumeAttachment)
|
||||||
|
|
||||||
|
resp, err := v.client.DoRequest("POST", url, volAttachParam, volumeAttachment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return volumeAttachment, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets attachment by id
|
||||||
|
func (v *VolumeAttachmentServiceOp) Get(attachmentID string) (*VolumeAttachment, *Response, error) {
|
||||||
|
path := fmt.Sprintf("%s%s/%s", volumeBasePath, attachmentsBasePath, attachmentID)
|
||||||
|
volumeAttachment := new(VolumeAttachment)
|
||||||
|
|
||||||
|
resp, err := v.client.DoRequest("GET", path, nil, volumeAttachment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumeAttachment, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes attachment by id
|
||||||
|
func (v *VolumeAttachmentServiceOp) Delete(attachmentID string) (*Response, error) {
|
||||||
|
path := fmt.Sprintf("%s%s/%s", volumeBasePath, attachmentsBasePath, attachmentID)
|
||||||
|
|
||||||
|
return v.client.DoRequest("DELETE", path, nil, nil)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user