1
0
mirror of https://github.com/rancher/os.git synced 2025-06-27 15:26:50 +00:00

Update Godeps

This commit is contained in:
Darren Shepherd 2015-02-17 17:02:41 -07:00
parent fe5cef0ba6
commit c4fc978b47
7 changed files with 621 additions and 0 deletions

5
Godeps/Godeps.json generated
View File

@ -126,6 +126,11 @@
"ImportPath": "github.com/docker/libtrust",
"Rev": "c54fbb67c1f1e68d7d6f8d2ad7c9360404616a41"
},
{
"ImportPath": "github.com/docker/machine/utils",
"Comment": "v0.1.0-rc3-18-gd674e87",
"Rev": "d674e87813ffc10048f55d884396be1af327705e"
},
{
"ImportPath": "github.com/flynn/go-shlex",
"Rev": "70644ac2a65dbf1691ce00c209d185163a14edc6"

View File

@ -0,0 +1,110 @@
package utils
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"path/filepath"
"time"
)
const (
timeout = time.Second * 5
)
func defaultTimeout(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, timeout)
}
func getClient() *http.Client {
transport := http.Transport{
Dial: defaultTimeout,
}
client := http.Client{
Transport: &transport,
}
return &client
}
type B2dUtils struct {
githubApiBaseUrl string
githubBaseUrl string
}
func NewB2dUtils(githubApiBaseUrl, githubBaseUrl string) *B2dUtils {
defaultBaseApiUrl := "https://api.github.com"
defaultBaseUrl := "https://github.com"
if githubApiBaseUrl == "" {
githubApiBaseUrl = defaultBaseApiUrl
}
if githubBaseUrl == "" {
githubBaseUrl = defaultBaseUrl
}
return &B2dUtils{
githubApiBaseUrl: githubApiBaseUrl,
githubBaseUrl: githubBaseUrl,
}
}
// Get the latest boot2docker release tag name (e.g. "v0.6.0").
// FIXME: find or create some other way to get the "latest release" of boot2docker since the GitHub API has a pretty low rate limit on API requests
func (b *B2dUtils) GetLatestBoot2DockerReleaseURL() (string, error) {
client := getClient()
apiUrl := fmt.Sprintf("%s/repos/boot2docker/boot2docker/releases", b.githubApiBaseUrl)
rsp, err := client.Get(apiUrl)
if err != nil {
return "", err
}
defer rsp.Body.Close()
var t []struct {
TagName string `json:"tag_name"`
}
if err := json.NewDecoder(rsp.Body).Decode(&t); err != nil {
return "", err
}
if len(t) == 0 {
return "", fmt.Errorf("no releases found")
}
tag := t[0].TagName
isoUrl := fmt.Sprintf("%s/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", b.githubBaseUrl, tag)
return isoUrl, nil
}
// Download boot2docker ISO image for the given tag and save it at dest.
func (b *B2dUtils) DownloadISO(dir, file, url string) error {
client := getClient()
rsp, err := client.Get(url)
if err != nil {
return err
}
defer rsp.Body.Close()
// Download to a temp file first then rename it to avoid partial download.
f, err := ioutil.TempFile(dir, file+".tmp")
if err != nil {
return err
}
defer os.Remove(f.Name())
if _, err := io.Copy(f, rsp.Body); err != nil {
// TODO: display download progress?
return err
}
if err := f.Close(); err != nil {
return err
}
if err := os.Rename(f.Name(), filepath.Join(dir, file)); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,58 @@
package utils
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
)
func TestGetLatestBoot2DockerReleaseUrl(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
respText := `[{"tag_name": "0.1"}]`
w.Write([]byte(respText))
}))
defer ts.Close()
b := NewB2dUtils(ts.URL, ts.URL)
isoUrl, err := b.GetLatestBoot2DockerReleaseURL()
if err != nil {
t.Fatal(err)
}
expectedUrl := fmt.Sprintf("%s/boot2docker/boot2docker/releases/download/0.1/boot2docker.iso", ts.URL)
if isoUrl != expectedUrl {
t.Fatalf("expected url %s; received %s", isoUrl)
}
}
func TestDownloadIso(t *testing.T) {
testData := "test-download"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(testData))
}))
defer ts.Close()
filename := "test"
tmpDir, err := ioutil.TempDir("", "machine-test-")
if err != nil {
t.Fatal(err)
}
b := NewB2dUtils(ts.URL, ts.URL)
if err := b.DownloadISO(tmpDir, filename, ts.URL); err != nil {
t.Fatal(err)
}
data, err := ioutil.ReadFile(filepath.Join(tmpDir, filename))
if err != nil {
t.Fatal(err)
}
if string(data) != testData {
t.Fatalf("expected data \"%s\"; received \"%s\"", testData, string(data))
}
}

View File

@ -0,0 +1,150 @@
package utils
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"time"
)
func newCertificate(org string) (*x509.Certificate, error) {
now := time.Now()
// need to set notBefore slightly in the past to account for time
// skew in the VMs otherwise the certs sometimes are not yet valid
notBefore := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-5, 0, 0, time.Local)
notAfter := notBefore.Add(time.Hour * 24 * 1080)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, err
}
return &x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{org},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
BasicConstraintsValid: true,
}, nil
}
// GenerateCACertificate generates a new certificate authority from the specified org
// and bit size and stores the resulting certificate and key file
// in the arguments.
func GenerateCACertificate(certFile, keyFile, org string, bits int) error {
template, err := newCertificate(org)
if err != nil {
return err
}
template.IsCA = true
template.KeyUsage |= x509.KeyUsageCertSign
priv, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
if err != nil {
return err
}
certOut, err := os.Create(certFile)
if err != nil {
return err
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
return nil
}
// GenerateCert generates a new certificate signed using the provided
// certificate authority files and stores the result in the certificate
// file and key provided. The provided host names are set to the
// appropriate certificate fields.
func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile, org string, bits int) error {
template, err := newCertificate(org)
if err != nil {
return err
}
// client
if len(hosts) == 1 && hosts[0] == "" {
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}
template.KeyUsage = x509.KeyUsageDigitalSignature
} else { // server
for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, h)
}
}
}
tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile)
if err != nil {
return err
}
priv, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
if err != nil {
return err
}
derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey)
if err != nil {
return err
}
certOut, err := os.Create(certFile)
if err != nil {
return err
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
return nil
}

View File

@ -0,0 +1,76 @@
package utils
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestGenerateCACertificate(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "machine-test-")
if err != nil {
t.Fatal(err)
}
os.Setenv("MACHINE_DIR", tmpDir)
caCertPath := filepath.Join(tmpDir, "ca.pem")
caKeyPath := filepath.Join(tmpDir, "key.pem")
testOrg := "test-org"
bits := 2048
if err := GenerateCACertificate(caCertPath, caKeyPath, testOrg, bits); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(caCertPath); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(caKeyPath); err != nil {
t.Fatal(err)
}
os.Setenv("MACHINE_DIR", "")
// cleanup
_ = os.RemoveAll(tmpDir)
}
func TestGenerateCert(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "machine-test-")
if err != nil {
t.Fatal(err)
}
os.Setenv("MACHINE_DIR", tmpDir)
caCertPath := filepath.Join(tmpDir, "ca.pem")
caKeyPath := filepath.Join(tmpDir, "key.pem")
certPath := filepath.Join(tmpDir, "cert.pem")
keyPath := filepath.Join(tmpDir, "cert-key.pem")
testOrg := "test-org"
bits := 2048
if err := GenerateCACertificate(caCertPath, caKeyPath, testOrg, bits); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(caCertPath); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(caKeyPath); err != nil {
t.Fatal(err)
}
os.Setenv("MACHINE_DIR", "")
if err := GenerateCert([]string{}, certPath, keyPath, caCertPath, caKeyPath, testOrg, bits); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(certPath); err != nil {
t.Fatalf("certificate not created at %s", certPath)
}
if _, err := os.Stat(keyPath); err != nil {
t.Fatalf("key not created at %s", keyPath)
}
// cleanup
_ = os.RemoveAll(tmpDir)
}

View File

