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
5f2dae4d
Commit
5f2dae4d
authored
Jan 07, 2015
by
Tim Hockin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3195 from lavalamp/numericWire
Add numeric type into api
parents
2c54dd5c
2050131b
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
361 additions
and
440 deletions
+361
-440
controller-manager.go
cmd/kube-controller-manager/controller-manager.go
+5
-17
helpers.go
pkg/api/helpers.go
+22
-0
latest_test.go
pkg/api/latest/latest_test.go
+1
-2
quantity.go
pkg/api/resource/quantity.go
+7
-10
quantity_example_test.go
pkg/api/resource/quantity_example_test.go
+5
-5
serialization_test.go
pkg/api/serialization_test.go
+16
-3
types.go
pkg/api/types.go
+27
-6
conversion.go
pkg/api/v1beta1/conversion.go
+60
-1
conversion_test.go
pkg/api/v1beta1/conversion_test.go
+2
-2
types.go
pkg/api/v1beta1/types.go
+8
-1
conversion.go
pkg/api/v1beta2/conversion.go
+60
-1
types.go
pkg/api/v1beta2/types.go
+8
-1
types.go
pkg/api/v1beta3/types.go
+18
-8
validation.go
pkg/api/validation/validation.go
+3
-4
validation_test.go
pkg/api/validation/validation_test.go
+13
-12
client_test.go
pkg/client/client_test.go
+4
-4
gce.go
pkg/cloudprovider/gce/gce.go
+9
-7
openstack.go
pkg/cloudprovider/openstack/openstack.go
+6
-6
replication_controller_test.go
pkg/controller/replication_controller_test.go
+2
-3
deep_equal_test.go
pkg/conversion/deep_equal_test.go
+17
-0
config_test.go
pkg/kubelet/config/config_test.go
+1
-8
file_test.go
pkg/kubelet/config/file_test.go
+4
-5
http_test.go
pkg/kubelet/config/http_test.go
+1
-2
kubelet.go
pkg/kubelet/kubelet.go
+3
-3
rest_test.go
pkg/registry/controller/rest_test.go
+3
-4
etcd_test.go
pkg/registry/etcd/etcd_test.go
+3
-3
doc.go
pkg/resources/doc.go
+0
-18
resources.go
pkg/resources/resources.go
+0
-75
resources_test.go
pkg/resources/resources_test.go
+0
-169
predicates.go
pkg/scheduler/predicates.go
+8
-10
predicates_test.go
pkg/scheduler/predicates_test.go
+6
-13
priorities.go
pkg/scheduler/priorities.go
+20
-12
priorities_test.go
pkg/scheduler/priorities_test.go
+8
-9
standalone.go
pkg/standalone/standalone.go
+3
-16
util.go
pkg/util/util.go
+8
-0
No files found.
cmd/kube-controller-manager/controller-manager.go
View file @
5f2dae4d
...
...
@@ -22,20 +22,19 @@ package main
import
(
"flag"
"math"
"net"
"net/http"
"strconv"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
minionControllerPkg
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
replicationControllerPkg
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
_
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag"
...
...
@@ -51,8 +50,9 @@ var (
minionRegexp
=
flag
.
String
(
"minion_regexp"
,
""
,
"If non empty, and -cloud_provider is specified, a regular expression for matching minion VMs."
)
machineList
util
.
StringList
// TODO: Discover these by pinging the host machines, and rip out these flags.
// TODO: in the meantime, use resource.QuantityFlag() instead of these
nodeMilliCPU
=
flag
.
Int64
(
"node_milli_cpu"
,
1000
,
"The amount of MilliCPU provisioned on each node"
)
nodeMemory
=
flag
.
Int64
(
"node_memory"
,
3
*
1024
*
1024
*
1024
,
"The amount of memory (in bytes) provisioned on each node"
)
nodeMemory
=
resource
.
QuantityFlag
(
"node_memory"
,
"3Gi"
,
"The amount of memory (in bytes) provisioned on each node"
)
)
func
init
()
{
...
...
@@ -90,18 +90,6 @@ func main() {
glog
.
Fatalf
(
"Invalid API configuration: %v"
,
err
)
}
if
int64
(
int
(
*
nodeMilliCPU
))
!=
*
nodeMilliCPU
{
glog
.
Warningf
(
"node_milli_cpu is too big for platform. Clamping: %d -> %d"
,
*
nodeMilliCPU
,
math
.
MaxInt32
)
*
nodeMilliCPU
=
math
.
MaxInt32
}
if
int64
(
int
(
*
nodeMemory
))
!=
*
nodeMemory
{
glog
.
Warningf
(
"node_memory is too big for platform. Clamping: %d -> %d"
,
*
nodeMemory
,
math
.
MaxInt32
)
*
nodeMemory
=
math
.
MaxInt32
}
go
http
.
ListenAndServe
(
net
.
JoinHostPort
(
address
.
String
(),
strconv
.
Itoa
(
*
port
)),
nil
)
endpoints
:=
service
.
NewEndpointController
(
kubeClient
)
...
...
@@ -113,8 +101,8 @@ func main() {
cloud
:=
cloudprovider
.
InitCloudProvider
(
*
cloudProvider
,
*
cloudConfigFile
)
nodeResources
:=
&
api
.
NodeResources
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
NewIntOrStringFromInt
(
int
(
*
nodeMilliCPU
)
),
resources
.
Memory
:
util
.
NewIntOrStringFromInt
(
int
(
*
nodeMemory
))
,
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
*
nodeMilliCPU
,
resource
.
DecimalSI
),
api
.
ResourceMemory
:
*
nodeMemory
,
},
}
minionController
:=
minionControllerPkg
.
NewMinionController
(
cloud
,
*
minionRegexp
,
machineList
,
nodeResources
,
kubeClient
)
...
...
pkg/api/helpers.go
View file @
5f2dae4d
...
...
@@ -18,6 +18,28 @@ package api
import
(
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
// Semantic can do semantic deep equality checks for api objects.
// Example: api.Semantic.DeepEqual(aPod, aPodWithNonNilButEmptyMaps) == true
var
Semantic
=
conversion
.
EqualitiesOrDie
(
func
(
a
,
b
resource
.
Quantity
)
bool
{
// Ignore formatting, only care that numeric value stayed the same.
// TODO: if we decide it's important, after we drop v1beta1/2, we
// could start comparing format.
//
// Uninitialized quantities are equivilent to 0 quantities.
if
a
.
Amount
==
nil
&&
b
.
MilliValue
()
==
0
{
return
true
}
if
b
.
Amount
==
nil
&&
a
.
MilliValue
()
==
0
{
return
true
}
return
a
.
Amount
.
Cmp
(
b
.
Amount
)
==
0
},
)
// TODO: Address these per #1502
...
...
pkg/api/latest/latest_test.go
View file @
5f2dae4d
...
...
@@ -18,7 +18,6 @@ package latest
import
(
"encoding/json"
"reflect"
"strconv"
"testing"
...
...
@@ -167,7 +166,7 @@ func TestInternalRoundTrip(t *testing.T) {
continue
}
if
!
reflect
.
DeepEqual
(
obj
,
actual
)
{
if
!
internal
.
Semantic
.
DeepEqual
(
obj
,
actual
)
{
t
.
Errorf
(
"%s: diff %s"
,
k
,
util
.
ObjectDiff
(
obj
,
actual
))
}
}
...
...
pkg/api/resource/quantity.go
View file @
5f2dae4d
...
...
@@ -102,14 +102,14 @@ const (
DecimalSI
=
Format
(
"DecimalSI"
)
// e.g., 12M (12 * 10^6)
)
//
ParseOrDi
e turns the given string into a quantity or panics; for tests
//
MustPars
e turns the given string into a quantity or panics; for tests
// or others cases where you know the string is valid.
func
ParseOrDie
(
str
string
)
*
Quantity
{
func
MustParse
(
str
string
)
Quantity
{
q
,
err
:=
ParseQuantity
(
str
)
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"cannot parse '%v': %v"
,
str
,
err
))
}
return
q
return
*
q
}
const
(
...
...
@@ -148,7 +148,7 @@ var (
// The maximum value we can represent milli-units for.
// Compare with the return value of Quantity.Value() to
// see if it's safe to use Quantity.MilliValue().
MaxMilliValue
=
((
1
<<
63
)
-
1
)
/
1000
MaxMilliValue
=
int64
(((
1
<<
63
)
-
1
)
/
1000
)
)
// ParseQuantity turns str into a Quantity, or returns an error.
...
...
@@ -403,10 +403,7 @@ func (qf qFlag) String() string {
// QuantityFlag is a helper that makes a quantity flag (using standard flag package).
// Will panic if defaultValue is not a valid quantity.
func
QuantityFlag
(
flagName
,
defaultValue
,
description
string
)
*
Quantity
{
q
,
err
:=
ParseQuantity
(
defaultValue
)
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"can't use %v as a quantity: %v"
,
defaultValue
,
err
))
}
flag
.
Var
(
qFlag
{
q
},
flagName
,
description
)
return
q
q
:=
MustParse
(
defaultValue
)
flag
.
Var
(
qFlag
{
&
q
},
flagName
,
description
)
return
&
q
}
pkg/api/resource/quantity_example_test.go
View file @
5f2dae4d
...
...
@@ -38,17 +38,17 @@ func ExampleFormat() {
// cores = 5300m
}
func
Example
ParseOrDi
e
()
{
memorySize
:=
resource
.
ParseOrDi
e
(
"5Gi"
)
func
Example
MustPars
e
()
{
memorySize
:=
resource
.
MustPars
e
(
"5Gi"
)
fmt
.
Printf
(
"memorySize = %v (%v)
\n
"
,
memorySize
.
Value
(),
memorySize
.
Format
)
diskSize
:=
resource
.
ParseOrDi
e
(
"5G"
)
diskSize
:=
resource
.
MustPars
e
(
"5G"
)
fmt
.
Printf
(
"diskSize = %v (%v)
\n
"
,
diskSize
.
Value
(),
diskSize
.
Format
)
cores
:=
resource
.
ParseOrDi
e
(
"5300m"
)
cores
:=
resource
.
MustPars
e
(
"5300m"
)
fmt
.
Printf
(
"milliCores = %v (%v)
\n
"
,
cores
.
MilliValue
(),
cores
.
Format
)
cores2
:=
resource
.
ParseOrDi
e
(
"5.4"
)
cores2
:=
resource
.
MustPars
e
(
"5.4"
)
fmt
.
Printf
(
"milliCores = %v (%v)
\n
"
,
cores2
.
MilliValue
(),
cores2
.
Format
)
// Output:
...
...
pkg/api/serialization_test.go
View file @
5f2dae4d
...
...
@@ -27,12 +27,15 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
docker
"github.com/fsouza/go-dockerclient"
fuzz
"github.com/google/gofuzz"
"speter.net/go/exp/math/dec/inf"
)
var
fuzzIters
=
flag
.
Int
(
"fuzz_iters"
,
40
,
"How many fuzzing iterations to do."
)
...
...
@@ -136,6 +139,16 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
c
.
RandString
()
:
c
.
RandString
(),
}
},
func
(
q
*
resource
.
Quantity
,
c
fuzz
.
Continue
)
{
// Real Quantity fuzz testing is done elsewhere;
// this limited subset of functionality survives
// round-tripping to v1beta1/2.
q
.
Amount
=
&
inf
.
Dec
{}
q
.
Format
=
resource
.
DecimalExponent
//q.Amount.SetScale(inf.Scale(-c.Intn(12)))
q
.
Amount
.
SetUnscaled
(
c
.
Int63n
(
1000
))
},
)
func
runTest
(
t
*
testing
.
T
,
codec
runtime
.
Codec
,
source
runtime
.
Object
)
{
...
...
@@ -159,7 +172,7 @@ func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) {
t
.
Errorf
(
"0: %v: %v
\n
Codec: %v
\n
Data: %s
\n
Source: %#v"
,
name
,
err
,
codec
,
string
(
data
),
source
)
return
}
if
!
reflect
.
DeepEqual
(
source
,
obj2
)
{
if
!
api
.
Semantic
.
DeepEqual
(
source
,
obj2
)
{
t
.
Errorf
(
"1: %v: diff: %v
\n
Codec: %v
\n
Data: %s
\n
Source: %#v"
,
name
,
util
.
ObjectGoPrintDiff
(
source
,
obj2
),
codec
,
string
(
data
),
source
)
return
}
...
...
@@ -170,7 +183,7 @@ func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) {
t
.
Errorf
(
"2: %v: %v"
,
name
,
err
)
return
}
if
!
reflect
.
DeepEqual
(
source
,
obj3
)
{
if
!
api
.
Semantic
.
DeepEqual
(
source
,
obj3
)
{
t
.
Errorf
(
"3: %v: diff: %v
\n
Codec: %v"
,
name
,
util
.
ObjectDiff
(
source
,
obj3
),
codec
)
return
}
...
...
@@ -244,7 +257,7 @@ func TestEncode_Ptr(t *testing.T) {
if
_
,
ok
:=
obj2
.
(
*
api
.
Pod
);
!
ok
{
t
.
Fatalf
(
"Got wrong type"
)
}
if
!
reflect
.
DeepEqual
(
obj2
,
pod
)
{
if
!
api
.
Semantic
.
DeepEqual
(
obj2
,
pod
)
{
t
.
Errorf
(
"Expected:
\n
%#v,
\n
Got:
\n
%#v"
,
&
pod
,
obj2
)
}
}
...
...
pkg/api/types.go
View file @
5f2dae4d
...
...
@@ -17,6 +17,7 @@ limitations under the License.
package
api
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
...
...
@@ -309,12 +310,12 @@ type Container struct {
Ports
[]
Port
`json:"ports,omitempty"`
Env
[]
EnvVar
`json:"env,omitempty"`
// Optional: Defaults to unlimited.
Memory
int
`json:"memory,omitempty"`
Memory
resource
.
Quantity
`json:"memory,omitempty"`
// Optional: Defaults to unlimited.
CPU
int
`json:"cpu,omitempty"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty"`
LivenessProbe
*
LivenessProbe
`json:"livenessProbe,omitempty"`
Lifecycle
*
Lifecycle
`json:"lifecycle,omitempty"`
CPU
resource
.
Quantity
`json:"cpu,omitempty"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty"`
LivenessProbe
*
LivenessProbe
`json:"livenessProbe,omitempty"`
Lifecycle
*
Lifecycle
`json:"lifecycle,omitempty"`
// Optional: Defaults to /dev/termination-log
TerminationMessagePath
string
`json:"terminationMessagePath,omitempty"`
// Optional: Default to false.
...
...
@@ -747,9 +748,29 @@ type NodeResources struct {
Capacity
ResourceList
`json:"capacity,omitempty"`
}
// ResourceName is the name identifying various resources in a ResourceList.
type
ResourceName
string
type
ResourceList
map
[
ResourceName
]
util
.
IntOrString
const
(
// CPU, in cores. (500m = .5 cores)
ResourceCPU
ResourceName
=
"cpu"
// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
ResourceMemory
ResourceName
=
"memory"
)
// ResourceList is a set of (resource name, quantity) pairs.
type
ResourceList
map
[
ResourceName
]
resource
.
Quantity
// Get is a convenience function, which returns a 0 quantity if the
// resource list is nil, empty, or lacks a value for the requested resource.
// Treat as read only!
func
(
rl
ResourceList
)
Get
(
name
ResourceName
)
*
resource
.
Quantity
{
if
rl
==
nil
{
return
&
resource
.
Quantity
{}
}
q
:=
rl
[
name
]
return
&
q
}
// Node is a worker node in Kubernetenes
// The name of the node according to etcd is in ObjectMeta.Name.
...
...
pkg/api/v1beta1/conversion.go
View file @
5f2dae4d
...
...
@@ -18,10 +18,13 @@ package v1beta1
import
(
"errors"
"fmt"
"strconv"
newer
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func
init
()
{
...
...
@@ -38,7 +41,7 @@ func init() {
// newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition")
// newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status")
newer
.
Scheme
.
AddConversionFuncs
(
err
:=
newer
.
Scheme
.
AddConversionFuncs
(
// TypeMeta must be split into two objects
func
(
in
*
newer
.
TypeMeta
,
out
*
TypeMeta
,
s
conversion
.
Scope
)
error
{
out
.
Kind
=
in
.
Kind
...
...
@@ -582,5 +585,61 @@ func init() {
out
.
Timestamp
=
in
.
Timestamp
return
s
.
Convert
(
&
in
.
InvolvedObject
,
&
out
.
InvolvedObject
,
0
)
},
// This is triggered for the Memory field of Container.
func
(
in
*
int64
,
out
*
resource
.
Quantity
,
s
conversion
.
Scope
)
error
{
out
.
Set
(
*
in
)
out
.
Format
=
resource
.
BinarySI
return
nil
},
func
(
in
*
resource
.
Quantity
,
out
*
int64
,
s
conversion
.
Scope
)
error
{
*
out
=
in
.
Value
()
return
nil
},
// This is triggered by the CPU field of Container.
// Note that if we add other int/Quantity conversions my
// simple hack (int64=Value(), int=MilliValue()) here won't work.
func
(
in
*
int
,
out
*
resource
.
Quantity
,
s
conversion
.
Scope
)
error
{
out
.
SetMilli
(
int64
(
*
in
))
out
.
Format
=
resource
.
DecimalSI
return
nil
},
func
(
in
*
resource
.
Quantity
,
out
*
int
,
s
conversion
.
Scope
)
error
{
*
out
=
int
(
in
.
MilliValue
())
return
nil
},
// Convert resource lists.
func
(
in
*
ResourceList
,
out
*
newer
.
ResourceList
,
s
conversion
.
Scope
)
error
{
*
out
=
newer
.
ResourceList
{}
for
k
,
v
:=
range
*
in
{
fv
,
err
:=
strconv
.
ParseFloat
(
v
.
String
(),
64
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"value '%v' of '%v': %v"
,
v
,
k
,
err
)
}
if
k
==
ResourceCPU
{
(
*
out
)[
newer
.
ResourceCPU
]
=
*
resource
.
NewMilliQuantity
(
int64
(
fv
*
1000
),
resource
.
DecimalSI
)
}
else
{
(
*
out
)[
newer
.
ResourceName
(
k
)]
=
*
resource
.
NewQuantity
(
int64
(
fv
),
resource
.
BinarySI
)
}
}
return
nil
},
func
(
in
*
newer
.
ResourceList
,
out
*
ResourceList
,
s
conversion
.
Scope
)
error
{
*
out
=
ResourceList
{}
for
k
,
v
:=
range
*
in
{
if
k
==
newer
.
ResourceCPU
{
(
*
out
)[
ResourceCPU
]
=
util
.
NewIntOrStringFromString
(
fmt
.
Sprintf
(
"%v"
,
float64
(
v
.
MilliValue
())
/
1000
))
}
else
{
(
*
out
)[
ResourceName
(
k
)]
=
util
.
NewIntOrStringFromInt
(
int
(
v
.
Value
()))
}
}
return
nil
},
)
if
err
!=
nil
{
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
}
}
pkg/api/v1beta1/conversion_test.go
View file @
5f2dae4d
...
...
@@ -201,7 +201,7 @@ func TestMinionListConversionToNew(t *testing.T) {
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
e
,
a
:=
item
.
newML
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
if
e
,
a
:=
item
.
newML
,
got
;
!
newer
.
Semantic
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Expected: %#v, got %#v"
,
e
,
a
)
}
}
...
...
@@ -234,7 +234,7 @@ func TestMinionListConversionToOld(t *testing.T) {
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
e
,
a
:=
oldML
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
if
e
,
a
:=
oldML
,
got
;
!
newer
.
Semantic
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Expected: %#v, got %#v"
,
e
,
a
)
}
}
...
...
pkg/api/v1beta1/types.go
View file @
5f2dae4d
...
...
@@ -254,7 +254,7 @@ type Container struct {
Ports
[]
Port
`json:"ports,omitempty" description:"list of ports to expose from the container"`
Env
[]
EnvVar
`json:"env,omitempty" description:"list of environment variables to set in the container"`
// Optional: Defaults to unlimited.
Memory
int
`json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
Memory
int
64
`json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
// Optional: Defaults to unlimited.
CPU
int
`json:"cpu,omitempty" description:"CPU share in thousandths of a core"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesystem"`
...
...
@@ -583,6 +583,13 @@ type NodeResources struct {
type
ResourceName
string
const
(
// CPU, in cores. (floating point w/ 3 decimal places)
ResourceCPU
ResourceName
=
"cpu"
// Memory, in bytes.
ResourceMemory
ResourceName
=
"memory"
)
type
ResourceList
map
[
ResourceName
]
util
.
IntOrString
// Minion is a worker node in Kubernetenes.
...
...
pkg/api/v1beta2/conversion.go
View file @
5f2dae4d
...
...
@@ -18,10 +18,13 @@ package v1beta2
import
(
"errors"
"fmt"
"strconv"
newer
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func
init
()
{
...
...
@@ -38,7 +41,7 @@ func init() {
// newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition")
// newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status")
newer
.
Scheme
.
AddConversionFuncs
(
err
:=
newer
.
Scheme
.
AddConversionFuncs
(
// TypeMeta must be split into two objects
func
(
in
*
newer
.
TypeMeta
,
out
*
TypeMeta
,
s
conversion
.
Scope
)
error
{
out
.
Kind
=
in
.
Kind
...
...
@@ -498,5 +501,61 @@ func init() {
out
.
Timestamp
=
in
.
Timestamp
return
s
.
Convert
(
&
in
.
InvolvedObject
,
&
out
.
InvolvedObject
,
0
)
},
// This is triggered for the Memory field of Container.
func
(
in
*
int64
,
out
*
resource
.
Quantity
,
s
conversion
.
Scope
)
error
{
out
.
Set
(
*
in
)
out
.
Format
=
resource
.
BinarySI
return
nil
},
func
(
in
*
resource
.
Quantity
,
out
*
int64
,
s
conversion
.
Scope
)
error
{
*
out
=
in
.
Value
()
return
nil
},
// This is triggered by the CPU field of Container.
// Note that if we add other int/Quantity conversions my
// simple hack (int64=Value(), int=MilliValue()) here won't work.
func
(
in
*
int
,
out
*
resource
.
Quantity
,
s
conversion
.
Scope
)
error
{
out
.
SetMilli
(
int64
(
*
in
))
out
.
Format
=
resource
.
DecimalSI
return
nil
},
func
(
in
*
resource
.
Quantity
,
out
*
int
,
s
conversion
.
Scope
)
error
{
*
out
=
int
(
in
.
MilliValue
())
return
nil
},
// Convert resource lists.
func
(
in
*
ResourceList
,
out
*
newer
.
ResourceList
,
s
conversion
.
Scope
)
error
{
*
out
=
newer
.
ResourceList
{}
for
k
,
v
:=
range
*
in
{
fv
,
err
:=
strconv
.
ParseFloat
(
v
.
String
(),
64
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"value '%v' of '%v': %v"
,
v
,
k
,
err
)
}
if
k
==
ResourceCPU
{
(
*
out
)[
newer
.
ResourceCPU
]
=
*
resource
.
NewMilliQuantity
(
int64
(
fv
*
1000
),
resource
.
DecimalSI
)
}
else
{
(
*
out
)[
newer
.
ResourceName
(
k
)]
=
*
resource
.
NewQuantity
(
int64
(
fv
),
resource
.
BinarySI
)
}
}
return
nil
},
func
(
in
*
newer
.
ResourceList
,
out
*
ResourceList
,
s
conversion
.
Scope
)
error
{
*
out
=
ResourceList
{}
for
k
,
v
:=
range
*
in
{
if
k
==
newer
.
ResourceCPU
{
(
*
out
)[
ResourceCPU
]
=
util
.
NewIntOrStringFromString
(
fmt
.
Sprintf
(
"%v"
,
float64
(
v
.
MilliValue
())
/
1000
))
}
else
{
(
*
out
)[
ResourceName
(
k
)]
=
util
.
NewIntOrStringFromInt
(
int
(
v
.
Value
()))
}
}
return
nil
},
)
if
err
!=
nil
{
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
}
}
pkg/api/v1beta2/types.go
View file @
5f2dae4d
...
...
@@ -218,7 +218,7 @@ type Container struct {
Ports
[]
Port
`json:"ports,omitempty" description:"list of ports to expose from the container"`
Env
[]
EnvVar
`json:"env,omitempty" description:"list of environment variables to set in the container"`
// Optional: Defaults to unlimited.
Memory
int
`json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
Memory
int
64
`json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
// Optional: Defaults to unlimited.
CPU
int
`json:"cpu,omitempty" description:"CPU share in thousandths of a core"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesystem"`
...
...
@@ -546,6 +546,13 @@ type NodeResources struct {
type
ResourceName
string
const
(
// CPU, in cores. (500m = .5 cores)
ResourceCPU
ResourceName
=
"cpu"
// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
ResourceMemory
ResourceName
=
"memory"
)
type
ResourceList
map
[
ResourceName
]
util
.
IntOrString
// Minion is a worker node in Kubernetenes.
...
...
pkg/api/v1beta3/types.go
View file @
5f2dae4d
...
...
@@ -17,6 +17,7 @@ limitations under the License.
package
v1beta3
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
...
...
@@ -326,13 +327,13 @@ type Container struct {
WorkingDir
string
`json:"workingDir,omitempty"`
Ports
[]
Port
`json:"ports,omitempty"`
Env
[]
EnvVar
`json:"env,omitempty"`
// Optional: Defaults to unlimited.
Memory
int
`json:"memory,omitempty"`
// Optional: Defaults to unlimited.
CPU
int
`json:"cpu,omitempty"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty"`
LivenessProbe
*
LivenessProbe
`json:"livenessProbe,omitempty"`
Lifecycle
*
Lifecycle
`json:"lifecycle,omitempty"`
// Optional: Defaults to unlimited.
Units: bytes.
Memory
resource
.
Quantity
`json:"memory,omitempty"`
// Optional: Defaults to unlimited.
Units: Cores. (500m == 1/2 core)
CPU
resource
.
Quantity
`json:"cpu,omitempty"`
VolumeMounts
[]
VolumeMount
`json:"volumeMounts,omitempty"`
LivenessProbe
*
LivenessProbe
`json:"livenessProbe,omitempty"`
Lifecycle
*
Lifecycle
`json:"lifecycle,omitempty"`
// Optional: Defaults to /dev/termination-log
TerminationMessagePath
string
`json:"terminationMessagePath,omitempty"`
// Optional: Default to false.
...
...
@@ -776,9 +777,18 @@ type NodeCondition struct {
Message
string
`json:"message,omitempty"`
}
// ResourceName is the name identifying various resources in a ResourceList.
type
ResourceName
string
type
ResourceList
map
[
ResourceName
]
util
.
IntOrString
const
(
// CPU, in cores. (500m = .5 cores)
ResourceCPU
ResourceName
=
"cpu"
// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
ResourceMemory
ResourceName
=
"memory"
)
// ResourceList is a set of (resource name, quantity) pairs.
type
ResourceList
map
[
ResourceName
]
resource
.
Quantity
// Node is a worker node in Kubernetes.
// The name of the node according to etcd is in ID.
...
...
pkg/api/validation/validation.go
View file @
5f2dae4d
...
...
@@ -18,7 +18,6 @@ package validation
import
(
"fmt"
"reflect"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...
...
@@ -429,7 +428,7 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
newContainers
=
append
(
newContainers
,
container
)
}
pod
.
Spec
.
Containers
=
newContainers
if
!
reflect
.
DeepEqual
(
pod
.
Spec
,
oldPod
.
Spec
)
{
if
!
api
.
Semantic
.
DeepEqual
(
pod
.
Spec
,
oldPod
.
Spec
)
{
// TODO: a better error would include all immutable fields explicitly.
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"spec.containers"
,
newPod
.
Spec
.
Containers
,
"some fields are immutable"
))
}
...
...
@@ -586,7 +585,7 @@ func ValidateMinion(minion *api.Node) errs.ValidationErrorList {
func
ValidateMinionUpdate
(
oldMinion
*
api
.
Node
,
minion
*
api
.
Node
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
if
!
reflect
.
DeepEqual
(
minion
.
Status
,
api
.
NodeStatus
{})
{
if
!
api
.
Semantic
.
DeepEqual
(
minion
.
Status
,
api
.
NodeStatus
{})
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"status"
,
minion
.
Status
,
"status must be empty"
))
}
...
...
@@ -596,7 +595,7 @@ func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.Validation
// Clear status
oldMinion
.
Status
=
minion
.
Status
if
!
reflect
.
DeepEqual
(
oldMinion
,
minion
)
{
if
!
api
.
Semantic
.
DeepEqual
(
oldMinion
,
minion
)
{
glog
.
V
(
4
)
.
Infof
(
"Update failed validation %#v vs %#v"
,
oldMinion
,
minion
)
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"update contains more than labels or capacity changes"
))
}
...
...
pkg/api/validation/validation_test.go
View file @
5f2dae4d
...
...
@@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
...
...
@@ -372,8 +373,8 @@ func TestValidateManifest(t *testing.T) {
Image
:
"image"
,
Command
:
[]
string
{
"foo"
,
"bar"
},
WorkingDir
:
"/tmp"
,
Memory
:
1
,
CPU
:
1
,
Memory
:
resource
.
MustParse
(
"1"
)
,
CPU
:
resource
.
MustParse
(
"1"
)
,
Ports
:
[]
api
.
Port
{
{
Name
:
"p1"
,
ContainerPort
:
80
,
HostPort
:
8080
},
{
Name
:
"p2"
,
ContainerPort
:
81
},
...
...
@@ -623,7 +624,7 @@ func TestValidatePodUpdate(t *testing.T) {
Containers
:
[]
api
.
Container
{
{
Image
:
"foo:V1"
,
CPU
:
100
,
CPU
:
resource
.
MustParse
(
"100m"
)
,
},
},
},
...
...
@@ -634,7 +635,7 @@ func TestValidatePodUpdate(t *testing.T) {
Containers
:
[]
api
.
Container
{
{
Image
:
"foo:V2"
,
CPU
:
1000
,
CPU
:
resource
.
MustParse
(
"1000m"
)
,
},
},
},
...
...
@@ -1300,8 +1301,8 @@ func TestValidateMinionUpdate(t *testing.T) {
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
"cpu"
:
util
.
NewIntOrStringFromInt
(
10000
),
"memory"
:
util
.
NewIntOrStringFromInt
(
100
),
api
.
ResourceCPU
:
resource
.
MustParse
(
"10000"
),
api
.
ResourceMemory
:
resource
.
MustParse
(
"100"
),
},
},
},
api
.
Node
{
...
...
@@ -1310,8 +1311,8 @@ func TestValidateMinionUpdate(t *testing.T) {
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
"cpu"
:
util
.
NewIntOrStringFromInt
(
100
),
"memory"
:
util
.
NewIntOrStringFromInt
(
10000
),
api
.
ResourceCPU
:
resource
.
MustParse
(
"100"
),
api
.
ResourceMemory
:
resource
.
MustParse
(
"10000"
),
},
},
},
true
},
...
...
@@ -1322,8 +1323,8 @@ func TestValidateMinionUpdate(t *testing.T) {
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
"cpu"
:
util
.
NewIntOrStringFromInt
(
10000
),
"memory"
:
util
.
NewIntOrStringFromInt
(
100
),
api
.
ResourceCPU
:
resource
.
MustParse
(
"10000"
),
api
.
ResourceMemory
:
resource
.
MustParse
(
"100"
),
},
},
},
api
.
Node
{
...
...
@@ -1333,8 +1334,8 @@ func TestValidateMinionUpdate(t *testing.T) {
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
"cpu"
:
util
.
NewIntOrStringFromInt
(
100
),
"memory"
:
util
.
NewIntOrStringFromInt
(
10000
),
api
.
ResourceCPU
:
resource
.
MustParse
(
"100"
),
api
.
ResourceMemory
:
resource
.
MustParse
(
"10000"
),
},
},
},
true
},
...
...
pkg/client/client_test.go
View file @
5f2dae4d
...
...
@@ -28,9 +28,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
...
...
@@ -96,7 +96,7 @@ func (c *testClient) Setup() *testClient {
func
(
c
*
testClient
)
Validate
(
t
*
testing
.
T
,
received
runtime
.
Object
,
err
error
)
{
c
.
ValidateCommon
(
t
,
err
)
if
c
.
Response
.
Body
!=
nil
&&
!
reflect
.
DeepEqual
(
c
.
Response
.
Body
,
received
)
{
if
c
.
Response
.
Body
!=
nil
&&
!
api
.
Semantic
.
DeepEqual
(
c
.
Response
.
Body
,
received
)
{
t
.
Errorf
(
"bad response for request %#v: expected %#v, got %#v"
,
c
.
Request
,
c
.
Response
.
Body
,
received
)
}
}
...
...
@@ -734,8 +734,8 @@ func TestCreateMinion(t *testing.T) {
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
NewIntOrStringFromInt
(
1000
),
resources
.
Memory
:
util
.
NewIntOrStringFromInt
(
1024
*
1024
),
api
.
ResourceCPU
:
resource
.
MustParse
(
"1000m"
),
api
.
ResourceMemory
:
resource
.
MustParse
(
"1Mi"
),
},
},
}
...
...
pkg/cloudprovider/gce/gce.go
View file @
5f2dae4d
...
...
@@ -28,13 +28,13 @@ import (
"strings"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"code.google.com/p/goauth2/compute/serviceaccount"
compute
"code.google.com/p/google-api-go-client/compute/v1"
container
"code.google.com/p/google-api-go-client/container/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
)
...
...
@@ -338,11 +338,12 @@ func (gce *GCECloud) List(filter string) ([]string, error) {
return
instances
,
nil
}
func
makeResources
(
cpu
float32
,
memory
float32
)
*
api
.
NodeResources
{
// cpu is in cores, memory is in GiB
func
makeResources
(
cpu
float64
,
memory
float64
)
*
api
.
NodeResources
{
return
&
api
.
NodeResources
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
NewIntOrStringFromInt
(
int
(
cpu
*
1000
)
),
resources
.
Memory
:
util
.
NewIntOrStringFromInt
(
int
(
memory
*
1024
*
1024
*
1024
)
),
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
int64
(
cpu
*
1000
),
resource
.
DecimalSI
),
api
.
ResourceMemory
:
*
resource
.
NewQuantity
(
int64
(
memory
*
1024
*
1024
*
1024
),
resource
.
BinarySI
),
},
}
}
...
...
@@ -359,6 +360,7 @@ func (gce *GCECloud) GetNodeResources(name string) (*api.NodeResources, error) {
if
err
!=
nil
{
return
nil
,
err
}
// TODO: actually read machine size instead of this awful hack.
switch
canonicalizeMachineType
(
res
.
MachineType
)
{
case
"f1-micro"
:
return
makeResources
(
1
,
0.6
),
nil
...
...
pkg/cloudprovider/openstack/openstack.go
View file @
5f2dae4d
...
...
@@ -36,8 +36,8 @@ import (
"github.com/rackspace/gophercloud/pagination"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
)
...
...
@@ -169,11 +169,11 @@ func (os *OpenStack) Instances() (cloudprovider.Instances, bool) {
for
_
,
flavor
:=
range
flavorList
{
rsrc
:=
api
.
NodeResources
{
Capacity
:
api
.
ResourceList
{
"cpu"
:
util
.
NewIntOrStringFromInt
(
flavor
.
VCPUs
),
"memory"
:
util
.
NewIntOrStringFromString
(
fmt
.
Sprintf
(
"%dMiB
"
,
flavor
.
RAM
)),
"openstack.org/disk"
:
util
.
NewIntOrStringFromString
(
fmt
.
Sprintf
(
"%dGB
"
,
flavor
.
Disk
)),
"openstack.org/rxTxFactor"
:
util
.
NewIntOrStringFromInt
(
int
(
flavor
.
RxTxFactor
*
1000
)
),
"openstack.org/swap"
:
util
.
NewIntOrStringFromString
(
fmt
.
Sprintf
(
"%dMiB
"
,
flavor
.
Swap
)),
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
int64
(
flavor
.
VCPUs
*
1000
),
resource
.
DecimalSI
),
api
.
ResourceMemory
:
resource
.
MustParse
(
fmt
.
Sprintf
(
"%dMi
"
,
flavor
.
RAM
)),
"openstack.org/disk"
:
resource
.
MustParse
(
fmt
.
Sprintf
(
"%dG
"
,
flavor
.
Disk
)),
"openstack.org/rxTxFactor"
:
*
resource
.
NewQuantity
(
int64
(
flavor
.
RxTxFactor
*
1000
),
resource
.
DecimalSI
),
"openstack.org/swap"
:
resource
.
MustParse
(
fmt
.
Sprintf
(
"%dMi
"
,
flavor
.
Swap
)),
},
}
flavor_to_resource
[
flavor
.
ID
]
=
&
rsrc
...
...
pkg/controller/replication_controller_test.go
View file @
5f2dae4d
...
...
@@ -21,7 +21,6 @@ import (
"net/http"
"net/http/httptest"
"path"
"reflect"
"sync"
"testing"
"time"
...
...
@@ -233,7 +232,7 @@ func TestCreateReplica(t *testing.T) {
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %#v"
,
err
)
}
if
!
reflect
.
DeepEqual
(
&
expectedPod
,
actualPod
)
{
if
!
api
.
Semantic
.
DeepEqual
(
&
expectedPod
,
actualPod
)
{
t
.
Logf
(
"Body: %s"
,
fakeHandler
.
RequestBody
)
t
.
Errorf
(
"Unexpected mismatch. Expected
\n
%#v,
\n
Got:
\n
%#v"
,
&
expectedPod
,
actualPod
)
}
...
...
@@ -345,7 +344,7 @@ func TestWatchControllers(t *testing.T) {
var
testControllerSpec
api
.
ReplicationController
received
:=
make
(
chan
struct
{})
manager
.
syncHandler
=
func
(
controllerSpec
api
.
ReplicationController
)
error
{
if
!
reflect
.
DeepEqual
(
controllerSpec
,
testControllerSpec
)
{
if
!
api
.
Semantic
.
DeepEqual
(
controllerSpec
,
testControllerSpec
)
{
t
.
Errorf
(
"Expected %#v, but got %#v"
,
testControllerSpec
,
controllerSpec
)
}
close
(
received
)
...
...
pkg/conversion/deep_equal_test.go
View file @
5f2dae4d
...
...
@@ -22,15 +22,28 @@ import (
func
TestEqualities
(
t
*
testing
.
T
)
{
e
:=
Equalities
{}
type
Bar
struct
{
X
int
}
type
Baz
struct
{
Y
Bar
}
err
:=
e
.
AddFuncs
(
func
(
a
,
b
int
)
bool
{
return
a
+
1
==
b
},
func
(
a
,
b
Bar
)
bool
{
return
a
.
X
*
10
==
b
.
X
},
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected: %v"
,
err
)
}
type
Foo
struct
{
X
int
}
table
:=
[]
struct
{
a
,
b
interface
{}
equal
bool
...
...
@@ -38,6 +51,10 @@ func TestEqualities(t *testing.T) {
{
1
,
2
,
true
},
{
2
,
1
,
false
},
{
"foo"
,
"foo"
,
true
},
{
Foo
{
1
},
Foo
{
2
},
true
},
{
Bar
{
1
},
Bar
{
10
},
true
},
{
&
Bar
{
1
},
&
Bar
{
10
},
true
},
{
Baz
{
Bar
{
1
}},
Baz
{
Bar
{
10
}},
true
},
{
map
[
string
]
int
{
"foo"
:
1
},
map
[
string
]
int
{
"foo"
:
2
},
true
},
{
map
[
string
]
int
{},
map
[
string
]
int
(
nil
),
true
},
{[]
int
{},
[]
int
(
nil
),
true
},
...
...
pkg/kubelet/config/config_test.go
View file @
5f2dae4d
...
...
@@ -17,7 +17,6 @@ limitations under the License.
package
config
import
(
"reflect"
"sort"
"testing"
...
...
@@ -65,13 +64,7 @@ func CreateValidPod(name, namespace, source string) api.BoundPod {
}
func
CreatePodUpdate
(
op
kubelet
.
PodOperation
,
source
string
,
pods
...
api
.
BoundPod
)
kubelet
.
PodUpdate
{
// We deliberately return an empty slice instead of a nil pointer here
// because reflect.DeepEqual differentiates between the two and we need to
// pick one for consistency.
newPods
:=
make
([]
api
.
BoundPod
,
len
(
pods
))
if
len
(
pods
)
==
0
{
return
kubelet
.
PodUpdate
{
newPods
,
op
,
source
}
}
for
i
:=
range
pods
{
newPods
[
i
]
=
pods
[
i
]
}
...
...
@@ -89,7 +82,7 @@ func expectPodUpdate(t *testing.T, ch <-chan kubelet.PodUpdate, expected ...kube
for
i
:=
range
expected
{
update
:=
<-
ch
sort
.
Sort
(
sortedPods
(
update
.
Pods
))
if
!
reflect
.
DeepEqual
(
expected
[
i
],
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
expected
[
i
],
update
)
{
t
.
Fatalf
(
"Expected %#v, Got %#v"
,
expected
[
i
],
update
)
}
}
...
...
pkg/kubelet/config/file_test.go
View file @
5f2dae4d
...
...
@@ -20,7 +20,6 @@ import (
"encoding/json"
"io/ioutil"
"os"
"reflect"
"sort"
"testing"
"time"
...
...
@@ -130,7 +129,7 @@ func TestReadFromFile(t *testing.T) {
Containers
:
[]
api
.
Container
{{
Image
:
"test/image"
,
TerminationMessagePath
:
"/dev/termination-log"
}},
},
})
if
!
reflect
.
DeepEqual
(
expected
,
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
expected
,
update
)
{
t
.
Fatalf
(
"Expected %#v, Got %#v"
,
expected
,
update
)
}
...
...
@@ -171,7 +170,7 @@ func TestExtractFromValidDataFile(t *testing.T) {
}
update
:=
(
<-
ch
)
.
(
kubelet
.
PodUpdate
)
expected
:=
CreatePodUpdate
(
kubelet
.
SET
,
kubelet
.
FileSource
,
expectedPod
)
if
!
reflect
.
DeepEqual
(
expected
,
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
expected
,
update
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
update
)
}
}
...
...
@@ -192,7 +191,7 @@ func TestExtractFromEmptyDir(t *testing.T) {
update
:=
(
<-
ch
)
.
(
kubelet
.
PodUpdate
)
expected
:=
CreatePodUpdate
(
kubelet
.
SET
,
kubelet
.
FileSource
)
if
!
reflect
.
DeepEqual
(
expected
,
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
expected
,
update
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
update
)
}
}
...
...
@@ -242,7 +241,7 @@ func TestExtractFromDir(t *testing.T) {
expected
:=
CreatePodUpdate
(
kubelet
.
SET
,
kubelet
.
FileSource
,
pods
...
)
sort
.
Sort
(
sortedPods
(
update
.
Pods
))
sort
.
Sort
(
sortedPods
(
expected
.
Pods
))
if
!
reflect
.
DeepEqual
(
expected
,
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
expected
,
update
)
{
t
.
Fatalf
(
"Expected %#v, Got %#v"
,
expected
,
update
)
}
for
i
:=
range
update
.
Pods
{
...
...
pkg/kubelet/config/http_test.go
View file @
5f2dae4d
...
...
@@ -19,7 +19,6 @@ package config
import
(
"encoding/json"
"net/http/httptest"
"reflect"
"testing"
"time"
...
...
@@ -193,7 +192,7 @@ func TestExtractFromHTTP(t *testing.T) {
continue
}
update
:=
(
<-
ch
)
.
(
kubelet
.
PodUpdate
)
if
!
reflect
.
DeepEqual
(
testCase
.
expected
,
update
)
{
if
!
api
.
Semantic
.
DeepEqual
(
testCase
.
expected
,
update
)
{
t
.
Errorf
(
"%s: Expected: %#v, Got: %#v"
,
testCase
.
desc
,
testCase
.
expected
,
update
)
}
for
i
:=
range
update
.
Pods
{
...
...
pkg/kubelet/kubelet.go
View file @
5f2dae4d
...
...
@@ -398,7 +398,7 @@ func makePortsAndBindings(container *api.Container) (map[docker.Port]struct{}, m
return
exposedPorts
,
portBindings
}
func
milliCPUToShares
(
milliCPU
int
)
int
{
func
milliCPUToShares
(
milliCPU
int
64
)
int64
{
if
milliCPU
==
0
{
// zero milliCPU means unset. Use kernel default.
return
0
...
...
@@ -537,8 +537,8 @@ func (kl *Kubelet) runContainer(pod *api.BoundPod, container *api.Container, pod
ExposedPorts
:
exposedPorts
,
Hostname
:
pod
.
Name
,
Image
:
container
.
Image
,
Memory
:
int64
(
container
.
Memory
),
CPUShares
:
int64
(
milliCPUToShares
(
container
.
CPU
)),
Memory
:
container
.
Memory
.
Value
(
),
CPUShares
:
milliCPUToShares
(
container
.
CPU
.
MilliValue
(
)),
WorkingDir
:
container
.
WorkingDir
,
},
}
...
...
pkg/registry/controller/rest_test.go
View file @
5f2dae4d
...
...
@@ -20,7 +20,6 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"reflect"
"strings"
"testing"
"time"
...
...
@@ -136,7 +135,7 @@ func TestControllerDecode(t *testing.T) {
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
!
reflect
.
DeepEqual
(
controller
,
controllerOut
)
{
if
!
api
.
Semantic
.
DeepEqual
(
controller
,
controllerOut
)
{
t
.
Errorf
(
"Expected %#v, found %#v"
,
controller
,
controllerOut
)
}
}
...
...
@@ -208,7 +207,7 @@ func TestControllerParsing(t *testing.T) {
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
!
reflect
.
DeepEqual
(
controller
,
expectedController
)
{
if
!
api
.
Semantic
.
DeepEqual
(
controller
,
expectedController
)
{
t
.
Errorf
(
"Parsing failed: %s %#v %#v"
,
string
(
data
),
controller
,
expectedController
)
}
}
...
...
@@ -375,7 +374,7 @@ func TestFillCurrentState(t *testing.T) {
if
controller
.
Status
.
Replicas
!=
2
{
t
.
Errorf
(
"expected 2, got: %d"
,
controller
.
Status
.
Replicas
)
}
if
!
reflect
.
DeepEqual
(
fakeLister
.
s
,
labels
.
Set
(
controller
.
Spec
.
Selector
)
.
AsSelector
())
{
if
!
api
.
Semantic
.
DeepEqual
(
fakeLister
.
s
,
labels
.
Set
(
controller
.
Spec
.
Selector
)
.
AsSelector
())
{
t
.
Errorf
(
"unexpected output: %#v %#v"
,
labels
.
Set
(
controller
.
Spec
.
Selector
)
.
AsSelector
(),
fakeLister
.
s
)
}
}
...
...
pkg/registry/etcd/etcd_test.go
View file @
5f2dae4d
...
...
@@ -448,7 +448,7 @@ func TestEtcdUpdatePodNotScheduled(t *testing.T) {
}
var
podOut
api
.
Pod
latest
.
Codec
.
DecodeInto
([]
byte
(
response
.
Node
.
Value
),
&
podOut
)
if
!
reflect
.
DeepEqual
(
podOut
,
podIn
)
{
if
!
api
.
Semantic
.
DeepEqual
(
podOut
,
podIn
)
{
t
.
Errorf
(
"expected: %v, got: %v"
,
podOut
,
podIn
)
}
}
...
...
@@ -529,7 +529,7 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
}
var
podOut
api
.
Pod
latest
.
Codec
.
DecodeInto
([]
byte
(
response
.
Node
.
Value
),
&
podOut
)
if
!
reflect
.
DeepEqual
(
podOut
,
podIn
)
{
if
!
api
.
Semantic
.
DeepEqual
(
podOut
,
podIn
)
{
t
.
Errorf
(
"expected: %#v, got: %#v"
,
podOut
,
podIn
)
}
...
...
@@ -542,7 +542,7 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
t
.
Fatalf
(
"unexpected error decoding response: %v"
,
err
)
}
if
len
(
list
.
Items
)
!=
2
||
!
reflect
.
DeepEqual
(
list
.
Items
[
0
]
.
Spec
,
podIn
.
Spec
)
{
if
len
(
list
.
Items
)
!=
2
||
!
api
.
Semantic
.
DeepEqual
(
list
.
Items
[
0
]
.
Spec
,
podIn
.
Spec
)
{
t
.
Errorf
(
"unexpected container list: %d
\n
items[0] - %#v
\n
podin.spec - %#v
\n
"
,
len
(
list
.
Items
),
list
.
Items
[
0
]
.
Spec
,
podIn
.
Spec
)
}
}
...
...
pkg/resources/doc.go
deleted
100644 → 0
View file @
2c54dd5c
/*
Copyright 2014 Google Inc. 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 resources has constants and utilities for dealing with resources
package
resources
pkg/resources/resources.go
deleted
100644 → 0
View file @
2c54dd5c
/*
Copyright 2014 Google Inc. 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
resources
import
(
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
)
const
(
CPU
api
.
ResourceName
=
"cpu"
Memory
api
.
ResourceName
=
"memory"
)
// TODO: None of these currently handle SI units
func
GetFloatResource
(
resources
api
.
ResourceList
,
name
api
.
ResourceName
,
def
float64
)
float64
{
value
,
found
:=
resources
[
name
]
if
!
found
{
return
def
}
if
value
.
Kind
==
util
.
IntstrInt
{
return
float64
(
value
.
IntVal
)
}
result
,
err
:=
strconv
.
ParseFloat
(
value
.
StrVal
,
64
)
if
err
!=
nil
{
glog
.
Errorf
(
"parsing failed for %s: %s"
,
name
,
value
.
StrVal
)
return
def
}
return
result
}
func
GetIntegerResource
(
resources
api
.
ResourceList
,
name
api
.
ResourceName
,
def
int
)
int
{
value
,
found
:=
resources
[
name
]
if
!
found
{
return
def
}
if
value
.
Kind
==
util
.
IntstrInt
{
return
value
.
IntVal
}
result
,
err
:=
strconv
.
Atoi
(
value
.
StrVal
)
if
err
!=
nil
{
glog
.
Errorf
(
"parsing failed for %s: %s"
,
name
,
value
.
StrVal
)
return
def
}
return
result
}
func
GetStringResource
(
resources
api
.
ResourceList
,
name
api
.
ResourceName
,
def
string
)
string
{
value
,
found
:=
resources
[
name
]
if
!
found
{
return
def
}
if
value
.
Kind
==
util
.
IntstrInt
{
return
strconv
.
Itoa
(
value
.
IntVal
)
}
return
value
.
StrVal
}
pkg/resources/resources_test.go
deleted
100644 → 0
View file @
2c54dd5c
/*
Copyright 2014 Google Inc. 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
resources
import
(
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func
TestGetInteger
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
res
api
.
ResourceList
name
api
.
ResourceName
expected
int
def
int
test
string
}{
{
res
:
api
.
ResourceList
{},
name
:
CPU
,
expected
:
1
,
def
:
1
,
test
:
"nothing present"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromInt
(
2
),
},
name
:
CPU
,
expected
:
2
,
def
:
1
,
test
:
"present"
,
},
{
res
:
api
.
ResourceList
{
Memory
:
util
.
NewIntOrStringFromInt
(
2
),
},
name
:
CPU
,
expected
:
1
,
def
:
1
,
test
:
"not-present"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromString
(
"2"
),
},
name
:
CPU
,
expected
:
2
,
def
:
1
,
test
:
"present-string"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromString
(
"foo"
),
},
name
:
CPU
,
expected
:
1
,
def
:
1
,
test
:
"present-invalid"
,
},
}
for
_
,
test
:=
range
tests
{
val
:=
GetIntegerResource
(
test
.
res
,
test
.
name
,
test
.
def
)
if
val
!=
test
.
expected
{
t
.
Errorf
(
"expected: %d found %d"
,
test
.
expected
,
val
)
}
}
}
func
TestGetFloat
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
res
api
.
ResourceList
name
api
.
ResourceName
expected
float64
def
float64
test
string
}{
{
res
:
api
.
ResourceList
{},
name
:
CPU
,
expected
:
1.5
,
def
:
1.5
,
test
:
"nothing present"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromInt
(
2
),
},
name
:
CPU
,
expected
:
2.0
,
def
:
1.5
,
test
:
"present"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromString
(
"2.5"
),
},
name
:
CPU
,
expected
:
2.5
,
def
:
1
,
test
:
"present-string"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromString
(
"foo"
),
},
name
:
CPU
,
expected
:
1
,
def
:
1
,
test
:
"present-invalid"
,
},
}
for
_
,
test
:=
range
tests
{
val
:=
GetFloatResource
(
test
.
res
,
test
.
name
,
test
.
def
)
if
val
!=
test
.
expected
{
t
.
Errorf
(
"expected: %f found %f"
,
test
.
expected
,
val
)
}
}
}
func
TestGetString
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
res
api
.
ResourceList
name
api
.
ResourceName
expected
string
def
string
test
string
}{
{
res
:
api
.
ResourceList
{},
name
:
CPU
,
expected
:
"foo"
,
def
:
"foo"
,
test
:
"nothing present"
,
},
{
res
:
api
.
ResourceList
{
CPU
:
util
.
NewIntOrStringFromString
(
"bar"
),
},
name
:
CPU
,
expected
:
"bar"
,
def
:
"foo"
,
test
:
"present"
,
},
}
for
_
,
test
:=
range
tests
{
val
:=
GetStringResource
(
test
.
res
,
test
.
name
,
test
.
def
)
if
val
!=
test
.
expected
{
t
.
Errorf
(
"expected: %s found %s"
,
test
.
expected
,
val
)
}
}
}
pkg/scheduler/predicates.go
View file @
5f2dae4d
...
...
@@ -22,7 +22,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/golang/glog"
)
...
...
@@ -89,15 +88,15 @@ type ResourceFit struct {
}
type
resourceRequest
struct
{
milliCPU
int
memory
int
milliCPU
int
64
memory
int
64
}
func
getResourceRequest
(
pod
*
api
.
Pod
)
resourceRequest
{
result
:=
resourceRequest
{}
for
ix
:=
range
pod
.
Spec
.
Containers
{
result
.
memory
+=
pod
.
Spec
.
Containers
[
ix
]
.
Memory
result
.
milliCPU
+=
pod
.
Spec
.
Containers
[
ix
]
.
CPU
result
.
memory
+=
pod
.
Spec
.
Containers
[
ix
]
.
Memory
.
Value
()
result
.
milliCPU
+=
pod
.
Spec
.
Containers
[
ix
]
.
CPU
.
MilliValue
()
}
return
result
}
...
...
@@ -113,17 +112,16 @@ func (r *ResourceFit) PodFitsResources(pod api.Pod, existingPods []api.Pod, node
if
err
!=
nil
{
return
false
,
err
}
milliCPURequested
:=
0
memoryRequested
:=
0
milliCPURequested
:=
int64
(
0
)
memoryRequested
:=
int64
(
0
)
for
ix
:=
range
existingPods
{
existingRequest
:=
getResourceRequest
(
&
existingPods
[
ix
])
milliCPURequested
+=
existingRequest
.
milliCPU
memoryRequested
+=
existingRequest
.
memory
}
// TODO: convert to general purpose resource matching, when pods ask for resources
totalMilliCPU
:=
int
(
resources
.
GetFloatResource
(
info
.
Spec
.
Capacity
,
resources
.
CPU
,
0
)
*
1000
)
totalMemory
:=
resources
.
GetIntegerResource
(
info
.
Spec
.
Capacity
,
resources
.
Memory
,
0
)
totalMilliCPU
:=
info
.
Spec
.
Capacity
.
Get
(
api
.
ResourceCPU
)
.
MilliValue
()
totalMemory
:=
info
.
Spec
.
Capacity
.
Get
(
api
.
ResourceMemory
)
.
Value
()
fitsCPU
:=
totalMilliCPU
==
0
||
(
totalMilliCPU
-
milliCPURequested
)
>=
podRequest
.
milliCPU
fitsMemory
:=
totalMemory
==
0
||
(
totalMemory
-
memoryRequested
)
>=
podRequest
.
memory
...
...
pkg/scheduler/predicates_test.go
View file @
5f2dae4d
...
...
@@ -21,8 +21,7 @@ import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
)
type
FakeNodeInfo
api
.
Node
...
...
@@ -32,17 +31,11 @@ func (n FakeNodeInfo) GetNodeInfo(nodeName string) (*api.Node, error) {
return
&
node
,
nil
}
func
makeResources
(
milliCPU
int
,
memory
int
)
api
.
NodeResources
{
func
makeResources
(
milliCPU
int
64
,
memory
int64
)
api
.
NodeResources
{
return
api
.
NodeResources
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
IntOrString
{
IntVal
:
milliCPU
,
Kind
:
util
.
IntstrInt
,
},
resources
.
Memory
:
util
.
IntOrString
{
IntVal
:
memory
,
Kind
:
util
.
IntstrInt
,
},
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
milliCPU
,
resource
.
DecimalSI
),
api
.
ResourceMemory
:
*
resource
.
NewQuantity
(
memory
,
resource
.
BinarySI
),
},
}
}
...
...
@@ -51,8 +44,8 @@ func newResourcePod(usage ...resourceRequest) api.Pod {
containers
:=
[]
api
.
Container
{}
for
_
,
req
:=
range
usage
{
containers
=
append
(
containers
,
api
.
Container
{
Memory
:
req
.
memory
,
CPU
:
req
.
milliCPU
,
Memory
:
*
resource
.
NewQuantity
(
req
.
memory
,
resource
.
BinarySI
)
,
CPU
:
*
resource
.
NewMilliQuantity
(
req
.
milliCPU
,
resource
.
DecimalSI
)
,
})
}
return
api
.
Pod
{
...
...
pkg/scheduler/priorities.go
View file @
5f2dae4d
...
...
@@ -18,13 +18,12 @@ package scheduler
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/golang/glog"
)
// the unused capacity is calculated on a scale of 0-10
// 0 being the lowest priority and 10 being the highest
func
calculateScore
(
requested
,
capacity
int
,
node
string
)
int
{
func
calculateScore
(
requested
,
capacity
int
64
,
node
string
)
int
{
if
capacity
==
0
{
return
0
}
...
...
@@ -32,30 +31,39 @@ func calculateScore(requested, capacity int, node string) int {
glog
.
Errorf
(
"Combined requested resources from existing pods exceeds capacity on minion: %s"
,
node
)
return
0
}
return
((
capacity
-
requested
)
*
10
)
/
capacity
return
int
(((
capacity
-
requested
)
*
10
)
/
capacity
)
}
// Calculate the occupancy on a node. 'node' has information about the resources on the node.
// 'pods' is a list of pods currently scheduled on the node.
func
calculateOccupancy
(
pod
api
.
Pod
,
node
api
.
Node
,
pods
[]
api
.
Pod
)
HostPriority
{
total
CPU
:=
0
totalMemory
:=
0
total
MilliCPU
:=
int64
(
0
)
totalMemory
:=
int64
(
0
)
for
_
,
existingPod
:=
range
pods
{
for
_
,
container
:=
range
existingPod
.
Spec
.
Containers
{
total
CPU
+=
container
.
CPU
totalMemory
+=
container
.
Memory
total
MilliCPU
+=
container
.
CPU
.
MilliValue
()
totalMemory
+=
container
.
Memory
.
Value
()
}
}
// Add the resources requested by the current pod being scheduled.
// This also helps differentiate between differently sized, but empty, minions.
for
_
,
container
:=
range
pod
.
Spec
.
Containers
{
total
CPU
+=
container
.
CPU
totalMemory
+=
container
.
Memory
total
MilliCPU
+=
container
.
CPU
.
MilliValue
()
totalMemory
+=
container
.
Memory
.
Value
()
}
cpuScore
:=
calculateScore
(
totalCPU
,
resources
.
GetIntegerResource
(
node
.
Spec
.
Capacity
,
resources
.
CPU
,
0
),
node
.
Name
)
memoryScore
:=
calculateScore
(
totalMemory
,
resources
.
GetIntegerResource
(
node
.
Spec
.
Capacity
,
resources
.
Memory
,
0
),
node
.
Name
)
glog
.
V
(
4
)
.
Infof
(
"Least Requested Priority, AbsoluteRequested: (%d, %d) Score:(%d, %d)"
,
totalCPU
,
totalMemory
,
cpuScore
,
memoryScore
)
capacityMilliCPU
:=
node
.
Spec
.
Capacity
.
Get
(
api
.
ResourceCPU
)
.
MilliValue
()
capacityMemory
:=
node
.
Spec
.
Capacity
.
Get
(
api
.
ResourceMemory
)
.
Value
()
cpuScore
:=
calculateScore
(
totalMilliCPU
,
capacityMilliCPU
,
node
.
Name
)
memoryScore
:=
calculateScore
(
totalMemory
,
capacityMemory
,
node
.
Name
)
glog
.
V
(
4
)
.
Infof
(
"%v -> %v: Least Requested Priority, AbsoluteRequested: (%d, %d) / (%d, %d) Score: (%d, %d)"
,
pod
.
Name
,
node
.
Name
,
totalMilliCPU
,
totalMemory
,
capacityMilliCPU
,
capacityMemory
,
cpuScore
,
memoryScore
,
)
return
HostPriority
{
host
:
node
.
Name
,
...
...
pkg/scheduler/priorities_test.go
View file @
5f2dae4d
...
...
@@ -21,17 +21,16 @@ import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
)
func
makeMinion
(
node
string
,
cpu
,
memory
int
)
api
.
Node
{
func
makeMinion
(
node
string
,
milliCPU
,
memory
int64
)
api
.
Node
{
return
api
.
Node
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
node
},
Spec
:
api
.
NodeSpec
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
NewIntOrStringFromInt
(
cpu
),
resources
.
Memory
:
util
.
NewIntOrStringFromInt
(
memory
),
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
milliCPU
,
resource
.
DecimalSI
),
api
.
ResourceMemory
:
*
resource
.
NewQuantity
(
memory
,
resource
.
BinarySI
),
},
},
}
...
...
@@ -57,14 +56,14 @@ func TestLeastRequested(t *testing.T) {
}
cpuOnly
:=
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
{
CPU
:
1000
},
{
CPU
:
2000
},
{
CPU
:
resource
.
MustParse
(
"1000m"
)
},
{
CPU
:
resource
.
MustParse
(
"2000m"
)
},
},
}
cpuAndMemory
:=
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
{
CPU
:
1000
,
Memory
:
2000
},
{
CPU
:
2000
,
Memory
:
3000
},
{
CPU
:
resource
.
MustParse
(
"1000m"
),
Memory
:
resource
.
MustParse
(
"2000"
)
},
{
CPU
:
resource
.
MustParse
(
"2000m"
),
Memory
:
resource
.
MustParse
(
"3000"
)
},
},
}
tests
:=
[]
struct
{
...
...
pkg/standalone/standalone.go
View file @
5f2dae4d
...
...
@@ -18,12 +18,12 @@ package standalone
import
(
"fmt"
"math"
"net"
"net/http"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
...
...
@@ -33,7 +33,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
...
...
@@ -125,22 +124,10 @@ func RunScheduler(cl *client.Client) {
// RunControllerManager starts a controller
func
RunControllerManager
(
machineList
[]
string
,
cl
*
client
.
Client
,
nodeMilliCPU
,
nodeMemory
int64
)
{
if
int64
(
int
(
nodeMilliCPU
))
!=
nodeMilliCPU
{
glog
.
Warningf
(
"node_milli_cpu is too big for platform. Clamping: %d -> %d"
,
nodeMilliCPU
,
math
.
MaxInt32
)
nodeMilliCPU
=
math
.
MaxInt32
}
if
int64
(
int
(
nodeMemory
))
!=
nodeMemory
{
glog
.
Warningf
(
"node_memory is too big for platform. Clamping: %d -> %d"
,
nodeMemory
,
math
.
MaxInt32
)
nodeMemory
=
math
.
MaxInt32
}
nodeResources
:=
&
api
.
NodeResources
{
Capacity
:
api
.
ResourceList
{
resources
.
CPU
:
util
.
NewIntOrStringFromInt
(
int
(
nodeMilliCPU
)
),
resources
.
Memory
:
util
.
NewIntOrStringFromInt
(
int
(
nodeMemory
)
),
api
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
nodeMilliCPU
,
resource
.
DecimalSI
),
api
.
ResourceMemory
:
*
resource
.
NewQuantity
(
nodeMemory
,
resource
.
BinarySI
),
},
}
minionController
:=
minionControllerPkg
.
NewMinionController
(
nil
,
""
,
machineList
,
nodeResources
,
cl
)
...
...
pkg/util/util.go
View file @
5f2dae4d
...
...
@@ -113,6 +113,14 @@ func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
return
json
.
Unmarshal
(
value
,
&
intstr
.
IntVal
)
}
// String returns the string value, or Itoa's the int value.
func
(
intstr
*
IntOrString
)
String
()
string
{
if
intstr
.
Kind
==
IntstrString
{
return
intstr
.
StrVal
}
return
strconv
.
Itoa
(
intstr
.
IntVal
)
}
// MarshalJSON implements the json.Marshaller interface.
func
(
intstr
IntOrString
)
MarshalJSON
()
([]
byte
,
error
)
{
switch
intstr
.
Kind
{
...
...
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