Change:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: BUG /kind bug What happened: is buggy. It prevents running hyperkube from other path. In fact, it shouldn't assume the code is just running in controller master at all, especially when cloud provider is running out of tree. What you expected to happen: How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): Cloud provider or hardware configuration**: OS (e.g. from /etc/os-release): Kernel (e.g. ): Install tools: Others:
/assign
This code logic is to make sure the blobController only initialize once in controller-manager other than in other component, e.g. kubelet, do you have any suggestion to use similar implementation? Current design is azure pv code could only run in controller-manager.
If the idea is to exclude other components, I prefer a black list, not a broken white a list as here.
there are multiple issues with this code: It shouldn't bootstrap any storage accounts at all. This is really poor user experience. Not all users want to/will use azure disk. These storage accounts are yet created without any explicit documentation or prior warning.Even with these storage accounts, it doesn't help accelerate PV provisioning.This is the only place to init . If controller master is launched from a different path (which is usually the case), then never gets initialized, and will cause a panic when being used.
thanks for the check, put the storage accounts bootstrap in could be more appropiate: that is only when user select kind and would like to create blob disk PVC, then those accounts would be created and it would only initialize before first PVC is created.
SGTM, looking forward to your PR and 1.7/1.8 cherry picks
update: code complete, I need to do some test before sending PR:

Discussion:
"bytes" "encoding/binary" "fmt" <del> "math" </del> "net/url" <del> "os" </del> "regexp" "sync"

var defaultContainerName = "" var storageAccountNamePrefix = "" var storageAccountNameMatch = "" <del> var initFlag int64 </del> var accountsLock = &sync.Mutex{} func newBlobDiskController(common *controllerCommon) (*BlobDiskController, error) { c := BlobDiskController{common: common} <del> err := c.init() </del> <ins> c.setUniqueStrings() // get accounts accounts, err := c.getAllStorageAccounts() </ins> if err != nil { <del> return nil, err </del> <ins> glog.Errorf("azureDisk - getAllStorageAccounts error: %v", err) c.accounts = make(map[string]*storageAccountState) return &c, nil </ins> } <ins> c.accounts = accounts </ins> return &c, nil }

return err } <del> // Init tries best effort to ensure that 2 accounts standard/premium were created // to be used by shared blob disks. This to increase the speed pvc provisioning (in most of cases) func (c *BlobDiskController) init() error { if !c.shouldInit() { return nil } c.setUniqueStrings() // get accounts accounts, err := c.getAllStorageAccounts() if err != nil { return err } c.accounts = accounts if len(c.accounts) == 0 { counter := 1 for counter <= storageAccountsCountInit { accountType := storage.PremiumLRS if n := math.Mod(float64(counter), 2); n == 0 { accountType = storage.StandardLRS } // We don't really care if these calls failed // at this stage, we are trying to ensure 2 accounts (Standard/Premium) // are there ready for PVC creation // if we failed here, the accounts will be created in the process // of creating PVC // nor do we care if they were partially created, as the entire // account creation process is idempotent go func(thisNext int) { newAccountName := getAccountNameForNum(thisNext) glog.Infof("azureDisk - BlobDiskController init process  will create new storageAccount:%s type:%s", newAccountName, accountType) err := c.createStorageAccount(newAccountName, accountType, c.common.location, true) // TODO return created and error from if err != nil { glog.Infof("azureDisk - BlobDiskController init: create account %s with error:%s", newAccountName, err.Error()) } else { glog.Infof("azureDisk - BlobDiskController init: created account %s", newAccountName) } }(counter) counter = counter + 1 } } return nil } </del> //Sets unique strings to be used as accountnames && || blob containers names func (c *BlobDiskController) setUniqueStrings() { uniqueString := c.common.resourceGroup + c.common.location + c.common.subscriptionID

return int(c.accounts[SAName].diskCount), nil } <del> // shouldInit ensures that we only init the plugin once // and we only do that in the controller func (c *BlobDiskController) shouldInit() bool { if os.Args[0] == "kube-controller-manager" || (os.Args[0] == "/hyperkube" && os.Args[1] == "controller-manager") { swapped := atomic.CompareAndSwapInt64(&initFlag, 0, 1) if swapped { return true } } return false } </del> func (c *BlobDiskController) getAllStorageAccounts() (map[string]*storageAccountState, error) { accountListResult, err := c.common.cloud.StorageAccountClient.List() if err != nil {