Merge pull request #1146 from aaron-prindle/transfer-refactor

Refactored file transfer code to better abstract ssh
pull/1177/head
Aaron Prindle 2017-02-23 14:07:01 -08:00 committed by GitHub
commit f247803779
2 changed files with 59 additions and 80 deletions

View File

@ -17,11 +17,9 @@ limitations under the License.
package cluster
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
@ -147,11 +145,11 @@ func GetHostStatus(api libmachine.API) (string, error) {
// GetLocalkubeStatus gets the status of localkube from the host VM.
func GetLocalkubeStatus(api libmachine.API) (string, error) {
host, err := CheckIfApiExistsAndLoad(api)
h, err := CheckIfApiExistsAndLoad(api)
if err != nil {
return "", err
}
s, err := host.RunSSHCommand(localkubeStatusCommand)
s, err := h.RunSSHCommand(localkubeStatusCommand)
if err != nil {
return "", err
}
@ -185,26 +183,27 @@ func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error {
}
func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
client, err := sshutil.NewSSHClient(d)
if err != nil {
return errors.Wrap(err, "Error creating new ssh client")
}
copyableFiles := []assets.CopyableFile{}
var localkubeFile assets.CopyableFile
var err error
// transfer localkube from cache/asset to vm
//add url/file/bundled localkube to file list
if localkubeURIWasSpecified(config) {
lCacher := localkubeCacher{config}
if err = lCacher.updateLocalkubeFromURI(client); err != nil {
localkubeFile, err = lCacher.fetchLocalkubeFromURI()
if err != nil {
return errors.Wrap(err, "Error updating localkube from uri")
}
} else {
if err = updateLocalkubeFromAsset(client); err != nil {
return errors.Wrap(err, "Error updating localkube from asset")
}
localkubeFile = assets.NewMemoryAsset("out/localkube", "/usr/local/bin", "localkube", "0777")
}
fileAssets := []assets.CopyableFile{}
assets.AddMinikubeAddonsDirToAssets(&fileAssets)
// merge files to copy
var copyableFiles []assets.CopyableFile
copyableFiles = append(copyableFiles, localkubeFile)
// add addons to file list
// custom addons
assets.AddMinikubeAddonsDirToAssets(&copyableFiles)
// bundled addons
for _, addonBundle := range assets.Addons {
if isEnabled, err := addonBundle.IsEnabled(); err == nil && isEnabled {
for _, addon := range addonBundle.Assets {
@ -214,10 +213,15 @@ func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
return err
}
}
copyableFiles = append(copyableFiles, fileAssets...)
// transfer files to vm
for _, copyableFile := range copyableFiles {
if err := sshutil.TransferFile(copyableFile, client); err != nil {
// transfer files to vm via SSH
client, err := sshutil.NewSSHClient(d)
if err != nil {
return errors.Wrap(err, "Error creating new ssh client")
}
for _, f := range copyableFiles {
if err := sshutil.TransferFile(f, client); err != nil {
return err
}
}
@ -247,23 +251,30 @@ func SetupCerts(d drivers.Driver) error {
return errors.Wrap(err, "Error generating certs")
}
copyableFiles := []assets.CopyableFile{}
for _, cert := range certs {
p := filepath.Join(localPath, cert)
perms := "0644"
if strings.HasSuffix(cert, ".key") {
perms = "0600"
}
certFile, err := assets.NewFileAsset(p, util.DefaultCertPath, cert, perms)
if err != nil {
return err
}
copyableFiles = append(copyableFiles, certFile)
}
// transfer files to vm via SSH
client, err := sshutil.NewSSHClient(d)
if err != nil {
return errors.Wrap(err, "Error creating new ssh client")
}
for _, cert := range certs {
p := filepath.Join(localPath, cert)
data, err := ioutil.ReadFile(p)
if err != nil {
return errors.Wrapf(err, "Error reading file: %s", p)
}
perms := "0644"
if strings.HasSuffix(cert, ".key") {
perms = "0600"
}
if err := sshutil.Transfer(bytes.NewReader(data), len(data), util.DefaultCertPath, cert, perms, client); err != nil {
return errors.Wrapf(err, "Error transferring data: %s", string(data))
for _, f := range copyableFiles {
if err := sshutil.TransferFile(f, client); err != nil {
return err
}
}
return nil
@ -361,11 +372,11 @@ func GetHostDockerEnv(api libmachine.API) (map[string]string, error) {
// GetHostLogs gets the localkube logs of the host VM.
func GetHostLogs(api libmachine.API) (string, error) {
host, err := CheckIfApiExistsAndLoad(api)
h, err := CheckIfApiExistsAndLoad(api)
if err != nil {
return "", errors.Wrap(err, "Error checking that api exists and loading it")
}
s, err := host.RunSSHCommand(logsCommand)
s, err := h.RunSSHCommand(logsCommand)
if err != nil {
return "", err
}

View File

@ -17,9 +17,7 @@ limitations under the License.
package cluster
import (
"bytes"
"fmt"
"io/ioutil"
"net/url"
"os"
"path/filepath"
@ -27,26 +25,12 @@ import (
download "github.com/jimmidyson/go-download"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/sshutil"
"k8s.io/minikube/pkg/util"
)
func updateLocalkubeFromAsset(client *ssh.Client) error {
contents, err := assets.Asset("out/localkube")
if err != nil {
return errors.Wrap(err, "Error loading asset out/localkube")
}
if err := sshutil.Transfer(bytes.NewReader(contents), len(contents), "/usr/local/bin",
"localkube", "0777", client); err != nil {
return errors.Wrap(err, "Error transferring localkube via ssh")
}
return nil
}
// localkubeCacher is a struct with methods designed for caching localkube
type localkubeCacher struct {
k8sConf KubernetesConfig
@ -82,52 +66,36 @@ func (l *localkubeCacher) downloadAndCacheLocalkube() error {
return download.ToFile(url, l.getLocalkubeCacheFilepath(), opts)
}
func (l *localkubeCacher) updateLocalkubeFromURI(client *ssh.Client) error {
func (l *localkubeCacher) fetchLocalkubeFromURI() (assets.CopyableFile, error) {
urlObj, err := url.Parse(l.k8sConf.KubernetesVersion)
if err != nil {
return errors.Wrap(err, "Error parsing --kubernetes-version url")
return nil, errors.Wrap(err, "Error parsing --kubernetes-version url")
}
if urlObj.Scheme == fileScheme {
return l.updateLocalkubeFromFile(client)
return l.genLocalkubeFileFromFile()
}
return l.updateLocalkubeFromURL(client)
return l.genLocalkubeFileFromURL()
}
func (l *localkubeCacher) updateLocalkubeFromURL(client *ssh.Client) error {
func (l *localkubeCacher) genLocalkubeFileFromURL() (assets.CopyableFile, error) {
if !l.isLocalkubeCached() {
if err := l.downloadAndCacheLocalkube(); err != nil {
return errors.Wrap(err, "Error attempting to download and cache localkube")
return nil, errors.Wrap(err, "Error attempting to download and cache localkube")
}
}
if err := l.transferCachedLocalkubeToVM(client); err != nil {
return errors.Wrap(err, "Error transferring cached localkube to VM")
}
return nil
}
func (l *localkubeCacher) transferCachedLocalkubeToVM(client *ssh.Client) error {
contents, err := ioutil.ReadFile(l.getLocalkubeCacheFilepath())
localkubeFile, err := assets.NewFileAsset(l.getLocalkubeCacheFilepath(), "/usr/local/bin", "localkube", "0777")
if err != nil {
return errors.Wrap(err, "Error reading file: localkube cache filepath")
return nil, errors.Wrap(err, "Error creating localkube asset from url")
}
if err = sshutil.Transfer(bytes.NewReader(contents), len(contents), "/usr/local/bin",
"localkube", "0777", client); err != nil {
return errors.Wrap(err, "Error transferring cached localkube to VM via ssh")
}
return nil
return localkubeFile, nil
}
func (l *localkubeCacher) updateLocalkubeFromFile(client *ssh.Client) error {
func (l *localkubeCacher) genLocalkubeFileFromFile() (assets.CopyableFile, error) {
path := strings.TrimPrefix(l.k8sConf.KubernetesVersion, "file://")
path = filepath.FromSlash(path)
contents, err := ioutil.ReadFile(path)
localkubeFile, err := assets.NewFileAsset(path, "/usr/local/bin", "localkube", "0777")
if err != nil {
return errors.Wrapf(err, "Error reading localkube file at %s", path)
return nil, errors.Wrap(err, "Error creating localkube asset from file")
}
if err := sshutil.Transfer(bytes.NewReader(contents), len(contents), "/usr/local/bin",
"localkube", "0777", client); err != nil {
return errors.Wrapf(err, "Error transferring specified localkube file at %s to VM via ssh", path)
}
return nil
return localkubeFile, nil
}