Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b2280db7
Commit
b2280db7
authored
May 13, 2015
by
Wojciech Tyczynski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Deep-copy functions autogeneration.
parent
11b058cc
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
568 additions
and
13 deletions
+568
-13
conversion.go
cmd/genconversion/conversion.go
+0
-0
deep_copy.go
cmd/gendeepcopy/deep_copy.go
+82
-0
golang.sh
hack/lib/golang.sh
+2
-0
update-generated-conversions.sh
hack/update-generated-conversions.sh
+1
-1
update-generated-deep-copies.sh
hack/update-generated-deep-copies.sh
+51
-0
verify-generated-conversions.sh
hack/verify-generated-conversions.sh
+3
-3
verify-generated-deep-copies.sh
hack/verify-generated-deep-copies.sh
+60
-0
deep_copy_test.go
pkg/api/deep_copy_test.go
+3
-4
cloner.go
pkg/conversion/cloner.go
+226
-0
scheme.go
pkg/conversion/scheme.go
+33
-0
conversion_generation_test.go
pkg/runtime/conversion_generation_test.go
+2
-5
deep_copy_generation_test.go
pkg/runtime/deep_copy_generation_test.go
+87
-0
deep_copy_generator.go
pkg/runtime/deep_copy_generator.go
+0
-0
scheme.go
pkg/runtime/scheme.go
+18
-0
No files found.
cmd/
kube-
conversion/conversion.go
→
cmd/
gen
conversion/conversion.go
View file @
b2280db7
File moved
cmd/gendeepcopy/deep_copy.go
0 → 100644
View file @
b2280db7
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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
main
import
(
"io"
"os"
"runtime"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
pkg_runtime
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/golang/glog"
flag
"github.com/spf13/pflag"
)
var
(
functionDest
=
flag
.
StringP
(
"func-dest"
,
"f"
,
"-"
,
"Output for deep copy functions; '-' means stdout"
)
version
=
flag
.
StringP
(
"version"
,
"v"
,
"v1beta3"
,
"Version for deep copies."
)
overwrites
=
flag
.
StringP
(
"overwrites"
,
"o"
,
""
,
"Comma-separated overwrites for package names"
)
)
func
main
()
{
runtime
.
GOMAXPROCS
(
runtime
.
NumCPU
())
flag
.
Parse
()
var
funcOut
io
.
Writer
if
*
functionDest
==
"-"
{
funcOut
=
os
.
Stdout
}
else
{
file
,
err
:=
os
.
Create
(
*
functionDest
)
if
err
!=
nil
{
glog
.
Fatalf
(
"Couldn't open %v: %v"
,
*
functionDest
,
err
)
}
defer
file
.
Close
()
funcOut
=
file
}
knownVersion
:=
*
version
if
knownVersion
==
"api"
{
knownVersion
=
api
.
Scheme
.
Raw
()
.
InternalVersion
}
generator
:=
pkg_runtime
.
NewDeepCopyGenerator
(
api
.
Scheme
.
Raw
())
for
_
,
overwrite
:=
range
strings
.
Split
(
*
overwrites
,
","
)
{
vals
:=
strings
.
Split
(
overwrite
,
"="
)
generator
.
OverwritePackage
(
vals
[
0
],
vals
[
1
])
}
for
_
,
knownType
:=
range
api
.
Scheme
.
KnownTypes
(
knownVersion
)
{
if
err
:=
generator
.
AddType
(
knownType
);
err
!=
nil
{
glog
.
Errorf
(
"error while generating deep copy functions for %v: %v"
,
knownType
,
err
)
}
}
if
err
:=
generator
.
WriteImports
(
funcOut
,
*
version
);
err
!=
nil
{
glog
.
Fatalf
(
"error while writing imports: %v"
,
err
)
}
if
err
:=
generator
.
WriteDeepCopyFunctions
(
funcOut
);
err
!=
nil
{
glog
.
Fatalf
(
"error while writing deep copy functions: %v"
,
err
)
}
if
err
:=
generator
.
RegisterDeepCopyFunctions
(
funcOut
,
*
version
);
err
!=
nil
{
glog
.
Fatalf
(
"error while registering deep copy functions: %v"
,
err
)
}
}
hack/lib/golang.sh
View file @
b2280db7
...
...
@@ -48,6 +48,8 @@ readonly KUBE_TEST_TARGETS=(
cmd/gendocs
cmd/genman
cmd/genbashcomp
cmd/genconversion
cmd/gendeepcopy
examples/k8petstore/web-server
github.com/onsi/ginkgo/ginkgo
test
/e2e/e2e.test
...
...
hack/update-generated-conversions.sh
View file @
b2280db7
...
...
@@ -39,7 +39,7 @@ import (
// AUTO-GENERATED FUNCTIONS START HERE
EOF
GOPATH
=
$(
godep path
)
:
$GOPATH
go run cmd/
kube-
conversion/conversion.go
-v
${
version
}
-f
-
>>
$TMPFILE
GOPATH
=
$(
godep path
)
:
$GOPATH
go run cmd/
gen
conversion/conversion.go
-v
${
version
}
-f
-
>>
$TMPFILE
cat
>>
$TMPFILE
<<
EOF
// AUTO-GENERATED FUNCTIONS END HERE
...
...
hack/update-generated-deep-copies.sh
0 → 100755
View file @
b2280db7
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
set
-o
errexit
set
-o
nounset
set
-o
pipefail
function
generate_version
()
{
local
version
=
$1
local
TMPFILE
=
"/tmp/deep_copy_generated.
$(
date
+%s
)
.go"
echo
"Generating for version
${
version
}
"
sed
's/YEAR/2015/'
hooks/boilerplate.go.txt
>
$TMPFILE
cat
>>
$TMPFILE
<<
EOF
package
${
version
}
// AUTO-GENERATED FUNCTIONS START HERE
EOF
GOPATH
=
$(
godep path
)
:
$GOPATH
go run cmd/gendeepcopy/deep_copy.go
-v
${
version
}
-f
-
-o
"
${
version
}
="
>>
$TMPFILE
cat
>>
$TMPFILE
<<
EOF
// AUTO-GENERATED FUNCTIONS END HERE
EOF
gofmt
-w
-s
$TMPFILE
if
[
"
${
version
}
"
==
"api"
]
;
then
mv
$TMPFILE
pkg/api/deep_copy_generated.go
else
mv
$TMPFILE
pkg/api/
${
version
}
/deep_copy_generated.go
fi
}
VERSIONS
=
"api v1beta3 v1"
for
ver
in
$VERSIONS
;
do
generate_version
"
${
ver
}
"
done
hack/verify-generated-conversions.sh
View file @
b2280db7
...
...
@@ -22,16 +22,16 @@ KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source
"
${
KUBE_ROOT
}
/hack/lib/init.sh"
kube::golang::setup_env
"
${
KUBE_ROOT
}
/hack/build-go.sh"
cmd/
kube-
conversion
"
${
KUBE_ROOT
}
/hack/build-go.sh"
cmd/
gen
conversion
genconversion
=
$(
kube::util::find-binary
"
kube-
conversion"
)
genconversion
=
$(
kube::util::find-binary
"
gen
conversion"
)
if
[[
!
-x
"
$genconversion
"
]]
;
then
{
echo
"It looks as if you don't have a compiled conversion binary"
echo
echo
"If you are running from a clone of the git repo, please run"
echo
"'./hack/build-go.sh cmd/
kube-
conversion'."
echo
"'./hack/build-go.sh cmd/
gen
conversion'."
}
>
&2
exit
1
fi
...
...
hack/verify-generated-deep-copies.sh
0 → 100755
View file @
b2280db7
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
set
-o
errexit
set
-o
nounset
set
-o
pipefail
KUBE_ROOT
=
$(
dirname
"
${
BASH_SOURCE
}
"
)
/..
source
"
${
KUBE_ROOT
}
/hack/lib/init.sh"
kube::golang::setup_env
"
${
KUBE_ROOT
}
/hack/build-go.sh"
cmd/gendeepcopy
genconversion
=
$(
kube::util::find-binary
"gendeepcopy"
)
if
[[
!
-x
"
$genconversion
"
]]
;
then
{
echo
"It looks as if you don't have a compiled conversion binary"
echo
echo
"If you are running from a clone of the git repo, please run"
echo
"'./hack/build-go.sh cmd/gendeepcopy'."
}
>
&2
exit
1
fi
APIROOT
=
"
${
KUBE_ROOT
}
/pkg/api"
TMP_APIROOT
=
"
${
KUBE_ROOT
}
/_tmp/api"
_tmp
=
"
${
KUBE_ROOT
}
/_tmp"
mkdir
-p
"
${
_tmp
}
"
cp
-a
"
${
APIROOT
}
"
"
${
TMP_APIROOT
}
"
"
${
KUBE_ROOT
}
/hack/update-generated-deep-copies.sh"
echo
"diffing
${
APIROOT
}
against freshly generated deep copies"
ret
=
0
diff
-Naupr
-I
'Auto generated by'
"
${
APIROOT
}
"
"
${
TMP_APIROOT
}
"
||
ret
=
$?
cp
-a
${
TMP_APIROOT
}
"
${
KUBE_ROOT
}
/pkg"
rm
-rf
"
${
_tmp
}
"
if
[[
$ret
-eq
0
]]
then
echo
"
${
APIROOT
}
up to date."
else
echo
"
${
APIROOT
}
is out of date. Please run hack/update-generated-deep-copies.sh"
exit
1
fi
# ex: ts=2 sw=2 et filetype=sh
pkg/api/deep_copy_test.go
View file @
b2280db7
...
...
@@ -21,7 +21,6 @@ import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
func
BenchmarkPodCopy
(
b
*
testing
.
B
)
{
...
...
@@ -36,7 +35,7 @@ func BenchmarkPodCopy(b *testing.B) {
var
result
*
api
.
Pod
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
obj
,
err
:=
conversion
.
DeepCopy
(
&
pod
)
obj
,
err
:=
api
.
Scheme
.
DeepCopy
(
&
pod
)
if
err
!=
nil
{
b
.
Fatalf
(
"Unexpected error copying pod: %v"
,
err
)
}
...
...
@@ -59,7 +58,7 @@ func BenchmarkNodeCopy(b *testing.B) {
var
result
*
api
.
Node
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
obj
,
err
:=
conversion
.
DeepCopy
(
&
node
)
obj
,
err
:=
api
.
Scheme
.
DeepCopy
(
&
node
)
if
err
!=
nil
{
b
.
Fatalf
(
"Unexpected error copying node: %v"
,
err
)
}
...
...
@@ -82,7 +81,7 @@ func BenchmarkReplicationControllerCopy(b *testing.B) {
var
result
*
api
.
ReplicationController
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
obj
,
err
:=
conversion
.
DeepCopy
(
&
replicationController
)
obj
,
err
:=
api
.
Scheme
.
DeepCopy
(
&
replicationController
)
if
err
!=
nil
{
b
.
Fatalf
(
"Unexpected error copying replication controller: %v"
,
err
)
}
...
...
pkg/conversion/cloner.go
0 → 100644
View file @
b2280db7
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
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
conversion
import
(
"fmt"
"reflect"
)
// Cloner knows how to copy one type to another.
type
Cloner
struct
{
// Map from the type to a function which can do the deep copy.
deepCopyFuncs
map
[
reflect
.
Type
]
reflect
.
Value
generatedDeepCopyFuncs
map
[
reflect
.
Type
]
reflect
.
Value
}
// NewCloner creates a new Cloner object.
func
NewCloner
()
*
Cloner
{
c
:=
&
Cloner
{
deepCopyFuncs
:
map
[
reflect
.
Type
]
reflect
.
Value
{},
generatedDeepCopyFuncs
:
map
[
reflect
.
Type
]
reflect
.
Value
{},
}
if
err
:=
c
.
RegisterDeepCopyFunc
(
byteSliceDeepCopy
);
err
!=
nil
{
// If one of the deep-copy functions is malformed, detect it immediately.
panic
(
err
)
}
return
c
}
// Prevent recursing into every byte...
func
byteSliceDeepCopy
(
in
[]
byte
,
out
*
[]
byte
,
c
*
Cloner
)
error
{
*
out
=
make
([]
byte
,
len
(
in
))
copy
(
*
out
,
in
)
return
nil
}
// Verifies whether a deep-copy function has a correct signature.
func
verifyDeepCopyFunctionSignature
(
ft
reflect
.
Type
)
error
{
if
ft
.
Kind
()
!=
reflect
.
Func
{
return
fmt
.
Errorf
(
"expected func, got: %v"
,
ft
)
}
if
ft
.
NumIn
()
!=
3
{
return
fmt
.
Errorf
(
"expected three 'in' params, got $v"
,
ft
)
}
if
ft
.
NumOut
()
!=
1
{
return
fmt
.
Errorf
(
"expected one 'out' param, got %v"
,
ft
)
}
if
ft
.
In
(
1
)
.
Kind
()
!=
reflect
.
Ptr
{
return
fmt
.
Errorf
(
"expected pointer arg for 'in' param 1, got: %v"
,
ft
)
}
if
ft
.
In
(
1
)
.
Elem
()
!=
ft
.
In
(
0
)
{
return
fmt
.
Errorf
(
"expected 'in' param 0 the same as param 1, got: %v"
,
ft
)
}
var
forClonerType
Cloner
if
expected
:=
reflect
.
TypeOf
(
&
forClonerType
);
ft
.
In
(
2
)
!=
expected
{
return
fmt
.
Errorf
(
"expected '%v' arg for 'in' param 2, got: '%v'"
,
expected
,
ft
.
In
(
2
))
}
var
forErrorType
error
// This convolution is necessary, otherwise TypeOf picks up on the fact
// that forErrorType is nil
errorType
:=
reflect
.
TypeOf
(
&
forErrorType
)
.
Elem
()
if
ft
.
Out
(
0
)
!=
errorType
{
return
fmt
.
Errorf
(
"expected error return, got: %v"
,
ft
)
}
return
nil
}
// RegisterGeneratedDeepCopyFunc registers a copying func with the Cloner.
// deepCopyFunc must take two parameters: a type and a pointer to Cloner
// and return an element of the same type and an error.
//
// Example:
// c.RegisterGeneratedDeepCopyFunc(
// func(in Pod, c *Cloner) (Pod, error) {
// // deep copy logic...
// return copy, nil
// })
func
(
c
*
Cloner
)
RegisterDeepCopyFunc
(
deepCopyFunc
interface
{})
error
{
fv
:=
reflect
.
ValueOf
(
deepCopyFunc
)
ft
:=
fv
.
Type
()
if
err
:=
verifyDeepCopyFunctionSignature
(
ft
);
err
!=
nil
{
return
err
}
c
.
deepCopyFuncs
[
ft
.
In
(
0
)]
=
fv
return
nil
}
// Similar to RegisterDeepCopyFunc, but registers deep copy function that were
// automatically generated.
func
(
c
*
Cloner
)
RegisterGeneratedDeepCopyFunc
(
deepCopyFunc
interface
{})
error
{
fv
:=
reflect
.
ValueOf
(
deepCopyFunc
)
ft
:=
fv
.
Type
()
if
err
:=
verifyDeepCopyFunctionSignature
(
ft
);
err
!=
nil
{
return
err
}
c
.
generatedDeepCopyFuncs
[
ft
.
In
(
0
)]
=
fv
return
nil
}
// DeepCopy will perform a deep copy of a given object.
func
(
c
*
Cloner
)
DeepCopy
(
in
interface
{})
(
interface
{},
error
)
{
inValue
:=
reflect
.
ValueOf
(
in
)
outValue
,
err
:=
c
.
deepCopy
(
inValue
)
if
err
!=
nil
{
return
nil
,
err
}
return
outValue
.
Interface
(),
nil
}
func
(
c
*
Cloner
)
deepCopy
(
src
reflect
.
Value
)
(
reflect
.
Value
,
error
)
{
inType
:=
src
.
Type
()
if
fv
,
ok
:=
c
.
deepCopyFuncs
[
inType
];
ok
{
return
c
.
customDeepCopy
(
src
,
fv
)
}
if
fv
,
ok
:=
c
.
generatedDeepCopyFuncs
[
inType
];
ok
{
return
c
.
customDeepCopy
(
src
,
fv
)
}
return
c
.
defaultDeepCopy
(
src
)
}
func
(
c
*
Cloner
)
customDeepCopy
(
src
,
fv
reflect
.
Value
)
(
reflect
.
Value
,
error
)
{
outValue
:=
reflect
.
New
(
src
.
Type
())
args
:=
[]
reflect
.
Value
{
src
,
outValue
,
reflect
.
ValueOf
(
c
)}
result
:=
fv
.
Call
(
args
)[
0
]
.
Interface
()
// This convolution is necessary because nil interfaces won't convert
// to error.
if
result
==
nil
{
return
outValue
.
Elem
(),
nil
}
return
outValue
.
Elem
(),
result
.
(
error
)
}
func
(
c
*
Cloner
)
defaultDeepCopy
(
src
reflect
.
Value
)
(
reflect
.
Value
,
error
)
{
switch
src
.
Kind
()
{
case
reflect
.
Chan
,
reflect
.
Func
,
reflect
.
UnsafePointer
,
reflect
.
Uintptr
:
return
src
,
fmt
.
Errorf
(
"cannot deep copy kind: %s"
,
src
.
Kind
())
case
reflect
.
Array
:
dst
:=
reflect
.
New
(
src
.
Type
())
for
i
:=
0
;
i
<
src
.
Len
();
i
++
{
copyVal
,
err
:=
c
.
deepCopy
(
src
.
Index
(
i
))
if
err
!=
nil
{
return
src
,
err
}
dst
.
Elem
()
.
Index
(
i
)
.
Set
(
copyVal
)
}
return
dst
.
Elem
(),
nil
case
reflect
.
Interface
:
if
src
.
IsNil
()
{
return
src
,
nil
}
return
c
.
deepCopy
(
src
.
Elem
())
case
reflect
.
Map
:
if
src
.
IsNil
()
{
return
src
,
nil
}
dst
:=
reflect
.
MakeMap
(
src
.
Type
())
for
_
,
k
:=
range
src
.
MapKeys
()
{
copyVal
,
err
:=
c
.
deepCopy
(
src
.
MapIndex
(
k
))
if
err
!=
nil
{
return
src
,
err
}
dst
.
SetMapIndex
(
k
,
copyVal
)
}
return
dst
,
nil
case
reflect
.
Ptr
:
if
src
.
IsNil
()
{
return
src
,
nil
}
dst
:=
reflect
.
New
(
src
.
Type
()
.
Elem
())
copyVal
,
err
:=
c
.
deepCopy
(
src
.
Elem
())
if
err
!=
nil
{
return
src
,
err
}
dst
.
Elem
()
.
Set
(
copyVal
)
return
dst
,
nil
case
reflect
.
Slice
:
if
src
.
IsNil
()
{
return
src
,
nil
}
dst
:=
reflect
.
MakeSlice
(
src
.
Type
(),
0
,
src
.
Len
())
for
i
:=
0
;
i
<
src
.
Len
();
i
++
{
copyVal
,
err
:=
c
.
deepCopy
(
src
.
Index
(
i
))
if
err
!=
nil
{
return
src
,
err
}
dst
=
reflect
.
Append
(
dst
,
copyVal
)
}
return
dst
,
nil
case
reflect
.
Struct
:
dst
:=
reflect
.
New
(
src
.
Type
())
for
i
:=
0
;
i
<
src
.
NumField
();
i
++
{
if
!
dst
.
Elem
()
.
Field
(
i
)
.
CanSet
()
{
// Can't set private fields. At this point, the
// best we can do is a shallow copy. For
// example, time.Time is a value type with
// private members that can be shallow copied.
return
src
,
nil
}
copyVal
,
err
:=
c
.
deepCopy
(
src
.
Field
(
i
))
if
err
!=
nil
{
return
src
,
err
}
dst
.
Elem
()
.
Field
(
i
)
.
Set
(
copyVal
)
}
return
dst
.
Elem
(),
nil
default
:
// Value types like numbers, booleans, and strings.
return
src
,
nil
}
}
pkg/conversion/scheme.go
View file @
b2280db7
...
...
@@ -40,6 +40,10 @@ type Scheme struct {
// default coverting behavior.
converter
*
Converter
// cloner stores all registered copy functions. It also has default
// deep copy behavior.
cloner
*
Cloner
// Indent will cause the JSON output from Encode to be indented, iff it is true.
Indent
bool
...
...
@@ -60,6 +64,7 @@ func NewScheme() *Scheme {
typeToVersion
:
map
[
reflect
.
Type
]
string
{},
typeToKind
:
map
[
reflect
.
Type
][]
string
{},
converter
:
NewConverter
(),
cloner
:
NewCloner
(),
InternalVersion
:
""
,
MetaFactory
:
DefaultMetaFactory
,
}
...
...
@@ -212,6 +217,29 @@ func (s *Scheme) AddGeneratedConversionFuncs(conversionFuncs ...interface{}) err
return
nil
}
// AddDeepCopyFuncs adds functions to the list of deep copy functions.
// Note that to copy sub-objects, you can use the conversion.Cloner object that
// will be passed to your deep-copy function.
func
(
s
*
Scheme
)
AddDeepCopyFuncs
(
deepCopyFuncs
...
interface
{})
error
{
for
_
,
f
:=
range
deepCopyFuncs
{
if
err
:=
s
.
cloner
.
RegisterDeepCopyFunc
(
f
);
err
!=
nil
{
return
err
}
}
return
nil
}
// Similar to AddDeepCopyFuncs, but registers deep copy functions that were
// automatically generated.
func
(
s
*
Scheme
)
AddGeneratedDeepCopyFuncs
(
deepCopyFuncs
...
interface
{})
error
{
for
_
,
f
:=
range
deepCopyFuncs
{
if
err
:=
s
.
cloner
.
RegisterGeneratedDeepCopyFunc
(
f
);
err
!=
nil
{
return
err
}
}
return
nil
}
// AddStructFieldConversion allows you to specify a mechanical copy for a moved
// or renamed struct field without writing an entire conversion function. See
// the comment in Converter.SetStructFieldCopy for parameter details.
...
...
@@ -262,6 +290,11 @@ func (s *Scheme) RegisterInputDefaults(in interface{}, fn FieldMappingFunc, defa
return
s
.
converter
.
RegisterInputDefaults
(
in
,
fn
,
defaultFlags
)
}
// Performs a deep copy of the given object.
func
(
s
*
Scheme
)
DeepCopy
(
in
interface
{})
(
interface
{},
error
)
{
return
s
.
cloner
.
DeepCopy
(
in
)
}
// Convert will attempt to convert in into out. Both must be pointers. For easy
// testing of conversion functions. Returns an error if the conversion isn't
// possible. You can call this with types that haven't been registered (for example,
...
...
pkg/runtime/conversion_generation_test.go
View file @
b2280db7
...
...
@@ -47,9 +47,6 @@ func generateConversions(t *testing.T, version string) bytes.Buffer {
if
err
:=
g
.
WriteConversionFunctions
(
functionsWriter
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't generate conversion functions: %v"
,
err
)
}
if
err
:=
functionsWriter
.
Flush
();
err
!=
nil
{
t
.
Fatalf
(
"error while flushing writer"
)
}
if
err
:=
g
.
RegisterConversionFunctions
(
functionsWriter
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't generate conversion function names: %v"
,
err
)
}
...
...
@@ -81,7 +78,7 @@ func readLinesUntil(t *testing.T, reader *bufio.Reader, stop string, buffer *byt
return
nil
}
func
bufferExisting
Conversions
(
t
*
testing
.
T
,
fileName
string
)
bytes
.
Buffer
{
func
bufferExisting
GeneratedCode
(
t
*
testing
.
T
,
fileName
string
)
bytes
.
Buffer
{
file
,
err
:=
os
.
Open
(
fileName
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't open file %s"
,
fileName
)
...
...
@@ -139,7 +136,7 @@ func TestNoManualChangesToGenerateConversions(t *testing.T) {
for
_
,
version
:=
range
versions
{
fileName
:=
fmt
.
Sprintf
(
"../../pkg/api/%s/conversion_generated.go"
,
version
)
existingFunctions
:=
bufferExisting
Conversions
(
t
,
fileName
)
existingFunctions
:=
bufferExisting
GeneratedCode
(
t
,
fileName
)
generatedFunctions
:=
generateConversions
(
t
,
version
)
functionsTxt
:=
fmt
.
Sprintf
(
"%s.functions.txt"
,
version
)
...
...
pkg/runtime/deep_copy_generation_test.go
0 → 100644
View file @
b2280db7
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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
runtime_test
import
(
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/golang/glog"
)
func
generateDeepCopies
(
t
*
testing
.
T
,
version
string
)
bytes
.
Buffer
{
g
:=
runtime
.
NewDeepCopyGenerator
(
api
.
Scheme
.
Raw
())
g
.
OverwritePackage
(
version
,
""
)
testedVersion
:=
version
if
version
==
"api"
{
testedVersion
=
api
.
Scheme
.
Raw
()
.
InternalVersion
}
for
_
,
knownType
:=
range
api
.
Scheme
.
KnownTypes
(
testedVersion
)
{
if
err
:=
g
.
AddType
(
knownType
);
err
!=
nil
{
glog
.
Errorf
(
"error while generating deep-copy functions for %v: %v"
,
knownType
,
err
)
}
}
var
functions
bytes
.
Buffer
functionsWriter
:=
bufio
.
NewWriter
(
&
functions
)
if
err
:=
g
.
WriteImports
(
functionsWriter
,
version
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't generate deep-copy function imports: %v"
,
err
)
}
if
err
:=
g
.
WriteDeepCopyFunctions
(
functionsWriter
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't generate deep-copy functions: %v"
,
err
)
}
if
err
:=
g
.
RegisterDeepCopyFunctions
(
functionsWriter
,
version
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't generate deep-copy function names: %v"
,
err
)
}
if
err
:=
functionsWriter
.
Flush
();
err
!=
nil
{
t
.
Fatalf
(
"error while flushing writer"
)
}
return
functions
}
func
TestNoManualChangesToGenerateDeepCopies
(
t
*
testing
.
T
)
{
versions
:=
[]
string
{
"api"
,
"v1beta3"
,
"v1"
}
for
_
,
version
:=
range
versions
{
fileName
:=
""
if
version
==
"api"
{
fileName
=
"../../pkg/api/deep_copy_generated.go"
}
else
{
fileName
=
fmt
.
Sprintf
(
"../../pkg/api/%s/deep_copy_generated.go"
,
version
)
}
existingFunctions
:=
bufferExistingGeneratedCode
(
t
,
fileName
)
generatedFunctions
:=
generateDeepCopies
(
t
,
version
)
functionsTxt
:=
fmt
.
Sprintf
(
"%s.deep_copy.txt"
,
version
)
ioutil
.
WriteFile
(
functionsTxt
,
generatedFunctions
.
Bytes
(),
os
.
FileMode
(
0644
))
if
ok
:=
compareBuffers
(
t
,
functionsTxt
,
existingFunctions
,
generatedFunctions
);
ok
{
os
.
Remove
(
functionsTxt
)
}
}
}
pkg/runtime/deep_copy_generator.go
0 → 100644
View file @
b2280db7
This diff is collapsed.
Click to expand it.
pkg/runtime/scheme.go
View file @
b2280db7
...
...
@@ -321,6 +321,19 @@ func (s *Scheme) AddGeneratedConversionFuncs(conversionFuncs ...interface{}) err
return
s
.
raw
.
AddGeneratedConversionFuncs
(
conversionFuncs
...
)
}
// AddDeepCopyFuncs adds a function to the list of deep-copy functions.
// For the expected format of deep-copy function, see the comment for
// Copier.RegisterDeepCopyFunction.
func
(
s
*
Scheme
)
AddDeepCopyFuncs
(
deepCopyFuncs
...
interface
{})
error
{
return
s
.
raw
.
AddDeepCopyFuncs
(
deepCopyFuncs
...
)
}
// Similar to AddDeepCopyFuncs, but registers deep-copy functions that were
// automatically generated.
func
(
s
*
Scheme
)
AddGeneratedDeepCopyFuncs
(
deepCopyFuncs
...
interface
{})
error
{
return
s
.
raw
.
AddGeneratedDeepCopyFuncs
(
deepCopyFuncs
...
)
}
// AddFieldLabelConversionFunc adds a conversion function to convert field selectors
// of the given kind from the given version to internal version representation.
func
(
s
*
Scheme
)
AddFieldLabelConversionFunc
(
version
,
kind
string
,
conversionFunc
FieldLabelConversionFunc
)
error
{
...
...
@@ -347,6 +360,11 @@ func (s *Scheme) AddDefaultingFuncs(defaultingFuncs ...interface{}) error {
return
s
.
raw
.
AddDefaultingFuncs
(
defaultingFuncs
...
)
}
// Performs a deep copy of the given object.
func
(
s
*
Scheme
)
DeepCopy
(
src
interface
{})
(
interface
{},
error
)
{
return
s
.
raw
.
DeepCopy
(
src
)
}
// Convert will attempt to convert in into out. Both must be pointers.
// For easy testing of conversion functions. Returns an error if the conversion isn't
// possible.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment