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/...
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
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{}
|
|
@ -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
|
|
@ -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.
|
||||
*/
|
||||
|
||||
package dockertasks
|
||||
package assettasks
|
||||
|
||||
import (
|
||||
"bufio"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package dockertasks
|
||||
package assettasks
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue