From c624d4ec6c4ebe1f4c00ba54baea4d5f333e60ca Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Sat, 15 Sep 2018 17:05:17 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9A1.=20=E9=98=BF?= =?UTF-8?q?=E9=87=8C=E4=BA=91=E5=88=9A=E5=88=A0=E9=99=A4=E4=B8=BB=E6=9C=BA?= =?UTF-8?q?=E7=9A=84IP=E5=9C=B0=E5=9D=80=E4=B8=8D=E8=83=BD=E5=8D=A0?= =?UTF-8?q?=E7=94=A8=202.=20rebuild=20root=20no-account-init=E6=97=A0?= =?UTF-8?q?=E6=95=88=203.=20=E5=85=B6=E4=BB=96=E9=97=AE=E9=A2=98...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/cloudcommon/db/resourcebase.go | 4 +++ pkg/cloudprovider/resources.go | 2 ++ pkg/compute/guestdrivers/aliyun.go | 4 +-- pkg/compute/guestdrivers/managedvirtual.go | 2 +- pkg/compute/models/disks.go | 5 ++- pkg/compute/models/guestnetworks.go | 29 +++++++++++++++- pkg/compute/models/guests.go | 29 ++++++++++++++++ pkg/compute/models/networks.go | 33 +++++++++++++++---- pkg/compute/tasks/guest_change_config_task.go | 5 +++ pkg/compute/tasks/guest_rebuild_root_task.go | 16 ++++----- pkg/util/aliyun/instance.go | 24 +++++++++++--- pkg/util/aliyun/vswitch.go | 4 +++ 12 files changed, 134 insertions(+), 23 deletions(-) diff --git a/pkg/cloudcommon/db/resourcebase.go b/pkg/cloudcommon/db/resourcebase.go index a4289f2df6..229298c86b 100644 --- a/pkg/cloudcommon/db/resourcebase.go +++ b/pkg/cloudcommon/db/resourcebase.go @@ -31,6 +31,10 @@ func (manager *SResourceBaseManager) Query(fields ...string) *sqlchemy.SQuery { return manager.SModelBaseManager.Query(fields...).IsFalse("deleted") } +func (manager *SResourceBaseManager) RawQuery(fields ...string) *sqlchemy.SQuery { + return manager.SModelBaseManager.Query(fields...) +} + func CanDelete(model IModel, ctx context.Context) bool { err := model.ValidateDeleteCondition(ctx) if err == nil { diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index ae0d7625d7..f4d95664b9 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -293,4 +293,6 @@ type ICloudNetwork interface { GetIsPublic() bool Delete() error + + GetAllocTimeoutSeconds() int } diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index 908bad6ff4..ea73d1c9e9 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -188,7 +188,7 @@ func fetchIVMinfo(desc SAliyunVMCreateConfig, iVM cloudprovider.ICloudVM, guestI func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) - + log.Debugf("RequestDeployGuestOnHost: %s", config) /* onfinish, err := config.GetString("on_finish") if err != nil { return err @@ -404,7 +404,7 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } if len(idisks) < len(desc.DataDisks) + 1 { if waited > maxWaitSecs { - log.Errorf("inconsistent disk number, wait timeout, must be something wrong one remote") + log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote") return nil, cloudprovider.ErrTimeout } log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 0a5901a783..9765dfda37 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -154,7 +154,7 @@ func (self *SManagedVirtualizedGuestDriver) GetGuestVncInfo(userCred mcclient.To } func (self *SManagedVirtualizedGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error { - subtask, err := taskman.TaskManager.NewTask(ctx, "ManagedGuestRebuildRootTask", guest, task.GetUserCred(), nil, task.GetTaskId(), "", nil) + subtask, err := taskman.TaskManager.NewTask(ctx, "ManagedGuestRebuildRootTask", guest, task.GetUserCred(), task.GetParams(), task.GetTaskId(), "", nil) if err != nil { return err } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 13774ab504..4c6bf6741c 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -245,6 +245,9 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc if !utils.IsInStringArray(storage.Status, []string{STORAGE_ENABLED, STORAGE_ONLINE}) { return nil, httperrors.NewInputParameterError("Cannot create disk with offline storage[%s]", storage.Name) } + if len(diskConfig.Backend) == 0 { + diskConfig.Backend = storage.StorageType + } if storage.StorageType != diskConfig.Backend { return nil, httperrors.NewInputParameterError("Storage type[%s] not match backend %s", storage.StorageType, diskConfig.Backend) } @@ -749,7 +752,7 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info } // default backend and medium type - diskConfig.Backend = STORAGE_LOCAL + diskConfig.Backend = "" // STORAGE_LOCAL diskConfig.Medium = DISK_TYPE_HYBRID diskStr, err := info.GetString() diff --git a/pkg/compute/models/guestnetworks.go b/pkg/compute/models/guestnetworks.go index 2df92532e1..b2cc9b7df5 100644 --- a/pkg/compute/models/guestnetworks.go +++ b/pkg/compute/models/guestnetworks.go @@ -137,7 +137,8 @@ func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCr gn.MacAddr = macAddr if !virtual { addrTable := network.GetUsedAddresses() - ipAddr, err := network.GetFreeIP(ctx, userCred, addrTable, address, allocDir, reserved) + recentAddrTable := manager.getRecentlyReleasedIPAddresses(network.Id, time.Duration(network.AllocTimoutSeconds)*time.Second) + ipAddr, err := network.GetFreeIP(ctx, userCred, addrTable, recentAddrTable, address, allocDir, reserved) if err != nil { return nil, err } @@ -552,3 +553,29 @@ func (self *SGuestnetwork) getJsonDescAtHost(host *SHost) jsonutils.JSONObject { return desc } + +func (manager *SGuestnetworkManager) getRecentlyReleasedIPAddresses(networkId string, recentDuration time.Duration) map[string]bool { + if recentDuration == 0 { + return nil + } + since := time.Now().UTC().Add(-recentDuration) + q := manager.RawQuery("ip_addr") + q = q.Equals("network_id", networkId).IsTrue("deleted") + q = q.GT("deleted_at", since).Distinct() + rows, err := q.Rows() + if err != nil { + log.Errorf("GetRecentlyReleasedIPAddresses fail %s", err) + return nil + } + ret := make(map[string]bool) + for rows.Next() { + var ip string + err = rows.Scan(&ip) + if err != nil { + log.Errorf("scan error %s", err) + } else { + ret[ip] = true + } + } + return ret +} \ No newline at end of file diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index b96c1e2081..5188a338c0 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -582,6 +582,11 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m return nil, httperrors.NewInputParameterError("Invalid root image: %s", err) } + if len(diskConfig.Backend) == 0 { + diskConfig.Backend = STORAGE_LOCAL + } + rootStorageType := diskConfig.Backend + data.Add(jsonutils.Marshal(diskConfig), "disk.0") imgProperties := diskConfig.ImageProperties @@ -713,6 +718,7 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m } data.Add(jsonutils.NewString(hypervisor), "hypervisor") + // start from data disk for idx := 1; data.Contains(fmt.Sprintf("disk.%d", idx)); idx += 1 { diskJson, err := data.Get(fmt.Sprintf("disk.%d", idx)) if err != nil { @@ -722,6 +728,9 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m if err != nil { return nil, httperrors.NewInputParameterError("parse disk description error %s", err) } + if len(diskConfig.Backend) == 0 { + diskConfig.Backend = rootStorageType + } if len(diskConfig.Driver) == 0 { diskConfig.Driver = osProf.DiskDriver } @@ -2553,6 +2562,9 @@ func (self *SGuest) PerformCreatedisk(ctx context.Context, userCred mcclient.Tok logclient.AddActionLog(self, logclient.ACT_CREATE, err.Error(), userCred, false) return nil, httperrors.NewBadRequestError(err.Error()) } + if len(diskInfo.Backend) == 0 { + diskInfo.Backend = self.getDefaultStorageType() + } disksConf.Set(diskSeq, jsonutils.Marshal(diskInfo)) if _, ok := diskSizes[diskInfo.Backend]; !ok { diskSizes[diskInfo.Backend] = diskInfo.Size @@ -2902,12 +2914,18 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T if err != nil { return nil, httperrors.NewBadRequestError("Parse disk info error: %s", err) } + if len(diskConf.Backend) == 0 { + diskConf.Backend = self.getDefaultStorageType() + } if diskConf.Size > 0 { if diskIdx >= len(disks) { newDisks.Add(jsonutils.Marshal(diskConf), fmt.Sprintf("disk.%d", newDiskIdx)) newDiskIdx += 1 addDisk += diskConf.Size storage := host.GetLeastUsedStorage(diskConf.Backend) + if storage == nil { + + } _, ok := diskSizes[storage.Id] if !ok { diskSizes[storage.Id] = 0 @@ -4273,3 +4291,14 @@ func (self *SGuest) SetDisableDelete(val bool) error { }) return err } + +func (self *SGuest) getDefaultStorageType() string { + diskCat := self.CategorizeDisks() + if diskCat.Root != nil { + rootStorage := diskCat.Root.GetStorage() + if rootStorage != nil { + return rootStorage.StorageType + } + } + return STORAGE_LOCAL +} diff --git a/pkg/compute/models/networks.go b/pkg/compute/models/networks.go index d090098234..52d9b44825 100644 --- a/pkg/compute/models/networks.go +++ b/pkg/compute/models/networks.go @@ -101,6 +101,8 @@ type SNetwork struct { ServerType string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user" create:"optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) AllocPolicy string `width:"16" charset:"ascii" nullable:"true" get:"user" update:"user" create:"optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True) + + AllocTimoutSeconds int `default:"0" nullable:"true" get:"admin"` } func (manager *SNetworkManager) GetContextManager() []db.IModelManager { @@ -188,7 +190,22 @@ func (self *SNetwork) getIPRange() netutils.IPV4AddrRange { return netutils.NewIPV4AddrRange(start, end) } -func (self *SNetwork) getFreeIP(addrTable map[string]bool, candidate string, allocDir IPAddlocationDirection) (string, error) { +func isIpUsed(ipstr string, addrTable map[string]bool, recentUsedAddrTable map[string]bool) bool { + _, ok := addrTable[ipstr] + if !ok { + recentUsed := false + if recentUsedAddrTable != nil { + if _, ok := recentUsedAddrTable[ipstr]; ok { + recentUsed = true + } + } + return recentUsed + } else { + return true + } +} + +func (self *SNetwork) getFreeIP(addrTable map[string]bool, recentUsedAddrTable map[string]bool, candidate string, allocDir IPAddlocationDirection) (string, error) { iprange := self.getIPRange() if len(candidate) > 0 { candIP, err := netutils.NewIPV4Addr(candidate) @@ -208,7 +225,7 @@ func (self *SNetwork) getFreeIP(addrTable map[string]bool, candidate string, all if len(allocDir) == 0 || allocDir == IPAllocationStepdown { ip, _ := netutils.NewIPV4Addr(self.GuestIpEnd) for iprange.Contains(ip) { - if _, ok := addrTable[ip.String()]; !ok { + if !isIpUsed(ip.String(), addrTable, recentUsedAddrTable) { return ip.String(), nil } ip = ip.StepDown() @@ -219,7 +236,7 @@ func (self *SNetwork) getFreeIP(addrTable map[string]bool, candidate string, all const MAX_TRIES = 5 for i := 0; i < MAX_TRIES; i += 1 { ip := iprange.Random() - if _, ok := addrTable[ip.String()]; !ok { + if !isIpUsed(ip.String(), addrTable, recentUsedAddrTable) { return ip.String(), nil } } @@ -227,7 +244,7 @@ func (self *SNetwork) getFreeIP(addrTable map[string]bool, candidate string, all } ip, _ := netutils.NewIPV4Addr(self.GuestIpStart) for iprange.Contains(ip) { - if _, ok := addrTable[ip.String()]; !ok { + if !isIpUsed(ip.String(), addrTable, recentUsedAddrTable) { return ip.String(), nil } ip = ip.StepUp() @@ -236,7 +253,7 @@ func (self *SNetwork) getFreeIP(addrTable map[string]bool, candidate string, all return "", httperrors.NewInsufficientResourceError("Out of IP address") } -func (self *SNetwork) GetFreeIP(ctx context.Context, userCred mcclient.TokenCredential, addrTable map[string]bool, candidate string, allocDir IPAddlocationDirection, reserved bool) (string, error) { +func (self *SNetwork) GetFreeIP(ctx context.Context, userCred mcclient.TokenCredential, addrTable map[string]bool, recentUsedAddrTable map[string]bool, candidate string, allocDir IPAddlocationDirection, reserved bool) (string, error) { if reserved { rip := ReservedipManager.GetReservedIP(self, candidate) if rip == nil { @@ -245,7 +262,7 @@ func (self *SNetwork) GetFreeIP(ctx context.Context, userCred mcclient.TokenCred rip.Release(ctx, userCred, self) return candidate, nil } else { - cand, err := self.getFreeIP(addrTable, candidate, allocDir) + cand, err := self.getFreeIP(addrTable, recentUsedAddrTable, candidate, allocDir) if err != nil { return "", err } @@ -471,6 +488,8 @@ func (self *SNetwork) SyncWithCloudNetwork(userCred mcclient.TokenCredential, ex self.ServerType = extNet.GetServerType() self.IsPublic = extNet.GetIsPublic() + self.AllocTimoutSeconds = extNet.GetAllocTimeoutSeconds() + self.ProjectId = userCred.GetProjectId() return nil }) @@ -495,6 +514,8 @@ func (manager *SNetworkManager) newFromCloudNetwork(userCred mcclient.TokenCrede net.ServerType = extNet.GetServerType() net.IsPublic = extNet.GetIsPublic() + net.AllocTimoutSeconds = extNet.GetAllocTimeoutSeconds() + net.ProjectId = userCred.GetProjectId() err := manager.TableSpec().Insert(&net) diff --git a/pkg/compute/tasks/guest_change_config_task.go b/pkg/compute/tasks/guest_change_config_task.go index a530ae70be..56f8ac401c 100644 --- a/pkg/compute/tasks/guest_change_config_task.go +++ b/pkg/compute/tasks/guest_change_config_task.go @@ -110,6 +110,11 @@ func (self *GuestChangeConfigTask) DoCreateDisksTask(ctx context.Context, guest } +func (self *GuestChangeConfigTask) OnCreateDisksCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) { + self.markStageFailed(obj, ctx, err.String()) + logclient.AddActionLog(obj, logclient.ACT_VM_CHANGE_FLAVOR, err, self.UserCred, false) +} + func (self *GuestChangeConfigTask) OnCreateDisksComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { iVcpuCount, errCpu := self.Params.Get("vcpu_count") iVmemSize, errMem := self.Params.Get("vmem_size") diff --git a/pkg/compute/tasks/guest_rebuild_root_task.go b/pkg/compute/tasks/guest_rebuild_root_task.go index ebceff6cd4..cda52cf983 100644 --- a/pkg/compute/tasks/guest_rebuild_root_task.go +++ b/pkg/compute/tasks/guest_rebuild_root_task.go @@ -59,6 +59,14 @@ func (self *GuestRebuildRootTask) StartRebuildRootDisk(ctx context.Context, gues self.SetStage("OnRebuildRootDiskComplete", nil) guest.SetStatus(self.UserCred, models.VM_REBUILD_ROOT, "") + + // clear logininfo + loginParams := make(map[string]interface{}) + loginParams["login_account"] = "none" + loginParams["login_key"] = "none" + loginParams["login_key_timestamp"] = "none" + guest.SetAllMetadata(ctx, loginParams, self.UserCred) + guest.GetDriver().RequestRebuildRootDisk(ctx, guest, self) } @@ -141,14 +149,6 @@ func (self *KVMGuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Conte guest.SetStatus(self.UserCred, models.VM_DEPLOYING, "") // params := jsonutils.NewDict() // params.Set("reset_password", jsonutils.JSONTrue) - - // clear logininfo - loginParams := make(map[string]interface{}) - loginParams["login_account"] = "none" - loginParams["login_key"] = "none" - loginParams["login_key_timestamp"] = "none" - guest.SetAllMetadata(ctx, loginParams, self.UserCred) - guest.StartGuestDeployTask(ctx, self.UserCred, self.GetParams(), "deploy", self.GetTaskId()) } diff --git a/pkg/util/aliyun/instance.go b/pkg/util/aliyun/instance.go index 33c7047281..5c26b7148b 100644 --- a/pkg/util/aliyun/instance.go +++ b/pkg/util/aliyun/instance.go @@ -314,11 +314,27 @@ func (self *SInstance) GetHypervisor() string { } func (self *SInstance) StartVM() error { - err := self.host.zone.region.StartVM(self.InstanceId) - if err != nil { - return err + timeout := 300*time.Second + interval := 15*time.Second + + startTime := time.Now() + for time.Now().Sub(startTime) < timeout { + err := self.Refresh() + if err != nil { + return err + } + log.Debugf("status %s expect %s", self.GetStatus(), models.VM_RUNNING) + if self.GetStatus() == models.VM_RUNNING { + return nil + } else if self.GetStatus() == models.VM_READY { + err := self.host.zone.region.StartVM(self.InstanceId) + if err != nil { + return err + } + } + time.Sleep(interval) } - return cloudprovider.WaitStatus(self, models.VM_RUNNING, 5*time.Second, 180*time.Second) // 3minutes + return cloudprovider.ErrTimeout } func (self *SInstance) StopVM(isForce bool) error { diff --git a/pkg/util/aliyun/vswitch.go b/pkg/util/aliyun/vswitch.go index bef2c3d74d..02a1cf1039 100644 --- a/pkg/util/aliyun/vswitch.go +++ b/pkg/util/aliyun/vswitch.go @@ -152,3 +152,7 @@ func (self *SRegion) deleteVSwitch(vswitchId string) error { func (self *SVSwitch) Delete() error { return self.wire.zone.region.deleteVSwitch(self.VSwitchId) } + +func (self *SVSwitch) GetAllocTimeoutSeconds() int { + return 120 // 2 minutes +} \ No newline at end of file From f43c278d90be437a6d7a9a0d453f6ced9fffc2c4 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Sat, 15 Sep 2018 18:04:08 +0800 Subject: [PATCH 2/4] guestdisk support index filter --- cmd/climc/shell/serverdisks.go | 7 +++++++ pkg/compute/models/guestdisks.go | 1 + pkg/mcclient/modules/mod_serverdisks.go | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/climc/shell/serverdisks.go b/cmd/climc/shell/serverdisks.go index 98186a768d..e9a5a12f2b 100644 --- a/cmd/climc/shell/serverdisks.go +++ b/cmd/climc/shell/serverdisks.go @@ -12,6 +12,8 @@ func init() { type ServerDiskListOptions struct { options.BaseListOptions Server string `help:"ID or Name of Server"` + Disk string `help:"ID or name of disk"` + Index int64 `help:"disk index" default:"-1"` } R(&ServerDiskListOptions{}, "server-disk-list", "List server disk pairs", func(s *mcclient.ClientSession, args *ServerDiskListOptions) error { var params *jsonutils.JSONDict @@ -23,10 +25,15 @@ func init() { } } + if args.Index >= 0 { + params.Add(jsonutils.NewInt(args.Index), "index") + } var result *modules.ListResult var err error if len(args.Server) > 0 { result, err = modules.Serverdisks.ListDescendent(s, args.Server, params) + } else if len(args.Disk) > 0 { + result, err = modules.Serverdisks.ListDescendent2(s, args.Disk, params) } else { result, err = modules.Serverdisks.List(s, params) } diff --git a/pkg/compute/models/guestdisks.go b/pkg/compute/models/guestdisks.go index 26e0c74c0c..a5834f258f 100644 --- a/pkg/compute/models/guestdisks.go +++ b/pkg/compute/models/guestdisks.go @@ -78,6 +78,7 @@ func (self *SGuestdisk) getExtraInfo(extra *jsonutils.JSONDict) *jsonutils.JSOND disk := self.GetDisk() extra.Add(jsonutils.NewInt(int64(disk.DiskSize)), "disk_size") extra.Add(jsonutils.NewString(disk.Status), "status") + extra.Add(jsonutils.NewString(disk.DiskType), "disk_type") return extra } diff --git a/pkg/mcclient/modules/mod_serverdisks.go b/pkg/mcclient/modules/mod_serverdisks.go index a43594c29a..cab81ea442 100644 --- a/pkg/mcclient/modules/mod_serverdisks.go +++ b/pkg/mcclient/modules/mod_serverdisks.go @@ -10,7 +10,7 @@ func init() { "guestdisks", []string{"Guest_ID", "Guest", "Disk_ID", "Disk", "Disk_size", - "Driver", "Cache_mode", "Index", "Status"}, + "Driver", "Cache_mode", "Index", "Status", "Disk_type"}, []string{}, &Servers, &Disks) From fc5b3e68dbeaa653cd394926fb5fe40ce96b37da Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Sat, 15 Sep 2018 18:12:20 +0800 Subject: [PATCH 3/4] minior fixes --- pkg/compute/models/guests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 5188a338c0..8bad2b8134 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -2924,7 +2924,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T addDisk += diskConf.Size storage := host.GetLeastUsedStorage(diskConf.Backend) if storage == nil { - + return nil, httperrors.NewResourceNotReadyError("host not connect storage %s", diskConf.Backend) } _, ok := diskSizes[storage.Id] if !ok { From e460919cbe404a9cda851eabadb96cc8575fa524 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Sat, 15 Sep 2018 19:44:48 +0800 Subject: [PATCH 4/4] minor fixes --- pkg/util/seclib2/seclib.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/util/seclib2/seclib.go b/pkg/util/seclib2/seclib.go index ef1c0bb3cc..017cc307aa 100644 --- a/pkg/util/seclib2/seclib.go +++ b/pkg/util/seclib2/seclib.go @@ -16,7 +16,7 @@ const ( ALL_DIGITS = "0123456789" ALL_LETTERS = "abcdefghijklmnopqrstuvwxyz" ALL_UPPERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - ALL_PUNC = "~`!@#$%^&*()-_=+[]{}|:':\",./<>?" + ALL_PUNC = "~`!@#$%^&*()-_=+[]{}|:';\",./<>?" ) type PasswordStrength struct {