mirror of https://github.com/kubernetes/kops.git
starting work on file assets builder
This commit is contained in:
parent
07aa30cdae
commit
ee17e6567c
2
Makefile
2
Makefile
|
@ -136,7 +136,7 @@ codegen: kops-gobindata
|
||||||
go install k8s.io/kops/upup/tools/generators/...
|
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/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/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
|
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/fitasks
|
||||||
|
|
||||||
.PHONY: protobuf
|
.PHONY: protobuf
|
||||||
|
|
|
@ -871,7 +871,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
|
||||||
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -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)
|
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)
|
fullCluster, err := cloudup.PopulateClusterSpec(newCluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results = editResults{
|
results = editResults{
|
||||||
|
|
|
@ -167,7 +167,7 @@ func RunEditInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string, ou
|
||||||
return fmt.Errorf("error populating configuration: %v", err)
|
return fmt.Errorf("error populating configuration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
|
||||||
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -284,7 +284,7 @@ func (c *UpgradeClusterCmd) Run(args []string) error {
|
||||||
return fmt.Errorf("error populating configuration: %v", err)
|
return fmt.Errorf("error populating configuration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
|
||||||
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -95,6 +95,7 @@ k8s.io/kops/tests/integration/channel
|
||||||
k8s.io/kops/tests/integration/conversion
|
k8s.io/kops/tests/integration/conversion
|
||||||
k8s.io/kops/upup/models
|
k8s.io/kops/upup/models
|
||||||
k8s.io/kops/upup/pkg/fi
|
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
|
||||||
k8s.io/kops/upup/pkg/fi/cloudup/awstasks
|
k8s.io/kops/upup/pkg/fi/cloudup/awstasks
|
||||||
k8s.io/kops/upup/pkg/fi/cloudup/awsup
|
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/terraform
|
||||||
k8s.io/kops/upup/pkg/fi/cloudup/vsphere
|
k8s.io/kops/upup/pkg/fi/cloudup/vsphere
|
||||||
k8s.io/kops/upup/pkg/fi/cloudup/vspheretasks
|
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/fitasks
|
||||||
k8s.io/kops/upup/pkg/fi/k8sapi
|
k8s.io/kops/upup/pkg/fi/k8sapi
|
||||||
k8s.io/kops/upup/pkg/fi/loader
|
k8s.io/kops/upup/pkg/fi/loader
|
||||||
|
|
|
@ -19,9 +19,11 @@ package assets
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/kops/pkg/apis/kops"
|
||||||
"k8s.io/kops/pkg/featureflag"
|
"k8s.io/kops/pkg/featureflag"
|
||||||
"k8s.io/kops/pkg/kubemanifest"
|
"k8s.io/kops/pkg/kubemanifest"
|
||||||
)
|
)
|
||||||
|
@ -32,10 +34,12 @@ var RewriteManifests = featureflag.New("RewriteManifests", featureflag.Bool(true
|
||||||
|
|
||||||
// AssetBuilder discovers and remaps assets
|
// AssetBuilder discovers and remaps assets
|
||||||
type AssetBuilder struct {
|
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 will be the name of the docker image we should run, if this is a docker image
|
||||||
DockerImage string
|
DockerImage string
|
||||||
|
|
||||||
|
@ -43,8 +47,18 @@ type Asset struct {
|
||||||
CanonicalLocation string
|
CanonicalLocation string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAssetBuilder() *AssetBuilder {
|
type FileAsset struct {
|
||||||
return &AssetBuilder{}
|
// 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.
|
// 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) {
|
func (a *AssetBuilder) RemapImage(image string) (string, error) {
|
||||||
asset := &Asset{}
|
asset := &ContainerAsset{}
|
||||||
|
|
||||||
asset.DockerImage = image
|
asset.DockerImage = image
|
||||||
|
|
||||||
|
@ -113,7 +127,33 @@ func (a *AssetBuilder) RemapImage(image string) (string, error) {
|
||||||
image = asset.DockerImage
|
image = asset.DockerImage
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Assets = append(a.Assets, asset)
|
a.ContainerAssets = append(a.ContainerAssets, asset)
|
||||||
|
|
||||||
return image, nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package dockertasks
|
package assettasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -30,6 +30,7 @@ type CopyDockerImage struct {
|
||||||
Name *string
|
Name *string
|
||||||
SourceImage *string
|
SourceImage *string
|
||||||
TargetImage *string
|
TargetImage *string
|
||||||
|
Lifecycle *fi.Lifecycle
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ fi.CompareWithID = &CopyDockerImage{}
|
var _ fi.CompareWithID = &CopyDockerImage{}
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
// Code generated by ""fitask" -type=CopyDockerImage"; DO NOT EDIT
|
// Code generated by ""fitask" -type=CopyDockerImage"; DO NOT EDIT
|
||||||
|
|
||||||
package dockertasks
|
package assettasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -45,6 +45,13 @@ func (o *CopyDockerImage) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
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{}
|
var _ fi.HasName = &CopyDockerImage{}
|
||||||
|
|
||||||
// GetName returns the Name of the object, implementing fi.HasName
|
// GetName returns the Name of the object, implementing fi.HasName
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package dockertasks
|
package assettasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package dockertasks
|
package assettasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -147,7 +147,7 @@ func (c *ApplyClusterCmd) Run() error {
|
||||||
}
|
}
|
||||||
c.channel = channel
|
c.channel = channel
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(c.Cluster.Spec.Assets)
|
||||||
err = c.upgradeSpecs(assetBuilder)
|
err = c.upgradeSpecs(assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -104,7 +104,7 @@ func TestElasticIPCreate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) {
|
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)
|
target := fi.NewDryRunTarget(assetBuilder, os.Stderr)
|
||||||
context, err := fi.NewContext(target, cloud, nil, nil, nil, true, allTasks)
|
context, err := fi.NewContext(target, cloud, nil, nil, nil, true, allTasks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -64,7 +64,7 @@ func runChannelBuilderTest(t *testing.T, key string) {
|
||||||
t.Fatalf("error from PerformAssignments: %v", err)
|
t.Fatalf("error from PerformAssignments: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
fullSpec, err := PopulateClusterSpec(cluster, assetBuilder)
|
fullSpec, err := PopulateClusterSpec(cluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error from PopulateClusterSpec: %v", err)
|
t.Fatalf("error from PopulateClusterSpec: %v", err)
|
||||||
|
@ -81,7 +81,7 @@ func runChannelBuilderTest(t *testing.T, key string) {
|
||||||
bcb := BootstrapChannelBuilder{
|
bcb := BootstrapChannelBuilder{
|
||||||
cluster: cluster,
|
cluster: cluster,
|
||||||
templates: templates,
|
templates: templates,
|
||||||
assetBuilder: assets.NewAssetBuilder(),
|
assetBuilder: assets.NewAssetBuilder(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
context := &fi.ModelBuilderContext{
|
context := &fi.ModelBuilderContext{
|
||||||
|
|
|
@ -26,16 +26,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
api "k8s.io/kops/pkg/apis/kops"
|
api "k8s.io/kops/pkg/apis/kops"
|
||||||
"k8s.io/kops/pkg/assets"
|
"k8s.io/kops/pkg/assets"
|
||||||
"k8s.io/kops/upup/pkg/fi"
|
"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/loader"
|
||||||
"k8s.io/kops/upup/pkg/fi/utils"
|
"k8s.io/kops/upup/pkg/fi/utils"
|
||||||
"k8s.io/kops/util/pkg/vfs"
|
"k8s.io/kops/util/pkg/vfs"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -182,7 +182,7 @@ func (l *Loader) BuildTasks(modelStore vfs.Path, models []string, assetBuilder *
|
||||||
l.tasks = context.Tasks
|
l.tasks = context.Tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := l.addAssetCopyTasks(assetBuilder.Assets); err != nil {
|
if err := l.addAssetCopyTasks(assetBuilder.ContainerAssets); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,14 +193,14 @@ func (l *Loader) BuildTasks(modelStore vfs.Path, models []string, assetBuilder *
|
||||||
return l.tasks, nil
|
return l.tasks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Loader) addAssetCopyTasks(assets []*assets.Asset) error {
|
func (l *Loader) addAssetCopyTasks(assets []*assets.ContainerAsset) error {
|
||||||
for _, asset := range assets {
|
for _, asset := range assets {
|
||||||
if asset.CanonicalLocation != "" && asset.DockerImage != asset.CanonicalLocation {
|
if asset.CanonicalLocation != "" && asset.DockerImage != asset.CanonicalLocation {
|
||||||
context := &fi.ModelBuilderContext{
|
context := &fi.ModelBuilderContext{
|
||||||
Tasks: l.tasks,
|
Tasks: l.tasks,
|
||||||
}
|
}
|
||||||
|
|
||||||
copyImageTask := &dockertasks.CopyDockerImage{
|
copyImageTask := &assettasks.CopyDockerImage{
|
||||||
Name: fi.String(asset.DockerImage),
|
Name: fi.String(asset.DockerImage),
|
||||||
SourceImage: fi.String(asset.CanonicalLocation),
|
SourceImage: fi.String(asset.CanonicalLocation),
|
||||||
TargetImage: fi.String(asset.DockerImage),
|
TargetImage: fi.String(asset.DockerImage),
|
||||||
|
|
|
@ -88,7 +88,7 @@ func TestPopulateCluster_Default_NoError(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
_, err = PopulateClusterSpec(c, assetBuilder)
|
_, err = PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -111,7 +111,7 @@ func TestPopulateCluster_Docker_Spec(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -142,7 +142,7 @@ func TestPopulateCluster_StorageDefault(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -160,7 +160,7 @@ func build(c *api.Cluster) (*api.Cluster, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Unexpected error from PopulateCluster: %v", err)
|
return nil, fmt.Errorf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -237,7 +237,7 @@ func TestPopulateCluster_Custom_CIDR(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -258,7 +258,7 @@ func TestPopulateCluster_IsolateMasters(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -282,7 +282,7 @@ func TestPopulateCluster_IsolateMastersFalse(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
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) {
|
func expectErrorFromPopulateCluster(t *testing.T, c *api.Cluster, message string) {
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
_, err := PopulateClusterSpec(c, assetBuilder)
|
_, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Expected error from PopulateCluster")
|
t.Fatalf("Expected error from PopulateCluster")
|
||||||
|
@ -409,7 +409,7 @@ func TestPopulateCluster_AnonymousAuth(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -435,7 +435,7 @@ func TestPopulateCluster_AnonymousAuth_14(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -487,7 +487,7 @@ func TestPopulateCluster_KubeController_High_Enough_Version(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
@ -510,7 +510,7 @@ func TestPopulateCluster_KubeController_Fail(t *testing.T) {
|
||||||
|
|
||||||
addEtcdClusters(c)
|
addEtcdClusters(c)
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
full, err := PopulateClusterSpec(c, assetBuilder)
|
full, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
|
||||||
|
|
|
@ -61,7 +61,7 @@ func buildDefaultCluster(t *testing.T) *api.Cluster {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(nil)
|
||||||
fullSpec, err := PopulateClusterSpec(c, assetBuilder)
|
fullSpec, err := PopulateClusterSpec(c, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error from PopulateClusterSpec: %v", err)
|
t.Fatalf("error from PopulateClusterSpec: %v", err)
|
||||||
|
|
|
@ -247,9 +247,9 @@ func (t *DryRunTarget) PrintReport(taskMap map[string]Task, out io.Writer) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(t.assetBuilder.Assets) != 0 {
|
if len(t.assetBuilder.ContainerAssets) != 0 {
|
||||||
glog.V(4).Infof("Assets:")
|
glog.V(4).Infof("ContainerAssets:")
|
||||||
for _, a := range t.assetBuilder.Assets {
|
for _, a := range t.assetBuilder.ContainerAssets {
|
||||||
glog.V(4).Infof(" %s %s", a.DockerImage, a.CanonicalLocation)
|
glog.V(4).Infof(" %s %s", a.DockerImage, a.CanonicalLocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
|
||||||
Tags: nodeTags,
|
Tags: nodeTags,
|
||||||
}
|
}
|
||||||
case "dryrun":
|
case "dryrun":
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(c.cluster.Spec.Assets)
|
||||||
target = fi.NewDryRunTarget(assetBuilder, out)
|
target = fi.NewDryRunTarget(assetBuilder, out)
|
||||||
case "cloudinit":
|
case "cloudinit":
|
||||||
checkExisting = false
|
checkExisting = false
|
||||||
|
|
|
@ -106,7 +106,7 @@ func (x *ConvertKubeupCluster) Upgrade() error {
|
||||||
delete(cluster.ObjectMeta.Annotations, api.AnnotationNameManagement)
|
delete(cluster.ObjectMeta.Annotations, api.AnnotationNameManagement)
|
||||||
}
|
}
|
||||||
|
|
||||||
assetBuilder := assets.NewAssetBuilder()
|
assetBuilder := assets.NewAssetBuilder(cluster.Spec.Assets)
|
||||||
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
fullCluster, err := cloudup.PopulateClusterSpec(cluster, assetBuilder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue