Add version to avoid conflicting writes.

This commit is contained in:
cuigh 2017-12-04 15:31:49 +08:00
parent ec3796d339
commit aaec9d54df
10 changed files with 23 additions and 14 deletions

View File

@ -60,7 +60,7 @@ func ConfigUpdate(info *model.ConfigUpdateInfo) error {
//spec.Name = info.Name //spec.Name = info.Name
//spec.Data = []byte(info.Data) //spec.Data = []byte(info.Data)
spec.Labels = info.Labels.ToMap() spec.Labels = info.Labels.ToMap()
return cli.ConfigUpdate(ctx, info.ID, cfg.Version, spec) return cli.ConfigUpdate(ctx, info.ID, version(info.Version), spec)
}) })
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/cuigh/auxo/log" "github.com/cuigh/auxo/log"
"github.com/cuigh/swirl/misc" "github.com/cuigh/swirl/misc"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
@ -61,3 +62,7 @@ func (m *manager) Logger() *log.Logger {
} }
return m.logger return m.logger
} }
func version(v uint64) swarm.Version {
return swarm.Version{Index: v}
}

View File

@ -64,15 +64,12 @@ func NodeInspect(id string) (node swarm.Node, raw []byte, err error) {
// NodeUpdate update a node. // NodeUpdate update a node.
func NodeUpdate(id string, info *model.NodeUpdateInfo) error { func NodeUpdate(id string, info *model.NodeUpdateInfo) error {
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
version := swarm.Version{
Index: info.Version,
}
spec := swarm.NodeSpec{ spec := swarm.NodeSpec{
Role: info.Role, Role: info.Role,
Availability: info.Availability, Availability: info.Availability,
} }
spec.Name = info.Name spec.Name = info.Name
spec.Labels = info.Labels.ToMap() spec.Labels = info.Labels.ToMap()
return cli.NodeUpdate(ctx, id, version, spec) return cli.NodeUpdate(ctx, id, version(info.Version), spec)
}) })
} }

View File

@ -60,7 +60,7 @@ func SecretUpdate(info *model.ConfigUpdateInfo) error {
//spec.Name = info.Name //spec.Name = info.Name
//spec.Data = []byte(info.Data) //spec.Data = []byte(info.Data)
spec.Labels = info.Labels.ToMap() spec.Labels = info.Labels.ToMap()
return cli.SecretUpdate(ctx, info.ID, secret.Version, spec) return cli.SecretUpdate(ctx, info.ID, version(info.Version), spec)
}) })
} }

View File

@ -308,7 +308,7 @@ func ServiceUpdate(info *model.ServiceInfo) error {
RegistryAuthFrom: types.RegistryAuthFromSpec, RegistryAuthFrom: types.RegistryAuthFromSpec,
QueryRegistry: false, QueryRegistry: false,
} }
resp, err := cli.ServiceUpdate(context.Background(), info.Name, service.Version, spec, options) resp, err := cli.ServiceUpdate(context.Background(), info.Name, version(info.Version), spec, options)
if err == nil && len(resp.Warnings) > 0 { if err == nil && len(resp.Warnings) > 0 {
mgr.Logger().Warnf("service %s was updated but got warnings: %v", info.Name, resp.Warnings) mgr.Logger().Warnf("service %s was updated but got warnings: %v", info.Name, resp.Warnings)
} }
@ -720,6 +720,7 @@ func ServiceRollback(name string) error {
options := types.ServiceUpdateOptions{ options := types.ServiceUpdateOptions{
RegistryAuthFrom: types.RegistryAuthFromPreviousSpec, RegistryAuthFrom: types.RegistryAuthFromPreviousSpec,
QueryRegistry: false, QueryRegistry: false,
Rollback: "previous",
} }
resp, err := cli.ServiceUpdate(context.Background(), name, service.Version, spec, options) resp, err := cli.ServiceUpdate(context.Background(), name, service.Version, spec, options)
if err == nil && len(resp.Warnings) > 0 { if err == nil && len(resp.Warnings) > 0 {

View File

@ -9,7 +9,7 @@ import (
"github.com/cuigh/auxo/errors" "github.com/cuigh/auxo/errors"
"github.com/cuigh/auxo/log" "github.com/cuigh/auxo/log"
"github.com/cuigh/auxo/net/web" "github.com/cuigh/auxo/net/web"
"github.com/cuigh/auxo/security/password" "github.com/cuigh/auxo/security/passwd"
"github.com/cuigh/swirl/dao" "github.com/cuigh/swirl/dao"
"github.com/cuigh/swirl/misc" "github.com/cuigh/swirl/misc"
"github.com/cuigh/swirl/model" "github.com/cuigh/swirl/model"
@ -43,7 +43,7 @@ func (b *userBiz) Create(user *model.User, ctxUser web.User) (err error) {
user.CreatedAt = time.Now() user.CreatedAt = time.Now()
user.UpdatedAt = user.CreatedAt user.UpdatedAt = user.CreatedAt
if user.Type == model.UserTypeInternal { if user.Type == model.UserTypeInternal {
user.Password, user.Salt, err = password.Generate(user.Password) user.Password, user.Salt, err = passwd.Generate(user.Password)
if err != nil { if err != nil {
return return
} }
@ -107,12 +107,12 @@ func (b *userBiz) UpdatePassword(id, oldPwd, newPwd string) (err error) {
return return
} }
if !password.Validate(oldPwd, user.Password, user.Salt) { if !passwd.Validate(oldPwd, user.Password, user.Salt) {
err = errors.New("Current password is incorrect") err = errors.New("Current password is incorrect")
return return
} }
pwd, salt, err = password.Generate(newPwd) pwd, salt, err = passwd.Generate(newPwd)
if err != nil { if err != nil {
return return
} }
@ -189,7 +189,7 @@ func (b *userBiz) Login(name, pwd string) (token string, err error) {
} }
func (b *userBiz) loginInternal(user *model.User, pwd string) error { func (b *userBiz) loginInternal(user *model.User, pwd string) error {
if !password.Validate(pwd, user.Password, user.Salt) { if !passwd.Validate(pwd, user.Password, user.Salt) {
return ErrIncorrectAuth return ErrIncorrectAuth
} }
return nil return nil

View File

@ -163,6 +163,7 @@ func NewServiceDetailInfo(service swarm.Service) *ServiceDetailInfo {
type ServiceInfo struct { type ServiceInfo struct {
Name string `json:"name"` Name string `json:"name"`
Version uint64 `json:"version"`
Registry string `json:"registry"` Registry string `json:"registry"`
RegistryURL string `json:"-"` RegistryURL string `json:"-"`
RegistryAuth string `json:"-"` RegistryAuth string `json:"-"`
@ -236,7 +237,8 @@ type ServiceInfo struct {
func NewServiceInfo(service swarm.Service) *ServiceInfo { func NewServiceInfo(service swarm.Service) *ServiceInfo {
spec := service.Spec spec := service.Spec
si := &ServiceInfo{ si := &ServiceInfo{
Name: spec.Name, Name: spec.Name,
Version: service.Version.Index,
//Hostname: spec.TaskTemplate.ContainerSpec.Hostname, //Hostname: spec.TaskTemplate.ContainerSpec.Hostname,
Image: spec.TaskTemplate.ContainerSpec.Image, Image: spec.TaskTemplate.ContainerSpec.Image,
Command: strings.Join(spec.TaskTemplate.ContainerSpec.Command, " "), Command: strings.Join(spec.TaskTemplate.ContainerSpec.Command, " "),
@ -549,7 +551,8 @@ type ConfigCreateInfo struct {
} }
type ConfigUpdateInfo struct { type ConfigUpdateInfo struct {
ID string `json:"id"` ID string `json:"id"`
Version uint64 `json:"version"`
ConfigCreateInfo ConfigCreateInfo
} }

View File

@ -48,6 +48,7 @@
<div class="container"> <div class="container">
<form method="post" action="update" data-form="ajax-json" data-form="ajax-json" data-url="/config/"> <form method="post" action="update" data-form="ajax-json" data-form="ajax-json" data-url="/config/">
<input name="id" value="{{ .Config.ID }}" type="hidden"> <input name="id" value="{{ .Config.ID }}" type="hidden">
<input name="version" value="{{ .Config.Version.Index }}" data-type="integer" type="hidden">
{*<div class="field">*} {*<div class="field">*}
{*<label class="label">Data</label>*} {*<label class="label">Data</label>*}
{*<div class="control">*} {*<div class="control">*}

View File

@ -48,6 +48,7 @@
<div class="container"> <div class="container">
<form method="post" action="update" data-form="ajax-json" data-form="ajax-json" data-url="/secret/"> <form method="post" action="update" data-form="ajax-json" data-form="ajax-json" data-url="/secret/">
<input name="id" value="{{ .Secret.ID }}" type="hidden"> <input name="id" value="{{ .Secret.ID }}" type="hidden">
<input name="version" value="{{ .Secret.Version.Index }}" data-type="integer" type="hidden">
<div class="field"> <div class="field">
<label class="label">Labels</label> <label class="label">Labels</label>
{{ yield options(name="label", items=.Secret.Spec.Labels) }} {{ yield options(name="label", items=.Secret.Spec.Labels) }}

View File

@ -36,6 +36,7 @@
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<form method="post" data-form="ajax-json" data-url="/service/"> <form method="post" data-form="ajax-json" data-url="/service/">
<input name="version" value="{{ .Service.Version }}" type="hidden" data-type="integer">
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">