starting work on file assets builder

This commit is contained in:
chrislovecnm 2017-07-22 21:29:03 -06:00
parent 07aa30cdae
commit ee17e6567c
24 changed files with 489 additions and 44 deletions

View File

@ -136,7 +136,7 @@ codegen: kops-gobindata
go install k8s.io/kops/upup/tools/generators/...
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/cloudup/awstasks
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/cloudup/gcetasks
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/dockertasks
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/assettasks
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/fitasks
.PHONY: protobuf

View File

@ -871,7 +871,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
return err
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
if err != nil {
return err

View File

@ -210,7 +210,7 @@ func RunEditCluster(f *util.Factory, cmd *cobra.Command, args []string, out io.W
return preservedFile(fmt.Errorf("error populating configuration: %v", err), file, out)
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(newCluster.Spec.Assets)
fullCluster, err := cloudup.PopulateClusterSpec(newCluster, assetBuilder)
if err != nil {
results = editResults{

View File

@ -167,7 +167,7 @@ func RunEditInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string, ou
return fmt.Errorf("error populating configuration: %v", err)
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
if err != nil {
return err

View File

@ -284,7 +284,7 @@ func (c *UpgradeClusterCmd) Run(args []string) error {
return fmt.Errorf("error populating configuration: %v", err)
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
if err != nil {
return err

View File

@ -95,6 +95,7 @@ k8s.io/kops/tests/integration/channel
k8s.io/kops/tests/integration/conversion
k8s.io/kops/upup/models
k8s.io/kops/upup/pkg/fi
k8s.io/kops/upup/pkg/fi/assettasks
k8s.io/kops/upup/pkg/fi/cloudup
k8s.io/kops/upup/pkg/fi/cloudup/awstasks
k8s.io/kops/upup/pkg/fi/cloudup/awsup
@ -106,7 +107,6 @@ k8s.io/kops/upup/pkg/fi/cloudup/gcetasks
k8s.io/kops/upup/pkg/fi/cloudup/terraform
k8s.io/kops/upup/pkg/fi/cloudup/vsphere
k8s.io/kops/upup/pkg/fi/cloudup/vspheretasks
k8s.io/kops/upup/pkg/fi/dockertasks
k8s.io/kops/upup/pkg/fi/fitasks
k8s.io/kops/upup/pkg/fi/k8sapi
k8s.io/kops/upup/pkg/fi/loader

View File

@ -19,9 +19,11 @@ package assets
import (
"bytes"
"fmt"
"net/url"
"os"
"strings"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/featureflag"
"k8s.io/kops/pkg/kubemanifest"
)
@ -32,10 +34,12 @@ var RewriteManifests = featureflag.New("RewriteManifests", featureflag.Bool(true
// AssetBuilder discovers and remaps assets
type AssetBuilder struct {
Assets []*Asset
ContainerAssets []*ContainerAsset
FileAssets []*FileAsset
AssetsLocation *kops.Assets
}
type Asset struct {
type ContainerAsset struct {
// DockerImage will be the name of the docker image we should run, if this is a docker image
DockerImage string
@ -43,8 +47,18 @@ type Asset struct {
CanonicalLocation string
}
func NewAssetBuilder() *AssetBuilder {
return &AssetBuilder{}
type FileAsset struct {
// File will be the name of the file we should use
File string
// CanonicalLocation will be the source location of the file, if we should copy it to the actual location
CanonicalLocation string
}
func NewAssetBuilder(assets *kops.Assets) *AssetBuilder {
return &AssetBuilder{
AssetsLocation: assets,
}
}
// RemapManifest transforms a kubernetes manifest.
@ -79,7 +93,7 @@ func (a *AssetBuilder) RemapManifest(data []byte) ([]byte, error) {
}
func (a *AssetBuilder) RemapImage(image string) (string, error) {
asset := &Asset{}
asset := &ContainerAsset{}
asset.DockerImage = image
@ -113,7 +127,33 @@ func (a *AssetBuilder) RemapImage(image string) (string, error) {
image = asset.DockerImage
}
a.Assets = append(a.Assets, asset)
a.ContainerAssets = append(a.ContainerAssets, asset)
return image, nil
}
// RemapFile sets a new url location for the file, if a AssetsLocation is defined.
func (a AssetBuilder) RemapFile(file string) (string, error) {
if file == "" {
return "", fmt.Errorf("unable to remap an empty string")
}
fileAsset := &FileAsset{
File: file,
CanonicalLocation: file,
}
if a.AssetsLocation != nil && a.AssetsLocation.FileRepository != nil {
fileURL, err := url.Parse(file)
if err != nil {
return "", fmt.Errorf("unable to parse file url %q: %v", file, err)
}
fileRepo := strings.TrimSuffix(*a.AssetsLocation.FileRepository, "/")
fileAsset.File = fileRepo + fileURL.Path
}
a.FileAssets = append(a.FileAssets, fileAsset)
return fileAsset.File, nil
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package assets
import (
"k8s.io/kops/pkg/apis/kops"
"testing"
)
func TestRemap_File(t *testing.T) {
grid := []struct {
testFile string
expected string
asset *FileAsset
kopsAssets *kops.Assets
}{
{
// FIXME - need https://s3.amazonaws.com/k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubelet
"https://gcr.io/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubelet",
"s3://k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubelet",
&FileAsset{
File: "s3://k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubelet",
CanonicalLocation: "https://gcr.io/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubelet",
},
&kops.Assets{
FileRepository: s("s3://k8s-for-greeks-kops"),
},
},
}
for _, g := range grid {
builder := NewAssetBuilder(g.kopsAssets)
actual, err := builder.RemapFile(g.testFile)
if err != nil {
t.Errorf("err occurred: %v", err)
}
if actual != g.expected {
t.Errorf("results did not match. actual=%q expected=%q", actual, g.expected)
}
}
}
func s(s string) *string {
return &s
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package dockertasks
package assettasks
import (
"fmt"
@ -30,6 +30,7 @@ type CopyDockerImage struct {
Name *string
SourceImage *string
TargetImage *string
Lifecycle *fi.Lifecycle
}
var _ fi.CompareWithID = &CopyDockerImage{}

View File

@ -16,7 +16,7 @@ limitations under the License.
// Code generated by ""fitask" -type=CopyDockerImage"; DO NOT EDIT
package dockertasks
package assettasks
import (
"encoding/json"
@ -45,6 +45,13 @@ func (o *CopyDockerImage) UnmarshalJSON(data []byte) error {
return nil
}
var _ fi.HasLifecycle = &CopyDockerImage{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *CopyDockerImage) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
var _ fi.HasName = &CopyDockerImage{}
// GetName returns the Name of the object, implementing fi.HasName

View File

@ -0,0 +1,203 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package assettasks
import (
"fmt"
"net/url"
"bytes"
"github.com/golang/glog"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/hashing"
"k8s.io/kops/util/pkg/vfs"
"strings"
)
// CopyFile copies an from a source file repository, to a target repository,
// typically used for highly secure clusters.
//go:generate fitask -type=CopyFile
type CopyFile struct {
Name *string
SourceFile *string
TargetFile *string
// @justinsb not sure I like this but the problem is knowing if the sha is a file or a string
// so I did a location or a sha. We have both SHAs in remote file locations, and SHAs in strings
SourceShaLocation *string
SourceSha *string
TargetSha *string
Lifecycle *fi.Lifecycle
}
var _ fi.CompareWithID = &CopyFile{}
func (e *CopyFile) CompareWithID() *string {
return e.Name
}
func (e *CopyFile) Find(c *fi.Context) (*CopyFile, error) {
// TODO do a head call on the file??
return nil, nil
}
func (e *CopyFile) Run(c *fi.Context) error {
return fi.DefaultDeltaRunMethod(e, c)
}
func (s *CopyFile) CheckChanges(a, e, changes *CopyFile) error {
if fi.StringValue(e.Name) == "" {
return fi.RequiredField("Name")
}
if fi.StringValue(e.SourceFile) == "" {
return fi.RequiredField("SourceFile")
}
if fi.StringValue(e.TargetFile) == "" {
return fi.RequiredField("TargetFile")
}
return nil
}
func (_ *CopyFile) Render(c *fi.Context, a, e, changes *CopyFile) error {
source := fi.StringValue(e.SourceFile)
target := fi.StringValue(e.TargetFile)
sourceSha := fi.StringValue(e.SourceSha)
sourceSHALocation := fi.StringValue(e.SourceShaLocation)
glog.Infof("copying bits from %q to %q", source, target)
if err := transferFile(source, target, sourceSha, sourceSHALocation); err != nil {
return fmt.Errorf("unable to transfer %q to %q: %v", source, target, err)
}
return nil
}
func transferFile(source string, target string, sourceSHA string, sourceSHALocation string) error {
data, err := vfs.Context.ReadFile(source)
if err != nil {
return fmt.Errorf("Error unable to read path %q: %v", source, err)
}
uploadVFS, err := buildVFSPath(target)
if err != nil {
return err
}
// Test the file matches the sourceSha
{
var sha string
if sourceSHA != "" {
sha = sourceSHA
} else if sourceSHALocation != "" {
shaBytes, err := vfs.Context.ReadFile(sourceSHALocation)
if err != nil {
return fmt.Errorf("Error unable to read path %q: %v", source, err)
}
sha = string(shaBytes)
}
if sha != "" {
trimmedSHA := strings.TrimSpace(sha)
in := bytes.NewReader(data)
dataHash, err := hashing.HashAlgorithmSHA1.Hash(in)
if err != nil {
return fmt.Errorf("unable to hash sha from data: %v", err)
}
shaHash, err := hashing.FromString(trimmedSHA)
if err != nil {
return fmt.Errorf("unable to hash sha: %q, %v", sha, err)
}
if !shaHash.Equal(dataHash) {
return fmt.Errorf("SHAs are not matching for %q", dataHash.String())
}
shaVFS, err := buildVFSPath(target + ".sha1")
if err != nil {
return err
}
b := bytes.NewBufferString(sha)
if err := writeFile(shaVFS, b.Bytes()); err != nil {
return fmt.Errorf("Error uploading file %q: %v", shaVFS, err)
}
}
}
if err := writeFile(uploadVFS, data); err != nil {
return fmt.Errorf("Error uploading file %q: %v", uploadVFS, err)
}
return nil
}
func writeFile(vfsPath string, data []byte) error {
glog.V(2).Infof("uploading to %q", vfsPath)
destinationRegistry, err := vfs.Context.BuildVfsPath(vfsPath)
if err != nil {
return fmt.Errorf("Error parsing registry path %q: %v", vfsPath, err)
}
if err = destinationRegistry.WriteFile(data); err != nil {
return fmt.Errorf("Error destination path %q: %v", vfsPath, err)
}
glog.V(2).Infof("upload complete: %q", vfsPath)
return nil
}
func buildVFSPath(target string) (string, error) {
if !strings.Contains(target, "://") || strings.HasPrefix(target, "memfs://") {
return target, nil
}
u, err := url.Parse(target)
if err != nil {
return "", fmt.Errorf("unable to parse: %q", target)
}
var vfsPath string
// remove the filename from the end of the path
//pathSlice := strings.Split(u.Path, "/")
//pathSlice = pathSlice[:len(pathSlice)-1]
//path := strings.Join(pathSlice, "/")
// TODO I am not a huge fan of this, but it would work
// TODO @justinsb should we require an URL?
if u.Host == "s3.amazonaws.com" {
vfsPath = "s3:/" + u.Path
} else if u.Host == "storage.googleapis.com" {
vfsPath = "gs:/" + u.Path
}
if vfsPath == "" {
glog.Errorf("unable to determine vfs path s3, google storage, and file paths are supported")
glog.Errorf("for s3 use s3.amazonaws.com and for google storage use storage.googleapis.com hostnames.")
return "", fmt.Errorf("unable to determine vfs for %q:", target)
}
return vfsPath, nil
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by ""fitask" -type=CopyFile"; DO NOT EDIT
package assettasks
import (
"encoding/json"
"k8s.io/kops/upup/pkg/fi"
)
// CopyFile
// JSON marshalling boilerplate
type realCopyFile CopyFile
// UnmarshalJSON implements conversion to JSON, supporitng an alternate specification of the object as a string
func (o *CopyFile) UnmarshalJSON(data []byte) error {
var jsonName string
if err := json.Unmarshal(data, &jsonName); err == nil {
o.Name = &jsonName
return nil
}
var r realCopyFile
if err := json.Unmarshal(data, &r); err != nil {
return err
}
*o = CopyFile(r)
return nil
}
var _ fi.HasLifecycle = &CopyFile{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *CopyFile) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
var _ fi.HasName = &CopyFile{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *CopyFile) GetName() *string {
return o.Name
}
// SetName sets the Name of the object, implementing fi.SetName
func (o *CopyFile) SetName(name string) {
o.Name = &name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *CopyFile) String() string {
return fi.TaskAsString(o)
}

View File

@ -0,0 +1,64 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package assettasks
import (
"testing"
)
func Test_BuildVFSPath(t *testing.T) {
grid := []struct {
target string
vfsPath string
pass bool
}{
{
"https://s3.amazonaws.com/k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
"s3://k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
true,
},
{
"https://foo/k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
"",
false,
},
{
"kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
"",
false,
},
{
"https://storage.googleapis.com/k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
"gs://k8s-for-greeks-kops/kubernetes-release/release/v1.7.2/bin/linux/amd64/kubectl",
true,
},
}
for _, test := range grid {
path, err := buildVFSPath(test.target)
if err != nil && test.pass {
t.Errorf("error thrown, but expected to pass: %q, %v", test.target, err)
}
if test.pass && path != test.vfsPath {
t.Errorf("incorrect url parsed %q", path)
}
}
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package dockertasks
package assettasks
import (
"bufio"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package dockertasks
package assettasks
import (
"fmt"

View File

@ -147,7 +147,7 @@ func (c *ApplyClusterCmd) Run() error {
}
c.channel = channel
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(c.Cluster.Spec.Assets)
err = c.upgradeSpecs(assetBuilder)
if err != nil {
return err

View File

@ -104,7 +104,7 @@ func TestElasticIPCreate(t *testing.T) {
}
func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) {
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
target := fi.NewDryRunTarget(assetBuilder, os.Stderr)
context, err := fi.NewContext(target, cloud, nil, nil, nil, true, allTasks)
if err != nil {

View File

@ -64,7 +64,7 @@ func runChannelBuilderTest(t *testing.T, key string) {
t.Fatalf("error from PerformAssignments: %v", err)
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
fullSpec, err := PopulateClusterSpec(cluster, assetBuilder)
if err != nil {
t.Fatalf("error from PopulateClusterSpec: %v", err)
@ -81,7 +81,7 @@ func runChannelBuilderTest(t *testing.T, key string) {
bcb := BootstrapChannelBuilder{
cluster: cluster,
templates: templates,
assetBuilder: assets.NewAssetBuilder(),
assetBuilder: assets.NewAssetBuilder(nil),
}
context := &fi.ModelBuilderContext{

View File

@ -26,16 +26,16 @@ import (
"strings"
"text/template"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/sets"
api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/assets"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/dockertasks"
"k8s.io/kops/upup/pkg/fi/assettasks"
"k8s.io/kops/upup/pkg/fi/loader"
"k8s.io/kops/upup/pkg/fi/utils"
"k8s.io/kops/util/pkg/vfs"
"github.com/golang/glog"
)
const (
@ -182,7 +182,7 @@ func (l *Loader) BuildTasks(modelStore vfs.Path, models []string, assetBuilder *
l.tasks = context.Tasks
}
if err := l.addAssetCopyTasks(assetBuilder.Assets); err != nil {
if err := l.addAssetCopyTasks(assetBuilder.ContainerAssets); err != nil {
return nil, err
}
@ -193,14 +193,14 @@ func (l *Loader) BuildTasks(modelStore vfs.Path, models []string, assetBuilder *
return l.tasks, nil
}
func (l *Loader) addAssetCopyTasks(assets []*assets.Asset) error {
func (l *Loader) addAssetCopyTasks(assets []*assets.ContainerAsset) error {
for _, asset := range assets {
if asset.CanonicalLocation != "" && asset.DockerImage != asset.CanonicalLocation {
context := &fi.ModelBuilderContext{
Tasks: l.tasks,
}
copyImageTask := &dockertasks.CopyDockerImage{
copyImageTask := &assettasks.CopyDockerImage{
Name: fi.String(asset.DockerImage),
SourceImage: fi.String(asset.CanonicalLocation),
TargetImage: fi.String(asset.DockerImage),

View File

@ -88,7 +88,7 @@ func TestPopulateCluster_Default_NoError(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
_, err = PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -111,7 +111,7 @@ func TestPopulateCluster_Docker_Spec(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -142,7 +142,7 @@ func TestPopulateCluster_StorageDefault(t *testing.T) {
}
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -160,7 +160,7 @@ func build(c *api.Cluster) (*api.Cluster, error) {
}
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
return nil, fmt.Errorf("Unexpected error from PopulateCluster: %v", err)
@ -237,7 +237,7 @@ func TestPopulateCluster_Custom_CIDR(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -258,7 +258,7 @@ func TestPopulateCluster_IsolateMasters(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -282,7 +282,7 @@ func TestPopulateCluster_IsolateMastersFalse(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -374,7 +374,7 @@ func TestPopulateCluster_BastionIdleTimeoutInvalidNegative_Required(t *testing.T
}
func expectErrorFromPopulateCluster(t *testing.T, c *api.Cluster, message string) {
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
_, err := PopulateClusterSpec(c, assetBuilder)
if err == nil {
t.Fatalf("Expected error from PopulateCluster")
@ -409,7 +409,7 @@ func TestPopulateCluster_AnonymousAuth(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -435,7 +435,7 @@ func TestPopulateCluster_AnonymousAuth_14(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -487,7 +487,7 @@ func TestPopulateCluster_KubeController_High_Enough_Version(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
@ -510,7 +510,7 @@ func TestPopulateCluster_KubeController_Fail(t *testing.T) {
addEtcdClusters(c)
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
full, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)

View File

@ -61,7 +61,7 @@ func buildDefaultCluster(t *testing.T) *api.Cluster {
}
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(nil)
fullSpec, err := PopulateClusterSpec(c, assetBuilder)
if err != nil {
t.Fatalf("error from PopulateClusterSpec: %v", err)

View File

@ -247,9 +247,9 @@ func (t *DryRunTarget) PrintReport(taskMap map[string]Task, out io.Writer) error
}
}
if len(t.assetBuilder.Assets) != 0 {
glog.V(4).Infof("Assets:")
for _, a := range t.assetBuilder.Assets {
if len(t.assetBuilder.ContainerAssets) != 0 {
glog.V(4).Infof("ContainerAssets:")
for _, a := range t.assetBuilder.ContainerAssets {
glog.V(4).Infof(" %s %s", a.DockerImage, a.CanonicalLocation)
}
}

View File

@ -253,7 +253,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
Tags: nodeTags,
}
case "dryrun":
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(c.cluster.Spec.Assets)
target = fi.NewDryRunTarget(assetBuilder, out)
case "cloudinit":
checkExisting = false

View File

@ -106,7 +106,7 @@ func (x *ConvertKubeupCluster) Upgrade() error {
delete(cluster.ObjectMeta.Annotations, api.AnnotationNameManagement)
}
assetBuilder := assets.NewAssetBuilder()
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
if err != nil {
return err