mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 18:11:35 +00:00
commit
cd1a472678
@ -40,11 +40,17 @@ retry the boot typically fixes this.
|
||||
|
||||
## Boot
|
||||
|
||||
LinuxKit on Packet boots the `kernel+initrd` output from moby
|
||||
via
|
||||
[iPXE](https://help.packet.net/technical/infrastructure/custom-ipxe). iPXE
|
||||
booting requires a HTTP server on which you can store your images. The
|
||||
`-base-url` option specifies the URL to the HTTP server.
|
||||
LinuxKit on Packet boots the `kernel+initrd` output from moby via
|
||||
[iPXE](https://help.packet.net/technical/infrastructure/custom-ipxe)
|
||||
which also requires a iPXE script. iPXE booting requires a HTTP server
|
||||
on which you can store your images. The `-base-url` option specifies
|
||||
the URL to a HTTP server from which `<name>-kernel`,
|
||||
`<name>-initrd.img`, and `<name>-packet.ipxe` can be downloaded during
|
||||
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
|
||||
`-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
|
||||
```
|
||||
|
||||
To boot a `arm64` image for Type 2a machine (`-machine
|
||||
baremetal_2a`) you currently need build using `linuxkit build packet.yml packet.arm64.yml` and then un-compress both the kernel and
|
||||
the initrd before booting, e.g:
|
||||
To boot a `arm64` image for Type 2a machine (`-machine baremetal_2a`)
|
||||
you currently need to build using `linuxkit build packet.yml
|
||||
packet.arm64.yml` and then un-compress both the kernel and the initrd
|
||||
before booting, e.g:
|
||||
|
||||
```sh
|
||||
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
|
||||
```
|
||||
|
||||
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
|
||||
are attached to the console, you should see the BIOS and the boot
|
||||
messages.
|
||||
|
||||
|
||||
|
||||
## Console
|
||||
|
||||
By default, `linuxkit run packet ...` will connect to the
|
||||
|
@ -76,6 +76,7 @@ func main() {
|
||||
fmt.Printf(" pkg Package building\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(" serve Run a local http server (for iPXE booting)\n")
|
||||
fmt.Printf(" version Print version information\n")
|
||||
fmt.Printf(" help Print this message\n")
|
||||
fmt.Printf("\n")
|
||||
@ -124,6 +125,8 @@ func main() {
|
||||
push(args[1:])
|
||||
case "run":
|
||||
run(args[1:])
|
||||
case "serve":
|
||||
serve(args[1:])
|
||||
case "version":
|
||||
printVersion()
|
||||
case "help":
|
||||
|
@ -18,6 +18,7 @@ func pushUsage() {
|
||||
fmt.Printf(" azure\n")
|
||||
fmt.Printf(" gcp\n")
|
||||
fmt.Printf(" openstack\n")
|
||||
fmt.Printf(" packet\n")
|
||||
fmt.Printf(" vcenter\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("'options' are the backend specific options.\n")
|
||||
@ -41,6 +42,8 @@ func push(args []string) {
|
||||
pushGcp(args[1:])
|
||||
case "openstack":
|
||||
pushOpenstack(args[1:])
|
||||
case "packet":
|
||||
pushPacket(args[1:])
|
||||
case "vcenter":
|
||||
pushVCenter(args[1:])
|
||||
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")
|
||||
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+")")
|
||||
machineFlag := flags.String("machine", packetDefaultMachine, "Packet Machine Type (or "+packetMachineVar+")")
|
||||
apiKeyFlag := flags.String("api-key", "", "Packet API key (or "+packetAPIKeyVar+")")
|
||||
@ -80,7 +80,7 @@ func runPacket(args []string) {
|
||||
|
||||
url := getStringValue(packetBaseURL, *baseURLFlag, "")
|
||||
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, "")
|
||||
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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name)
|
||||
|
||||
// Serve files with a local http server
|
||||
var httpServer *http.Server
|
||||
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)}}
|
||||
httpServer = &http.Server{Addr: ":8080", Handler: http.FileServer(fs)}
|
||||
mux.Handle("/", http.FileServer(fs))
|
||||
httpServer = &http.Server{Addr: *serveFlag, Handler: mux}
|
||||
go func() {
|
||||
log.Debugf("Listening on http://%s\n", *serveFlag)
|
||||
if err := httpServer.ListenAndServe(); err != nil {
|
||||
@ -122,38 +134,22 @@ func runPacket(args []string) {
|
||||
}()
|
||||
}
|
||||
|
||||
// Build the iPXE script
|
||||
// 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.
|
||||
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
|
||||
// Make sure the URLs work
|
||||
ipxeURL := fmt.Sprintf("%s/%s", url, ipxeScriptName)
|
||||
initrdURL := fmt.Sprintf("%s/%s-initrd.img", url, name)
|
||||
kernelURL := fmt.Sprintf("%s/%s-kernel", url, name)
|
||||
validateHTTPURL(kernelURL)
|
||||
validateHTTPURL(initrdURL)
|
||||
log.Infof("Validating URL: %s", ipxeURL)
|
||||
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)
|
||||
tags := []string{}
|
||||
@ -172,11 +168,11 @@ func runPacket(args []string) {
|
||||
log.Debugf("%s\n", string(b))
|
||||
|
||||
req := packngo.DeviceUpdateRequest{
|
||||
HostName: hostname,
|
||||
UserData: userData,
|
||||
Locked: dev.Locked,
|
||||
Tags: dev.Tags,
|
||||
AlwaysPXE: *alwaysPXE,
|
||||
Hostname: hostname,
|
||||
Locked: dev.Locked,
|
||||
Tags: dev.Tags,
|
||||
IPXEScriptURL: ipxeURL,
|
||||
AlwaysPXE: *alwaysPXE,
|
||||
}
|
||||
dev, _, err = client.Devices.Update(*deviceFlag, &req)
|
||||
if err != nil {
|
||||
@ -188,15 +184,15 @@ func runPacket(args []string) {
|
||||
} else {
|
||||
// Create a new device
|
||||
req := packngo.DeviceCreateRequest{
|
||||
HostName: hostname,
|
||||
Plan: plan,
|
||||
Facility: facility,
|
||||
OS: osType,
|
||||
BillingCycle: billing,
|
||||
ProjectID: projectID,
|
||||
UserData: userData,
|
||||
Tags: tags,
|
||||
AlwaysPXE: *alwaysPXE,
|
||||
Hostname: hostname,
|
||||
Plan: plan,
|
||||
Facility: facility,
|
||||
OS: osType,
|
||||
BillingCycle: billing,
|
||||
ProjectID: projectID,
|
||||
Tags: tags,
|
||||
IPXEScriptURL: ipxeURL,
|
||||
AlwaysPXE: *alwaysPXE,
|
||||
}
|
||||
dev, _, err = client.Devices.Create(&req)
|
||||
if err != nil {
|
||||
@ -214,7 +210,7 @@ func runPacket(args []string) {
|
||||
sshHost := "sos." + dev.Facility.Code + ".packet.net"
|
||||
if *consoleFlag {
|
||||
// Connect to the serial console
|
||||
if err := sshSOS(dev.ID, sshHost); err != nil {
|
||||
if err := packetSOS(dev.ID, sshHost); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
@ -249,20 +245,58 @@ func runPacket(args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
// validateHTTPURL does a sanity check that a URL returns a 200 or 300 response
|
||||
func validateHTTPURL(url string) {
|
||||
log.Infof("Validating URL: %s", url)
|
||||
resp, err := http.Head(url)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
// Convert machine type to architecture
|
||||
func packetMachineToArch(machine string) string {
|
||||
switch machine {
|
||||
case "baremetal_2a", "baremetal_2a2":
|
||||
return "aarch64"
|
||||
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)
|
||||
|
||||
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/image-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/pmezard/go-difflib v1.0.0
|
||||
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/))
|
||||
|
||||
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
|
||||
type Device struct {
|
||||
ID string `json:"id"`
|
||||
Href string `json:"href,omitempty"`
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
Updated string `json:"updated_at,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Network []*IPAddress `json:"ip_addresses"`
|
||||
OS *OS `json:"operating_system,omitempty"`
|
||||
Plan *Plan `json:"plan,omitempty"`
|
||||
Facility *Facility `json:"facility,omitempty"`
|
||||
Project *Project `json:"project,omitempty"`
|
||||
ProvisionPer float32 `json:"provisioning_percentage,omitempty"`
|
||||
UserData string `json:"userdata",omitempty`
|
||||
IPXEScriptUrl string `json:"ipxe_script_url,omitempty"`
|
||||
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Href string `json:"href,omitempty"`
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
Updated string `json:"updated_at,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||
Storage map[string]interface{} `json:"storage,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Network []*IPAddressAssignment `json:"ip_addresses"`
|
||||
Volumes []*Volume `json:"volumes"`
|
||||
OS *OS `json:"operating_system,omitempty"`
|
||||
Plan *Plan `json:"plan,omitempty"`
|
||||
Facility *Facility `json:"facility,omitempty"`
|
||||
Project *Project `json:"project,omitempty"`
|
||||
ProvisionEvents []*ProvisionEvent `json:"provisioning_events,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 {
|
||||
@ -50,28 +69,33 @@ func (d Device) String() string {
|
||||
|
||||
// DeviceCreateRequest type used to create a Packet device
|
||||
type DeviceCreateRequest struct {
|
||||
HostName string `json:"hostname"`
|
||||
Plan string `json:"plan"`
|
||||
Facility string `json:"facility"`
|
||||
OS string `json:"operating_system"`
|
||||
BillingCycle string `json:"billing_cycle"`
|
||||
ProjectID string `json:"project_id"`
|
||||
UserData string `json:"userdata"`
|
||||
Tags []string `json:"tags"`
|
||||
IPXEScriptUrl string `json:"ipxe_script_url,omitempty"`
|
||||
PublicIPv4SubnetSize int `json:"public_ipv4_subnet_size,omitempty"`
|
||||
AlwaysPXE bool `json:"always_pxe,omitempty"`
|
||||
Hostname string `json:"hostname"`
|
||||
Plan string `json:"plan"`
|
||||
Facility string `json:"facility"`
|
||||
OS string `json:"operating_system"`
|
||||
BillingCycle string `json:"billing_cycle"`
|
||||
ProjectID string `json:"project_id"`
|
||||
UserData string `json:"userdata"`
|
||||
Storage string `json:"storage,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
IPXEScriptURL string `json:"ipxe_script_url,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
|
||||
type DeviceUpdateRequest struct {
|
||||
HostName string `json:"hostname"`
|
||||
Hostname string `json:"hostname"`
|
||||
Description string `json:"description"`
|
||||
UserData string `json:"userdata"`
|
||||
Locked bool `json:"locked"`
|
||||
Tags []string `json:"tags"`
|
||||
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 {
|
||||
@ -95,14 +119,9 @@ type DeviceServiceOp struct {
|
||||
// List returns devices on a project
|
||||
func (s *DeviceServiceOp) List(projectID string) ([]Device, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", path, nil, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -113,14 +132,9 @@ func (s *DeviceServiceOp) List(projectID string) ([]Device, *Response, error) {
|
||||
// Get returns a device by id
|
||||
func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, device)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", path, nil, device)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -131,14 +145,9 @@ func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
|
||||
// Create creates a new device
|
||||
func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, device)
|
||||
|
||||
resp, err := s.client.DoRequest("POST", path, createRequest, device)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -149,14 +158,9 @@ func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *
|
||||
// Update updates an existing device
|
||||
func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateRequest) (*Device, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, device)
|
||||
|
||||
resp, err := s.client.DoRequest("PUT", path, updateRequest, device)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -168,59 +172,31 @@ func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateReq
|
||||
func (s *DeviceServiceOp) Delete(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
|
||||
return resp, err
|
||||
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
// Reboot reboots on a device
|
||||
func (s *DeviceServiceOp) Reboot(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||
|
||||
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 resp, err
|
||||
return s.client.DoRequest("POST", path, action, nil)
|
||||
}
|
||||
|
||||
// PowerOff powers on a device
|
||||
func (s *DeviceServiceOp) PowerOff(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||
|
||||
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 resp, err
|
||||
return s.client.DoRequest("POST", path, action, nil)
|
||||
}
|
||||
|
||||
// PowerOn powers on a device
|
||||
func (s *DeviceServiceOp) PowerOn(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
|
||||
|
||||
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 resp, err
|
||||
return s.client.DoRequest("POST", path, action, nil)
|
||||
}
|
||||
|
||||
type lockDeviceType struct {
|
||||
@ -230,30 +206,15 @@ type lockDeviceType struct {
|
||||
// Lock sets a device to "locked"
|
||||
func (s *DeviceServiceOp) Lock(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||
|
||||
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"
|
||||
func (s *DeviceServiceOp) Unlock(deviceID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
|
||||
|
||||
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 resp, err
|
||||
return s.client.DoRequest("PATCH", path, action, nil)
|
||||
}
|
||||
|
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
|
||||
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)
|
||||
resp, err := s.client.Do(req, email)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", emailBasePath, nil, email)
|
||||
if err != nil {
|
||||
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
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", facilityBasePath, nil, root)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const ipBasePath = "/ips"
|
||||
|
||||
// IPService interface defines available IP methods
|
||||
type IPService interface {
|
||||
Assign(deviceID string, assignRequest *IPAddressAssignRequest) (*IPAddress, *Response, error)
|
||||
Unassign(ipAddressID string) (*Response, error)
|
||||
Get(ipAddressID string) (*IPAddress, *Response, error)
|
||||
// DeviceIPService handles assignment of addresses from reserved blocks to instances in a project.
|
||||
type DeviceIPService interface {
|
||||
Assign(deviceID string, assignRequest *AddressStruct) (*IPAddressAssignment, *Response, error)
|
||||
Unassign(assignmentID string) (*Response, error)
|
||||
Get(assignmentID string) (*IPAddressAssignment, *Response, error)
|
||||
}
|
||||
|
||||
// IPAddress represents a ip address
|
||||
type IPAddress struct {
|
||||
ID string `json:"id"`
|
||||
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"`
|
||||
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)
|
||||
// ProjectIPService handles reservation of IP address blocks for a project.
|
||||
type ProjectIPService interface {
|
||||
Get(reservationID string) (*IPAddressReservation, *Response, error)
|
||||
List(projectID string) ([]IPAddressReservation, *Response, error)
|
||||
Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error)
|
||||
Remove(ipReservationID string) (*Response, error)
|
||||
AvailableAddresses(ipReservationID string, r *AvailableRequest) ([]string, *Response, error)
|
||||
}
|
||||
|
||||
// IPReservationServiceOp implements the IPReservationService interface
|
||||
type IPReservationServiceOp struct {
|
||||
client *Client
|
||||
type ipAddressCommon struct {
|
||||
ID string `json:"id"`
|
||||
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 string `json:"type"`
|
||||
Quantity int `json:"quantity"`
|
||||
@ -112,95 +73,122 @@ type IPReservationRequest struct {
|
||||
Facility string `json:"facility"`
|
||||
}
|
||||
|
||||
// IPReservation represent an IP reservation for a single project
|
||||
type IPReservation struct {
|
||||
ID string `json:"id"`
|
||||
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"`
|
||||
// AddressStruct is a helper type for request/response with dict like {"address": ... }
|
||||
type AddressStruct struct {
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
type ipReservationRoot struct {
|
||||
IPReservations []IPReservation `json:"ip_addresses"`
|
||||
func deleteFromIP(client *Client, resourceID string) (*Response, error) {
|
||||
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.
|
||||
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)
|
||||
reservations := new(struct {
|
||||
Reservations []IPAddressReservation `json:"ip_addresses"`
|
||||
})
|
||||
|
||||
req, err := i.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
reservations := new(ipReservationRoot)
|
||||
resp, err := i.client.Do(req, reservations)
|
||||
resp, err := i.client.DoRequest("GET", path, nil, reservations)
|
||||
if err != nil {
|
||||
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
|
||||
func (i *IPReservationServiceOp) RequestMore(projectID string, ipReservationReq *IPReservationRequest) (*IPReservation, *Response, error) {
|
||||
// Request requests more IP space for a project in order to have additional IP addresses to assign to devices.
|
||||
func (i *ProjectIPServiceOp) Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
||||
ipr := new(IPAddressReservation)
|
||||
|
||||
req, err := i.client.NewRequest("POST", path, &ipReservationReq)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ip := new(IPReservation)
|
||||
resp, err := i.client.Do(req, ip)
|
||||
resp, err := i.client.DoRequest("POST", path, ipReservationReq, ipr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return ip, 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
|
||||
return ipr, resp, err
|
||||
}
|
||||
|
||||
// Remove removes an IP reservation from the project.
|
||||
func (i *IPReservationServiceOp) Remove(ipReservationID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", ipBasePath, ipReservationID)
|
||||
|
||||
req, err := i.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := i.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, err
|
||||
func (i *ProjectIPServiceOp) Remove(ipReservationID string) (*Response, error) {
|
||||
return deleteFromIP(i.client, ipReservationID)
|
||||
}
|
||||
|
||||
// AvailableAddresses lists addresses available from a reserved block
|
||||
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.DoRequest("GET", path, r, ar)
|
||||
if err != nil {
|
||||
return nil, 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
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", osBasePath, nil, root)
|
||||
if err != nil {
|
||||
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"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -18,6 +21,7 @@ const (
|
||||
baseURL = "https://api.packet.net/"
|
||||
userAgent = "packngo/" + libraryVersion
|
||||
mediaType = "application/json"
|
||||
debugEnvVar = "PACKNGO_DEBUG"
|
||||
|
||||
headerRateLimit = "X-RateLimit-Limit"
|
||||
headerRateRemaining = "X-RateLimit-Remaining"
|
||||
@ -42,6 +46,11 @@ type Response struct {
|
||||
Rate
|
||||
}
|
||||
|
||||
// Href is an API link
|
||||
type Href struct {
|
||||
Href string `json:"href"`
|
||||
}
|
||||
|
||||
func (r *Response) populateRate() {
|
||||
// parse the rate limit headers and populate Response.Rate
|
||||
if limit := r.Header.Get(headerRateLimit); limit != "" {
|
||||
@ -59,18 +68,20 @@ func (r *Response) populateRate() {
|
||||
|
||||
// ErrorResponse is the http response used on errrors
|
||||
type ErrorResponse struct {
|
||||
Response *http.Response
|
||||
Errors []string `json:"errors"`
|
||||
Response *http.Response
|
||||
Errors []string `json:"errors"`
|
||||
SingleError string `json:"error"`
|
||||
}
|
||||
|
||||
func (r *ErrorResponse) Error() string {
|
||||
return fmt.Sprintf("%v %v: %d %v",
|
||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(r.Errors, ", "))
|
||||
return fmt.Sprintf("%v %v: %d %v %v",
|
||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(r.Errors, ", "), r.SingleError)
|
||||
}
|
||||
|
||||
// Client is the base API Client
|
||||
type Client struct {
|
||||
client *http.Client
|
||||
debug bool
|
||||
|
||||
BaseURL *url.URL
|
||||
|
||||
@ -81,17 +92,19 @@ type Client struct {
|
||||
RateLimit Rate
|
||||
|
||||
// Packet Api Objects
|
||||
Plans PlanService
|
||||
Users UserService
|
||||
Emails EmailService
|
||||
SSHKeys SSHKeyService
|
||||
Devices DeviceService
|
||||
Projects ProjectService
|
||||
Facilities FacilityService
|
||||
OperatingSystems OSService
|
||||
Ips IPService
|
||||
IpReservations IPReservationService
|
||||
Volumes VolumeService
|
||||
Plans PlanService
|
||||
Users UserService
|
||||
Emails EmailService
|
||||
SSHKeys SSHKeyService
|
||||
Devices DeviceService
|
||||
Projects ProjectService
|
||||
Facilities FacilityService
|
||||
OperatingSystems OSService
|
||||
DeviceIPs DeviceIPService
|
||||
ProjectIPs ProjectIPService
|
||||
Volumes VolumeService
|
||||
VolumeAttachments VolumeAttachmentService
|
||||
SpotMarket SpotMarketService
|
||||
}
|
||||
|
||||
// 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.populateRate()
|
||||
if c.debug {
|
||||
o, _ := httputil.DumpResponse(response.Response, true)
|
||||
log.Printf("%s\n", string(o))
|
||||
}
|
||||
c.RateLimit = response.Rate
|
||||
|
||||
err = checkResponse(resp)
|
||||
@ -163,6 +180,19 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
||||
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
|
||||
// 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
|
||||
@ -171,6 +201,9 @@ func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Cl
|
||||
client, _ := NewClientWithBaseURL(consumerToken, apiKey, httpClient, baseURL)
|
||||
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) {
|
||||
if httpClient == nil {
|
||||
// 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.debug = os.Getenv(debugEnvVar) != ""
|
||||
c.Plans = &PlanServiceOp{client: c}
|
||||
c.Users = &UserServiceOp{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.Facilities = &FacilityServiceOp{client: c}
|
||||
c.OperatingSystems = &OSServiceOp{client: c}
|
||||
c.Ips = &IPServiceOp{client: c}
|
||||
c.IpReservations = &IPReservationServiceOp{client: c}
|
||||
c.DeviceIPs = &DeviceIPServiceOp{client: c}
|
||||
c.ProjectIPs = &ProjectIPServiceOp{client: c}
|
||||
c.Volumes = &VolumeServiceOp{client: c}
|
||||
c.VolumeAttachments = &VolumeAttachmentServiceOp{client: c}
|
||||
c.SpotMarket = &SpotMarketServiceOp{client: c}
|
||||
|
||||
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
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", planBasePath, nil, root)
|
||||
if err != nil {
|
||||
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)
|
||||
Update(*ProjectUpdateRequest) (*Project, *Response, error)
|
||||
Delete(string) (*Response, error)
|
||||
ListIPAddresses(string) ([]IPAddress, *Response, error)
|
||||
ListVolumes(string) ([]Volume, *Response, error)
|
||||
}
|
||||
|
||||
type ipsRoot struct {
|
||||
IPAddresses []IPAddress `json:"ip_addresses"`
|
||||
}
|
||||
|
||||
type volumesRoot struct {
|
||||
Volumes []Volume `json:"volumes"`
|
||||
}
|
||||
@ -69,31 +64,11 @@ type ProjectServiceOp struct {
|
||||
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
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", projectBasePath, nil, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -104,13 +79,9 @@ func (s *ProjectServiceOp) List() ([]Project, *Response, error) {
|
||||
// Get returns a project by id
|
||||
func (s *ProjectServiceOp) Get(projectID string) (*Project, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, project)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", path, nil, project)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -120,13 +91,9 @@ func (s *ProjectServiceOp) Get(projectID string) (*Project, *Response, error) {
|
||||
|
||||
// Create creates a new project
|
||||
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)
|
||||
resp, err := s.client.Do(req, project)
|
||||
|
||||
resp, err := s.client.DoRequest("POST", projectBasePath, createRequest, project)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -137,13 +104,9 @@ func (s *ProjectServiceOp) Create(createRequest *ProjectCreateRequest) (*Project
|
||||
// Update updates a project
|
||||
func (s *ProjectServiceOp) Update(updateRequest *ProjectUpdateRequest) (*Project, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, project)
|
||||
|
||||
resp, err := s.client.DoRequest("PATCH", path, updateRequest, project)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -155,26 +118,15 @@ func (s *ProjectServiceOp) Update(updateRequest *ProjectUpdateRequest) (*Project
|
||||
func (s *ProjectServiceOp) Delete(projectID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", projectBasePath, projectID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
|
||||
return resp, err
|
||||
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
// List returns Volumes for a project
|
||||
// ListVolumes returns Volumes for a project
|
||||
func (s *ProjectServiceOp) ListVolumes(projectID string) ([]Volume, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", url, nil, root)
|
||||
if err != nil {
|
||||
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"
|
||||
|
||||
const sshKeyBasePath = "/ssh-keys"
|
||||
const (
|
||||
sshKeyBasePath = "/ssh-keys"
|
||||
)
|
||||
|
||||
// SSHKeyService interface defines available device methods
|
||||
type SSHKeyService interface {
|
||||
List() ([]SSHKey, *Response, error)
|
||||
ProjectList(string) ([]SSHKey, *Response, error)
|
||||
Get(string) (*SSHKey, *Response, error)
|
||||
Create(*SSHKeyCreateRequest) (*SSHKey, *Response, error)
|
||||
Update(*SSHKeyUpdateRequest) (*SSHKey, *Response, error)
|
||||
@ -60,15 +63,10 @@ type SSHKeyServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// List returns a user's ssh keys
|
||||
func (s *SSHKeyServiceOp) List() ([]SSHKey, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", sshKeyBasePath, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (s *SSHKeyServiceOp) list(url string) ([]SSHKey, *Response, error) {
|
||||
root := new(sshKeyRoot)
|
||||
resp, err := s.client.Do(req, root)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", url, nil, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -76,17 +74,23 @@ func (s *SSHKeyServiceOp) List() ([]SSHKey, *Response, error) {
|
||||
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
|
||||
func (s *SSHKeyServiceOp) Get(sshKeyID string) (*SSHKey, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, sshKey)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", path, nil, sshKey)
|
||||
if err != nil {
|
||||
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) {
|
||||
path := sshKeyBasePath
|
||||
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)
|
||||
resp, err := s.client.Do(req, sshKey)
|
||||
|
||||
resp, err := s.client.DoRequest("POST", path, createRequest, sshKey)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -117,13 +117,9 @@ func (s *SSHKeyServiceOp) Create(createRequest *SSHKeyCreateRequest) (*SSHKey, *
|
||||
// Update updates an ssh key
|
||||
func (s *SSHKeyServiceOp) Update(updateRequest *SSHKeyUpdateRequest) (*SSHKey, *Response, error) {
|
||||
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)
|
||||
resp, err := s.client.Do(req, sshKey)
|
||||
|
||||
resp, err := s.client.DoRequest("PATCH", path, updateRequest, sshKey)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -135,12 +131,5 @@ func (s *SSHKeyServiceOp) Update(updateRequest *SSHKeyUpdateRequest) (*SSHKey, *
|
||||
func (s *SSHKeyServiceOp) Delete(sshKeyID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", sshKeyBasePath, sshKeyID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
|
||||
return resp, err
|
||||
return s.client.DoRequest("DELETE", path, nil, nil)
|
||||
}
|
||||
|
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"`
|
||||
Updated string `json:"updated_at,omitempty"`
|
||||
TimeZone string `json:"timezone,omitempty"`
|
||||
Emails []Email `json:"email,omitempty"`
|
||||
Emails []Email `json:"emails,omitempty"`
|
||||
PhoneNumber string `json:"phone_number,omitempty"`
|
||||
URL string `json:"href,omitempty"`
|
||||
}
|
||||
@ -38,13 +38,9 @@ type UserServiceOp struct {
|
||||
|
||||
// Get method gets a user by userID
|
||||
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)
|
||||
resp, err := s.client.Do(req, user)
|
||||
|
||||
resp, err := s.client.DoRequest("GET", userBasePath, nil, user)
|
||||
if err != nil {
|
||||
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()
|
||||
}
|
||||
|
||||
// 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
|
||||
func StreamToString(stream io.Reader) string {
|
||||
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"
|
||||
|
||||
const volumeBasePath = "/storage"
|
||||
const (
|
||||
volumeBasePath = "/storage"
|
||||
attachmentsBasePath = "/attachments"
|
||||
)
|
||||
|
||||
// VolumeService interface defines available Volume methods
|
||||
type VolumeService interface {
|
||||
Get(string) (*Volume, *Response, error)
|
||||
Update(*VolumeUpdateRequest) (*Volume, *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
|
||||
type Volume struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
Updated string `json:"updated_at,omitempty"`
|
||||
Href string `json:"href,omitempty"`
|
||||
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
|
||||
Attachments []*Attachment `json:"attachments,omitempty"`
|
||||
Plan *Plan `json:"plan,omitempty"`
|
||||
Facility *Facility `json:"facility,omitempty"`
|
||||
Project *Project `json:"project,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
BillingCycle string `json:"billing_cycle,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
Updated string `json:"updated_at,omitempty"`
|
||||
Href string `json:"href,omitempty"`
|
||||
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
|
||||
Attachments []*VolumeAttachment `json:"attachments,omitempty"`
|
||||
Plan *Plan `json:"plan,omitempty"`
|
||||
Facility *Facility `json:"facility,omitempty"`
|
||||
Project *Project `json:"project,omitempty"`
|
||||
}
|
||||
|
||||
// SnapshotPolicy used to execute actions on volume
|
||||
@ -39,12 +49,6 @@ type SnapshotPolicy struct {
|
||||
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 {
|
||||
return Stringify(v)
|
||||
}
|
||||
@ -71,10 +75,23 @@ type VolumeUpdateRequest struct {
|
||||
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 {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// VolumeAttachmentServiceOp implements VolumeService
|
||||
type VolumeAttachmentServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// VolumeServiceOp implements VolumeService
|
||||
type VolumeServiceOp struct {
|
||||
client *Client
|
||||
@ -83,13 +100,9 @@ type VolumeServiceOp struct {
|
||||
// Get returns a volume by id
|
||||
func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
|
||||
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)
|
||||
resp, err := v.client.Do(req, volume)
|
||||
|
||||
resp, err := v.client.DoRequest("GET", path, nil, volume)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -100,13 +113,9 @@ func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
|
||||
// Update updates a volume
|
||||
func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *Response, error) {
|
||||
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)
|
||||
resp, err := v.client.Do(req, volume)
|
||||
|
||||
resp, err := v.client.DoRequest("PATCH", path, updateRequest, volume)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
@ -118,29 +127,55 @@ func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *
|
||||
func (v *VolumeServiceOp) Delete(volumeID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", volumeBasePath, volumeID)
|
||||
|
||||
req, err := v.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := v.client.Do(req, nil)
|
||||
|
||||
return resp, err
|
||||
return v.client.DoRequest("DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
// Create creates a new volume for a project
|
||||
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest) (*Volume, *Response, error) {
|
||||
url := fmt.Sprintf("%s/%s%s", projectBasePath, createRequest.ProjectID, volumeBasePath)
|
||||
req, err := v.client.NewRequest("POST", url, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest, projectID string) (*Volume, *Response, error) {
|
||||
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
|
||||
volume := new(Volume)
|
||||
resp, err := v.client.Do(req, volume)
|
||||
|
||||
resp, err := v.client.DoRequest("POST", url, createRequest, volume)
|
||||
if err != nil {
|
||||
return nil, 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