@@ -33,6 +33,7 @@ import (
3333 timestamp "github.com/golang/protobuf/ptypes/timestamp"
3434 "google.golang.org/grpc/codes"
3535 "google.golang.org/grpc/status"
36+ "k8s.io/apimachinery/pkg/api/resource"
3637 fs "k8s.io/kubernetes/pkg/volume/util/fs"
3738 "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
3839 utilexec "k8s.io/utils/exec"
@@ -219,12 +220,6 @@ func (hp *hostPath) discoveryExistingVolumes() error {
219220 if err != nil {
220221 return err
221222 }
222-
223- if hpv .Kind != "" && hp .config .Capacity .Enabled () {
224- if _ , err := hp .config .Capacity .Alloc (hpv .Kind , hpv .VolSize ); err != nil {
225- return fmt .Errorf ("existing volume(s) do not match new capacity configuration: %v" , err )
226- }
227- }
228223 hp .volumes [hpv .VolID ] = * hpv
229224 }
230225
@@ -281,17 +276,26 @@ func (hp *hostPath) createVolume(volID, name string, cap int64, volAccessType ac
281276 return nil , status .Errorf (codes .OutOfRange , "Requested capacity %d exceeds maximum allowed %d" , cap , hp .config .MaxVolumeSize )
282277 }
283278 if hp .config .Capacity .Enabled () {
284- actualKind , err := hp .config .Capacity .Alloc (kind , cap )
285- if err != nil {
286- return nil , err
287- }
288- // Free the capacity in case of any error - either a volume gets created or it doesn't.
289- defer func () {
290- if finalErr != nil {
291- hp .config .Capacity .Free (actualKind , cap )
279+ if kind == "" {
280+ // Pick some kind with sufficient remaining capacity.
281+ for k , c := range hp .config .Capacity {
282+ if hp .sumVolumeSizes (k )+ cap <= c .Value () {
283+ kind = k
284+ break
285+ }
292286 }
293- }()
294- kind = actualKind
287+ }
288+ if kind == "" {
289+ // Still nothing?!
290+ return nil , status .Errorf (codes .OutOfRange , "requested capacity %d of arbitrary storage exceeds all remaining capacity" , cap )
291+ }
292+ used := hp .sumVolumeSizes (kind )
293+ available := hp .config .Capacity [kind ]
294+ if used + cap > available .Value () {
295+
296+ return nil , status .Errorf (codes .OutOfRange , "requested capacity %d exceeds remaining capacity for %q, %s out of %s already used" ,
297+ cap , kind , resource .NewQuantity (used , resource .BinarySI ).String (), available .String ())
298+ }
295299 } else if kind != "" {
296300 return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("capacity tracking disabled, specifying kind %q is invalid" , kind ))
297301 }
@@ -383,14 +387,20 @@ func (hp *hostPath) deleteVolume(volID string) error {
383387 if err := os .RemoveAll (path ); err != nil && ! os .IsNotExist (err ) {
384388 return err
385389 }
386- if hp .config .Capacity .Enabled () {
387- hp .config .Capacity .Free (vol .Kind , vol .VolSize )
388- }
389390 delete (hp .volumes , volID )
390391 glog .V (4 ).Infof ("deleted hostpath volume: %s = %+v" , volID , vol )
391392 return nil
392393}
393394
395+ func (hp * hostPath ) sumVolumeSizes (kind string ) (sum int64 ) {
396+ for _ , volume := range hp .volumes {
397+ if volume .Kind == kind {
398+ sum += volume .VolSize
399+ }
400+ }
401+ return
402+ }
403+
394404// hostPathIsEmpty is a simple check to determine if the specified hostpath directory
395405// is empty or not.
396406func hostPathIsEmpty (p string ) (bool , error ) {
0 commit comments