@ -0,0 +1,73 @@
package utils
import (
"io"
"os"
"path/filepath"
"runtime"
)
func GetHomeDir() string {
if runtime.GOOS == "windows" {
return os.Getenv("USERPROFILE")
}
return os.Getenv("HOME")
}
func GetBaseDir() string {
baseDir := os.Getenv("MACHINE_DIR")
if baseDir == "" {
baseDir = GetHomeDir()
}
return baseDir
}
func GetDockerDir() string {
return filepath.Join(GetBaseDir(), ".docker")
}
func GetMachineDir() string {
return filepath.Join(GetDockerDir(), "machines")
}
func GetMachineClientCertDir() string {
return filepath.Join(GetMachineDir(), ".client")
}
func GetUsername() string {
u := "unknown"
osUser := ""
switch runtime.GOOS {
case "darwin", "linux":
osUser = os.Getenv("USER")
case "windows":
osUser = os.Getenv("USERNAME")
}
if osUser != "" {
u = osUser
}
return u
}
func CopyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
if _, err = io.Copy(out, in); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,149 @@
package utils
import (
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestGetBaseDir(t *testing.T) {
// reset any override env var
homeDir := GetHomeDir()
baseDir := GetBaseDir()
if strings.Index(homeDir, baseDir) != 0 {
t.Fatalf("expected base dir with prefix %s; received %s", homeDir, baseDir)
}
}
func TestGetCustomBaseDir(t *testing.T) {
root := "/tmp"
os.Setenv("MACHINE_DIR", root)
baseDir := GetBaseDir()
if strings.Index(root, baseDir) != 0 {
t.Fatalf("expected base dir with prefix %s; received %s", root, baseDir)
}
os.Setenv("MACHINE_DIR", "")
}
func TestGetDockerDir(t *testing.T) {
root := "/tmp"
os.Setenv("MACHINE_DIR", root)
dockerDir := GetDockerDir()
if strings.Index(dockerDir, root) != 0 {
t.Fatalf("expected docker dir with prefix %s; received %s", root, dockerDir)
}
path, filename := path.Split(dockerDir)
if strings.Index(path, root) != 0 {
t.Fatalf("expected base path of %s; received %s", root, path)
}
if filename != ".docker" {
t.Fatalf("expected docker dir \".docker\"; received %s", filename)
}
os.Setenv("MACHINE_DIR", "")
}
func TestGetMachineDir(t *testing.T) {
root := "/tmp"
os.Setenv("MACHINE_DIR", root)
machineDir := GetMachineDir()
if strings.Index(machineDir, root) != 0 {
t.Fatalf("expected machine dir with prefix %s; received %s", root, machineDir)
}
path, filename := path.Split(machineDir)
if strings.Index(path, root) != 0 {
t.Fatalf("expected base path of %s; received %s", root, path)
}
if filename != "machines" {
t.Fatalf("expected machine dir \"machines\"; received %s", filename)
}
os.Setenv("MACHINE_DIR", "")
}
func TestGetMachineClientCertDir(t *testing.T) {
root := "/tmp"
os.Setenv("MACHINE_DIR", root)
clientDir := GetMachineClientCertDir()
if strings.Index(clientDir, root) != 0 {
t.Fatalf("expected machine client cert dir with prefix %s; received %s", root, clientDir)
}
path, filename := path.Split(clientDir)
if strings.Index(path, root) != 0 {
t.Fatalf("expected base path of %s; received %s", root, path)
}
if filename != ".client" {
t.Fatalf("expected machine client dir \".client\"; received %s", filename)
}
os.Setenv("MACHINE_DIR", "")
}
func TestCopyFile(t *testing.T) {
testStr := "test-machine"
srcFile, err := ioutil.TempFile("", "machine-test-")
if err != nil {
t.Fatal(err)
}
srcFi, err := srcFile.Stat()
if err != nil {
t.Fatal(err)
}
srcFile.Write([]byte(testStr))
srcFile.Close()
srcFilePath := filepath.Join(os.TempDir(), srcFi.Name())
destFile, err := ioutil.TempFile("", "machine-copy-test-")
if err != nil {
t.Fatal(err)
}
destFi, err := destFile.Stat()
if err != nil {
t.Fatal(err)
}
destFile.Close()
destFilePath := filepath.Join(os.TempDir(), destFi.Name())
if err := CopyFile(srcFilePath, destFilePath); err != nil {
t.Fatal(err)
}
data, err := ioutil.ReadFile(destFilePath)
if err != nil {
t.Fatal(err)
}
if string(data) != testStr {
t.Fatalf("expected data \"%s\"; received \"%\"", testStr, string(data))
}
}
func TestGetUsername(t *testing.T) {
currentUser := "unknown"
switch runtime.GOOS {
case "darwin", "linux":
currentUser = os.Getenv("USER")
case "windows":
currentUser = os.Getenv("USERNAME")
}
username := GetUsername()
if username != currentUser {
t.Fatalf("expected username %s; received %s", currentUser, username)
}
}